I am facing a strange and very frustrating issue while realizing a basic radio comunication between 2 arduino boards, one Arduino Nano and one Arduino Uno. For such a purpose, I am using the NRF24L01 wireless module, which comunicate with the boards through SPI. The library I am using to handle this module is the "RF24" library by TMRh20, version 1.3.4.
I'd like to specify that for my academic background and my current job, I am a Software Engineer graduated in Computer Science. I started doing some projects with arduino and raspberry a few years ago, I realized a small car robot controlled through the home Wi-Fi and now I'd like to step up and build a quadcopter. My electronics knowledge is limited to what can be learned in a technical high school, so I'll probably do some theoretical mistakes and I would be very pleasant to know if there are any in what will follow.
The Arduino Uno is placed upon a quadcopter frame and four ESCs are connected to digital pins 5,6,7 and 8. In the following picture I'll show my radio pinout for both Uno and Nano.
Arduino UNO:
Arduino Nano:
Nano is communicating with a Desktop Application through USB Serial. The desktop application shall acquire joystick input, put this into a custom defined data structure and send it to the Nano. Serial comunication is working fine, and the Nano successfully receives data from joystick. The same data structure is then forwarded through radio:
uint8_t* msgId = (uint8_t*)(serialRxBuffer); //serialRxBuffer contains the message from desktop app
if (CTRL_TO_RADIO_CMD_ID == *msgId)
{
CtrlToRadioCommandMessage* msgIn = (CtrlToRadioCommandMessage*)(serialRxBuffer);
lastCmdMessage.l2_axis = msgIn->l2_axis;
lastCmdMessage.r2_axis = msgIn->r2_axis;
lastCmdMessage.l3_x_axis = msgIn->l3_x_axis;
lastCmdMessage.l3_y_axis = msgIn->l3_y_axis;
lastCmdMessage.r3_x_axis = msgIn->r3_x_axis;
lastCmdMessage.r3_y_axis = msgIn->r3_y_axis;
/** Forwarding data to radio **/
radio.write((char*)&lastCmdMessage, sizeof(CtrlToRadioCommandMessage));
}
The Uno is then doing:
if (!radio.available())
{
count += 1;
radioAvailable = false;
}
else
{
radioAvailable = true;
count = 0;
radio.read((char*)&commandMsg, sizeof(CtrlToRadioCommandMessage));
}
/* Do something with ESCs using commandMsg... */
radio.writeAckPayload(1, &responseMsg, sizeof(DroneToRadioResponseMessage));
Where "responseMsg" is a custom data structure sent from the Uno to the Nano as an ack payload (and then to the desktop application) which carries informations about current motor speed, heading, pitch, roll, yaw and baro altitude, which is 29 < 32 bytes length.
Here we get to the strange part! With NO PROPELLERS attached to motors, comunication is working pretty good, but when propellers start to spin the comunication ends in few seconds and the quadcopter becomes uncontrollable.
This is what I've tried so far: Try other pair of the same module, but I've noticed the same behavior. I've triead at least ten different pairs.
Try the NRF24L01 module with Antenna: no wireless comunication at all (even basic one-direction examples won't work, in fact neither this).
Try to upgrade the library version: no wireless comunication at all, and even basic one-direction examples won't work, as above.
It may be possible that these modules aren't suitable for a quadcopter environment? It will be great to know if there are any other more resilient wireless module which fits out there, if someone of you have the experience, or if I'm doing something wrong with the cables or with the code. Here the setup() functions for the Uno:
void setup(void)
{
Serial.begin(9600); //Debug purposes
motor1.attach(MOTOR_PIN1);
motor2.attach(MOTOR_PIN2);
motor3.attach(MOTOR_PIN3);
motor4.attach(MOTOR_PIN4);
radio.begin();
radio.openReadingPipe(1, rx_pipe); //long 0x6e6e6e6e6e6e6e6e
radio.enableAckPayload();
radio.startListening();
radio.writeAckPayload(1, &responseMsg, sizeof(DroneToRadioResponseMessage));
}
And here for the Nano:
void setup()
{
radio.begin();
radio.enableAckPayload();
radio.setRetries(5,5);
radio.openWritingPipe(tx_pipe); //long 0x6e6e6e6e6e6e6e6e
Serial.begin(115200); // Desktop app communication, functional purposes
}