Dagu Rover 5 Control problems

I am in the process to build a rover 5 with the SFE joystick remote, today i spent most of the day trying to get communication working between remote and rover and with the help op Paul and AWOL got that working but now i have another problem and need advice

the rover 5 has tracks so turning left or right is a combination of motors moving. ( my rover has 4 motors)
the problem is I had switch cases setup to switch bewteen left ,right,forward and back. but my problem was every time i entered one of the switch cases it would not exit after the joystick centered again. (confirmed the switch case trigger does go back to the stop position ) but the motors will keep on running in a a direction until i reset the board.

Now what i have noticed from debugging is that when the rover code enters a switch the communication stops. since then i have tried if statements but also with limited success. Receiver code below

#include <VirtualWire.h>
  
int RX_ID;
int TX_ID =3;
#define MDir1 2 // Direction ch1 front right motor
#define MDir2 8 // Direction ch2 front left motor
#define MDir3 4 // Direction ch3 back right motor
#define MDir4 7 // Direction ch4 back left motor

#define MSpeed1 3 //Speed Ch1
#define MSpeed2 5 //Speed Ch2
#define MSpeed3 6 //Speed Ch3
#define MSpeed4 9 //Speed Ch4

typedef struct roverRemoteData
{
int    TX_ID; 
int    Speed;// The variable were the data from each sensor
int    Direction;// will be stored
int    Sensor3Data;
int    Sensor4Data;
int    Sensor5Data;// will be stored
int    Sensor6Data;
};

int Led_Tx = 12;
int Led_Rx = 13;


void setup() {
              Serial.begin(9600);
              pinMode(Led_Tx,OUTPUT);
              pinMode(Led_Rx,OUTPUT);
              pinMode(MDir1,OUTPUT);
          pinMode(MDir2,OUTPUT);
          pinMode(MDir3,OUTPUT);
          pinMode(MDir4,OUTPUT);
          pinMode(MSpeed1,OUTPUT);
          pinMode(MSpeed2,OUTPUT);
          pinMode(MSpeed3,OUTPUT);
          pinMode(MSpeed4,OUTPUT);
              vw_setup(4000);
              vw_set_rx_pin(11); 
              vw_rx_start(); 
                   
              }  
void loop()
{
  // struct roverRemoteData receivedData;
struct roverRemoteData receivedData;
uint8_t rcvdSize = sizeof(receivedData);

if (vw_get_message((uint8_t *)&receivedData, &rcvdSize)) 
{
  if (receivedData.TX_ID == 3) 
    {
     if(receivedData.Direction == 0)  
             {
              Serial.println("Stopped");
              digitalWrite(MDir1,0);
              digitalWrite(MDir2,0);
              analogWrite (MSpeed1,receivedData.Speed);
              analogWrite (MSpeed2,receivedData.Speed);
              digitalWrite(MDir3,0);
              digitalWrite(MDir4,0);
              analogWrite (MSpeed3,receivedData.Speed);
              analogWrite (MSpeed4,receivedData.Speed);
              
             }
              if(receivedData.Direction == 2)
                  {   
              Serial.println("Forward");            
              digitalWrite(MDir1,0);
              digitalWrite(MDir2,0);
              digitalWrite(MDir3,1);
              digitalWrite(MDir4,1);
              analogWrite(MSpeed1,receivedData.Speed);
              analogWrite(MSpeed2,receivedData.Speed);
              analogWrite(MSpeed3,receivedData.Speed);
              analogWrite(MSpeed4,receivedData.Speed);
             
                  }
             if(receivedData.Direction == 3)
              {
              Serial.println("Left");
              digitalWrite(MDir1,0);
              digitalWrite(MDir2,1);
              digitalWrite(MDir3,1);
              digitalWrite(MDir4,0);
              analogWrite (MSpeed1,receivedData.Speed);
              analogWrite (MSpeed2,(receivedData.Speed-(receivedData.Speed/2)));
              analogWrite (MSpeed3,receivedData.Speed);
              analogWrite (MSpeed4,(receivedData.Speed-(receivedData.Speed/2)));
              
              }
              if(receivedData.Direction == 4)
             { 
               Serial.println("Right");
               Serial.println("Right");
              digitalWrite(MDir1,1);
              digitalWrite(MDir2,0);
              digitalWrite(MDir3,0);
              digitalWrite(MDir4,1);
              analogWrite (MSpeed1,(receivedData.Speed-(receivedData.Speed/2)));
              analogWrite (MSpeed2,receivedData.Speed);
              analogWrite (MSpeed3,(receivedData.Speed-(receivedData.Speed/2)));
              analogWrite (MSpeed4,receivedData.Speed);
              
             }
              if(receivedData.Direction == 1)
              {
              Serial.println("Back");
              digitalWrite(MDir1,1);
              digitalWrite(MDir2,1);
              analogWrite(MSpeed1,receivedData.Speed);
              analogWrite(MSpeed2,receivedData.Speed);
              digitalWrite(MDir3,0);
              digitalWrite(MDir4,0);
              analogWrite(MSpeed3,receivedData.Speed);
              analogWrite(MSpeed4,receivedData.Speed);
              
              }
              delay(50);
    }
      else
        {
          Serial.println(" ID Does not match waiting for next transmission ");
         // memset( StringReceived, 0, sizeof( StringReceived));
        }
      //Serial.println(StringReceived);
         // memset( StringReceived, 0, sizeof( StringReceived));
 
}
}

