Remote Control Sailboat RF transmitter and receiver

Hello. I am creating a remote control sailboat and I am using two nRF24L01. I am having difficulty with creating the two-way, simultaneous, communication. From one Arduino (Arduino A) two joysticks transmit signals to the other Arduino (Arduino B), one for the sail winch (using a dc motor with a motor shield), and one for the rudder (using an analog servo motor). From Arduino B to Arduino A, there is a compass that transmits the Azimuth value. Arduino A receives the Azimuth value and graphs it on a digital compass that projects onto an OLED monitor connected to Arduino A. Could someone please help with the error in the code, there is no response on either end? Thank you!

Arduino A:

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

#include <Wire.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define LOGO_HEIGHT   16
#define LOGO_WIDTH    16
int last_dx, last_dy, dx, dy, angle;
const int centreX = 86;
const int centreY = 32;
const int radius  = 30;
RF24 radio(9, 10); // CE, CSN ************
const byte addresses[][6] = {"00001", "00002"};    //Byte of array representing the address. This is the address where we will send the data. This should be same on the receiving side.*****
int x_key1 = A1;//check pin
int y_key1 = A0;//check pin
int x_pos1;
int y_pos1;
int x_key2 = A3;//check pin
int y_key2 = A2;//check pin
int x_pos2;
int y_pos2;

int data[2];
int boat[4];

int x_valreceived;
int y_valreceived;
void setup() {
  Serial.begin(9600);
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;); // Don't proceed, loop forever
  }
  display.display();
  delay(2000); // Pause for 2 seconds
  pinMode (x_key1, INPUT);
  pinMode (x_key2, INPUT);
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.clearDisplay();
  display.display();
  last_dx = centreX;
  last_dy = centreY;
  radio.begin();              //Starting the Wireless communication
  radio.openWritingPipe(addresses[0]);
  radio.openReadingPipe(1, addresses[1]);
  radio.setPALevel(RF24_PA_MIN);
}
void loop()
{

  delay(5);
  radio.startListening();
  if (radio.available()) {
   while(radio.available()) {
    radio.read(&boat, sizeof(boat));
    Serial.print("X: ");
    Serial.print(boat[0]);
    Serial.print("   Y: ");
    Serial.print(boat[1]);
    Serial.print("   Z: ");
    Serial.print(boat[2]);
    Serial.print("   Azimuth: ");
    Serial.print(boat[3]);
  }
  
  
delay(5);
  radio.stopListening();
  data[0] = analogRead(x_key1);
  data[1] = analogRead(x_key2);
  Serial.print("data[0]:"); Serial.print(data[0]); Serial.print(" ");
  Serial.print("data[1]:"); Serial.println(data[1]);
  radio.write(&data, sizeof(data));
  
  display.clearDisplay();
  Draw_Compass();
  angle = boat[3];

  dx = (0.7 * radius * cos((angle - 90) * 3.14 / 180)) + centreX; // calculate X position for the screen coordinates - can be confusing!
  dy = (0.7 * radius * sin((angle - 90) * 3.14 / 180)) + centreY; // calculate Y position for the screen coordinates - can be confusing!
  draw_arrow(last_dx, last_dy, centreX, centreY, 2, 2, BLACK);   // Erase last arrow
  draw_arrow(dx, dy, centreX, centreY, 2, 2, WHITE);             // Draw arrow in new position
  last_dx = dx;
  last_dy = dy;
  display.setCursor(0, 48);
  display.setTextSize(2);
  display.print(angle);
  display.print(char(247)); // and the degree symbol
  display.display();
  //delay(2000);
}
}

void display_direction(int x, int y, String dir) {
  display.setCursor(x, y);
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.print(dir);
}

void draw_arrow(int x2, int y2, int x1, int y1, int alength, int awidth, int colour) {
  float distance;
  int dx, dy, x2o, y2o, x3, y3, x4, y4, k;
  distance = sqrt(pow((x1 - x2), 2) + pow((y1 - y2), 2));
  dx = x2 + (x1 - x2) * alength / distance;
  dy = y2 + (y1 - y2) * alength / distance;
  k = awidth / alength;
  x2o = x2 - dx;
  y2o = dy - y2;
  x3 = y2o * k + dx;
  y3 = x2o * k + dy;
  x4 = dx - y2o * k;
  y4 = dy - x2o * k;
  display.drawLine(x1, y1, x2, y2, colour);
  display.drawLine(x1, y1, dx, dy, colour);
  display.drawLine(x3, y3, x4, y4, colour);
  display.drawLine(x3, y3, x2, y2, colour);
  display.drawLine(x2, y2, x4, y4, colour);
}

void Draw_Compass() {
  int dxo, dyo, dxi, dyi;
  display.drawCircle(centreX, centreY, radius, WHITE); // Draw compass circle
  for (float i = 0; i < 360; i = i + 22.5) {
    dxo = radius * cos(i * 3.14 / 180);
    dyo = radius * sin(i * 3.14 / 180);
    dxi = dxo * 0.95;
    dyi = dyo * 0.95;
    display.drawLine(dxi + centreX, dyi + centreY, dxo + centreX, dyo + centreY, WHITE);
  }
  display_direction((centreX - 2), (centreY - 24), "N");
  display_direction((centreX - 2), (centreY + 17), "S");
  display_direction((centreX + 19), (centreY - 3), "E");
  display_direction((centreX - 23), (centreY - 3), "W");
}

