About while loop, for loop and interrupt

Dear all,

I have a project which I want to select different speed of blinking LEDs by a 3-pin rotary switch.

I see different tutorials about the while loop, for loop and interrupt. The problem is that I am confused with which one and how I should make use to write my codes for my project.

I am a bit new to Arduino programming, so all you help and assistance would be much appreciated.

See the "blink without delay" tutorial.

Henry_Best:
See the "blink without delay" tutorial.

Thanks, will take a look.

Any more advice ?

while loops usually are used to loop while a condition is true or fase

while(digitalRead(ledpin) == HIGH) 
{
  do something until ledpin goes low
}

for loops are usually used to count

for(int i = 0; i < 256; i++);
{
  do something 255 tmes
}

interrupts are used to trigger an action, based on an input (external, or internal like a timer) no matter where the code is in its loop, it says "HEY STOP EVERYTHING AND DO THIS" then once its done it goes back to the normal loop wherever it left off

/* Blink without Delay

Turns on and off a light emitting diode(LED) connected to a digital
pin, without using the delay() function. This means that other code
can run at the same time without being interrupted by the LED code.

The circuit:

  • LED attached from pin 13 to ground.
  • Note: on most Arduinos, there is already an LED on the board
    that's attached to pin 13, so no hardware is needed for this example.

created 2005
by David A. Mellis
modified 8 Feb 2010
by Paul Stoffregen

This example code is in the public domain.

http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
*/

// constants won't change. Used here to
// set pin numbers:
const int ledPin = 13; // the number of the LED pin

// Variables will change:
int ledState = LOW; // ledState used to set the LED
long previousMillis = 0; // will store last time LED was updated

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 1000; // interval at which to blink (milliseconds)

void setup() {
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
}

