Pages: [1] 2   Go Down
Author Topic: Motor control after making a turn  (Read 1274 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey guys hows it going!

so i've just started looking into arduino programming. Im trying to help my little brother with some programming for a school project but we've run into a dead end.
Basically the project requires you control a robot through an obstacle course. What sort of code would you need to run this?

Were using an IR sensor to measure distance (were only using the analog values so no need to convert it to physical distance) till the bot is close enough to a wall, then it turns right or left, and follows this procedure through a series of turns. Problem we have is, its a 2 wheeled bot, so i know how to make it stop and turn e.g. left by turning left motor off or reverse and right motor forwards, but then after that, how do you make it move both motors? I know it seems like a easy problem but i cant figure it out smiley-sad

Any help is appreciated smiley
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 212
Posts: 8952
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You have to decide how long to leave it turning, then set both motors to forward to make it go forward.

To decide when to stop turning you might want to check the IR distance measurement and stop turning when the wall is no longer seen.
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 309
Posts: 26484
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It always helps if you post your code - it may be that your motor controller is unusual.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

here is my program code so far. Does it seem correct? Note that i have purposely left the sensor values (sensvalue) blank in the if statements. The intervals are also not correctly timed so ignore the actual value


Code:
// Define the sensor and motors as variables
int IRsensor = 0;
int leftmotor = 1;
int rightmotor = 2;

// This variable holds the state the system is in. It will start at 0 and count upwards for
// how every many state the system will have.
int state = 0;
//Create Flag Variable for State
int flag = 0;

// This long variable will hold the previous number of milli seconds that have ellapsed since
// the board was turned on. It is used for timing delays.
long previousMillis;

// This long variable will hold the current amount of ellapsed millis seconds since the board was turned on
long currentMillis;

// This variable will hold the desired delay time in millis seconds
long interval;

void setup()
{
  Serial.begin(9600);
  
  //Define the inputs and outputs
  pinMode(IRsensor,INPUT);
  pinMode(leftmotor,OUTPUT);
  pinMode(rightmotor,OUTPUT);

}

void loop()
{
  //Create variable 'val', and print sensor value into it
  int sensval = analogRead(IRsensor);
  
   // Update the current milli seconds. Millis() returns the number
  // of milli seconds that have ellapsed sincethe board was turned on
  currentMillis = millis();
  
  //Define the variosu cases depending on IR sensor input
  switch(state)
  
  case 0: //wait two seconds before moving
    previousMillis = currentMillis;
    interval = 3000;
    state = 1;
    break;
    
        
    case 1: // check if wait time has finished then move forwards.
    if(currentMillis - previousMillis > interval){
      Forwards(); // This function is defined at the bottom.
      state = 2;
    }
    break;
    
    
    
    case 2: // continue moving forward untill the 1st wall is close, then turn right
    if(sensvalue < && state == 2){
      RightTurn(); // This function is defined at the bottom.
      previousMillis = currentMillis;
      interval = 3000;
      state = 3;
    }
    break;
    
    
    
    case 3: //Keep moving after first turn
    if(currentMillis - previousMillis > interval && state == 3){
      Forwards(); // This function is defined at the bottom.
      flag = 1
    }
    break;
    
    case 4: // Keep moving forward till 2nd wall, then turn Right
    if(sensvalue < && flag == 1){
      RightTurn(); // This function is defined at the bottom.
      previousMillis = currentMillis;
      interval = 3000;
      state = 4;
    }
    break;
    
    case 5: //Keep moving after 2nd turn
    if(currentMillis - previousMillis > interval && state == 4){
      Forwards(); // This function is defined at the bottom.
      flag = 2
    }
    break;
    
    case 6: // Keep moving forward till 3rd wall, then turn Left
    if(sensvalue < && flag == 2){
      LeftTurn(); // This function is defined at the bottom.
      previousMillis = currentMillis;
      interval = 3000;
      state = 5;
    }
    break;
    
    case 7: //Keep moving after 3rd turn
    if(currentMillis - previousMillis > interval && state == 5){
      Forwards(); // This function is defined at the bottom.
      flag = 2
    }
    break;
    
    default: // if no cases match then default is executed.
    //Do nothing
    break;
    
  }

  
}  

// Motor control programs, depending on the case
void Forwards(){
  digitalWrite(leftmotor,HIGH);
  digitalWrite(rightMotor,HIGH);
}

void LeftTurn(){
  digitalWrite(leftmotor,LOW);
  digitalWrite(rightmotor,HIGH);
}

void RightTurn(){
  digitalWrite(leftmotor,HIGH);
  digitalWrite(rightmotor,LOW);
}

void Stop(){
  digitalWrite(leftmotor,LOW);
  digitalWrite(rightmotor,LOW);
}


Moderator edit: [code] ... [/code] tags added. (Nick Gammon)
« Last Edit: May 29, 2012, 04:57:43 pm by Nick Gammon » Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 212
Posts: 8952
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The switch statement takes care of the state so you don't need to put "&& state == n" in all those if-statements.

