firefighter racecar - serial xbee easydriver stepper

Hi all,

I am making a firefighter-racecar to learn the program basics.
3 ardiuno's 3 xbee's joystickschield and the big easy driver and polulu motor driver etcetera...
I ran into a problem with giving pulses to the easydriver. My code is receiving data from serial port and adds it to variables so i have a simple remote control.
Almost Everything is working right now, sending pwm and direction to the DC motor driver, steering with the racecar servo.
All remote with the joystick schield, ardiuno and xbee...

The code that doenst work is the code for giving pulses to the easydriver to step...
I think it can not use a DELAY or my code delays because the stepper motor turns really slow...

RECEIVER

/////////////////INCULDE////////////////

#include <Servo.h> 

/////////////////XBEE///////////////////

boolean checkBegin = false;
byte incomingByte;  
int buf[6];      
int i = 0;  
int r = 0;  
int gas;        
int stuur;        
int btn_1; 
int btn_2; 
int btn_3; 
int btn_4; 

/////////////////GAS////////////////////

int gasDir = 5;     // GASGEVEN DIRECTION 
int gasOut = 6;     // GASGEVEN MOTOR
int gasstop = 0;    // GASGEVEN PAUZE
int gasvoor = 0;    // GASGEVEN VOOR
int gasachter = 0;  // GASGEVEN ACHTER

/////////////////STUUR//////////////////

Servo myservo;

/////////////////STEPPER////////////////

//OUTPUTS
int STEP = 11;        // PIN 2 = STEP
int STEPDIR = 10;     // PIN 3 = DIR
//int SLEEP = 7;       // PIN 7 = SLP
//int MS1 = ?;      // PIN  = MS1
//int MS2 = ?;       // PIN  = MS2
//INPUTS
int RANGE = A6;
//SOFTWARE
//int SWEEP_LEFT= 0;
//int SWEEP_RIGHT= 0;

/////////////////SETUP//////////////////

void setup(){
Serial.begin(19200);       // serialsnelheid

//GAS
pinMode(gasDir, OUTPUT);
pinMode(gasOut, OUTPUT); 
pinMode(13, OUTPUT);     
//STUUR
myservo.attach(9);         // attaches the servo on pin 9 
myservo.write(90);
//STEPPER INPUT
//pinMode(RANGE, INPUT);
//analogRead(RANGE);
//STEPPER OUTPUT
pinMode(STEPDIR, OUTPUT);      // set pin 3 to output
pinMode(STEP, OUTPUT);         // set pin 2 to output
//pinMode(SLEEP, OUTPUT);      // set pin 12 to output
//digitalWrite(SLEEP, HIGH);
}

/////////////////BEGIN//////////////////

void loop () {
if (Serial.available() > 0) {
      digitalWrite(13, LOW); 
      r=0;
      incomingByte = Serial.read();
      if(checkBegin == true){
        
      buf[i] = int(incomingByte);
      i++;
      if(i==6){
      checkBegin = false;
      processPackage(); 
      }
    // BUFFER VULLEN
      }else{
    // BEGIN BUFFER CHECK
      i = 0;
      if(int(incomingByte) == 255){ 
      checkBegin = true;
      }
    }
}   
// NIET BESCHIKBAAR RESET
else if((Serial.available() == 0) && (r < 32000)){
r++;
}
else {
gasstop = 0;
analogWrite (gasOut, gasstop);
  digitalWrite(13, HIGH);   // set the LED on
// int stuur = 60;
//btn_1 = HIGH;
//btn_2 = HIGH;
//btn_3 = HIGH;
//btn_4 = HIGH;
}

} // einde loop

/////////////////BEGIN//////////////////