void loop()
{
// here is where you'd put code that needs to be running all the time.

// check to see if it's time to blink the LED; that is, if the
// difference between the current time and last time you blinked
// the LED is bigger than the interval at which you want to
// blink the LED.
unsigned long currentMillis = millis();

if(currentMillis - previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;

// if the LED is off turn it on and vice-versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;

// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}

Excuse me, I just take a look on the "blink without delay".

I can see that the blinking frequency is fixed by the interval variable.

I want to select different frequency of blinking LEDs.

Any more suggestion ?

Peter_Lam:
I want to select different frequency of blinking LEDs.

Any more suggestion ?

The value of the interval variable can be changed, both manually and in the code.

const int ledPin = 13; // the number of the LED pin

int input1 = 2; //INPUT PINS

// Variables will change:
int ledState = LOW; // ledState used to set the LED

int buttonState1 = input1; // variable for reading the rotary switch status
boolean go = LOW;
long previousMillis = 0; // will store last time LED was updated

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 1000; // interval at which to blink (milliseconds)

void setup() {
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
pinMode(input1, INPUT);

}

void loop()
{
buttonState1 = digitalRead(input1); // blink frequency 5000 if on

while (buttonState1 == HIGH){
go = HIGH;
}

// check to see if it's time to blink the LED; that is, if the
// difference between the current time and last time you blinked
// the LED is bigger than the interval at which you want to
// blink the LED.
unsigned long currentMillis = millis();

if((currentMillis - previousMillis > interval) && (go = HIGH)){
// save the last time you blinked the LED
previousMillis = currentMillis;

// if the LED is off turn it on and vice-versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;

// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}

Before I go further, I decide to make a test first.

I have a press button and a LED, I want to press and hold down the button to make the LED blink.

Above is my code, I upload it to an Arduino mega 2560. The LED keeps blinking no matter the button is pressed or not.

Can anyone provide help ? Cheers

Peter_Lam:

void loop()
{
  buttonState1 = digitalRead(input1); // blink frequency 5000 if on
  while  (buttonState1 == HIGH){
  go = HIGH;
  }  //move this curly brace to the end of your code.
  while  (buttonState1 == HIGH){
  go = HIGH;
  }

Once the buttonState1 goes HIGH, this will get stuck in an infinite loop as buttonState1 will never change. I doubt that is your intention.

  if((currentMillis - previousMillis > interval) &&  (go = HIGH)){

go = HIGH assigns the value of HIGH to go and return HIGH, which would evaluate to true

go == HIGH will return true if go is HIGH, otherwise, it will return false.

Arrch:

  while  (buttonState1 == HIGH){

go = HIGH;
 }




Once the buttonState1 goes HIGH, this will get stuck in an infinite loop as buttonState1 will never change. I doubt that is your intention.



if((currentMillis - previousMillis > interval) &&  (go = HIGH)){




go = HIGH assigns the value of HIGH to go and return HIGH, which would evaluate to true

go == HIGH will return true if go is HIGH, otherwise, it will return false.

Here is my new code after referring to your comment.

const int ledPin = 13; // the number of the LED pin

int input1 = 2; //INPUT PINS

// Variables will change:
int ledState = LOW; // ledState used to set the LED

int buttonState1 = input1; // variable for reading the rotary switch status
boolean go = LOW;
long previousMillis = 0; // will store last time LED was updated

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 1000; // interval at which to blink (milliseconds)

void setup() {
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
pinMode(input1, INPUT);

}

void loop()
{
buttonState1 = digitalRead(input1); // blink frequency 1000 if on

while (buttonState1 == HIGH){
go = HIGH;

// check to see if it's time to blink the LED; that is, if the
// difference between the current time and last time you blinked
// the LED is bigger than the interval at which you want to
// blink the LED.
unsigned long currentMillis = millis();

if((currentMillis - previousMillis > interval) && (go == HIGH)){
// save the last time you blinked the LED
previousMillis = currentMillis;

// if the LED is off turn it on and vice-versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;

// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}
}

At the beginning, when I press and hold down the button, the LED starts blinking as I wanted, but when I release the button, it still blinks.

What could be the problem ?

Like I said, buttonState1 is never updated inside the while loop

Arrch:
Like I said, buttonState1 is never updated inside the while loop

Did a few trials, just can't get it right.

Can you please provide some more hint or help ? I am learning.

I appreciate that you are just starting, but what do you think is wrong with it?

You need to read the buttonState1 inside the while loop, i.e. between the while loop's {} braces.

Can you start using code tags please, and not quote tags?

How to use this forum

As for the problem, read this:

dannable:
I appreciate that you are just starting, but what do you think is wrong with it?

To me, I thought checking the buttonState1 is already doing the update ?

void loop()
{
  buttonState1 = digitalRead(input1); // blink frequency 1000 if on
  
  while  (buttonState1 == HIGH){
  go = HIGH; 

...

AWOL:
You need to read the buttonState1 inside the while loop, i.e. between the while loop's {} braces.

Thanks for the comment, I will try when I am back to office.

Peter_Lam:
To me, I thought checking the buttonState1 is already doing the update ?

void loop()

{
  buttonState1 = digitalRead(input1); // blink frequency 1000 if on
 
  while  (buttonState1 == HIGH){
  go = HIGH;

...

You do it once, before you enter the while loop. Once you're in the while loop, you never update it again. You would be better off getting rid of the go variable, as it is useless at the moment, and changing the while statement into an if statement. That way, you can utilize the switch state polling that you're doing in the first line of loop().

Coming from a computer engineer, while and for loops can be used interchangeably. I like using while when I am not incrementing and exiting the loop when a condition is met. A for loop can be also used for this but I'm meh about it

akshaykirti:
Coming from a computer engineer, while and for loops can be used interchangeably. I like using while when I am not incrementing and exiting the loop when a condition is met. A for loop can be also used for this but I'm meh about it

They can, but that doesn't mean they should. From a practical perspective for loops should be used for a specific number of iterations and while loops should be used when the amount of iterations is unknown.

Yup. As I said,I'm pretty meh about using for loops for that purpose. You could, but well it looks weird.