time out function

Hey,
So I’m currently working on a program that will drive a motor that is grabbing vials placed on a surface. When a set of pins grip a vial, and can no longer move freely, a clutch engages. This causes an encoder wheel that is passing through an optical sensor to stop spinning. In my code I am trying to get my arduino to recognize the wheel has stopped spinning, and stop driving the motor.
However when I test it out the motor stays on indefinably unless the NoVial sensor is triggered.
Your help would be appericiated.

Here’s my code:

#define TIMEOUT 10000 //set for 10 seconds
//initalize sensor, motor, and button pins. set button state to 0. call timer:
const int NoVial = 2;
const int Home = 3; 
const int ENC = 6;
const int motorFWD = 10;
const int motorRWD = 16;
const int FWDbutton = 4;
const int RWDbutton = 5;
int button1State = 0;
int button2State = 0;
int ENC_State = 0;
int ENC_lastState = 0;
volatile unsigned long duration = 0;
 



void setup() {
  // set pin I/O options. tactile buttons go low when pushed.
  pinMode(Home, INPUT);
  pinMode(NoVial, INPUT);
  pinMode(ENC, INPUT_PULLUP);
  pinMode(motorFWD, OUTPUT);
  pinMode(motorRWD, OUTPUT);
  pinMode(FWDbutton, INPUT_PULLUP);
  pinMode(RWDbutton, INPUT_PULLUP);


  


  do
  {
  digitalWrite(motorFWD, LOW);
  digitalWrite(motorRWD, HIGH);
  } while (digitalRead(Home) == HIGH);
 
}
void loop() {
  //setting motor direction based on button pushes
  //motor stops when it either a sensor sees a magnet, or encoder times out

  button1State = digitalRead(FWDbutton);
  button2State = digitalRead(RWDbutton);
  duration = pulseIn(ENC, HIGH);

  if (duration < TIMEOUT){
       if (button1State == LOW){
       do{
         digitalWrite(motorFWD, HIGH);
         digitalWrite(motorRWD, LOW);
     } while (digitalRead(NoVial) == HIGH); 
     } else {
            digitalWrite(motorFWD, LOW);
            digitalWrite(motorRWD, LOW);
     }
     if (button2State == LOW){
       do{
         digitalWrite(motorFWD, LOW);
         digitalWrite(motorRWD, HIGH);
         } while (digitalRead(Home) == HIGH);
         } else {
         digitalWrite(motorFWD, LOW);
         digitalWrite(motorRWD, LOW);
        }    
  } else {
    digitalWrite(motorFWD, LOW);
    digitalWrite(motorRWD, LOW);
  }
}

Hexanon:
indefinably

What's that?

Your problem is that you are using do-while loops where you shouldn't. So your code checks the encoder once at the top of loop and then starts doing its thing inside a do-while loop that doesn't involve looking at the encoder again. Best bet would be to rewrite as a state machine. Search that term and you should find many many examples of what it means. Either way I see a few distinct states, looking for a vial, grabbing vial, no vial found, returning with vial, etc.

thanks for the suggestion! I’ll look into it. :slight_smile:

The do loops are wrong indeed.

Worse: you’re comparing your timeout to some kind of pulseIn() result. As long as that pulse is shorter than 10,000 µs, your motor continues to run. You probably meant to look for millis() here:

uint32_t lastTrigger;

void loop() {
  if (millis() - lastTrigger < TIMEOUT) {
    dostuff();
  }
  else {
    stopStuff();
  }
  if (gotTrigger()) {  // a trigger to start the 10 second interval is received.
    lastTrigger = millis();
  }
}

What’s the purpose of this pulseIn() in the first place? You’re not doing anything with the result, other than the incorrect if statement.