I forgot to add, the rover motors require two things , input of ether 1 or 0 for direction and PWM for the speed.

Your problems nothing to do with switch/if but with the data RX'ed put a debug statement in so you can see the data your bring sent.

Mark

Hi Mark,
I have done debug on the program and all the information is as its being sent, so i have confirmed it is working, what i have noticed is when you comment out 3 of the 4 motors and only work with one the code seems to work, work being after you leave the stick the motor stops but enable all motors and they just keep running.

post the debug and the code that generated it.

Mark

See attached

the 250 is throttle value that maps from 0 -255 in all directions and the second number"2" is the direction indicator which would also be the switch var. the actual code running on the remote is as follows

#include <LiquidCrystal.h>
#include <VirtualWire.h>


const int Throttle_Direct_Y = A1;// The pins were sensor are attached
const int Direct_Left_Right_X = A0;
const int TxRxPin = A5;
const int ShootPin = 2;
 int Button1 = 3;
 int Button2 = 4;
 int Button3 = 5;
 int Button4 = 6;




int    ButtonState;
int    ButtonReading;
int    ShootState;
int    DirFinal;
int    DirValue;
int    SpdValue;
int    ThrottleMap;
int    ThrottleValue;
int    FireState;
int    LCDSpeedMap;

typedef struct roverRemoteData 
{
int    TX_ID; 
int    Speed;// The variable were the data from each sensor
int    Direction;// will be stored
int    Button;
int    Shoot;
int    Sensor5Data;// will be stored
int    CheckSum;
};

// The string that we are going to send trought rf
LiquidCrystal lcd(12, 13, 10, 9, 8, 7);

void setup() 
    {
    Serial.begin(9600);
    lcd.begin(8,2);
    lcd.print("Starting");
    delay(1000);
 // buttons
    pinMode(Button1,INPUT);
    digitalWrite(Button1, HIGH);
    pinMode(Button2,INPUT);
    digitalWrite(Button2, HIGH);
    pinMode(Button3,INPUT);
    digitalWrite(Button3, HIGH);
    pinMode(Button4,INPUT);
    digitalWrite(Button4, HIGH);
    
    pinMode(ShootPin,INPUT);
    digitalWrite(ShootPin,HIGH);
    pinMode(TxRxPin,OUTPUT);
 // Sensor(s)
    pinMode(Throttle_Direct_Y,INPUT);
    pinMode(Direct_Left_Right_X,INPUT);
 // VirtualWire setup
    vw_setup(2000); // Bits per sec
    vw_set_tx_pin(11);
    }
 
