Jumpy motor control due to software

Hi, I have been working on a remote control car. I have gotten it to the remote point however forward and reverse are very jumpy. What happens is the car has spurts of speed, and wrong direction spurts. I would like to eliminate the spurts in the wrong direction and even out the correct direction spurts.

The wireless uses a basic 433 Mhz module. I bought the modules on Ebay at this site:
http://www.ebay.com/itm/261143280474?_trksid=p2060778.m2749.l2649&ssPageName=STRK%3AMEBIDX%3AIT

The motor and steering control are based off of the L293D. The motor also has an h-bridge I made to increase current capability.

The main problem is in the code, I beleive. I am currently using pulse width modulation. One pulse I send through is between 500 and 1000 micro seconds and is for forward and reverse. The other is between 1500 and 2000 micro seconds and holds the data for left and right.

It is possible, with my home made bridge to short circuit the bridge and burn up the tip120 s and tip125 s. So I made a stopCar() function to keep the bridge from getting too hot and braking. This could be part of the problem since there is a recursive call to stop car in the goForward() function.

This is the main code.

/*Stenquist
test on sending digital data with 
FS1000A
09/03/2014*/

//pins
  //receiver
int in1 = 3;//BusA p1
int in2 = 2;//BusA d1
  //control of car
int forward1 = 7;//Bus B d1
int forward2 = 8;//Bus b d2
int forwardSpeed = 9;//Bus b p1

int reverse1 = 10; //Bus B p2
int reverse2 = 12; //bus b d3
int reverseSpeed = 11; // bus b p3

int left = 4;//bus A d2
int right = 13;//bus A d3
int amountTurned = 5;//bus a p2
  
//global vars
//boolean sender = true;
volatile int amountFR = -1;
volatile int amountLR = -1;
//remember volatile(changes)
volatile unsigned long signal = -1;
volatile unsigned long time1 = -1;
volatile unsigned long time2 = -1;
volatile unsigned long count = 0;
volatile boolean even = true;

volatile boolean forward = true;
volatile boolean reverse = true;

void setup()
{ 
  Serial.begin(9600);
  pinMode(forward1, OUTPUT);
  pinMode(forward2, OUTPUT);
  pinMode(forwardSpeed, OUTPUT);
  pinMode(reverse1, OUTPUT);
  pinMode(reverse2, OUTPUT);
  pinMode(reverseSpeed, OUTPUT);
  
  stopCar();
  
  pinMode(left, OUTPUT);
  pinMode(right, OUTPUT);
  pinMode(amountTurned, OUTPUT);
  
  goStraight();
  
  pinMode(in2, INPUT);
  pinMode(in1, INPUT);
  
    //attachInterrupt(0, timing, CHANGE);
    attachInterrupt(0, timing1, RISING);
    attachInterrupt(1, timing2, FALLING);
  
}

void loop()
{  
  //noInterrupts();
    Serial.print("received ");
    Serial.println(signal);

  if(signal < 2000 && signal > 1400)
  {
    amountLR = signal - 1000;
    Serial.print("amountLR ");
    Serial.println(amountLR);
  } 
  else if(signal < 1000 && signal > 400)
  {
    amountFR = signal;
    Serial.print("amountFR ");
    Serial.println(amountFR);
  }
 //noInterrupts();
 Serial.println();
  
 //control speed
 if(amountFR > 750)
 {
   goForward(1, 255);
 } 
 else if(amountFR > 550 && amountFR < 710 )
 {
   stopCar(); 
 }
 else if (amountFR < 600)
 {
   goBack(1, 255); //needs work
 }
 //interrupts();
 
 //control direction
  if(amountLR > 800)
 {
   goRight();//0, (amountFR - 450)/250);
 } 
 else if(amountLR > 700 && amountLR < 800 )
 {
   goStraight(); 
 }
 else
 {
   goLeft(); 
 }
  delay(1000);
}//end loop

void timing1()
{
 time1 = micros(); 
 
}

void timing2()
{
 time2 = micros();
  signal = (time2 - time1) ;
}

This is where the functions are found.

