Help with Joystick control for 4WD

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.

I see your code is all set to use the serial print capability so you can see the values your code is working with. IF you actually want to debug the program, begin identifying and printing values so you can see your logic and track down the culprit.

Paul

I tried it as you said and the Serial printing does not show any errors, but error occurs on the field. I even paid attention to the distance between the robot and the RF joystick. Furthermore, my Arduino Mega cannot run that code. I don't know the reason, it perfectly runs on an UNO. I think it's some sort of library, could you help me figure out what's wrong.

haritha2000:
I tried it as you said and the Serial printing does not show any errors, but error occurs on the field. I even paid attention to the distance between the robot and the RF joystick. Furthermore, my Arduino Mega cannot run that code. I don't know the reason, it perfectly runs on an UNO. I think it's some sort of library, could you help me figure out what's wrong.

The purpose of printing various variable values is not to discover errors, but to enable you to examine your code's logic so you can be sure each step is as you expected it to be.

Did your logic always perform correctly with various input changes?

Paul

Yes

hi, I think I found the issue, as im using 433 RF receiver, its range doesn’t seem to be more than 1M. So, when it goes out of range, the robot doesn’t listen. So I am trying to increase the range of the receiver. Thank you very much