I want to make an RC car based on two Arduino Nanos, two nRF24L01s (Rx and Tx), and a Pololu brushed motor driver, and it works, more or less.
Sometimes it works very well and everything goes nicely and suddenly it will "freeze" and stop receiving and when it does, the servo always goes to 0° (I think it must be the Rx because it prints the same value until the next restart in the serial monitor).
It seems the servo trebles in the same direction (to 0°) only when I send high PWM values until it stops reading new data and "freezes".
I have 2 batteries, one for the Nano with a step-up converter, and another for the servo and the brushed motor; they share a common ground. Everything is close to each other and connected by wires soldered to a prototype breadboard. It is really messy but makes a good contact.
So it seems it is a noise problem, doesn't it? But what else could it be? How can I suppress that noise? I have already watched the Pololu guide about noise but I didn't try the bypass capacitors since I don't know how to solder them properly (can they burn the servo?)
Here is the code for the Tx
#include <SPI.h>
#include "RF24.h"
const int ledBot = 8;
const int padx = A0;
const int pady = A1;
const int sw = 3;
int sws;
int x;
int y;
int botState;
int aBotState;
int ledState;
const float un = 0.25;
const float fy = 0.176;
int sens [4]; // 0: throttle, 1: foward/backwards, 2: steering, 3: lights
RF24 radio(9, 10); // CE, CSN
const byte address[6] = "00001";
void setup() {
//Serial.begin(9600);
pinMode(padx, INPUT);
pinMode(pady, INPUT);
pinMode(sw, INPUT);
pinMode(ledBot, INPUT_PULLUP);
radio.begin();
radio.setDataRate (RF24_2MBPS);
radio.openWritingPipe(address);
radio.setPALevel(RF24_PA_MIN);
radio.stopListening();
}
void loop() {
x = analogRead(padx);
y = analogRead(pady);
sws = digitalRead(sw);
botState = digitalRead(ledBot);
y = 1024-y;
switch (sws){ //foward and backwards
case 0:
sens [0] = un*x;
sens [1] = 0;
sens [2] = min(135, max(50, y*fy-2));
break;
case 1:
sens [0] = un*x;
sens [1] = 1;
sens [2] = min(135, max(50, y*fy-2));
break;
}
if ( botState == HIGH && aBotState == LOW) { //button switch part
if (ledState == 0) {
ledState = 1;
sens [3] = ledState;
}
else {
ledState = 0;
sens [3] = ledState;
}
}
aBotState = botState;
radio.write(&sens, sizeof(sens));
//Serial.println(sens[0]);
//Serial.println(ledState);
// Serial.println(sens[1]);
//Serial.println(sens [3]);
}
And here for the Rx:
#include <Servo.h>
#include <SPI.h>
#include "RF24.h"
int sens [4];
const int polph = 7;
const int polen = 6;
const int led1 = 2;
const int led2 = 3;
const int ledError = 8;
Servo servo;
RF24 radio(9, 10); //
const byte address[6] = "00001";
void setup() {
pinMode(polph, OUTPUT);
pinMode(polen, OUTPUT);
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(ledError, OUTPUT);
digitalWrite(led1, HIGH);
digitalWrite(led2, HIGH);
delay(300);
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
delay(300);
digitalWrite(led1, HIGH);
digitalWrite(led2, HIGH);
delay(300);
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
servo.attach(5);
//Serial.begin(9600);
radio.begin();
radio.setDataRate (RF24_2MBPS);
radio.openReadingPipe(0, address);
radio.setPALevel(RF24_PA_MIN);
radio.startListening();
}
void loop() {
if (radio.available()) {
digitalWrite(ledError, LOW);
radio.read(&sens, sizeof(sens));
analogWrite(polen, sens [0]);
digitalWrite(polph, sens[1]);
servo.write(sens [2]);
digitalWrite(led1, sens [3]);
digitalWrite(led2, sens [3]);
}
}
-
2It’s really hard to diagnose a problem when you can’t see it. Post the codes and a wiring diagram so someone can actually have a hope of seeing the problem.Delta_G– Delta_G2020年06月25日 01:29:51 +00:00Commented Jun 25, 2020 at 1:29
1 Answer 1
Electrical noise is the problem quite often. In order to minimize noise, several key points must be observed:
Solder one 0.1uF ceramic capacitor from each terminal to the motor case. These are called decoupling capacitors and are used to suppress HF noise creeping in from the motors due to sparking/arching.
Choose appropriate AWS rating for your motor leads and adequate power supply. Inappropriately thin leads or insufficient battery discharge current can cause abrupt voltage drop on acceleration which will lead to sudden MCU resets (brown out resets).
Twist the leads around each other. This helps to further nullify arching noise.
As for Arduino, it is not the best way for making reliable RC software because it does simple things terribly wrong, e.g. sequential software polling instead of using hardware input capture. I would highly recommend learning how to write firmware for MCUs in native mode.
Check out this link to gain some inspiration on how to build an RC motor driver:
https://github.com/neoxic/STM8-RC-Dual-Motor-Driver#building-a-dual-12a-bidirectional-esc