Arduino B:

#include <Wire.h>
// QMC5883L Compass Library
#include <QMC5883LCompass.h>
QMC5883LCompass compass;
#include <Adafruit_MotorShield.h>
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_DCMotor *myMotor = AFMS.getMotor(1);
//communication 2 way
//firstly download library https://github.com/nRF24/RF24
#include<Servo.h>
Servo Myservo1;
Servo Myservo2;
int x_val;
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 10); // CE, CSN //*****
const byte addresses[][6] = {"00001", "00002"}; //******
int x_pos1;
int x_pos2;
int position1;
int position2;
int servoVal2;
int servoVal1;

const int servo_pin1 = 3;

int data[2];
//int xval;
int boat[4];
int x, y, z, a, b;
char myArray[3];

void setup() {
  Serial.begin(9600);
  Wire.begin();// Initialize I2C.
  compass.init(); // Initialize the Compass.
  //compass.setCalibration(-32768, 1915, -32768, 456, -591, 1085);
  Myservo1.attach(servo_pin1);
//  Myservo2.attach(servo_pin2);
 
  Serial.println("test");
//  myMotor->run(FORWARD);
//   myMotor->setSpeed(150);
//  // turn on motor
//  myMotor->run(RELEASE);
  radio.begin();
  radio.openWritingPipe(addresses[1]);
  radio.openReadingPipe(1, addresses[0]);
  radio.setPALevel(RF24_PA_MIN);
  Serial.println("check");
}

void loop()
{
  delay(5);
  radio.stopListening();
  compass.read();
  boat[0] = compass.getX();
  boat[1] = compass.getY();
  boat[2] = compass.getZ();
  boat[3] = compass.getAzimuth();
Serial.print("X: "); Serial.print(boat[0]); Serial.print(" ");
Serial.print(" Y: "); Serial.print(boat[1]); Serial.print(" ");
Serial.print(" Z: "); Serial.print(boat[2]); Serial.print(" ");
Serial.print(" Azimuth: "); Serial.println(boat[3]); 
 radio.write(&boat, sizeof(boat));
delay(5);

  radio.startListening();
  while (!radio.available());
    radio.read(&data, sizeof(data));
 Serial.print("data[0]:"); Serial.print(data[0]); Serial.print(" ");
Serial.print("data[1]:"); Serial.println(data[1]);
    
    data[0] = map(data[0], 0, 1023, 0, 180);
    if (data[0] > 400 && data[0] < 600)
    {
 
    }
    else {
      Myservo1.write(data[0]) ;
    
    }
 data[1] = map(data[1], 0, 1023, -100, 100);
    if (data[1] > 0) {
      myMotor->run(FORWARD);
      myMotor->setSpeed(data[1]);
      
    }
    if (data[1] < 0) {
      myMotor->run(BACKWARD);
      myMotor->setSpeed(data[1] * -1);
      
    }
}

Have you got a simpler sketch, simply sending messages between units, without all the peripherals?

This is not an installation issue - please move it to a more appropriate forum section.

@arduinouser3, moved to project guidance.

Can you please click Tools->Auto Format in the IDE then re-post your code? It will make it easier for all of us to spot mistakes. Please do that each time you post code to the forum. Thanks for using code tags, by the way!

I would remove all delay() if you can. If you want to the code to wait until all data has been transmitted, you can use radio.flush() I think.

Not surprised, there. What you are asking for is NOT possible with the equipment you have. Why not settle for rapid, one way at a time, communication?

Thank you so much for clarifying this. How could I go about doing that?

Begin by getting simple communications working with the devices a few meters apart. When that is working, think about using the ack payload feature to receive the boat telemetry data.
You seem to be forgetting that you sailboat will always be in visual range while you are operating RC.

There are plenty of basic tutorials for Arduino and the NRF24L01. Start by getting a couple of the examples to work, and when you understand the data transfer mechanisms, then add elements of the code for the boat.

One step at a time!

That is what I did; however, it is not working.

thank you!

Then go back to the last working step, and figure out what went wrong. The mistake has to be in the newly added code.

I can not find any simple (and working) example codes of this online. I can not find any two way communication between nrf24l01 with the ack payload feature. Could you please assist me?

No, the mistake is within getting any form of two-way communication between the two nrf24l01. Do you know of any code that successfully operates two-way communication between the two Arduino?

There are plenty of tutorials showing how to establish two way communication with those radios.

One example from forum member Robin2: Simple nRF24L01+ 2.4GHz transceiver demo

Thank you; however, I have already checked that out, and like all the comments on the post, the serial monitor of the transistor does not work and repeats "Tx failed"

I suspect that you made one or more mistakes in following the tutorial. Many people have found it helpful.

If you want help correcting the problem, please read and follow the instructions in the "How to get the best out of the forum" post, linked at the head of every forum category.

In any case, that particular tutorial just one of hundreds of similar offerings.

One here from iForce2D

https://www.youtube.com/watch?v=lR60toEjHl8

Thank you; however, he did not post the code. I can not find it.

He has his code listed on another link .....Out at the moment, will find it later today....cheers

Thank you!