void processPackage(){
  //VULVARS
  gas   = buf[0];
  stuur = buf[1];
  btn_1 = buf[2];
  btn_2 = buf[3];
  btn_3 = buf[4];
  btn_4 = buf[5];

  //MIDDEN 
  if (gas > 125 && gas < 135) 
  {       
   gasstop = 0;
   analogWrite (gasOut, gasstop);
  }
  //LAAG
   else if (gas < 125) 
  {  
   gasachter = map (gas, 125, 0, 0, 200);
   digitalWrite(gasDir, HIGH); //Reverse motor direction, 1 high, 2 
   analogWrite (gasOut, gasachter);
  }
  //HOOG 
   else if (gas > 135) 
  {
   gasvoor = map (gas, 135, 250, 0, 200);
   digitalWrite(gasDir, LOW);  //Reverse motor direction, 1 high, 2 
   analogWrite (gasOut, gasvoor); 
  }
  

/////////////////STUUR//////////////////

   stuur = map(stuur, 0, 179, 0, 179);     // scale it to use it with the servo (value between 0 and 180) 
   myservo.write(stuur);                   // sets the servo position according to the scaled value 
  
/////////////////STEPPER////////////////
  
  
// STEPPER BUTTONS  
  if (btn_1 == LOW) {     
         gotoRight();
         digitalWrite(STEP, LOW);  
         delayMicroseconds(100);           
         digitalWrite(STEP, HIGH);
         delayMicroseconds(100); 
    } 

  if (btn_4 == LOW) {
         gotoLeft(); 
         digitalWrite(STEP, LOW);    
         delayMicroseconds(100); 
         digitalWrite(STEP, HIGH); 
         delayMicroseconds(100);
  }
    
  if (btn_2 == LOW) {
  //
  }
  
  if (btn_3 == LOW) {
  //
  }
           
}// EINDE PROCES PACKAGE


// STEPPER FUNCTIONS
  void gotoLeft(){
         digitalWrite(STEPDIR, LOW); 
         
         //delay(5); 
  }
  void gotoRight(){ 
         digitalWrite(STEPDIR, HIGH); 
          
        // delay(5); 
  }

SENDER

byte buf[7];           // an array of pin numbers to which LEDs are attached
//                     byte buf2[] = {1,2,3,4,5,6};
int len = 7;           // the number of pins (i.e. the length of the array)

int analogPin1 = 0;  int analogPin0 = 1;  int analogPin2 = 2;  int analogPin3 = 3;  

int digitalPin3 = 3; int digitalPin4 = 4; int digitalPin5 = 5; int digitalPin6 = 6; 

int val0 = 0; int val1 = 0;    // variable to store the value read ana        

int val2 = 0; int val3 = 0; int val4 = 0; int val5 = 0; // variable to store the value read dig           

int sensorValue1 = 0;      
int sensorValue2 = 0;    

void setup(){
Serial.begin(19200);               //  setup serial

pinMode(digitalPin3, INPUT);      // sets the digital pin 3 as input
digitalWrite(digitalPin3, HIGH);      // sets the digital pin 3 high
pinMode(digitalPin4, INPUT);      // sets the digital pin 4 as input
digitalWrite(digitalPin4, HIGH);      // sets the digital pin 4 high
pinMode(digitalPin5, INPUT);      // sets the digital pin 5 as input
digitalWrite(digitalPin5, HIGH);      // sets the digital pin 5 high
pinMode(digitalPin6, INPUT);      // sets the digital pin 6 as input
digitalWrite(digitalPin6, HIGH);      // sets the digital pin 6 high
}

void loop(){
  
sensorValue1 = analogRead(analogPin0); //gas
sensorValue2 = analogRead(analogPin3); //stuur

//val0 = analogRead(A0);    // read the input pin
//val1 = analogRead(A1);    // read the input pin

val0 = map (sensorValue1, 0, 1023, 0, 250);
val1 = map (sensorValue2, 0, 1023, 0, 180);

val2 = digitalRead(3);   // read the input pin
val3 = digitalRead(4);   // read the input pin
val4 = digitalRead(5);   // read the input pin
val5 = digitalRead(6);   // read the input pin

buf[0] =  byte (255); // check voor begin an array
buf[1] =  byte (val0);
buf[2] =  byte (val1);
buf[3] =  byte (val2);
buf[4] =  byte (val3);
buf[5] =  byte (val4);
buf[6] =  byte (val5);

Serial.write(buf, len); 

//Serial.write(buf2, len); 

//Serial.print(val0);             // debug value
//Serial.print(val1);             // debug value
//Serial.print(val2);             // debug value
//Serial.print(val3);             // debug value
//Serial.print(val4);             // debug value
//Serial.println(val5);           // debug value

delay(100);

}