void goForward(int time,  int velocity)  //velocity 
{
  if(reverse == false)
  {
    digitalWrite(forward1, LOW);
    digitalWrite(forward2, HIGH);
    analogWrite(forwardSpeed, velocity);
  }
  else
  {
    stopCar();
    goForward(0, velocity);
  }
  forward = true;
  delay(time);
}

void goBack(int time,  int velocity)
{
  if(forward == false)
  {
    digitalWrite(reverse1, LOW);
    digitalWrite(reverse2, HIGH);
    analogWrite(reverseSpeed, velocity);
  }
  else
  {
    stopCar();
    goBack(0, velocity);
  }
  reverse = true;
  delay(time);
}

void stopCar(/*int time*/)
{
  digitalWrite(forward1, HIGH);
  digitalWrite(forward2, LOW);
  digitalWrite(reverse1, HIGH);
  digitalWrite(reverse2, LOW);
  
  forward = false;
  reverse = false;
  
  delay(10);
}

void goRight()
{
   analogWrite(amountTurned, 255);
   digitalWrite(left, LOW);
   digitalWrite(right, HIGH);
   
}

void goLeft()
{  
   analogWrite(amountTurned, 255);
   digitalWrite(right, LOW );
   digitalWrite(left, HIGH);
}

void goStraight()
{
  digitalWrite(right, LOW);
  digitalWrite(left, LOW);
  digitalWrite(amountTurned, LOW);
}

Any help with this problem would be greatly appreciated!

Can you provide a comprehensive description of how your code is supposed to work.

For example,

What is causing the interrupts?

What role has PWM to play (if any) apart from controlling the speeds of the motors?

...R

It sounds like you are sending control data using PWM on 433mhz, possibly because this is what your controller is generating

This is not a good way to send data, and if you are doing it this way, its antisocial as 433mhz is a shared frequency for all users in your locality e.g wireless door bells, wireless temperature sensors etc etc

If you are doing what I think you are doing, your transmitter will be constantly sending data and blocking other people's use of 433mhz

You should send data using Virtual wire, from another arduino in the form of data not PWM, as this will allow you to just send data when there is a change in your controls

The controller is constantly sending as rogerClark guessed. This was a simple way to transmit so I thought I would try it. I know the transmitter/receiver needs work and I would like to learn more about the virtualWire library if you have a good link to how to use it. I have tried to use virtualWire before but it has a lot of lag as I recall. This might be because I was using code from an example that transmitted characters. I don't know how to use virtualWire to send numbers.

My main question for this post though is why would the motor be jumping from forward to reverse.

The idea is to use two interrupts, one rising and one falling, to get the length of the pulse sent from the transmitter. Depending on the length of the pulse it is assigned to the signal for left-right or forward-reverse. Then depending on the signal the arduino should set forward-reverse, left-right to high or low. Right now there is no middle ground or no speed between forward and stop, since that requires more time to get the code right. I am trying to get the basic signal through then work on the details.

One problem with my current code is it can receive the signal for say steering several times before it receives the signal for speed. This can cause delays and needs to be fixed.

After it has the signal, the code calls a function and that function sends the signal to the motors. There is a recursive call in the forward and reverse functions to prevent forward and reverse being called at the same time.

I would drop the recursive call and just improve the stopCar() function to do whatever is needed.

I would simplify the reading of the pulses so that different pulse widths cause appropriate state variable to be set. For example (using made up numbers)

if (pulseWidth > 2000) {
    forward = true;
    reverse = false;
}
else if (pulseWidth > 1700) {
    forward = false;
    reverse = false;
}
else if (pulseWidth > 1400) {
    forward = false;
    reverse = true;
}
else if (pulseWidth > 1100) {
     turnRight = true;
     turnLeft = false;
}
else ... etc etc

Then the code to move the motors or the steering will be based on the sate variables

I can't remember if you are using the pulsewidths to represent speed as well as Fwd/Rev, but that could easily be picked up in the appropriate IF statement.

BUT ... as @rogerClark has said the code would be much more reliable and versatile if you transmit data rather than pulsewidths..

...R