Hello there,
I have been working on a tracked robot for several weeks now and it has been going fairly well until today.
I am using a pair of nRF24 transceivers (with capacitors) and a joystick for remote control. The joystick is wired to a Nano while the robot is managed by an Uno and a L298N motor controller.
Today I decided to make a mount for my controller as up until this point it has just been a loose board and joystick. After screwing the board down and plugging the battery back in, I noticed my robot was behaving strangely and spinning in place. This is a feature of my code but is only supposed to happen when the joystick is deflected directly right or left, in this case it was in the neutral position. I have reviewed my code and cannot find anything I might have accidentally changed, such as adding a character somewhere and it being wrong but still compiling (it can happen I guess?). I also did not unplug any of the wires and I know it was wired and working correctly last time I used it.
When I checked the serial monitor, the transmitter was outputting expected values but my receiver was reading in the y-axis ~ +67.
Below are my transmitter and receiver code as well as their respective serial outputs.
Robot_Tx.ino
/**
* August 11, 2020
* Battle Bot Radio Reciever
* Gareth Koch
*
* nRF24 Wiring
* GND ----- GND
* VCC ----- 3.3V
* CE ----- 8
* CSN ----- 9
* SCK ----- 13
* MOSI ----- 11
* MISO ----- 12
*
* Joystick Wiring
* GND ----- GND
* VCC ----- +5V
* VRX ----- A0
* VRY ----- A1
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
const byte address[6] = {'T', 'A', 'L', 'E', 'K', 'K'};
// Create radio and set CE and CSE pins to 8 and 9 respectively
RF24 radio(8, 9);
struct Joystick
{
byte x;
byte y;
};
// Variable of above struct
Joystick joystick;
void setup()
{
Serial.begin(9600);
// Start radio
radio.begin();
Serial.println("Radio begin");
// Set data rate
radio.setDataRate(RF24_250KBPS);
Serial.println("Data rate: 250kbps");
// Set address
radio.openWritingPipe(address);
Serial.print("Address set");
// Set channel values to "middle" of 0-255
joystick.x = 127;
joystick.y = 127;
}
void loop()
{
joystick.x = map (analogRead(A0), 0, 1023, 0, 255);
joystick.y = map (analogRead(A1), 0, 1023, 0, 255);
radio.write(&joystick, sizeof(Joystick));
Serial.print("x: ");
Serial.print(joystick.x);
Serial.print(" y: ");
Serial.print(joystick.y);
Serial.print(" A0: ");
Serial.print(analogRead(A0));
Serial.print(" A1: ");
Serial.println(analogRead(A1));
}
Tx Serial
18:52:37.000 → A0: 509 x: 126 A1: 529 y: 132
18:52:37.033 → A0: 509 x: 126 A1: 530 y: 132
Robot_Rx.ino
/**
August 15, 2020
Battle Bot Radio Reciever
Gareth Koch
nRF24 Wiring
GND ----- GND
VCC ----- 3.3V
CE ----- 8
CSN ----- 9
SCK ----- 13
MOSI ----- 11
MISO ----- 12
L298N Wiring
+12V ----- 9V
GND ----- GND
+5V ----- +5V
ENA ----- 10
IN1 ----- 7
IN2 ----- 6
IN3 ----- 5
IN4 ----- 4
ENB ----- 3
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
// Define left motor pins
#define Len 10
#define L1 6
#define L2 7
// Define right motor pins
#define Ren 3
#define R1 4
#define R2 5
// Set address for radio
// This must be the same for both the transmitter and receiver
const byte address[6] = {'T', 'A', 'L', 'E', 'K', 'K'};
// Create radio and set CE and CSE pins to 8 and 9 respectively
RF24 radio(8, 9);
// Joystick data format to be read
struct Joystick
{
byte x;
byte y;
};
// Variable of above struct
Joystick joystick;
// Check if a joystick axis is in the neutral position
bool isCentered(int value) {
return (value > 120 && value < 135);
}
void setup()
{
Serial.begin(9600);
//Start radio
radio.begin();
Serial.println("Radio begin");
// Set data rate
radio.setDataRate(RF24_250KBPS);
Serial.println("Data rate: 250kbps");
// Set address
radio.openReadingPipe(1, address);
Serial.println("Address set");
// Set radio to be receiver
radio.startListening();
// Set channel values to "middle" of 0-255
joystick.x = 127;
joystick.y = 127;
// Set pinouts for motor controller
pinMode(L1, OUTPUT);
pinMode(L2, OUTPUT);
pinMode(Len, OUTPUT);
pinMode(R1, OUTPUT);
pinMode(R2, OUTPUT);
pinMode(Ren, OUTPUT);
}
void loop() {
while (radio.available()) {
// Read joystick data
radio.read(&joystick, sizeof(Joystick));
/*
// Test data received
x_value = joystick.x;
y_value = joystick.y;
Serial.print("x: ");
Serial.print(x_value);
Serial.print(" y: ");
Serial.println(y_value);
*/
// Actually move
control(joystick.x, joystick.y);
}
}
void control (int x, int y) {
// Define forward velocity in terms of x axis
int fwSpeed = map(x, 0, 255, -255, 255);
// Define left and right motor velocity in terms of forward velocity
int lSpeed = fwSpeed;
int rSpeed = fwSpeed;
// If joystick is in neutral position, do not move
if (isCentered(x) && isCentered(y)) {
lSpeed = 0;
rSpeed = 0;
// Turn in place if no forward velocity
} else if (isCentered(x)) {
lSpeed = map(y, 0, 255, 255, -255);
rSpeed = - lSpeed;
// Scale forward velocity of right and left motors relative to y axis
} else {
if (y < 120) {
// left turn
rSpeed = fwSpeed - map(y, 135, 255, 0, fwSpeed);
}
else if (y > 135) {
lSpeed = fwSpeed - map(y, 0, 120, fwSpeed, 0);
}
}
// Test motor input/output
Serial.print("x: ");
Serial.print(x);
Serial.print(" ");
Serial.print("y: ");
Serial.print(y);
Serial.print(" ");
Serial.print("L: ");
Serial.print(lSpeed);
Serial.print(" ");
Serial.print("R: ");
Serial.println(rSpeed);
// Process final "speed" values to movement
trackMove(lSpeed, rSpeed);
}
void trackMove(int lSpe, int rSpe) {
if (lSpe > 8) {
// Move forward
digitalWrite(L1, HIGH);
digitalWrite(L2, LOW);
analogWrite(Len, lSpe);
} else if (lSpe < -8) {
// Move backwards
digitalWrite(L1, LOW);
digitalWrite(L2, HIGH);
analogWrite(Len, -lSpe);
} else {
digitalWrite(L1, LOW);
digitalWrite(L2, LOW);
analogWrite(Len, 0);
}
if (rSpe > 8) {
// Move forward
digitalWrite(R1, HIGH);
digitalWrite(R2, LOW);
analogWrite(Ren, rSpe);
} else if (rSpe < -8) {
// Move backwards
digitalWrite(R1, LOW);
digitalWrite(R2, HIGH);
analogWrite(Ren, -rSpe);
} else {
digitalWrite(R1, LOW);
digitalWrite(R2, LOW);
analogWrite(Ren, 0);
}
}
void halt() {
// Stop
digitalWrite(L1, LOW);
digitalWrite(L2, LOW);
analogWrite(Len, 0);
digitalWrite(R1, LOW);
digitalWrite(R2, LOW);
analogWrite(Ren, 0);
}
Rx Serial
18:52:37.018 → x: 127 y: 198 L: -141 R: 141
18:52:37.053 → x: 127 y: 198 L: -141 R: 141
Any insight into potential causes or solutions would be greatly appreciated.
Thank you for your time.