//void analog1(){}
//void analog2(){}
   stuur = map(stuur, 0, 179, 0, 179);     // scale it to use it with the servo (value between 0 and 180)

What? Map some value from the range 0 to 179 to a value in the range 0 to 179.

The code that doenst work is the code for giving pulses to the easydriver to step...

It is not at all clear how the easy driver is connected to the Arduino, so it is impossible to tell what part of the code is sending step information to the easy driver.

What, exactly, is the stepper motor doing?

You are right that you do not want to use delay() in your code. I think we need more information, though, in order to help you figure out what/where to replace, to make the stepper work correctly.

What are the other 2 Arduinos doing?

I have a picture to get a better view of the racecar:

1 arduino and xbee in the car to receive
1 arduino and xbee in the remote control with a joystick schield to send

edit*
1 arduino/jeenode/xbee
to be on top of the car/stepper reading a analogue sensors and powering the water kanon

The easydriver is conected to the arduino pins

10 direction
11 steps

The stepper motor needs to turn right or left depending what button i push on the remote.
The remote is sending 255 and then 6 byte. The receiver received the 255 then starts to fill the variables...

gas
steer
btn1
btn2
btn3
btn4

if btn 1 is low then the easydriver gets the pulses from the arduino pin 11...
There it gows wrong because it uses delay, or the receiver code also uses delay so my pulses from pin 11 are not fast enough to lett the stepper spin.

This default stepper code is working perfect

//////////////////////////////////////////////////////////////////
//©2011 bildr
//Released under the MIT License - Please reuse change and share
//Using the easy stepper with your arduino
//use rotate and/or rotateDeg to controll stepper motor
//speed is any number from .01 -> 1 with 1 being fastest - 
//Slower Speed == Stronger movement
/////////////////////////////////////////////////////////////////

#define DIR_PIN 10
#define STEP_PIN 11

void setup() {
  pinMode(DIR_PIN, OUTPUT);
  pinMode(STEP_PIN, OUTPUT);
} 

void loop(){ 



  //rotate a specific number of microsteps (8 microsteps per step)
  //a 200 step stepper would take 1600 micro steps for one full revolution
  rotate(1600, .5);
  delay(1000); 

  rotate(-1600, .25); //reverse
  delay(1000);
}

void rotate(int steps, float speed){
  //rotate a specific number of microsteps (8 microsteps per step) - (negitive for reverse movement)
  //speed is any number from .01 -> 1 with 1 being fastest - Slower is stronger
  int dir = (steps > 0)? HIGH:LOW;
  steps = abs(steps);

  digitalWrite(DIR_PIN,dir); 

  float usDelay = (1/speed) * 70;

  for(int i=0; i < steps; i++){
    digitalWrite(STEP_PIN, HIGH);
    delayMicroseconds(usDelay); 

    digitalWrite(STEP_PIN, LOW);
    delayMicroseconds(usDelay);
  }
}

What, exactly, is the stepper motor doing?

Missed one...

PaulS:

What, exactly, is the stepper motor doing?

Missed one...

Added right now :slight_smile: thanks for helping

What we have here is a failure to communicate. Why is there a stepper motor at all?

It must have some reason for being there...

if btn 1 is low then the easydriver gets the pulses from the arduino pin 11...

What does btn 1 being low mean? Step once? Step 100 times? Step once ever n seconds, milliseconds, months, etc. until told to stop?

hehe yeah guns n roses :slight_smile:

