0

maybe my problem is just that my thinking is wrong. I hope you can help me. First of all I will point out what I think in general, then I show you some code to work with.

In general my problem is to wrap me head around a push-button (or any other input) that stops (or better restarts) a running program at any time. If i use the digitalRead(pin-whatsoever)-statement don't I have to tackle the exact mili/microsecond my MC is working on that specific line of code? I don't want to use an interrupt either, i want to restart the program, not to interrupt it.

My project is some kind of turn-indicators for a bicycle. The lights shall "run" from right to left on left-turns and vice versa. But i want to stop the sequence at any point (or at least after one loop-run) if I push the corresponding button again. After that the MC shall wait for another button-push to run the indicator either till the for-loop is finished or i press the same button earlier.

Another (general) question: Is there a way to get rid of delay-statements and achieve similar results?

Thank You so far.

   // Var-Setup
  const int mtime = 120; // Time between lights lighting up
  const int ftime = 100; // Time between lights turning out

void setup() {
  // put your setup code here, to run once:
  // Pin-Setup
    // LED-Pins
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);

  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);

    // Button-Pins
  pinMode(12, INPUT);
  pinMode(13, INPUT);

}

void right(){ 
  for(int i=0; i<5; i++){
      // Indicator right with running light (like a "half-knight-rider" ;) )
      // Rise
      digitalWrite(11, HIGH);
      delay(mtime);
      digitalWrite(10, HIGH);
      delay(mtime);
      digitalWrite(9, HIGH);
      delay(mtime);  
      digitalWrite(8, HIGH);
      delay(mtime);
      digitalWrite(7, HIGH);
      delay(mtime);
      delay(mtime);

      // Fade
      digitalWrite(11, LOW);
      delay(ftime);
      digitalWrite(10, LOW);
      delay(ftime);
      digitalWrite(9, LOW);
      delay(ftime);
      digitalWrite(8, LOW);
      delay(ftime);
      digitalWrite(7, LOW);
      delay(250);
    }
}

void left (){
  for(int i=0; i<5; i++){
    // Indicator left with running light
    // Rise
    digitalWrite(2, HIGH);
    delay(mtime);
    digitalWrite(3, HIGH);
    delay(mtime);
    digitalWrite(4, HIGH);
    delay(mtime);  
    digitalWrite(5, HIGH);
    delay(mtime);
    digitalWrite(6, HIGH);
    delay(mtime);
    delay(mtime);

    // Fade
    digitalWrite(2, LOW);
    delay(ftime);
    digitalWrite(3, LOW);
    delay(ftime);
    digitalWrite(4, LOW);
    delay(ftime);
    digitalWrite(5, LOW);
    delay(ftime);
    digitalWrite(6, LOW);
    delay(250);
  }
}

void loop() {
  // put your main code here, to run repeatedly:
  int sensorL = digitalRead(12);
  int sensorR = digitalRead(13);
  if(sensorL == HIGH){
    left();
  }else if(sensorR == HIGH){
    right();
  }
}
1

replace each delay chain with a switch statement where each delay is replaced by saving the current millis counter, a increment of the state, a case label for the new state and a if(millis()-timestamp < timeout) return;

switch(state){
case 0;
      // Indicator right with running light (like a "half-knight-rider" ;) )
      // Rise
      digitalWrite(11, HIGH);
  timestamp = millis();
  state++;
case 1:
   if(millis()-timestamp  < mtime) return;

      digitalWrite(10, HIGH);
  timestamp = millis();
  state++;
case 2:
      digitalWrite(9, HIGH);
//etc.

The for loop around the entire thing will need to be replaced. Make i global and incrementing it in the last state and resetting it as needed. When i has been incremented to beyond 5 you always return.

This means that the left and right functions only do a few things: set the led, check a timestamp against the current time, and increment a state before returning.

This means that they will take very little time to execute and that you can check the button in the main loop() body and if pressed initiate the statemachine or end it (and putting out the LED when needed).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.