433 MHz RF module failing due to... motor interference?

Hello all,

First timer here, and I've run into an issue with the 433MHz RF module I'm using as a remote control (Four-channel 433 MHz radio module + remote control Botland - Robotic Shop).

I'm making a basic robot, and I have everything set up, but once the robot gets a command to start moving, the receiver doesn't pickup inputs from the remote control unless they're practically next to each other. Control, check. Remote, not so much.... I confirmed this both by the robot's behavior, and by checking the Serial Monitor.

I'm using two DAGU robot DG01D motors within a Magician Chassis v2.

From what I've read on some similar topics here, interference from the DC motors might be the cause. If that's the case, how would you suggest I fix it?

Do I...

  • Get a new / better RF module?
  • Get different (?better-shielded?) motors?
  • Setup the wiring to reduce RF interference? (I read a bit about LC circuits...)
  • OR something else that I don't know about?

Any help would be much appreciated.

All the best,
Josh

P.S. Other potentially relevant details:

  • I'm using the Leonardo board
  • I'm using 6xAA to power the system through the 2.1mm plug, and I see ~12V running through circuit with my multimeter
  • I'm using the SparkFun Motor Driver - Dual TB6612FNG to transform my outputs to the motor controls
  • I'm using 2 capacitors: 1000uF/25V and 100uF/16V

Setup diagram from the inspiration of the project, Simon Monk's Hacking Electronics. (Circuit diagram in the next post due to image limits.)

Code, modified from Simon Monk's repo to suit my slightly different wiring due to headers being on the reverse side as in the tutorial. (hacking_electronics/rover at master · simonmonk/hacking_electronics · GitHub)

// rover
// Arduino Uno or Leonardo

int fullPower = 192;
int slowPower = 128;

int PWMApin = 3;
int AIN1pin = 5;
int AIN2pin = 4;
int PWMBpin = 9;
int BIN1pin = 7;
int BIN2pin = 8;

int remotePins[] = {10, 11, 12, 13};
int lastPinStates[] = {0, 0, 0, 0};

void setup()
{
  pinMode(PWMApin, OUTPUT);
  pinMode(AIN1pin, OUTPUT);
  pinMode(AIN2pin, OUTPUT);
  pinMode(PWMBpin, OUTPUT);
  pinMode(BIN1pin, OUTPUT);
  pinMode(BIN2pin, OUTPUT);
  for (int i = 0; i < 4; i++)
  {
    pinMode(remotePins[i], INPUT);
  }
  Serial.begin(9600);
}

void loop()
{
   Serial.print("Pressed :");
   Serial.print(digitalRead(remotePins[0]));
   Serial.print(digitalRead(remotePins[1]));
   Serial.print(digitalRead(remotePins[2]));
   Serial.print(digitalRead(remotePins[3]));
   Serial.print("   Pin States: ");
   Serial.print(lastPinStates[0]);
   Serial.print(lastPinStates[1]);
   Serial.print(lastPinStates[2]);
   Serial.println(lastPinStates[3]);
   int keyPressed = getKeyPress();
   Serial.print("   Pin States: ");
   Serial.print(lastPinStates[0]);
   Serial.print(lastPinStates[1]);
   Serial.print(lastPinStates[2]);
   Serial.print(lastPinStates[3]);
   Serial.print("   Key Press: ");
   Serial.println(keyPressed);
   if (keyPressed == 1)
   {
     stopMotors();
     Serial.println("Stopping Motors");
   }
   else if (keyPressed == 3)
   {
     turnLeft();
     Serial.println("Turning Left");
   }
   else if (keyPressed == 0)
   {
     turnRight();
     Serial.println("Turning Right");
   }
   else if (keyPressed == 2)
   {
     forward();
     Serial.println("CHARGE!");
   }
   delay(500);
}

void stopMotors()
{
  digitalWrite(AIN1pin, LOW);
  digitalWrite(AIN2pin, LOW);
  analogWrite(PWMApin, 0);
  digitalWrite(BIN1pin, LOW);
  digitalWrite(BIN2pin, LOW);
  analogWrite(PWMBpin, 0);
}
  
