hello guys,
i am trying to learn how to make the nRF24L01, i managed to make an LED lights up by pressing a button but my goal is to make a real transceiver, sending and receiving on both side, which means having 2 arduinos and to each arduino there is an LED and a tactile button connected so if i press the tactile on the first, the LED of the second will lights up, and if i press the tactile of the second, the LED of the first will light up. I can't find any example on how to make this, so i tried some codes myself but not working so far, so i would like some guidance please on what should be done to make this happen ?
thanks in advance
here are my codes, same sketch for both arduinos :
#include <SPI.h>
#include <RF24.h>
RF24 radio(9,10);
uint64_t addresses[] = {0xABABABABABLL, 0xC3C3C3C3C3LL};
/****** Configure this for sender or receiver *****/
boolean sender = 0; // Change this from 0 to 1 to switch between sending or receiving sketch
int msgRX[1];
int msgTX[1];
int LED1 = 4;
int ledOnReceive = 0;
int switchPin = 7;
boolean lastButton = HIGH;
boolean currentButton = HIGH;
boolean ledOnTransmit = false;
void setup() {
pinMode(switchPin, INPUT_PULLUP);
pinMode(LED1, OUTPUT);
Serial.begin(9600);
radio.begin();
if(sender == 0){
radio.openWritingPipe(addresses[1]);
radio.openReadingPipe(1,addresses[0]);
radio.startListening();
}else{
radio.openWritingPipe(addresses[0]); //*Edit to correct address assignments
radio.openReadingPipe(1,addresses[1]);
radio.stopListening();
}
}
boolean debounce(boolean last)
{
boolean current = digitalRead(switchPin);
if(last != current)
{
delay(5);
current = digitalRead(switchPin);
}
return current;
}
void loop() {
if(sender == 0){
if(radio.available()){
radio.read(msgRX, sizeof(msgRX)); //sizeof(tmpArray) to give us the size of the array or we put the size number
Serial.println(msgRX[0]);
if (msgRX[0] == 111){
ledOnReceive = 0;
}else if(msgRX[0] == 000){
ledOnReceive = 1;
}
digitalWrite(LED1, ledOnReceive);
delay(10);
}
sender = 1;
}else{
currentButton = debounce(lastButton);
if(lastButton == HIGH && currentButton == LOW)
{
ledOnTransmit = !ledOnTransmit;
}
lastButton = currentButton;
if (ledOnTransmit == HIGH){
msgTX[0] = 111;
radio.write(msgTX, 1);
}else if (ledOnTransmit == LOW){
msgTX[0] = 000;
radio.write(msgTX, 1);
}
sender = 0;
}
}
If you use the writeAckPayload() function in Arduino B you will automatically get the data in Arduino A as part of the acknowledgement of the transmission from A to B. That means that there is no need for your code to swap between sending and listening.
If you have not got any communication working I recommend this tutorial to get you started.
Robin2:
If you have not got any communication working I recommend this tutorial to get you started.
...R
hello robin2, yes this is the tutorial i worked from the start and i took note but when i reached the example of the joystick i stopped because i first wanted to make a simple one which is just a LED and then come back to this example
Robin2:
If you use the writeAckPayload() function in Arduino B you will automatically get the data in Arduino A as part of the acknowledgement of the transmission from A to B. That means that there is no need for your code to swap between sending and listening.
you mean this function should be used in the main loop() after i transmit a message and want to start receiving ?
The acknowledge payload has to be loaded into the NRF before a packet is received,
because that data will be appended to the normal acknowledge.
Likewise it has to be reloaded after a reception because it was consumed.
Each waiting acknowledge payload is associated to a single rx-pipe,
there can be at most 3 of them waiting at a time.
Whandall:
The acknowledge payload has to be loaded into the NRF before a packet is received,
because that data will be appended to the normal acknowledge.
Likewise it has to be reloaded after a reception because it was consumed.
Each waiting ackknowledge payload is associated to a single rx-pipe,
there can be at most 3 of them waiting at a time.
ok but how would this receiver become a transmitter then ?
Whandall:
By using ack-payload the receiver transmits already (the previously posted data).
The switching to transmit mode and back to receive mode is handled by the NRF.
ah you mean receiving data by using " enableAckPayload() " would make a back and forth ?!
i am reading about these functions but i don't understand or they doesn't speak about that and no example about it !
it's really weird how every example out there is a one way communication, how can someone by this 2 ways com to use it as a 1 way com !
In simple terms, when an nRF24 is commanded to transmit some data it automatically expects an acknowledgment from the "receiver". If the receiver has previously been prepared with an ackPayload it will send that data as part of the acknowledgement process without any need for further intervention.
I am attaching the two programs I have developed for model railway control. You can consider the TrackControl program to be the transmitter and the HandController to be the receiver. I did it like this so that the TrackContoller could interact with several separate HandControllers. In this application the data sent by the TrackControl is irrelevant - it is the data returned in the acknowledgement that is important - basically the value from a potentiometer.
You can ignore the way I have dealt with the #include for the library and just use the normal way.
By the way, @Whandall was a great help to me when I was trying to figure things out.
Robin2:
In simple terms, when an nRF24 is commanded to transmit some data it automatically expects an acknowledgment from the "receiver". If the receiver has previously been prepared with an ackPayload it will send that data as part of the acknowledgement process without any need for further intervention.
I am attaching the two programs I have developed for model railway control. You can consider the TrackControl program to be the transmitter and the HandController to be the receiver. I did it like this so that the TrackContoller could interact with several separate HandControllers. In this application the data sent by the TrackControl is irrelevant - it is the data returned in the acknowledgement that is important - basically the value from a potentiometer.
You can ignore the way I have dealt with the #include for the library and just use the normal way.
By the, @Whandall was a great help to me when I was trying to figure things out.
...R
thanks for sharing Robin2, i am now reading the documentation again from the beginning
so if i have 2 arduinos with 1 tactile input button each and 1 LED each, all i have to do is 1 consider it as a transmitter and the other as a receiver and use the ackPayload so both they can act as TX and both act as RX ?
about the download, seems that i hit open by mistake and not download and now they disappeared, I can not download it anymore
Please note I made a small change to the attachments - perhaps while you were typing.
I deleted and re-uploaded them which may have caused your problem. If there continues to be a problem let me know.
all i have to do is 1 consider it as a transmitter and the other as a receiver and use the ackPayload so both they can act as TX and both act as RX ?
That is very loose language. It may be correct, or you may be assuming things I am not aware of.
With a transceiver you can listen for incoming packets whenever possible, switching to transmit
only if you've something to send. So long as both ends transmit rarely there are few collisions.
The built-in auto-acknowledge of that chip isn't mandatory, you can choose to manage all
packets yourself if you choose to and implement a different scheme, such as using timeslots
Robin2:
Please note I made a small change to the attachments - perhaps while you were typing.
I deleted and re-uploaded them which may have caused your problem. If there continues to be a problem let me know.
That is very loose language. It may be correct, or you may be assuming things I am not aware of.
...R
ok thanks Robin2, i will take a look and i am learning the documentation now and some C++ and after will get back
MarkT:
With a transceiver you can listen for incoming packets whenever possible, switching to transmit
only if you've something to send. So long as both ends transmit rarely there are few collisions.
The built-in auto-acknowledge of that chip isn't mandatory, you can choose to manage all
packets yourself if you choose to and implement a different scheme, such as using timeslots
yes but i still do not get what you exactly saying
i made an example of how to send from one part and receive on the other, and i understood how it works this way, but i can't understand how to make them do both each side !
hello everyone, i would like please to know something, is the address for the pipes arbitrary ? or it's already something constant that comes in the datasheet ?
You are basically free to use any address/quintuple, some seem to be 'better' than others.
7.3.1 Preamble
The preamble is a bit sequence used to synchronize the receivers demodulator to the incoming bit stream.
The preamble is one byte long and is either 01010101 or 10101010. If the first bit in the address is 1 the
preamble is automatically set to 10101010 and if the first bit is 0 the preamble is automatically set to
01010101. This is done to ensure there are enough transitions in the preamble to stabilize the receiver.
7.3.2 Address
This is the address for the receiver. An address ensures that the packet is detected and received by the
correct receiver, preventing accidental cross talk between multiple nRF24L01+ systems. You can configure
the address field width in the AW register to be 3, 4 or 5 bytes, see Table 28. on page 63.
Note: Addresses where the level shifts only one time (that is, 000FFFFFFF) can often be detected in
noise and can give a false detection, which may give a raised Packet Error Rate. Addresses
as a continuation of the preamble (hi-low toggling) also raises the Packet Error Rate.
Whandall:
You are basically free to use any address/quintuple, some seem to be 'better' than others.
7.3.1 Preamble
The preamble is a bit sequence used to synchronize the receivers demodulator to the incoming bit stream.
The preamble is one byte long and is either 01010101 or 10101010. If the first bit in the address is 1 the
preamble is automatically set to 10101010 and if the first bit is 0 the preamble is automatically set to
01010101. This is done to ensure there are enough transitions in the preamble to stabilize the receiver.
7.3.2 Address
This is the address for the receiver. An address ensures that the packet is detected and received by the
correct receiver, preventing accidental cross talk between multiple nRF24L01+ systems. You can configure
the address field width in the AW register to be 3, 4 or 5 bytes, see Table 28. on page 63.
Note: Addresses where the level shifts only one time (that is, 000FFFFFFF) can often be detected in
noise and can give a false detection, which may give a raised Packet Error Rate. Addresses
as a continuation of the preamble (hi-low toggling) also raises the Packet Error Rate.
thanks whandall for your reply,
i am reading the documentation of RF24 i feel better now and of course using the datasheet of the nRF24L01+ for understanding the concept, i just need to know something for now, is the beginTransaction () needed in the setup () or loop() necessary to make the SPI ? maybe my codes doesn't work because they miss this line ??