Offline
Newbie
Karma: 0
Posts: 8
|
 |
« on: May 29, 2012, 07:48:29 am » |
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  Any help is appreciated
|
|
|
|
|
Logged
|
|
|
|
|
Massachusetts, USA
Offline
Tesla Member
Karma: 108
Posts: 6611
|
 |
« Reply #1 on: May 29, 2012, 08:11:05 am » |
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
|
|
|
|
|
Global Moderator
UK
Offline
Brattain Member
Karma: 143
Posts: 19374
I don't think you connected the grounds, Dave.
|
 |
« Reply #2 on: May 29, 2012, 08:25:36 am » |
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.
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 8
|
 |
« Reply #3 on: May 29, 2012, 09:02:36 am » |
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 // 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
Tesla Member
Karma: 108
Posts: 6611
|
 |
« Reply #4 on: May 29, 2012, 08:40:21 pm » |
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
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 8
|
 |
« Reply #5 on: May 30, 2012, 04:24:29 am » |
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
Melbourne, Australia
Offline
Shannon Member
Karma: 226
Posts: 14101
Lua rocks!
|
 |
« Reply #6 on: May 30, 2012, 04:43:38 am » |
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
Brattain Member
Karma: 143
Posts: 19374
I don't think you connected the grounds, Dave.
|
 |
« Reply #7 on: May 30, 2012, 04:44:34 am » |
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.
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 226
Posts: 14101
Lua rocks!
|
 |
« Reply #8 on: May 30, 2012, 04:48:24 am » |
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: 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
Newbie
Karma: 0
Posts: 8
|
 |
« Reply #9 on: May 30, 2012, 08:39:38 am » |
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 
|
|
|
|
« Last Edit: May 30, 2012, 08:57:12 am by kenny0987 »
|
Logged
|
|
|
|
|
New Jersey
Online
Edison Member
Karma: 26
Posts: 2454
|
 |
« Reply #10 on: May 30, 2012, 12:22:18 pm » |
So then my program would run case 0, then halt? No, it likely ends up in state 3 as noted above. 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. 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
Newbie
Karma: 0
Posts: 8
|
 |
« Reply #11 on: May 31, 2012, 01:29:55 am » |
How about this then? // 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
Melbourne, Australia
Offline
Shannon Member
Karma: 226
Posts: 14101
Lua rocks!
|
 |
« Reply #12 on: May 31, 2012, 01:44:42 am » |
Looks OK. Somewhat more simply though: //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
Newbie
Karma: 0
Posts: 8
|
 |
« Reply #13 on: May 31, 2012, 02:24:42 am » |
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
Melbourne, Australia
Offline
Shannon Member
Karma: 226
Posts: 14101
Lua rocks!
|
 |
« Reply #14 on: May 31, 2012, 05:47:25 am » |
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. state++; // next state if (state > 11) state = 0;
|
|
|
|
|
Logged
|
|
|
|
|
|