State 0:  Prepare some data and go to State 1

State 1: When 3 seconds expires, go to State 2

State 2: If sensor value below some limit, start turning right an go to State 3

State 3: After 3 seconds, change direction to forward.  STAY IN STATE 3  ////  This seems wrong.

As near as I can tell the other states are never reached.
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

my idea was to set a value to teh state variable, then use that as a condition for the next step. Im trying to get multiple conditions before each case is run e.g for case 2, it will only occur if the sensor value is below some value, and when state = 2, which is after case 1 has occured, thus forcing each step to happen in sequence.
Isnt the program run in a step structure, i.e. case 0, case 1, case 2, etc ? Im an undergrad in engineering so i've done some statement list programming on PLC's and i was trying to apply that to this.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 495
Posts: 19040
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Isnt the program run in a step structure, i.e. case 0, case 1, case 2, etc ? Im an undergrad in engineering so i've done some statement list programming on PLC's and i was trying to apply that to this.

Not at all.

The switch (and cases) are like a lengthy "if". IF case 1 ELSE case 2 ELSE case 3 and so on. But the whole thing is done once.
Logged


Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 309
Posts: 26484
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Once you're in "state == 3", there are no more assignments to "state", so that's where you'll stay.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 495
Posts: 19040
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

here is my program code so far. Does it seem correct?

Not according to the compiler, for which I have quite a bit of respect:

