VirtualWire speed problem ?

Hello,

I'm using virtualWire to control my micro rover.

It works well, but I can't have a continuous move:

I transmit data continuously, but my rover is stopping after each order.
I've tried to change wireless communication with serial transmitting and it work really well, so the problem might be on this line :

if (vw_get_message(buf, &buflen))

It seem to take time to execute, nearly blocking...
Anyone know how is it possible to make my rover moving like RC car ?

I use motorSpeed2 library.

My loop :

int ordre;

    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;
    if (vw_get_message(buf, &buflen)) // Non-blocking
    {
      int i;
      for (i = 0; i < buflen; i++)
      {
        Serial.println(buf[i]);
        ordre = buf[i];
      }
    
    if(mode == 1){
      if (ordre == 'F'){
        mode = 0;
      }else{
        mode_auto();
      }
    }else{  
      switch (ordre) {
          case 'A':
            avancer();
            motor_standby(true);
            break;
            
          case 'B':
            reculer();
            motor_standby(true);
            break;
            
          case 'C':
            tournerDroite();
            motor_standby(true);
            break;
            
          case 'D':
            tournerGauche();
            motor_standby(true);
            break;
            
          case 'E':
            mode = 1;
            break;
            
          case 'F':
            mode = 0;
            break;
            
          case 'S':
            stopper();
            break;
          }
        }
      }

and an example of function :

void avancer()
{
  motor_speed2(motor_A,20);
  motor_speed2(motor_B,25);
  delay(1000);
}

Thx in advance and sorry for my bad english.

MadProf

Try using a "do while" loop instead of an if statement.
do{
move motor
see if A is there
}while (A is there);

My RC car does not delay after setting the motor speed:

void avancer()
{
  motor_speed2(motor_A,20);
  motor_speed2(motor_B,25);
[glow]  delay(1000);
[/glow]}

I'm pretty sure your Arduino-driven car will be more responsive if you don't do this, either.

What do the two hard-coded values (20 and 25) mean? What does the motor_speed2 function do?

Thanx for your responses,

The 2 values 20 and 25 are motors's speed. My little tank is a cheap one so I must trim to go straight :-[

I've tested first without the delay, but the motors never run...

I use a code by JoakimCh from this forum to control my motor driver TB6612FNG :
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1263858213

And the full code:

#include <VirtualWire.h>

//declaration des pins du controleur de moteurs
#define out_A_PWM 3
#define out_A_IN2 2
#define out_A_IN1 4
#define out_STBY 5
#define out_B_PWM 6
#define out_B_IN2 7
#define out_B_IN1 8
#define motor_A 0
#define motor_B 1
#define motor_AB 2

//IR Detection
int irPin = 11;   // capteur IR connecté sur pin 11
int val = 0;

int mode = 0; //0 = radio 1 = auto 

void setup()
{  
  pinMode(irPin, INPUT);
  
  //configuration des pins du controleur de moteurs
  pinMode(out_STBY,OUTPUT);
  pinMode(out_A_PWM,OUTPUT);
  pinMode(out_A_IN1,OUTPUT);
  pinMode(out_A_IN2,OUTPUT);
  pinMode(out_B_PWM,OUTPUT);
  pinMode(out_B_IN1,OUTPUT);
  pinMode(out_B_IN2,OUTPUT);
  
  vw_setup(2000); // Bits per sec
  vw_set_rx_pin(9);
  vw_rx_start(); // Start the receiver PLL running
}


int lireCapteurDistance(){
  //detection IR digital (10cm)
  val = digitalRead(irPin);
  return val;
}