The stepper is in the car to control the water kanon on top of the car... with the remote i can turn the stepper.

btn 1 is high in default state... if i push button 1 it will become low or 0
the low is then sended to my reciever and then the stepper needs to turn right until it becomes HIGH again

btn 4 is high in default state... if i push button 1 it will become low or 0
the low is then sended to my reciever and then the stepper needs to turn left until it becomes HIGH again

the low is then sended to my reciever and then the stepper needs to turn right until it becomes HIGH again

Stepper motors are like little soldiers. They don't do anything unless told to. If you want a soldier to march, you have to call cadence. Step, step, step, step. As soon as you stop, so do they. The faster you call step, the faster the soldiers go.

With your stepper motor, you can't just tell it to start turning one way or the other. You must set the direction and tell it to step on a regular basis. That regular basis can be defined using millis() to see if it is time to step again.

Add something like this to loop, after the code to read the serial data:

if(stepping)
{
   unsigned long now = millis();
   if(now - lastStep > stepTime)
   {
      step();
      lastStep = now;
   }
}

Then, what the code you have now does is simply set stepping to true or false, and set up the direction pin. Don't forget to declare the global variables stepping (boolean),lastStep and stepTime (unsigned long) and assign default values. Then, write the step() function to actually make the motor step.

Paul thanks you so much it works :), its difficult to understand what to do, and exactly what i did because im a beginner but i used that snipped and it works...

I think this code works because loop is reminding a boolean? So keeps repeating?
I am really happy:)

Here is the code...

/////////////////INCULDE////////////////

#include <Servo.h> 

/////////////////XBEE///////////////////
boolean checkBegin = false;
byte incomingByte;  
int buf[6];      
int i = 0;  
int r = 0;  
int gas;        
int stuur;        
int btn_1; 
int btn_2; 
int btn_3; 
int btn_4; 
/////////////////GAS////////////////////
int gasDir = 5;     // GASGEVEN DIRECTION 
int gasOut = 6;     // GASGEVEN MOTOR
int gasstop = 0;    // GASGEVEN PAUZE
int gasvoor = 0;    // GASGEVEN VOOR
int gasachter = 0;  // GASGEVEN ACHTER
/////////////////STUUR//////////////////
Servo myservo;
/////////////////STEPPER////////////////
int STEPDIR = 10;
int STEP = 11;

boolean steppingleft = false;
boolean steppingright = false;
unsigned long stepTimeleft = 0;
unsigned long stepTimeright = 0;
unsigned long lastStepleft = 0;
unsigned long lastStepright = 0;


/////////////////SETUP//////////////////
void setup(){
Serial.begin(19200);       // serialsnelheid
//GAS
pinMode(gasDir, OUTPUT);
pinMode(gasOut, OUTPUT); 
pinMode(13, OUTPUT);     
//STUUR
myservo.attach(9);         // attaches the servo on pin 9 
myservo.write(90);
//STEPPER OUTPUT
pinMode(STEPDIR, OUTPUT);      // set pin 3 to output
pinMode(STEP, OUTPUT);         // set pin 2 to output
}
/////////////////BEGIN//////////////////
void loop () {
if (Serial.available() > 0) {
      digitalWrite(13, LOW); 
      r=0;
      incomingByte = Serial.read();
      if(checkBegin == true){
        
      buf[i] = int(incomingByte);
      i++;
      if(i==6){
      checkBegin = false;
      processPackage(); 
      }
    // BUFFER VULLEN
      }else{
    // BEGIN BUFFER CHECK
      i = 0;
      if(int(incomingByte) == 255){ 
      checkBegin = true;
      }
    }
}   
// NIET BESCHIKBAAR RESET
else if((Serial.available() == 0) && (r < 32000)){
r++;
}
else {
gasstop = 0;
analogWrite (gasOut, gasstop);
  digitalWrite(13, HIGH);   // set the LED on
// int stuur = 60;
//btn_1 = HIGH;
//btn_2 = HIGH;
//btn_3 = HIGH;
//btn_4 = HIGH;
}


/////STEPPER BOOLEAN
if(steppingleft == true)
{
   unsigned long now = millis();
   if(now - lastStepleft > stepTimeleft)
   {
      step();
      lastStepleft = now;
   }
}

if(steppingright == true)
{
   unsigned long now = millis();
   if(now - lastStepright > stepTimeright)
   {
      step();
      lastStepright = now;
   }
}


} // END LOOP