void loop() 
 {
  SpdValue = analogRead(Throttle_Direct_Y);//read joystick   Y
  DirValue = analogRead(Direct_Left_Right_X);//read joystick X
  //Serial.print(SpdValue  );
  //Serial.println(DirValue);
  
  if (SpdValue > 490 && SpdValue < 516 && DirValue > 490 && DirValue < 540 )    
     { 
      DirFinal = 0; 
      ThrottleMap= 0;
      lcd.setCursor(0, 1);
      lcd.print("Stopped");
     }// Stopped
  if (SpdValue > 530 && DirValue > 400 && DirValue < 600)
     
     { 
      DirFinal = 2;
      ThrottleMap= map(SpdValue,500,1023,0,250);
      lcd.setCursor(0, 1);
      lcd.print("Forward");  
      }// Forward
  if (SpdValue < 500 && DirValue > 400 && DirValue < 600)
     { 
      DirFinal = 1;
      ThrottleMap= map (SpdValue,500,5,0,250);
      lcd.setCursor(0, 1);
      lcd.print("Reverse");  
      }// Backward
  if (DirValue < 495 && SpdValue > 400 && SpdValue < 600)  
     { 
      DirFinal = 3;
      ThrottleMap= map(DirValue,500,5,0,250);
      lcd.setCursor(0, 1);
      lcd.print("Left");  
      }// Left
  if (DirValue > 530 && SpdValue > 400 && SpdValue < 600) 
     { 
      DirFinal = 4;
      ThrottleMap= map(DirValue,500,1023,0,250); 
      lcd.setCursor(0, 1);
      lcd.print("Right");  
      }// Right
      
      LCDSpeedMap = map(ThrottleMap,0,250,0,100);
                      lcd.clear();
                      lcd.setCursor(1, 1);
                      lcd.print("Spd:");
                      lcd.print(LCDSpeedMap);
                      lcd.print("%");
      
  // Reading buttons and sending.
     ButtonReading = digitalRead(Button1);
     if (ButtonReading == LOW)
        { ButtonState = 1; }
        else
       {    
         ButtonReading = digitalRead(Button2);
           if (ButtonReading == LOW)
             { ButtonState = 2; }
             else
              { 
               ButtonReading = digitalRead(Button3);
               if (ButtonReading == LOW)
                  { ButtonState = 3; }
                  else
                   {
                     ButtonReading = digitalRead(Button4);
                       if (ButtonReading == LOW)
                           { ButtonState = 4; }
                           else
                           { ButtonState = 0; }
     }
   }
 }
   
        // Shooting fire pin state
     ShootState = digitalRead(ShootPin); 
     if (ShootState == LOW)
     {FireState = 1;}
     else
     {FireState = 0;}
 
  //Compile Struct to send
 //Serial.println(DirFinal);
    struct roverRemoteData payload;
  
  payload.TX_ID = 3;
  payload.Speed = ThrottleMap;
  payload.Direction = DirFinal;// analogRead(Sensor1Pin);
  payload.Button = ButtonState;// analogRead(Sensor2Pin);
  payload.Shoot = FireState; // analogRead(Sensor3Pin);
  payload.Sensor5Data = 0;// analogRead(Sensor4Pin);
  payload.CheckSum = 1;// analogRead(Sensor1Pin);
  
vw_send((uint8_t *)&payload, sizeof(payload));
vw_wait_tx();

 //Serial.println(roverRemoteData.payload);
 digitalWrite(TxRxPin,HIGH);
 //delay(1);
 digitalWrite(TxRxPin,LOW);
 // Turn off a light after transmission
 //delay(1000);// to be removed when testing 
}

debug result.jpg

The best way to get this going is to connect the Arduino on the rover to to your PC. Chock the rover up so it can't get away. Then put debug prints in to the code running on the rover.

Now a bit of your code

void loop()
{
  // struct roverRemoteData receivedData;
struct roverRemoteData receivedData;
uint8_t rcvdSize = sizeof(receivedData);

if (vw_get_message((uint8_t *)&receivedData, &rcvdSize)) 
{ //debug prints co here or
  if (receivedData.TX_ID == 3) 
// here so we can see what you have really got
    {
     if(receivedData.Direction == 0)  
             {
              Serial.println("Stopped");
              digitalWrite(MDir1,0);
              digitalWrite(MDir2,0);
              analogWrite (MSpeed1,receivedData.Speed);
              analogWrite (MSpeed2,receivedData.Speed);
              digitalWrite(MDir3,0);
              digitalWrite(MDir4,0);
              analogWrite (MSpeed3,receivedData.Speed);
              analogWrite (MSpeed4,receivedData.Speed);
if (vw_get_message((uint8_t *)&receivedData, &rcvdSize))

IF &rcvdSize is the size of the buffer the it should read rcvdSize as you want the size of the buffer not the address of the var holding the size. However if its the number of bytes received. Let me check what vw_get_message() is doing.

Both rcvdSize and receivedData should be global.

Mark

if (vw_get_message((uint8_t *)&receivedData, &rcvdSize))

I'v just downloaded VirtualWire and looked at the code and &rcvdSize is correct as its use to both provide the max size of the buffer and return the number of bytes that virtualWire copied to the buffer.

But &receivedData needs to lose the &. The name of an array or instance of a struct is already a pointer.

Try,

if (vw_get_message(receivedData, &rcvdSize) )

Look in the virtulWire examples that come with the lib.

You would help if everyone if you auto format your code.

Mark

Hi Mark

iv i make you changes i get this error on both sides

Rover_RX_Final:64: error: cannot convert 'roverRemoteData' to 'uint8_t*' for argument '1' to 'uint8_t vw_get_message(uint8_t*, uint8_t*)'

PS thanx for the Auto format tip , i forgot bout is completely