void loop()
{
  int ordre;

  uint8_t buf[VW_MAX_MESSAGE_LEN];
  uint8_t buflen = VW_MAX_MESSAGE_LEN;
    
  if (vw_get_message(buf, &buflen)) // Non-blocking
  {
    int i;
    // Message with a good checksum received, dump HEX
    for (i = 0; i < buflen; i++)
    {
      ordre = buf[i];
    }

    if(mode == 1){
      if (ordre == 'F'){
        mode = 0;
      }else{
        mode_auto();
      }
    }else{   
      switch (ordre) {
          case 'A':
            avancer();
            motor_standby(true);
            break;
            
          case 'B':
            reculer();
            motor_standby(true);
            break;
            
          case 'C':
            tournerDroite();
            motor_standby(true);
            break;
            
          case 'D':
            tournerGauche();
            motor_standby(true);
            break;
            
          case 'E':
            mode = 1;
            break;
            
          case 'F':
            mode = 0;
            break;
            
          case 'S':
            stopper();
            break;
          }
        }
  }

}

void mode_auto(){
 //Serial.println(lireCapteurDistance()); 
 //TODO
}


void avancer()
{
  motor_standby(false);
  motor_speed2(motor_A,20);
  motor_speed2(motor_B,25);
}

void reculer()
{
  motor_standby(false);
  motor_speed2(motor_A,-20);
  motor_speed2(motor_B,-25);
}

void stopper()
{
  motor_brake(motor_A);
  motor_brake(motor_B);
}

void tournerGauche()
{
  motor_standby(false);
  motor_speed2(motor_A,20);
  motor_speed2(motor_B,-25);
}

void tournerDroite()
{
  motor_standby(false);
  motor_speed2(motor_A,-20);
  motor_speed2(motor_B,25);
}



void motor_speed2(boolean motor, char speed) { //speed from -100 to 100
  byte PWMvalue=0;
  PWMvalue = map(abs(speed),0,100,50,255); //anything below 50 is very weak
  if (speed > 0)
    motor_speed(motor,0,PWMvalue);
  else if (speed < 0)
    motor_speed(motor,1,PWMvalue);
  else {
    motor_coast(motor);
  }
}
void motor_speed(boolean motor, boolean direction, byte speed) { //speed from 0 to 255
  if (motor == motor_A) {
    if (direction == 0) {
      digitalWrite(out_A_IN1,HIGH);
      digitalWrite(out_A_IN2,LOW);
    } else {
      digitalWrite(out_A_IN1,LOW);
      digitalWrite(out_A_IN2,HIGH);
    }
    analogWrite(out_A_PWM,speed);
  } else {
    if (direction == 0) {
      digitalWrite(out_B_IN1,HIGH);
      digitalWrite(out_B_IN2,LOW);
    } else {
      digitalWrite(out_B_IN1,LOW);
      digitalWrite(out_B_IN2,HIGH);
    }
    analogWrite(out_B_PWM,speed);
  }
}

void motor_standby(boolean state) { //low power mode
  if (state == true)
    digitalWrite(out_STBY,LOW);
  else
    digitalWrite(out_STBY,HIGH);
}

void motor_brake(boolean motor) {
  if (motor == motor_A) {
    digitalWrite(out_A_IN1,HIGH);
    digitalWrite(out_A_IN2,HIGH);
  } else {
    digitalWrite(out_B_IN1,HIGH);
    digitalWrite(out_B_IN2,HIGH);
  }
}

void motor_coast(boolean motor) {
  if (motor == motor_A) {
    digitalWrite(out_A_IN1,LOW);
    digitalWrite(out_A_IN2,LOW);
    digitalWrite(out_A_PWM,HIGH);
  } else {
    digitalWrite(out_B_IN1,LOW);
    digitalWrite(out_B_IN2,LOW);
    digitalWrite(out_B_PWM,HIGH);
  }
}

MadProf

You are turning the motors on in the various directional functions. As soon as the functions end (immediately, without the delay), you shut them off. Why are you doing that? You shouldn't need to change the motor values unless a different direction is needed.

That's the was a RC car works (except the controls are spring loaded so they want to return to idle/center).

Yes I've tried without shuting off the motor, but in this case the motors never stopped... and I can't receive anymore, as if the function motor_speed2 was blocking.

What's up with this?

void motor_speed2(boolean motor, char speed)

The motor to use is the first argument. That's not a boolean. A byte, maybe.
The second argument if the speed, from -255 to 255. That's not a char. It should be an int.