/////////////////BEGIN//////////////////
void processPackage(){
  //VULVARS
  gas   = buf[0];
  stuur = buf[1];
  btn_1 = buf[2];
  btn_2 = buf[3];
  btn_3 = buf[4];
  btn_4 = buf[5];

  //MIDDEN 
  if (gas > 125 && gas < 135) 
  {       
   gasstop = 0;
   analogWrite (gasOut, gasstop);
  }
  //LAAG
   else if (gas < 125) 
  {  
   gasachter = map (gas, 125, 0, 0, 200);
   digitalWrite(gasDir, HIGH); //Reverse motor direction, 1 high, 2 
   analogWrite (gasOut, gasachter);
  }
  //HOOG 
   else if (gas > 135) 
  {
   gasvoor = map (gas, 135, 250, 0, 200);
   digitalWrite(gasDir, LOW);  //Reverse motor direction, 1 high, 2 
   analogWrite (gasOut, gasvoor); 
  }
/////////////////STUUR//////////////////
   myservo.write(stuur);                   // sets the servo position according to the scaled value 
/////////////////STEPPER////////////////

// right

   if(btn_1 == LOW){
     digitalWrite(STEPDIR, LOW);   
     steppingleft = true;
   }
   else if(btn_1 == HIGH){
     steppingleft = false;
   }  
    
   // left
   if(btn_2 == LOW){  
     digitalWrite(STEPDIR, HIGH); 
     steppingright = true;     
   }
   else if(btn_2 == HIGH){
     steppingright = false;
      
   }       
   
   
}
// EINDE PROCES PACKAGE

// FUNCTIONS

void step(){    
        digitalWrite(STEP, LOW);  
        delayMicroseconds(100);           
        digitalWrite(STEP, HIGH);
        delayMicroseconds(100);  
}

You can change how often the stepper steps in each direction by setting stepTimeleft and stepTimeright to larger values. Although why you would want different speeds in each direction escapes me. I would think that one stepTime would be sufficient.

Different speeds are not necessary. Changed the code again :slight_smile: I did that because i noticed a problem for left/right direction.
I am someone that use to much code. This is better...

/////////////////INCULDE////////////////

#include <Servo.h> 

/////////////////XBEE///////////////////
boolean checkBegin = false;
byte incomingByte;  
int buf[6];      
int i = 0;  
int r = 0;  
int gas;        
int stuur;        
int btn_1; 
int btn_2; 
int btn_3; 
int btn_4; 


/////////////////GAS////////////////////
int gasDir = 5;     // GASGEVEN DIRECTION 
int gasOut = 6;     // GASGEVEN MOTOR
int gasstop = 0;    // GASGEVEN PAUZE
int gasvoor = 0;    // GASGEVEN VOOR
int gasachter = 0;  // GASGEVEN ACHTER
/////////////////STUUR//////////////////
Servo myservo;



/////////////////STEPPER////////////////
int STEPDIR = 10;
int STEP = 11;

boolean steppingleft = false;
boolean steppingright = false;

unsigned long stepTimer = 0;
unsigned long lastStep = 0;

