1
\$\begingroup\$

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:

enter image description here

Arduino Nano:

enter image description here

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

}
\$\endgroup\$
7
  • 1
    \$\begingroup\$ Apparently EMI gods are not kind to your layout of ground and signals so motor current pulses might be interfering somewhere. Without a full layout and list of assumptions from known good designs and where you deviated might help us. The obvious missing info in schematic is path of all shared grounds. Gnd = local 0V. You don't want motor power sharing lines with signals to the battery. Shielding and filters help \$\endgroup\$
    – D.A.S.
    Commented Apr 27, 2022 at 1:44
  • \$\begingroup\$ are the propellers made of metal? \$\endgroup\$ Commented Apr 27, 2022 at 1:50
  • \$\begingroup\$ @Jasen, no the propellers are made of plastic. \$\endgroup\$ Commented Apr 27, 2022 at 1:58
  • \$\begingroup\$ @TonyStewartEE75 ok, I thought the same but what I found strange is: without propellers, why current flowing through escs does not interfere with the radio module? Anyway, the frame has 4 "arms" and at the center I have the Arduino, a power distribution board and at each arm end I have the ESCs and the brushlesses. Motor LiPo goes to the +/- of the power distribution board, so to the "red and black big cables" of each ESC. Arduino battery + goes to the +5V on the Arduino, Arduino battery - goes to the common gnd. The common gnd is a line where it is also connected ESCs gnd and radio gnd. \$\endgroup\$ Commented Apr 27, 2022 at 2:03
  • 1
    \$\begingroup\$ With the propellers, the motors have to work harder because they have a load on them. That means they draw more current, which increases the output ripple of the motor drive circuitry, which increases the radiated noise. This is an unfortunate side effect of driving a motor from an inverter. In industrial applications, they use special shielded cable to connect the motor to the drive electronics. You could also mitigate the problem by adding a filter to the ESC's output, but such a filter would be heavy (bad for copters). Moving the ESCs closer to the motors and using shorter cable may help. \$\endgroup\$
    – Hearth
    Commented Apr 27, 2022 at 15:18

1 Answer 1

3
\$\begingroup\$

Apparently, the EMI gods are not kind to your layout of ground and signals so motor current pulses might be interfering somewhere. Without a full layout and list of assumptions from known good designs and where you deviated might help us. The obvious missing info in the schematic is the path of all shared grounds. Gnd = local 0V. You don't want motor power-sharing lines with signals to the battery. Shielding and filters help

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.