Some Serial.print() statements might help identify where the holdup is. motor_speed2() and motor_speed() do not appear to be the culprits, though.

I've tested with several println to know where the pb occurs.
The first order receive is read correctly and after that the program never enter the "if (vw_get_message(buf, &buflen))" condition. The main loop is still running.

Hello,
I'm just retrying other things to solve my pb but I stille have the same issue.
I've tried to simplify the code in order to determine where the pb is.

#include <VirtualWire.h>

//declaration des pins du controleur de moteurs

#define out_A_PWM 3
#define out_A_IN2 2
#define out_A_IN1 4
#define out_STBY 5
#define out_B_PWM 6
#define out_B_IN2 7
#define out_B_IN1 8

int ordrePrecedent = 0;
int ordre = 0;

void setup()
{
  //pins configuration
  pinMode(out_STBY,OUTPUT);
  pinMode(out_A_PWM,OUTPUT);
  pinMode(out_A_IN1,OUTPUT);
  pinMode(out_A_IN2,OUTPUT);
  pinMode(out_B_PWM,OUTPUT);
  pinMode(out_B_IN1,OUTPUT);
  pinMode(out_B_IN2,OUTPUT);
  
  vw_setup(2400); // Bits per sec
  vw_set_rx_pin(9);
  vw_rx_start(); // Start the receiver PLL running
  analogWrite (out_A_PWM, 80);//set motors speed
  analogWrite (out_B_PWM, 80);
  Serial.begin(9600);
  Serial.println("setup");
}

void loop()
{
     
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;
    
    // PB: while digitalWrite(out_STBY,HIGH), no reception possible. 
    // out_STBY must be set to LOW in order to get new message, so I can't have a continuous move...
    if (vw_get_message(buf, &buflen)) // Non-blocking
    {
      int i;
      // Message with a good checksum received, dump HEX
      Serial.print("Got: ");
      for (i = 0; i < buflen; i++)
      {
        Serial.println(buf[i]);
        ordre = buf[i];
      }
      
      if(ordre!=ordrePrecedent){
        switch (ordre) {
          case 'A':
            avancer();
            break;
            
          case 'B':
            reculer();
            break;
            
          case 'C':
            tournerDroite();
            break;
            
          case 'D':
            tournerGauche();
            break;
            
          case 'E':
            //mode = 1;
            break;
            
          case 'F':
            //mode = 0;
            break;
            
          case 'S':
            stopper();
            break;
          }
          ordrePrecedent=ordre;
      }
  }
}


void avancer()
{
  digitalWrite(out_STBY,HIGH);
  digitalWrite(out_A_IN2, LOW);
  digitalWrite(out_A_IN1, HIGH);
  digitalWrite(out_B_IN2, LOW);
  digitalWrite(out_B_IN1, HIGH);
}

void reculer()
{
  digitalWrite(out_STBY,HIGH);
  digitalWrite(out_A_IN2, HIGH);
  digitalWrite(out_A_IN1, LOW);
  digitalWrite(out_B_IN2, HIGH);
  digitalWrite(out_B_IN1, LOW);
}

void stopper()
{
  digitalWrite(out_STBY,LOW);
}

void tournerGauche()
{
  digitalWrite(out_STBY,HIGH);
  digitalWrite(out_A_IN2, HIGH);
  digitalWrite(out_A_IN1, LOW);
  digitalWrite(out_B_IN2, LOW);
  digitalWrite(out_B_IN1, HIGH); 
}

void tournerDroite()
{
  digitalWrite(out_STBY,HIGH);
  digitalWrite(out_A_IN2, LOW);
  digitalWrite(out_A_IN1, HIGH);
  digitalWrite(out_B_IN2, HIGH);
  digitalWrite(out_B_IN1, LOW);
}

I know what the pb is but don't know how to fix it. While digitalWrite(out_STBY,HIGH), no reception possible.
out_STBY must be set to LOW in order to get new message, so I can't have a continuous move. Does someone use this motor driver with vitualWire ?
Why out_STBY=HIGH is a prb to receive datas ?

MadProf