void turnLeft()
{
  digitalWrite(AIN1pin, HIGH);
  digitalWrite(AIN2pin, LOW);
  analogWrite(PWMApin, slowPower);
  digitalWrite(BIN1pin, LOW);
  digitalWrite(BIN2pin, HIGH);
  analogWrite(PWMBpin, slowPower);
}

void turnRight()
{
  digitalWrite(AIN1pin, LOW);
  digitalWrite(AIN2pin, HIGH);
  analogWrite(PWMApin, slowPower);
  digitalWrite(BIN1pin, HIGH);
  digitalWrite(BIN2pin, LOW);
  analogWrite(PWMBpin, slowPower);
}

void forward()
{
  digitalWrite(AIN1pin, LOW);
  digitalWrite(AIN2pin, HIGH);
  analogWrite(PWMApin, fullPower);
  digitalWrite(BIN1pin, LOW);
  digitalWrite(BIN2pin, HIGH);
  analogWrite(PWMBpin, fullPower);
}

int getKeyPress()
{
  int result = -1;
  for (int i = 0; i < 4; i++)
  {
    int remoteInput = digitalRead(remotePins[i]);
    if (remoteInput != lastPinStates[i] and lastPinStates[i] == 0)
    {
      result = i;
    }
    lastPinStates[i] = remoteInput;
  }
  return result;
}

Circuit diagram not allowed in my first post b/c I'm new, so here it is

More likely, the motor interference is getting into the digital signal wiring of the Arduino. Use short, direct wires for signal connections and route them away from motor wires. In severe cases, you may need grounded shielding as well.

Be sure to add capacitors across the motor brush terminals, as shown here: Pololu - 9. Dealing with Motor Noise

Power the Arduino from a separate power supply or use a buck converter to drop the 9V to 5V and connect that to the Arduino 5V pin.

Put 0.1uF caps across each motor to bypass brush noise.

Hey there, thanks for the responses!

I put a 0.1uF cap across each motor and it seemed to help. The RF module now picks up commands from a few inches away instead of having to be right next to it. I will add some capacitors from the leads to the motor case as well, b/c it seems like I need more noice dampening.

@groundFungus , do you mean that I should have one power supply for the Arduino and one for the motors, instead of having them connected together? If so, how would that work, given that the motor commands are coming directly from the Arduino? Also, could you explain the reasoning behind this idea? I'm a complete beginner to electronics and I'd love to learn more about how all of this works.

Another general question:
I used a multimeter to look at the voltage across the whole circuit and across the RF module, and both were constant. Does this mean there are no voltage jumps, or do they just happen so quickly that my multimeter can't pick them up, or...?

There are 2 reasons why I would use a buck converter to convert the 9V motor supply to 5V and connect the buck converter output to the 5V pin of the Arduino.

  1. The buck converter will go a long way towards filtering motor noise from the power supply
  2. If you feed the 9V to the Vin of the Arduino the 5V is supplied by the on board 5V regulator. The onboard 5V regulator is not well heat sinked so will supply limited current (around 200mA) before it gets hot and, maybe, shuts down. Supplying the Arduino with the buck converter means that the 5V rail can handle the full current capability of the buck converter.

You can also try a 0.1uF cap on each of the power leads to ground to bypass more motor/brush noise.

motor caps

Have you tried transmitting from across the room -- 4 or more metres? Some of the modules will have trouble with a transmitter that is too close/strong and not receive properly unless the signal is attenuated a bit by distance. Also what are you using for a receive antenna?

To eliminate the motor interference as a possible problem you could replace the motors with incandescent bulbs temporarily. You'd be able to visually verify operation and totally eliminate inductive and commutator noise.

Good luck.

Good question, and now I feel a little silly, as I'm not using an antenna :man_facepalming: I will add one and then report back!

I have tried transmitting from further away and that doesn't work either.

Thanks for the suggestion about the bulbs, will try that out too!