Virtualwire RF receiver and motors control

Hello,

I’m building a remote controlled car via RF link. The car itself is controlled by an arduino connected to a RF receiver and a set H-bridge (connected to two motors).

RF link is working fine with Virtualwire.

Once the RF receiver get the message from the transmitter, depending on the message the motors are moved forward, backward or each one in different directions (left and right direction of the car).

However, the problem is that after the first message is received and the action is done correctly (for example moving forward) the receiver doesn’t get any second message.

Here is the code:

#include <VirtualWire.h>

#define MOTOR1_CTL1  8  // I1
#define MOTOR1_CTL2  9  // I2
#define MOTOR1_PWM   11 // EA

#define MOTOR2_CTL1  6  // I3
#define MOTOR2_CTL2  7  // I4
#define MOTOR2_PWM   10 // EB

#define MOTOR_DIR_FORWARD  0
#define MOTOR_DIR_BACKWARD   1

void setup()
{
    // Setup pins for motor 1
   pinMode(MOTOR1_CTL1,OUTPUT);
   pinMode(MOTOR1_CTL2,OUTPUT);
   pinMode(MOTOR1_PWM,OUTPUT);
   
  // Setup pins for motor 2
   pinMode(MOTOR2_CTL1,OUTPUT);
   pinMode(MOTOR2_CTL2,OUTPUT);
   pinMode(MOTOR2_PWM,OUTPUT); 
   Serial.begin(9600);	// Debugging only
    
    // Initialise the IO and ISR
    vw_set_rx_pin(12);
    vw_set_ptt_inverted(true); // Required for DR3100
    vw_setup(2000);	 // Bits per sec
    
    vw_rx_start();       // Start the receiver PLL running
}

void loop()
{
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;
    
    if (vw_get_message(buf, &buflen)) // Non-blocking
    {
	switch (buf[0])
        {
	  case 50:
	    //FORWARD           
            motorStart(1, MOTOR_DIR_FORWARD);  
            setSpeed(1, 200);
            motorStart(2, MOTOR_DIR_FORWARD);      
            setSpeed(2, 200);
            break;
          case 52:
	    //LEFT
            motorStart(1, MOTOR_DIR_BACKWARD);  
            setSpeed(1, 140);
            motorStart(2, MOTOR_DIR_FORWARD);      
            setSpeed(2, 140);
	    break;
          case 53:
	    //STOP
            motorStop(1);
            motorStop(2);
            break;
          case 54:
	    //RIGHT
            motorStart(1, MOTOR_DIR_FORWARD);  
            setSpeed(1, 140);
            motorStart(2, MOTOR_DIR_BACKWARD);      
            setSpeed(2, 140);
            break;
          case 56:
	    //BACKWARD
            motorStart(1, MOTOR_DIR_BACKWARD);  
            setSpeed(1, 200);
            motorStart(2, MOTOR_DIR_BACKWARD);      
            setSpeed(2, 200);
	    break;
        }
    } 
}

void setSpeed(char motor_num, char motor_speed)
{
   if (motor_num == 1)
   {
      analogWrite(MOTOR1_PWM, motor_speed);
   }   
   else
   {
      analogWrite(MOTOR2_PWM, motor_speed);
   }
}

void motorStart(char motor_num, byte direction)
{
  
   char pin_ctl1;
   char pin_ctl2;
   
   if (motor_num == 1)
   {
      pin_ctl1 = MOTOR1_CTL1;
      pin_ctl2 = MOTOR1_CTL2;
   }   
   else
   {
      pin_ctl1 = MOTOR2_CTL1;
      pin_ctl2 = MOTOR2_CTL2;     
   }
  
   switch (direction)
   {
     case MOTOR_DIR_FORWARD:
     {
       digitalWrite(pin_ctl1,LOW);
       digitalWrite(pin_ctl2,HIGH);          
     }
     break; 
          
     case MOTOR_DIR_BACKWARD:
     {
        digitalWrite(pin_ctl1,HIGH);
        digitalWrite(pin_ctl2,LOW);          
     }
     break;         
   }
}

void motorStop(char motor_num)
{
   setSpeed(motor_num, 0);
   if (motor_num == 1)
   {
     digitalWrite(MOTOR1_CTL1,HIGH);
     digitalWrite(MOTOR1_CTL2,HIGH);     
   }
   else
   {
     digitalWrite(MOTOR2_CTL1,HIGH);
     digitalWrite(MOTOR2_CTL2,HIGH);     
   }
}

I did some trobleshooting with “Serial.print” commands and I detected that the program is not blocked, so loop function is repeating and repeating. However, with the second message it is not entering the condition “if (vw_get_message(buf, &buflen))”, meaning the second message is not detected.

On the other hand, I tested to do the same without calling the external functions motorStart, motorStop or setSpeed. In this case, the second and further massages are processed correctly (the program is entering the “if” condition properly). That means, only when some motor starts to run, the next message is not processed anymore.

Do you have some ideas why is this happening?

Thanks for your support!!
Pablo

Some help?

get rid of this unless you have a part with push to talk feature.

vw_set_ptt_inverted(true); // Required for DR3100

Change these case 50:

to case 'letter': that you are sending.

I have exactly the same problem. Is there any solution for it?