APM / Pixhawk telemetry using nRF24L01P and arduino mega2560

Hi guys
i'm trying to make a telemetry for apm using two nRF24L01P and two arduino mega2560(because of tree serial inputs). i made two sketches one for receiver and the other one for transmitter. the telemetry port of APM has RX and TX pins, at first i connect the RX pin of APM to TX1 pin(pin 18) on arduino mega2560, TX pin of APM to RX1 pin(pin 17) on arduino then i wrote some easy sketch like below and it works mission planner connected to APM using arduino without any problem.

void setup() {
// initialize both serial ports:
Serial.begin(115200);
Serial1.begin(115200);
}

void loop() {
// read from APM , send it to arduino serial:
while (Serial1.available()) {
uint8_t inByte = Serial1.read(); // it works with char and byte also
Serial.write(inByte);

}

// read from arduino serial, send it to APM:
while (Serial.available()) {
uint8_t inByte1 = Serial.read(); // it works with char and byte also
Serial1.write(inByte1);

}
}

it is working well with mega2560 i try this with arduino nano (but different code) it works fine but slow cuase of that i had to use mega2560 and thats fine by me.

so with this idea i'm trying to use nRF24L01p to communicate with each other , but it seems to have a problem sometimes it connects and sends data BUT it seems that there is a problem in communication because APM sends data again and again like there is not ack or some data losts.

Transmitter code:

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

const int CE_pin = 7;
const int CSN_pin = 8;

RF24 radio(CE_pin, CSN_pin);

const byte rxAddr[][6] = {"Miki1" , "Miki2" };
const int led_pin = 46;
const int led_pin1 = 47;
const int led_pin2 = 13;
bool radio_state = 1;

void setup()
{
SPI.begin();
pinMode(led_pin,OUTPUT);
pinMode(led_pin1,OUTPUT);
pinMode(led_pin2,OUTPUT);
digitalWrite(led_pin,LOW);
digitalWrite(led_pin1,LOW);
digitalWrite(led_pin2,LOW);

Serial.begin(115200);
Serial1.begin(115200);

radio.begin();
//radio.enableDynamicPayloads();
//radio.enableDynamicAck();
//radio.enableAckPayload();
//radio.setPayloadSize(128);
radio.setChannel(123);
radio.setDataRate(RF24_2MBPS);
radio.setPALevel(RF24_PA_MAX);
//radio.openReadingPipe(1, rxAddr[0]);
//radio.openWritingPipe(rxAddr[1]);
//radio.setRetries(0, 15);
//radio.startListening();
radio.stopListening();

}

void loop()
{
digitalWrite(led_pin,LOW);
digitalWrite(led_pin1,LOW);

if(!radio_state){
radio.openReadingPipe(1, rxAddr[0]);
radio.startListening();

while (radio.available() ){

digitalWrite(led_pin,HIGH);
byte inByte1;
radio.read(&inByte1,sizeof(inByte1));
Serial1.write(inByte1);}
delay(5);
radio_state = !radio_state;}

if(radio_state){
radio.openWritingPipe(rxAddr[1]);
radio.stopListening();

while (Serial1.available() ) {
digitalWrite(led_pin1,HIGH);
byte inByte= Serial1.read();
radio.write(&inByte,sizeof(inByte));}
radio_state = !radio_state;}

}

Receiver Code :

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

const int CE_pin = 7;
const int CSN_pin = 8;

RF24 radio(CE_pin, CSN_pin);

const byte rxAddr[][6] = {"Miki1" , "Miki2" };
//const int led_pin = 2;
//const int led_pin1 = 3;
const int led_pin = 46;
const int led_pin1 = 47;
const int led_pin2 = 13;
bool radio_state = 0;

void setup()
{
SPI.begin();
pinMode(led_pin,OUTPUT);
pinMode(led_pin1,OUTPUT);
pinMode(led_pin2,OUTPUT);
digitalWrite(led_pin,LOW);
digitalWrite(led_pin1,LOW);
digitalWrite(led_pin2,LOW);

Serial.begin(115200);

radio.begin();
//radio.enableDynamicPayloads();
//radio.enableDynamicAck();
//radio.enableAckPayload();
//radio.setPayloadSize(128);
radio.setChannel(123);
radio.setDataRate(RF24_250KBPS);
radio.setPALevel(RF24_PA_MAX);
//radio.openReadingPipe(1, rxAddr[1]);
//radio.openWritingPipe(rxAddr[0]);
//radio.setRetries(0, 15);
radio.startListening();

}

void loop()
{
digitalWrite(led_pin,LOW);
digitalWrite(led_pin1,LOW);

if(!radio_state){
radio.openReadingPipe(0, rxAddr[1]);
radio.startListening();
while (radio.available() ){
digitalWrite(led_pin,HIGH);
byte inByte1;
radio.read(&inByte1,sizeof(inByte1));
Serial.write(inByte1);}
delay(5);
radio_state = !radio_state;}

if(radio_state){
radio.openWritingPipe(rxAddr[0]);
radio.stopListening();
while (Serial.available()) {
digitalWrite(led_pin1,HIGH);
byte inByte = Serial.read();
radio.write(&inByte,sizeof(inByte));}
radio_state = !radio_state; }

}

Dont mind the led pins i put them to check where the data flows or not.

if anyone did this please help me or point me to the problem in my code, i will appreciate it.
thanks

1 Like

I see a couple of issues. Getting data from the serial port should be COMPLETELY independent of the mode that the radio is in. When there is data to send, you need to put the radio in talk mode, and send the data, then put the radio back in listen mode.

You need to sh*tcan the delay()s.

When I reply to your post, do you read one letter, close your eyes for a while, then read another letter, and close your eyes again?

Of course not. You read as long as there is something to read. So, in listen mode, you should have NO delay()s.

99.9% of the times that loop() iterates, where will be no data from the radio to receive.

You do NOT want to switch to talk mode just because you received something from the radio. You switch to talk mode because you have something to say. You have something to say because there is serial data to read.