Reading rotary encoders during For Loops?

How would I go about reading rotary encoders while inside a for loop? I want to make the delay between each count in the loop variable by a rotary encoder. However, the delay doesnt update with the rotation of the rotary encoder until the entire loop has been run through. How would I be able to change it within the loop? would that require an interrupt?

it’s hard to help since you didn’t post the code but from what I understand you may be able to change the for loop to a while loop. before every delay check your condition again. for example

while (blah == blahblah)
{
digitalRead(encoder);
if (blah == blahblah)
{
delay(delaytime); whatever variable holds your delay time
}
else
{
break;
}

digitalRead(encoder);
if (blah == blahblah)
{
delay(delaytime); whatever variable holds your delay time
}
else
{
break;
}
}

it can keep doing different things, I just copied and pasted for example sake. I could be of much more help if you uploaded your code since I don’t even know if that answered your question but hopefully I was of some help. If this isn’t what you were looking for, upload your code, and elaborate a bit and I’ll try again.
Good Luck! :smiley:

The moment your program enters the delay() subroutine, the program loses its ability to read the encoder to see if it changes - for the duration of the delay time. Reliance on the delay() subroutine is very a common newbie issue and the solution is found in the Arduino IDE example program entitled "Blink without delay".

When using for() and while() loops, you also want to read up on how to utilize the keywords break; and continue;

for(int i = 0; i<step_num;i++){
      doEncoder0A();
      doEncoder0B();
      lcd.setCursor(i,1);
      lcd.write(255);
      analogWrite(outpin, step1[round(val[i]/10)]);
      lcd.setCursor(i,1);
      delay(60000/tempo);
      lcd.setCursor(i,1);
      lcd.write(" ");
     }
  }

Here is the doEncoders section:

void doEncoder0A() {
    if (digitalRead(encoder0PinA) == HIGH) {
      if (digitalRead(encoder0PinB) == LOW) {
        tempo = tempo + 1;         // CW
      }
      else {
        tempo = tempo - 1;         // CCW
      }
    }
    else{
     if (digitalRead(encoder0PinB) == HIGH) {
       tempo = tempo + 1;         // CW
       tempo = min(990, max(0, tempo));
      }
      else {
        tempo = tempo - 1;         // CCW
        tempo = min(990, max(0, tempo));
    }
  }a
}

void doEncoder0B() {
    if (digitalRead(encoder0PinB) == HIGH) {
      if (digitalRead(encoder0PinA) == HIGH) {
        tempo = tempo + 1;         // CW
        tempo = min(990, max(0, tempo));
      }
      else {
        tempo = tempo - 1;         // CCW
        tempo = min(990, max(0, tempo));
      }
    }
    else {
   
      if (digitalRead(encoder0PinA) == LOW) {
        tempo = tempo + 1;         // CW
        tempo = min(990, max(0, tempo));
      }
      else {
        tempo = tempo - 1;         // CCW
        tempo = min(990, max(0, tempo));
      }
    }
}

however, this is obviously not working as I would like it to and the value of tempo only adjusts after the for loop has been completed.

avr_fred:
The moment your program enters the delay() subroutine, the program loses its ability to read the encoder to see if it changes - for the duration of the delay time. Reliance on the delay() subroutine is very a common newbie issue and the solution is found in the Arduino IDE example program entitled "Blink without delay".

When using for() and while() loops, you also want to read up on how to utilize the keywords break; and continue;

ah ok I will look into this!

The demo Several Things at a Time is an extended example of BWoD and illustrates the use of millis() to manage timing. It may help with understanding the technique.

In general only use FOR or WHILE in circumstances where they will complete in a few microseconds. For longer periods of repetition just allow loop() to do the iteration. That way you can read the encoder hundreds of times per second.

...R

when reading rotary encoders on microcontrollers without a hardware QEI interface I use interrupts to detect changes in the A and B signals

Paul Soffregen's Encoder Library is a great place to start. It is capable of reading encoders on any pins but if you put at least one of the encoder pins on an Arduino interrupt pin (pin 2 and 3 on an Uno, check the docs for other Arduinos) then it will work everywhere in your program without having to be called explicitly.

This might be a good time to go to the Arduino online learning pages to read about interrupts.

this is where I need some project guidance - would it be more beneficial to ditch the delays or use interrupts?

tjm56:
this is where I need some project guidance - would it be more beneficial to ditch the delays or use interrupts?

Even if you decide to use interrupts you should ditch the delay()s

...R