Was wondering if someone would like to share an simple code to send 3 different int variabels when some of the 3 int variabels have changed.
I have attached the code from Robin2´s guide, that code works fine with my hardware.
I use NRF24 as reciever and transmitter.
Best Regards
Andreas
// SimpleTx - the master or the transmitter
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define CE_PIN 9
#define CSN_PIN 10
const byte slaveAddress[5] = {'R','x','A','A','A'};
RF24 radio(CE_PIN, CSN_PIN); // Create a Radio
char dataToSend[10] = "Message 0";
char txNum = '0';
unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 1000; // send once per second
void setup() {
Serial.begin(9600);
Serial.println("SimpleTx Starting");
radio.begin();
radio.setDataRate( RF24_250KBPS );
radio.setRetries(3,5); // delay, count
radio.openWritingPipe(slaveAddress);
}
//====================
void loop() {
currentMillis = millis();
if (currentMillis - prevMillis >= txIntervalMillis) {
send();
prevMillis = millis();
}
}
//====================
void send() {
bool rslt;
rslt = radio.write( &dataToSend, sizeof(dataToSend) );
// Always use sizeof() as it gives the size as the number of bytes.
// For example if dataToSend was an int sizeof() would correctly return 2
Serial.print("Data Sent ");
Serial.print(dataToSend);
if (rslt) {
Serial.println(" Acknowledge received");
updateMessage();
}
else {
Serial.println(" Tx failed");
}
}
//================
void updateMessage() {
// so you can see that new data is being sent
txNum += 1;
if (txNum > '9') {
txNum = '0';
}
dataToSend[8] = txNum;
}
// SimpleRx - the slave or the receiver
#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);
char dataReceived[10]; // this must match dataToSend in the TX
bool newData = false;
//===========
void setup() {
Serial.begin(9600);
Serial.println("SimpleRx Starting");
radio.begin();
radio.setDataRate( RF24_250KBPS );
radio.openReadingPipe(1, thisSlaveAddress);
radio.startListening();
}
//=============
void loop() {
getData();
showData();
}
//==============
void getData() {
if ( radio.available() ) {
radio.read( &dataReceived, sizeof(dataReceived) );
newData = true;
}
}
void showData() {
if (newData == true) {
Serial.print("Data received ");
Serial.println(dataReceived);
newData = false;
}
}
Thank you for the quick answer.
I tried to add some values in to " dataToSend" but something is not right. The original code works and updates the value on the reciever but not value1, value2, value3. Best Regards
TX
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
// Nano oldbootloader
#define CE_PIN 7
#define CSN_PIN 8
const byte slaveAddress[5] = {'R','x','A','A','A'};
RF24 radio(CE_PIN, CSN_PIN); // Create a Radio
char dataToSend[10] = "Message 0";
char txNum = '0';
int value1 = 10;
int value2 = 11;
int value3 = 12;
unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 1000; // send once per second
void setup() {
Serial.begin(9600);
Serial.println("SimpleTx Starting");
radio.begin();
radio.setDataRate( RF24_250KBPS );
radio.setRetries(3,5); // delay, count
radio.openWritingPipe(slaveAddress);
}
//====================
void loop() {
currentMillis = millis();
if (currentMillis - prevMillis >= txIntervalMillis) {
send();
prevMillis = millis();
}
}
//====================
void send() {
bool rslt;
rslt = radio.write( &dataToSend, sizeof(dataToSend) );
rslt = radio.write( &dataToSend, sizeof(value1) );
rslt = radio.write( &dataToSend, sizeof(value2) );
rslt = radio.write( &dataToSend, sizeof(value3) );
// Always use sizeof() as it gives the size as the number of bytes.
// For example if dataToSend was an int sizeof() would correctly return 2
Serial.print("Data Sent ");
Serial.print(dataToSend);
if (rslt) {
Serial.println(" Acknowledge received");
updateMessage();
}
else {
Serial.println(" Tx failed");
}
}
//================
void updateMessage() {
// so you can see that new data is being sent
txNum += 1;
if (txNum > '9') {
txNum = '0';
}
dataToSend[8] = txNum;
}
RX
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
// UNO
#define CE_PIN 9
#define CSN_PIN 10
const byte thisSlaveAddress[5] = {'R','x','A','A','A'};
RF24 radio(CE_PIN, CSN_PIN);
char dataReceived[10]; // this must match dataToSend in the TX
bool newData = false;
int value1;
int value2;
int value3;
//===========
void setup() {
Serial.begin(9600);
Serial.println("SimpleRx Starting");
radio.begin();
radio.setDataRate( RF24_250KBPS );
radio.openReadingPipe(1, thisSlaveAddress);
radio.startListening();
}
//=============
void loop() {
getData();
showData();
}
//==============
void getData() {
if ( radio.available() ) {
radio.read( &dataReceived, sizeof(dataReceived) );
radio.read( &dataReceived, sizeof(value1) );
radio.read( &dataReceived, sizeof(value2) );
radio.read( &dataReceived, sizeof(value3) );
newData = true;
}
}
void showData() {
if (newData == true) {
Serial.print("Data received ");
Serial.print(dataReceived);
Serial.print(value1);
Serial.print(value2);
Serial.println(value3);
newData = false;
}
}
You should populate your dataToSend buffer with ALL the data you need to send in one go - within the constraints of the hardware - max 32 bytes I think.
If you send each piece of data individually, you will end up with synchronisation issues between the Tx and the Rx.
Follow the advice in post #2 regarding sprintf or snprintf to send your data as ASCII text.
If you want/need to send/receive binary data, then there are examples of sending a struct. That way you don't need to handle the conversion to/from ASCII chars. However, there are issues (which are easily solvable) if the sender and receiver use different processors, such as AVR to ARM.
this is what was suggested.
your dataToSend[] is too small, only 10 bytes. so s[] was used. and strlen() is used to determine the # of characters in the s[] buffer, not the total size of s[]
That will cause problems as NRF24 packets are limited to 32 data bytes.
Plus converting all the numerical data to a c-string simply makes for extra work on both the TX and RX ends. The transmission is packetized. So the simplest thing to do is pack the data into a struct and send the whole thing at once (up to 32 bytes). At the RX end you simply receive the same size struct and pull out your values.
In another thread I suggested replacing snprintf() with dtostrf() and demonstrated for printing formatted floats, but I wonder if it is not a valid method (not for all compilers, et c).
apparently the OP didn't understand the suggestion in post #2 and i tried to explain it more clearly. the OP's code did separate writes and reads, suggesting he didn't understand the concept of a message containing multiple data.
seems like a single c-string msg was a good place to start before optimizing the message format
you seem to try to get a code that does what you want right out of the box without learning.
The latest code not
check if one out of 3 int-variables has changed and then send all three values
it does not even send 3 int values
The usual way of help in this forum is:
asking an initial question. If the question is very general you get generalised answers. It is very unusual to get a ready to use code.
You won't get ready to use code even if you ask 50 times.
If something is unclear you have to to do two things:
making an attempt how it might work. It doesn't matter if your attempt not even compiles.The important thing is to have made an own attempt.
ask for what the error-message means or how to modify your attempt to make a certain detail work.
In this way you learn from it.
Your attempt was
You did not yet understand how the command write works:
the first parameter &dataToSend must contain the data
hence the variable name that says exactly that dataToSend
the second parameter specifies how many bytes shall be transmitted
with comments what your code does
rslt = radio.write( &dataToSend, sizeof(dataToSend) ); // send content of variable with name "dataToSend" with "X" bytes. Where "X" is the number of bytes that variable "dataToSend" occupies in RAM
rslt = radio.write( &dataToSend, sizeof(value1) ); // send content of variable with name "dataToSend" with "X" bytes. Where "X" is the number of bytes that variable "**value1**" occupies in RAM
This means still the same data that is stored in variable "dataToSend" will be send but only a part of
all data. The number of bytes beeing send is the number of bytes the variable value1 occupies in RAM.
rslt = radio.write( &dataToSend, sizeof(value2) );
rslt = radio.write( &dataToSend, sizeof(value3) );
The way to go is:
store your value1 in variable dataToSend
append your value2 in variable dataToSend after value1
append your value3 in variable dataToSend after value2
then send variable "dataToSend"
This is the basic principle.
If you know nothing yet about different variable-types
and if you don't know nothing yet about "struct" you completely dependant on somebody else to write readyto use code which will not happen.
Because you would stay dependant without learning some basics and with each modification of the code you would have to beg other for again writing the ready to use code
The ususal way is:
showing some own effort and asking a question
getting an answer
showing some own effort in proceeding at least a small step
and asking a question
showing some own effort in proceeding at least a small step
and asking a question
showing some own effort in proceeding at least a small step
and asking a question
...
best regards Stefan