DAMI-M3 Software – base station v1

dami_nrf24l01_rxbase_v1

 

//
// DAMI nRF24L01 RX base station
//
// fixed station that collect real time data from robot
// using the nRF24L01 2.4GHz transciver
//
// it provides output to display on serial monitor
// or to use in a processing3 sketch for map display
//
// based on SimpleRxAckPayload - the slave or the receiver
// http://forum.arduino.cc/index.php?topic=421081
//

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

#define CE_PIN 9
#define CSN_PIN 10

const byte thisSlaveAddress[5] = {'R','x','A','A','A'};

RF24 radio(CE_PIN, CSN_PIN);

int ackData[8] = {109, -4000, 1 , 2 , 3, 6, 7 }; // the two values to be sent to the master
bool newData = false;


char dataReceived[32]; // this must match dataToSend in the TX

union u_tag {
byte b[4];
int i[2];
long l;
double d;
} rf_data[8];


byte cmdCode = 0;

//==============

void setup() {
Serial.begin(115200);
//Serial.println("DAMI nRF24L01 RX base station starting...");
radio.begin();
radio.setDataRate( RF24_250KBPS );
radio.openReadingPipe(1, thisSlaveAddress);
radio.enableAckPayload();
radio.writeAckPayload(1, &ackData, sizeof(ackData)); // pre-load data
radio.startListening();
}

//==========

void loop() {
// get remote robot data
getRadioData();

// get serial data
getSerialData();

// show remote robot data
showData();
}

//============

void getRadioData() {
if ( radio.available() ) {
radio.read( &dataReceived, sizeof(dataReceived) );
updateReplyData();
newData = true;
}
}

//============

void getSerialData() {
// if there's any serial available, read it:
while (Serial.available() > 0) {
// look for the next valid integer in the incoming serial stream:
byte tmp = Serial.parseInt();
if (Serial.read() == '\n') {
cmdCode = tmp;
}
}
}

//============

void showData() {

int i;
if (newData == true) {
// manage received radio data
for(i=0; i < 8; i++) {
rf_data[i].b[0] = dataReceived[i*4 + 0];
rf_data[i].b[1] = dataReceived[i*4 + 1];
rf_data[i].b[2] = dataReceived[i*4 + 2];
rf_data[i].b[3] = dataReceived[i*4 + 3];
}

// select the output for data
switch(cmdCode) {
case 0:
showData4ProcessingMap();
break;
case 1:
showData4ProcessingMap();
break;
case 10:
showData4SerialMonitor();
break;
}

// reset flag
newData = false;
}
}

void showData4SerialMonitor() {

Serial.print("D0 ");
Serial.print(rf_data[0].b[0]); Serial.print(" "); // prgIdx
Serial.print(rf_data[0].b[1]); Serial.print(" "); // cmd
Serial.print(rf_data[0].b[2]); Serial.print(" "); // prgCmd[prgIdx].intCmd
Serial.print(rf_data[0].b[3]); Serial.print(" "); // internalCmdProcessStatus
Serial.print(rf_data[1].b[0]); Serial.print(" "); // prgCmd[prgIdx].extCmd
Serial.print(rf_data[1].b[1]); Serial.print(" "); // bodyMoveProcessStatus
Serial.print(rf_data[1].b[2]); Serial.print(" "); // slaveCmdRequestId
Serial.print(rf_data[1].b[3]); Serial.print(" "); // slaveCmdWaitingId
Serial.print(rf_data[2].i[0]); Serial.print(" "); // bodyFrontLaserRead
Serial.print(rf_data[2].i[1]); Serial.print(" "); // bodyFrontLaserDistance
Serial.print(rf_data[3].i[0]); Serial.print(" "); // bodySonarDistance[0]
Serial.print(rf_data[3].i[1]); Serial.print(" "); // bodySonarDistance[1]

Serial.print(rf_data[4].d); Serial.print(" "); // bodyThetaRadians * 180 / PI
Serial.print(rf_data[5].d); Serial.print(" "); // bodyPosX
Serial.print(rf_data[6].d); Serial.print(" "); // bodyPosY
Serial.print(rf_data[7].b[0]); Serial.print(" "); // loopTime

//Serial.print(dataReceived);
Serial.print(" ackPayload sent ");
Serial.print(ackData[0]);
Serial.print(", ");
Serial.println(ackData[1]);

}

void showData4ProcessingMap() {

float bodyThetaRadians;

Serial.print(0); Serial.print(" ");
Serial.print(rf_data[5].d); Serial.print(" "); // bodyPosX
Serial.print(rf_data[6].d); Serial.print(" "); // bodyPosY
Serial.print(rf_data[4].d); Serial.print(" "); // bodyThetaRadians * 180 / PI

bodyThetaRadians = rf_data[4].d / 180 * PI;

Serial.print(getPointXpos(rf_data[2].i[1], 0, bodyThetaRadians)); Serial.print("\t"); // bodyFrontLaserDistance X
Serial.print(getPointYpos(rf_data[2].i[1], 0, bodyThetaRadians)); Serial.print("\t"); // bodyFrontLaserDistance Y

Serial.print(getPointXpos(rf_data[3].i[0], 90, bodyThetaRadians)); Serial.print("\t"); // bodySonarDistance[0] X
Serial.print(getPointYpos(rf_data[3].i[0], 90, bodyThetaRadians)); Serial.print("\t"); // bodySonarDistance[0] Y

Serial.print(getPointXpos(rf_data[3].i[1], -90, bodyThetaRadians)); Serial.print("\t"); // bodySonarDistance[1] X
Serial.print(getPointYpos(rf_data[3].i[1], -90, bodyThetaRadians)); Serial.print("\t"); // bodySonarDistance[1] Y

Serial.print(rf_data[2].i[1]); Serial.print(" "); // bodyFrontLaserDistance
Serial.print(rf_data[3].i[0]); Serial.print(" "); // bodySonarDistance[0]
Serial.print(rf_data[3].i[1]); Serial.print(" "); // bodySonarDistance[1]

Serial.print(rf_data[0].b[0]); Serial.print(" "); // prgIdx
Serial.print(rf_data[0].b[1]); Serial.print(" "); // cmd
Serial.print(rf_data[0].b[2]); Serial.print(" "); // prgCmd[prgIdx].intCmd
Serial.print(rf_data[0].b[3]); Serial.print(" "); // internalCmdProcessStatus
Serial.print(rf_data[1].b[0]); Serial.print(" "); // prgCmd[prgIdx].extCmd
Serial.print(rf_data[1].b[1]); Serial.print(" "); // bodyMoveProcessStatus

Serial.println("");

}

//================

// coordinates based on polar coordinates and pose
// point distante, point angle and robot orientation
float getPointXpos(int d, float a, float t) {
float b = t + (float)(a / 180.0) * PI;
return d * cos(b);
}

float getPointYpos(int d, float a, float t) {
float b = t + (float)(a / 180.0) * PI;
return d * sin(b);
}


//
// TODO: updateReplyData()
//
void updateReplyData() {
ackData[0] -= 1;
ackData[1] -= 1;
if (ackData[0] < 100) {
ackData[0] = 109;
}
if (ackData[1] < -4009) {
ackData[1] = -4000;
}
radio.writeAckPayload(1, &ackData, sizeof(ackData)); // load the payload for the next time
}