I made these codes to send parameters from a computer to an arduino over wireless, using two nrf24 module. It works as follow:
Parameters are entered in a Python terminal then sent to an Arduino "Bridge" (through serial, then repeated over RF). Finally they are received by the Arduino "Controller", which send a feedback to the Bridge.
So, the parameters are first validated in python, then validated again in the controller, and the controller sends a feedback (either LISTENING, TIMEOUT or SUCCESS)
For exemple; in the Bridge serial I enter these 3 commands
PROFIL;2 (2 indicate that two parameters will follow)
(feedback: LISTENING)
1;2 (parameter 1)
3;4 (parameter 2)
(feedback: SUCCESS)
Overall it works fine, but the feedback are out of sync. Often they are not received immediatly, and seems to be stuck in some kind of buffer. So as soon as a new packet is sent, the queued one is received, as if it would be pushed out of a buffer. I looked at the Radiohead API for nRF24 module but I'm still clueless about why this is happenning. So there is the code;
Bridge code (repeater):
#include <SPI.h>
#include <RH_NRF24.h>
RH_NRF24 nrf24;
const unsigned long timeoutInterval = 30*1000L;
unsigned long previousTimeoutInterval;
uint8_t rf_data[11];
int profil[10][2];
char c;
char serial_data[11];
int n;
int i;
void setup() {
delay(1000);
Serial.begin(9600);
Serial.setTimeout(150);
Serial.println("BRIDGE");
if (!nrf24.init()) Serial.println("init failed");
if (!nrf24.setChannel(1)) Serial.println("setChannel failed");
if (!nrf24.setRF(RH_NRF24::DataRate2Mbps, RH_NRF24::TransmitPower0dBm)) Serial.println("setRF failed");
}
void loop() {
serial_listen();
rf_listen();
}
void serial_listen() {
if (Serial.available())
{
while (Serial.available() > 0) { //Read string
c = Serial.read();
while (c != '\n')
{
if (c != (char)-1)
{
serial_data[i] = c;
i++;
}
c = Serial.read();
}
}
strcpy((char*)rf_data, serial_data);
rf_query(); //Repeat string to controller
memset(serial_data, 0, sizeof serial_data);
i = 0;
}
}
void rf_query() {
delay(200);
nrf24.send(rf_data, sizeof(rf_data));
nrf24.waitPacketSent();
Serial.print("sent: "); Serial.println((char*)rf_data);
}
void rf_listen() {
if (nrf24.available())
{
uint8_t buf[RH_NRF24_MAX_MESSAGE_LEN];
uint8_t len = sizeof(buf);
if (nrf24.recv(buf, &len))
{
Serial.print("got: "); Serial.println((char*)buf);
if (!strcmp((char*)buf, "LISTENING")) { Serial.println("Controller: LISTENING"); }
else if (!strcmp((char*)buf, "TIMEOUT")) { Serial.println("Controller: TIMEOUT"); }
else if (!strcmp((char*)buf, "SUCCESS")) { Serial.println("Controller: SUCCESS"); }
else
{
//Get temperature from controller
}
}
}
}
Controller code (receiver)
#include <SPI.h>
#include <RH_NRF24.h>
RH_NRF24 nrf24;
uint8_t data[11];
int n; int i; int j; int arguments; int buffer;
byte saveArguments;
int profil[10][2];
char* param;
const unsigned long timeoutInterval = 10*1000L;
unsigned long previousTimeoutInterval;
byte timeout;
void setup()
{
delay(1000);
Serial.begin(9600);
Serial.setTimeout(150);
Serial.println("CONTROLLER");
if (!nrf24.init()) Serial.println("nrf24: init failed");
if (!nrf24.setChannel(1)) Serial.println("nrf24: setChannel failed");
if (!nrf24.setRF(RH_NRF24::DataRate2Mbps, RH_NRF24::TransmitPower0dBm)) Serial.println("nrf24: setRF failed");
}
void loop()
{
rf_listen();
}
void rf_query() {
delay(200);
nrf24.send(data, sizeof(data));
nrf24.waitPacketSent();
Serial.print("sent: "); Serial.println((char*)data);
}
void rf_sendString(int s) {
switch (s) {
case 0: strcpy((char*)data, "LISTENING"); break;
case 1: strcpy((char*)data, "TIMEOUT "); break;
case 2: strcpy((char*)data, "SUCCESS "); break;
}
rf_query();
}
void rf_listen() {
if ((timeout == true) && (millis() - previousTimeoutInterval >= timeoutInterval)) {
memset(profil, 0, sizeof(profil[0][0]) * 10 * 2);
i = j = arguments = 0;
rf_sendString(1); Serial.println("TIMEOUT");
timeout = false;
}
if (nrf24.available())
{
uint8_t buf[RH_NRF24_MAX_MESSAGE_LEN];
uint8_t len = sizeof(buf);
if (nrf24.recv(buf, &len))
{
Serial.print("got: "); Serial.println((char*)buf);
param = strtok((char*)buf, ";");
while(param != NULL) //explode(param,";")
{
if (!strcmp(param, "PROFIL"))
{
memset(profil, 0, sizeof(profil[0][0]) * 10 * 2);
previousTimeoutInterval = millis();
saveArguments = timeout = true;
rf_sendString(0); //Serial.println("LISTENING");
}
else if (saveArguments == true) {
arguments = atoi(param);
saveArguments = false;
}
else if ((arguments > 0) && (i < arguments)) //RF parameters -> 2D array
{
buffer = atoi(param);
if (j <= 1) {
if (j == 0 && buffer < 1) { buffer = 1; } //Parameter[i][0] = Time
profil[i][j] = buffer;
Serial.print("profil["); Serial.print(i); Serial.print("]["); Serial.print(j); Serial.print("] = "); Serial.println(buffer);
}
if (j == 1) { i++; j = 0; } else { j++; }
if (i == arguments) //Done entering array
{
i = j = arguments = 0;
timeout = false;
//tone(speakerPin,120,150); delay(200); tone(speakerPin,120,150);
rf_sendString(2); //Serial.println("SUCCESS");
}
}
param = strtok(NULL, ";"); //tells strtok to continue on the previous string
}
}
}
}