Code:
sketch_may30i.cpp: In function 'void loop()':
sketch_may30i:48: error: break statement not within loop or switch
sketch_may30i:51: error: case label '1' not within a switch statement
sketch_may30i:56: error: break statement not within loop or switch
sketch_may30i:60: error: case label '2' not within a switch statement
sketch_may30i:61: error: 'sensvalue' was not declared in this scope
sketch_may30i:67: error: break statement not within loop or switch
sketch_may30i:71: error: case label '3' not within a switch statement
sketch_may30i:75: error: expected `;' before '}' token
sketch_may30i:76: error: break statement not within loop or switch
sketch_may30i:78: error: case label '4' not within a switch statement
sketch_may30i:79: error: 'sensvalue' was not declared in this scope
sketch_may30i:85: error: break statement not within loop or switch
sketch_may30i:87: error: case label '5' not within a switch statement
sketch_may30i:91: error: expected `;' before '}' token
sketch_may30i:92: error: break statement not within loop or switch
sketch_may30i:94: error: case label '6' not within a switch statement
sketch_may30i:95: error: 'sensvalue' was not declared in this scope
sketch_may30i:101: error: break statement not within loop or switch
sketch_may30i:103: error: case label '7' not within a switch statement
sketch_may30i:107: error: expected `;' before '}' token
sketch_may30i:108: error: break statement not within loop or switch
sketch_may30i:110: error: case label not within a switch statement
sketch_may30i:112: error: break statement not within loop or switch
sketch_may30i:61: error: label 'state' used but not defined
sketch_may30i:79: error: label 'flag' used but not defined
sketch_may30i.cpp: At global scope:
sketch_may30i:117: error: expected declaration before '}' token
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So then my program would run case 0, then halt? I thought it looped  and ran whichever case had the conditions satisfied?
How would i be able to make it run those steps in sequence?

Thanks again for the help guys  smiley
« Last Edit: May 30, 2012, 08:57:12 am by kenny0987 » Logged

New Jersey
Online Online
Faraday Member
**
Karma: 70
Posts: 3727
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So then my program would run case 0, then halt?
No, it likely ends up in state 3 as noted above.
Quote
I thought it looped  and ran whichever case had the conditions satisfied?
It does loop and the switch statement runs whichever case matches your state variable.
Quote
How would i be able to make it run those steps in sequence?
You control it with the state variable - your code needs to set it to an appropriate value for the next iteration of loop. If you want it to run those steps in ascending order, each case needs to increment the state variable. Try searching the forums for state machine; there are a number of examples posted that illustrate this.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

How about this then?

Code:
// Define the sensor and motors as variables
int IRsensor = 0;
int leftmotor = 1;
int rightmotor = 2;

// This variable holds the state the system is in. It will start at 0 and count upwards for
// how every many state the system will have.
int state = 0;
//Create Flag Variable for State
int flag = 0;

// This long variable will hold the previous number of milli seconds that have ellapsed since
// the board was turned on. It is used for timing delays.
long previousMillis;

// This long variable will hold the current amount of ellapsed millis seconds since the board was turned on
long currentMillis;

// This variable will hold the desired delay time in millis seconds
long interval;

void setup()
{
  Serial.begin(9600);
 
  //Define the inputs and outputs
  pinMode(IRsensor,INPUT);
  pinMode(leftmotor,OUTPUT);
  pinMode(rightmotor,OUTPUT);

}

void loop()
{
  //Create variable 'val', and print sensor value into it
  int sensvalue = analogRead(IRsensor);
 
   // Update the current milli seconds. Millis() returns the number
  // of milli seconds that have ellapsed sincethe board was turned on
  currentMillis = millis();
 
  //Define the variosu cases depending on IR sensor input
  switch(state){
 
  case 0: //wait four seconds before moving
    previousMillis = currentMillis;
    interval = 4000;
    state = 1;
    break;
   
       
    case 1: // check if 4 sec has finished then move forwards.
    if(currentMillis - previousMillis > interval){
      Forwards(); // This function is defined at the bottom.
      state = 2;
    }
    break;
   
   
   
    case 2: // continue moving forward untill the FIRST DEAD END is close, then turn right
    if(sensvalue < 135 && state == 2){
      RightTurn(); // This function is defined at the bottom.
      previousMillis = currentMillis;
      interval = 435;
      state = 3;
    }
    break;
   
   
   
    case 3: //Keep moving after first turn
    if(currentMillis - previousMillis > interval && state == 3){
      Forwards(); // This function is defined at the bottom.
      flag = 1;
      state = 4;
    }
    break;
   
   
    case 4: // Keep moving forward till OBSTACLE, then turn Right
    if(sensvalue < 135 && flag == 1){
      RightTurn(); // This function is defined at the bottom.
      previousMillis = currentMillis;
      interval = 435;
      state = 5;
    }
   
    break;
   
    case 5: //Keep moving after 2nd turn
    if(currentMillis - previousMillis > interval && state == 5){
      Forwards(); // This function is defined at the bottom.
      flag = 2;
      state = 6;
    }
   
    break;
   
    case 6: // Keep moving forward till DED END, then turn Left
    if(sensvalue < 135 && flag == 2){
      LeftTurn(); // This function is defined at the bottom.
      previousMillis = currentMillis;
      interval = 435;
      state = 7;
    }
   
    break;
   
    case 7: //Keep moving after DEAD END
    if(currentMillis - previousMillis > interval && state == 7){
      Forwards(); // This function is defined at the bottom.
      flag = 3;
      state = 8;
      interval = 1500;
    }
   
    break;
   
    case 8: //Turn 15 degrees Left
    if(currentMillis - previousMillis > interval && flag == 8){
      LeftTurn(); // This function is defined at the bottom.
      flag = 4;
      state = 9;
      interval = 110;
    }
   
    break;
   
    case 9: //Keep moving after Turning 15 Degrees for 5 seconds
    if(currentMillis - previousMillis > interval && state == 9){
      Forwards(); // This function is defined at the bottom.
      flag = 5;
      state = 10;
      interval = 5000;
    }
   
    break;
   
    case 10: //Stop after 5 seconds
    if(currentMillis - previousMillis > interval && flag == 5){
      Stop(); // This function is defined at the bottom.
      flag = 6;
      state = 11;
      }
     
      break;
         
    default: // if no cases match then default is executed.
    //Do nothing
    break;
   
  }
 


// Motor control programs, depending on the case
void Forwards(){
  digitalWrite(leftmotor,HIGH);
  digitalWrite(rightmotor,HIGH);
}

void LeftTurn(){
  digitalWrite(leftmotor,LOW);
  digitalWrite(rightmotor,HIGH);
}

void RightTurn(){
  digitalWrite(leftmotor,HIGH);
  digitalWrite(rightmotor,LOW);
}

void Stop(){
  digitalWrite(leftmotor,LOW);
  digitalWrite(rightmotor,LOW);
}
 
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 495
Posts: 19040
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Looks OK. Somewhat more simply though:

Code:
  //Define the various cases depending on IR sensor input
  switch(state)
  {

  // blah blah

  }

  state++;  // next state

Why have each state add 1 when you always want to go from one state to the next?

Also, looking at your code I'm sorta wondering what happens when you reach state 11.
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

i dont quite follow. Correct me if im wrong, but you mean that, rather than have state = ... after each case, i simply delete each of these, then at the end of the switch statement, add in state ++ ?

Basically for this project, the bot is split into 2 parts. The first part, containing all the electronics, transports a ball though an path with obstacles till it gets to a bucket, whereby the bot drops the ball into the bucket. Within the bucket lies the 2nd part, purely mechanical, and is supposed to climb a certain length rope while holding onto the ball, then stop and hold it up there indefinitely.

...easy right?
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 495
Posts: 19040
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

i dont quite follow. Correct me if im wrong, but you mean that, rather than have state = ... after each case, i simply delete each of these, then at the end of the switch statement, add in state ++ ?

Yes that was what I was getting at. Some state machines have all sorts of complex states (eg. state 5 leads to state 9 which leads to state 2 or 3). But in your case you seem to be going up one state at a time.

You still need to think of how to handle what to do when you reach your last state.

eg.

Code:
  state++;  // next state
  if (state > 11)
    state = 0;
Logged


Pages: [1] 2   Go Up
Jump to: