Hi, I made a 4WD Robot which works with an RF Joystick, which has an Atmega8 chip. The joy stick constantly transmits its position to the RF receiver in the robot. The position of the joystick determines the direction the robot should move. It works really fine but at random instances, the robot doesn’t stop when the joystick is released. It just continues the last command it received, resulting in the robot to hit on something.
This happens only at certain times, making the stop function less reliable.
By the way, the 4WD robot is controlled by a L293D Motor Driver Shield, 4 TT DC Motors, an Arduino Mega, an the RF receiver. The robot uses differential steering for turning.
The power for the robot is supplied by 4 18650 batteries connected together in series, which gives a little bit too much power which is around 16 volts, so I don’t think there is a power issue.
Furthermore, the power supply is connected to the shield and the Arduino is powered through the shield itself.
This is the Code I have uploaded to the Joystick module which is controlled by the Atmega8 chip.
#include <VirtualWire.h>
#include <OS_JoystickCtrl.h>
JoystickCtrl remote;
int RF_TX_PIN = 6;//connect the sent module to D2 to use
//you can change it to the idle port you want.
void setup()
{
remote.init();
vw_set_tx_pin(RF_TX_PIN); // Setup transmit pin
vw_setup(2000); // Transmission speed in bits per second.
}
uint8_t buffer[5]= {0X7E,5250,5250,0,0XEF}; // buffer array for data recieve over serial port
void loop()
{
int x;int y;
uint8_t xh,xl,yh,yl;
uint8_t z;
if(remote.isChange())
{
x=remote.nowX;
x = x>>2;
y=remote.nowY;
y = y>>2;
z=remote.nowZ;
z <<= 3;
uint8_t button = remote.nowkey;
buffer[3] = z|button;
buffer[1] = x;
buffer[2] = y;
}
vw_send(buffer, 5); //
delay(50);//between two message, you should delay 400ms so that the receiver may not miss it.
}
This is the joystick I am using.
The 4WD robot code is as follows.
#include <VirtualWire.h>
#include <Wire.h>
#include <AFMotor.h>
int RF_RX_PIN = 2;
void(* resetFunc) (void) = 0;
AF_DCMotor rb(2);// rb means Right Backward Wheel and so on.
AF_DCMotor lb(1);
AF_DCMotor rf(3);
AF_DCMotor lf(4);
int xh,xl,yh,yl;
uint8_t z;
uint8_t button;
void setup()
{
Serial.begin(9600);
vw_set_rx_pin(RF_RX_PIN); // Setup receive pin.
vw_setup(2000); // Transmission speed in bits per second.
vw_rx_start(); // Start the PLL receiver.
pinMode(13,OUTPUT);
rf.run(RELEASE);lf.run(RELEASE);lb.run(RELEASE);rb.run(RELEASE);
digitalWrite(13,HIGH);
}
uint8_t buffer[VW_MAX_MESSAGE_LEN]; // buffer array for data recieve over serial port
uint8_t buflen = VW_MAX_MESSAGE_LEN;
int x;
int y;
int state=2;// used for dynamic braking
void loop()
{
if(vw_get_message(buffer, &buflen)) // non-blocking I/O
{
decode();
}
if (z!=1){
godirection(x,y);
}
else{rstop();}
}
void decode()
{
if((buffer[0]!=0x7E)||(buffer[4]!=0xEF))
{
resetFunc();
}
uint8_t i = 0;
x = buffer[1]<<2;
y = buffer[2]<<2;
z = buffer[3]>>3;
button = buffer[3]&0x07;
if (x>600){
x=1;
}else if (x<=600 && x>=400){x=0;}
else {x=-1;}
if (y>600){
y=1;
}else if (y<=600 && y>=400){y=0;}
else {y=-1;}
}
void clearBufferArray() // function to clear buffer array
{
for (int i=0; i<VW_MAX_MESSAGE_LEN;i++)
{ buffer[i]=0;} // clear all index of array with command NULL
}
void godirection(int x,int y) {
if (x==0){
if (y==1){forward();}
else if (y==0){rstop();}
else if (y==-1){backward();}
}
else if (x==1){
if (y==1){srf();}
else if (y==0){right();}
else if (y==-1){srb();}
}
else if (x==-1){
if(y==1){slf();}
else if (y==0){left();}
else if (y==-1){slb();}
}
}
void rstop (){
if (state==0){
rf.run(FORWARD);lf.run(FORWARD);lb.run(FORWARD);rb.run(FORWARD);
rf.setSpeed(200);lf.setSpeed(200);rb.setSpeed(200);lb.setSpeed(200);
delay(50);
rf.run(RELEASE);lf.run(RELEASE);lb.run(RELEASE);rb.run(RELEASE);
rf.setSpeed(0);lf.setSpeed(0);rb.setSpeed(0);lb.setSpeed(0);
state=2;
}
else if (state==1){
rf.run(BACKWARD);lf.run(BACKWARD);lb.run(BACKWARD);rb.run(BACKWARD);
rf.setSpeed(200);lf.setSpeed(200);rb.setSpeed(200);lb.setSpeed(200);
delay(50);
rf.run(RELEASE);lf.run(RELEASE);lb.run(RELEASE);rb.run(RELEASE);
rf.setSpeed(0);lf.setSpeed(0);rb.setSpeed(0);lb.setSpeed(0);
state=2;
}
else if (state==2){
rf.run(RELEASE);lf.run(RELEASE);lb.run(RELEASE);rb.run(RELEASE);
rf.setSpeed(0);lf.setSpeed(0);rb.setSpeed(0);lb.setSpeed(0);
}
}
void forward(){
state=1;
rf.run(FORWARD);lf.run(FORWARD);lb.run(FORWARD);rb.run(FORWARD);
rf.setSpeed(200);lf.setSpeed(200);rb.setSpeed(200);lb.setSpeed(200);
}
void backward(){
state=0;
rf.run(BACKWARD);lf.run(BACKWARD);lb.run(BACKWARD);rb.run(BACKWARD);
rf.setSpeed(200);lf.setSpeed(200);rb.setSpeed(200);lb.setSpeed(200);
}
void right(){
state=2;
rf.run(BACKWARD);lf.run(FORWARD);lb.run(FORWARD);rb.run(BACKWARD);
rf.setSpeed(140);lf.setSpeed(140);rb.setSpeed(140);lb.setSpeed(140);
}
void left(){
state=2;
lf.run(BACKWARD);rf.run(FORWARD);rb.run(FORWARD);lb.run(BACKWARD);
rf.setSpeed(140);lf.setSpeed(140);rb.setSpeed(140);lb.setSpeed(140);
}
void srf(){
state=1;
rf.run(FORWARD);lf.run(FORWARD);lb.run(FORWARD);rb.run(FORWARD);
rf.setSpeed(50);lf.setSpeed(200);rb.setSpeed(50);lb.setSpeed(200);
}
void srb(){
state=0;
rf.run(BACKWARD);lf.run(BACKWARD);lb.run(BACKWARD);rb.run(BACKWARD);
rf.setSpeed(50);lf.setSpeed(200);rb.setSpeed(50);lb.setSpeed(200);
}
void slf(){
state=1;
rf.run(FORWARD);lf.run(FORWARD);lb.run(FORWARD);rb.run(FORWARD);
lf.setSpeed(50);rf.setSpeed(200);lb.setSpeed(50);rb.setSpeed(200);
}
void slb(){
state=0;
rf.run(BACKWARD);lf.run(BACKWARD);lb.run(BACKWARD);rb.run(BACKWARD);
lf.setSpeed(50);rf.setSpeed(200);lb.setSpeed(50);rb.setSpeed(200);
}
I have been trying to make this robot to stop reliably for like a month now. But I couldn’t achieve it. Also, I even reserved a special emergency stop button, which is the JoyStick’s Z, to stop the robot immediately. But once it starts to go crazy, it doesn’t even listen to that button for a few moments.
I believe this is a programming issue so please help me.
It would be a big help if you could help me.
Thank you very much.