Desperately need help controlling some Motors in a project
Here is my objective:
If the value of EMGv is at or above 900, start moving the motors left. The motors should continue to move left for a maximum of one second, provided EMGv stays at or above 900. If EMGv goes below 900 during or after this time, the motors should move right for one second. Then the motors should stop. At any time after this should EMGv go above 900 again, the process should repeat.
In simpler terms, the project is a robotic hand, wired to an EMG circuit. When the EMG signal gets above 900 the hand should close by the motors all turning left for one second and when the signal goes below 900 the hand should open by the motors turning right for one second.
Here is my loop atm when move(motor #, speed, direction (1 for left, 0 for right)) is the function to move the motors and stop() stops all motors.
void loop(){
int EMGv = analogRead(EMG);
if (EMGv >= 900) {
unsigned long starttime = millis();
You declared starttime as a normal local variable. Its value will be lost each time loop() ends. Declare it as static so it is stored.
You should record the FIRST time that it goes above 900. The code presented updates the starttime every time, so the timer never expires.
A quick way to do this is to initialise the timer to a special value, like 0. Then you can do the following...
void loop() {
static unsigned long starttime = 0; //zero is a special value, meaning we're not currently timing
int EMGv = analogRead(EMG);
if(starttime == 0) {
//we aren't timing the left movement - is it time to start a left movement?
if (EMGv >= 900) {
starttime = millis();
} else {
move(0, 255, 0); //move right (or continue moving right)
}
} else {
//we are in the middle of a timed movement
move(0, 255, 1); //move left (continue a movement)
if((EMGv < 900) || (millis()-starttime > 1000) ){
//fell below threshold or the timer ran out
starttime = 0;
}
}
}
Hello MorganS! This code works in the sense that when the value is over 900 the motors turn left and when the value is less than 900 they turn right, but it does not successfully impose a time limit on such movement. The motors can only rotate a maximum of one second in either direction before the hand gets too tight/too lose. Any suggestions?
Yessir. I understand the concept but not how to translate it into a working code. Also I still dont know how to impose a time limit on the movement in either direction to be one second. The code provided by MorganS successfully turns the motors left if the signal is above 900 and right if it is below 900. It just doesnt impose a one second time limit, and it always turns right when the value is below 900 rather than waiting for it to fall from above 900 to below 900 to turn right (reversing the previous left movement).
z12332:
Yessir. I understand the concept but not how to translate it into a working code.
OK, try to translate it into a non-working code then and we'll see if we can sort it out. But you have to at least give it a try. It's not rocket science. You need a variable to hold the old value.
int oldValue = 0;
void loop(){
int newValue = readSensor();
if((oldValue < 900) && (newValue > 900)){
// the value changed from less than to greater than.
}
oldValue = newValue
}
Thank you for the help. I've finally got it working with this code. I've yet to figure out what to do if the value dips below 900 in the middle of a second and its still a little buggy so any suggestions from a more experienced user like yourselves is much appreciated!
boolean motorIsRunning = false;
unsigned long motorStartedTime = 0;
void loop(){
if (motorIsRunning){
currentTime = millis();
// see if it is time to turn off the motor.
// if it is then do:
motorIsRunning = false;
}
else {
// motor is not running
// see if it is time to turn on the motor
// if it is then do:
motorIsRunning = true;
motorStartedTime = millis;
}
}
You can't think about stopping everything to do one thing. Just start the motor, then come back later to check on it. As long as nothing blocks (ie uses delay) it will work because the loop function will repeat super fast.