/////////////////SETUP//////////////////
void setup(){
Serial.begin(19200);       // serialsnelheid
//GAS
pinMode(gasDir, OUTPUT);
pinMode(gasOut, OUTPUT); 
pinMode(13, OUTPUT);     
//STUUR
myservo.attach(9);         // attaches the servo on pin 9 
myservo.write(90);
//STEPPER OUTPUT
pinMode(STEPDIR, OUTPUT);      // set pin 3 to output
pinMode(STEP, OUTPUT);         // set pin 2 to output
}
/////////////////BEGIN//////////////////
void loop () {
if (Serial.available() > 0) {
      digitalWrite(13, LOW); 
      r=0;
      incomingByte = Serial.read();
      if(checkBegin == true){
        
      buf[i] = int(incomingByte);
      i++;
      if(i==6){
      checkBegin = false;
      processPackage(); 
      }
    // BUFFER VULLEN
      }else{
    // BEGIN BUFFER CHECK
      i = 0;
      if(int(incomingByte) == 255){ 
      checkBegin = true;
      }
    }
}   
// NIET BESCHIKBAAR RESET
else if((Serial.available() == 0) && (r < 32000)){
r++;
}
else {
gasstop = 0;
analogWrite (gasOut, gasstop);
  digitalWrite(13, HIGH);   // set the LED on
// int stuur = 60;
//btn_1 = HIGH;
//btn_2 = HIGH;
//btn_3 = HIGH;
//btn_4 = HIGH;
}


/////STEPPER BOOLEAN
if(steppingleft == true)
{
   unsigned long now = millis();
   if(now - lastStep > stepTimer)
   {
      step();
      lastStep = now;
   }
}

if(steppingright == true)
{
   unsigned long now = millis();
   if(now - lastStep > stepTimer)
   {
      step();
      lastStep = now;
   }
}


} // END LOOP


/////////////////BEGIN//////////////////
void processPackage(){
  //VULVARS
  gas   = buf[0];
  stuur = buf[1];
  btn_1 = buf[2];
  btn_2 = buf[3];
  btn_3 = buf[4];
  btn_4 = buf[5];

  //MIDDEN 
  if (gas > 125 && gas < 135) 
  {       
   gasstop = 0;
   analogWrite (gasOut, gasstop);
  }
  //LAAG
   else if (gas < 125) 
  {  
   gasachter = map (gas, 125, 0, 0, 200);
   digitalWrite(gasDir, HIGH); //Reverse motor direction, 1 high, 2 
   analogWrite (gasOut, gasachter);
  }
  //HOOG 
   else if (gas > 135) 
  {
   gasvoor = map (gas, 135, 250, 0, 200);
   digitalWrite(gasDir, LOW);  //Reverse motor direction, 1 high, 2 
   analogWrite (gasOut, gasvoor); 
  }
/////////////////STUUR//////////////////
   myservo.write(stuur);                   // sets the servo position according to the scaled value 
/////////////////STEPPER////////////////

// right

   if(btn_1 == LOW){
     digitalWrite(STEPDIR, LOW);   
     steppingleft = true;
   }
   else if(btn_1 == HIGH){
     steppingleft = false;
   }  
    
   // left
   if(btn_2 == LOW){  
     digitalWrite(STEPDIR, HIGH); 
     steppingright = true;     
   }
   else if(btn_2 == HIGH){
     steppingright = false;
      
   }       
   
   
}
// EINDE PROCES PACKAGE

// FUNCTIONS

void step(){    
        digitalWrite(STEP, LOW);  
        delayMicroseconds(100);           
        digitalWrite(STEP, HIGH);
        delayMicroseconds(100);  
}

I am someone that use to much code. This is better...

You still have a bit too much. The motor may be stepping. The direction is defined by whether the STEPDIR pin is HIGH or LOW, not whether steppingleft is true or false or whether steppingright is true or false. The need to step is determined by whether steppingleft or steppingright is true. But, you'll notice that exactly the same stuff happens if steppingleft is true as happens if steppingright is true. Therefore, you only need one boolean variable, stepping, and one block of code.

You can't have both steppingleft and steppingright true at the same time (I hope).

Thanks Paul,

Think I understand just make 1 boolean "stepping" .
Then use and if , else if, else statement so the direction and or tue or false is set there.