Turning loopy with nested loops

Hello all,

Though I'm quite technical (in software and systems), my experience with Arduino is all of a week for me, and I'm seriously going loopy from it. For 3 days I've been trying to understand the best way (or any way) to use a pushbutton as a toggle. When pressed, an external LED flashes a repeating pattern (think aircraft wing lights - a double strobe). When pressed again, it should stop the flashing.

I've tried two ways - using a very modified example sketch, and listening to Google's Gemini - needless to say, neither works. They either flash all the time, or never. I've even tried adding some text output on them to try to understand what state the strobe light is in (on or off) via the Serial Monitor.

Can anyone please, please help me see the error in my ways? I'd be most appreciative!

My code is here:

// Firstly, we set the constants.  Constants won't change. They're used here to set pin numbers:
const int buttonPin = 2;  // the number of the pushbutton pin
const int ledPin = 13;    // the number of the LED pin

// variables will change. Here we set the timings of the flashes and which pi
int buttonState = 0;  // variable for reading the pushbutton status
bool strobeOn = LOW; //This allows a pushbutton to act as a switch (True=on, false=off)
int i = 0;       // used in the "for" loop
int ontime = 100; // how long to keep the LED on in ms
int offtime = 50; // how long to keep the LED off in ms
int seqcount = 1; //number of times the strobe flashes during a sequence
int pausetime = 1000; // how long between flash sequences

void setup() {
 
  pinMode(ledPin, OUTPUT); // initialize the LED pin as an output:
  pinMode(buttonPin, INPUT_PULLUP); // initialize the pushbutton pin as an input:
  Serial.begin(9600); 
}

void loop() {
  // First, read the state of the pushbutton value:
  int buttonState = digitalRead(buttonPin);

  // if the button is pressed (ie buttonState is HIGH)
  // then change strobeOn to opposite of current state.
  if (buttonState == LOW) {
    strobeOn = !strobeOn; 
    delay(10);  //to debounces button press
    Serial.print("strobeOn value is: ");
    Serial.println(strobeOn);  
  }
//    else{
//      strobeOn = strobeOn;
//    }


  while (strobeOn=1) {
    for (int i = 0; i < seqcount; i++) {
      digitalWrite(ledPin, HIGH);
      delay(ontime);                // wait for "delay in ms"
      digitalWrite(ledPin, LOW);    // turn the LED off by making the voltage LOW
      delay(offtime);               // wait for "delay in ms"
      
      digitalWrite(ledPin, HIGH);
      delay(ontime);                // wait for "delay in ms"
      digitalWrite(ledPin, LOW);    // turn the LED off by making the voltage LOW
      delay(offtime);               // wait for "delay in ms"

    }
    delay(pausetime);
    
  int buttonState = digitalRead(buttonPin);

  // if the button is pressed (ie buttonState is HIGH)
  // then change strobeOn to opposite of current state.
    if (buttonState == LOW) {
      strobeOn = !strobeOn; 
      delay(10);  //to debounces button press
      Serial.print("strobeOn value is: ");
      Serial.println(strobeOn);  

    }
  }  
  
}

and Gemini's attempt (I understand where it's going, but it still doesn't work) is here:

const int buttonPin = 2; // Button connected to digital pin 2
const int ledPin = 13;    // the number of the LED pin


int buttonState = LOW;  // variable for reading the pushbutton status
bool strobeOn = true; //This allows a pushbutton to act as a switch (True=on, false=off)
int i = 0;       // used in the "for" loop
int ontime = 100; // how long to keep the LED on in ms
int offtime = 50; // how long to keep the LED off in ms
int seqcount = 1; //number of times the strobe flashes during a sequence
int pausetime = 1000; // how long between flash sequences


void setup() {
  pinMode(ledPin, OUTPUT); // initialize the LED pin as an output:
  pinMode(buttonPin, INPUT_PULLUP); // Use internal pull-up resistor
  Serial.begin(9600);
}

void loop() {
  int reading = digitalRead(buttonPin);

  if (reading == LOW) { // Button pressed
    delay(50); // Debounce button press
    buttonState = !buttonState; // Toggle button state
//    strobeOn = !strobeOn;
    

    if (buttonState == 1) {
    
      for (int i = 0; i < seqcount; i++) {
      strobeSequence(); 
      }
    
    }
  }
  
    else {
      
    }  
    delay(pausetime);
    Serial.print("buttonState value is: ");
    Serial.println(buttonState);  
 
}



void strobeSequence() {

  digitalWrite(ledPin, HIGH);
  delay(ontime);                // wait for "delay in ms"
  digitalWrite(ledPin, LOW);    // turn the LED off by making the voltage LOW
  delay(offtime);               // wait for "delay in ms"
      
}

Only read buttonPin once in each loop. Next, toggle the buttonstate after each press. At any time, do what you need according to the buttonstate.

If you read buttonstate more than once in each loop, the buttonstate will change "that" many times.

Read about Arduino button debounce.

Try the state machine approach. Works like a charm

@homerhudson

Hi

There are a few issues that I can see...

There is no need for 2 instances of this code block (in your version of the code)

int buttonState = digitalRead(buttonPin);

  // if the button is pressed (ie buttonState is HIGH)
  // then change strobeOn to opposite of current state.
    if (buttonState == LOW) {
      strobeOn = !strobeOn; 
      delay(10);  //to debounces button press
      Serial.print("strobeOn value is: ");
      Serial.println(strobeOn);  

    }

Try this

// Firstly, we set the constants.  Constants won't change. They're used here to set pin numbers:
const int buttonPin = 2;  // the number of the pushbutton pin
const int ledPin = 13;    // the number of the LED pin

// variables will change. Here we set the timings of the flashes and which pi
int buttonState = 0;  // variable for reading the pushbutton status
bool strobeOn = LOW; //This allows a pushbutton to act as a switch (True=on, false=off)
int i = 0;       // used in the "for" loop
int ontime = 100; // how long to keep the LED on in ms
int offtime = 50; // how long to keep the LED off in ms
int seqcount = 10; //number of times the strobe flashes during a sequence
int pausetime = 1000; // how long between flash sequences

void setup() {
 
  pinMode(ledPin, OUTPUT); // initialize the LED pin as an output:
  pinMode(buttonPin, INPUT_PULLUP); // initialize the pushbutton pin as an input:
  Serial.begin(9600); 
}

void loop() {
  // First, read the state of the pushbutton value:
  int buttonState = digitalRead(buttonPin);

  // if the button is pressed (ie buttonState is HIGH)
  // then change strobeOn to opposite of current state.
  if (buttonState == LOW) {
    strobeOn = !strobeOn; 
    delay(10);  //to debounces button press
    Serial.print("strobeOn value is: ");
    Serial.println(strobeOn);  
  }
  if (strobeOn == 1) {
    strobeOn = 0;
    for (int i = 0; i < seqcount; i++) {
      digitalWrite(ledPin, HIGH);
      delay(ontime);                // wait for "delay in ms"
      digitalWrite(ledPin, LOW);    // turn the LED off by making the voltage LOW
      delay(offtime);               // wait for "delay in ms"
      
      digitalWrite(ledPin, HIGH);
      delay(ontime);                // wait for "delay in ms"
      digitalWrite(ledPin, LOW);    // turn the LED off by making the voltage LOW
      delay(offtime);               // wait for "delay in ms"
     
      delay(pausetime);
    }
    //delay(pausetime);
  }
}
    

look this over

  • separate handle monitor for button and LED timing
// flash LEDs controlled by button

const int ButtonPin = 2;     // pin number of pushbutton
const int LedPin    = 13;    // pin number of LED

enum { LedOff = HIGH, LedOn = LOW };    // depends on wiring

int  buttonState;

    // Capitalize Constants
const unsigned long OnTime    = 100;  // how long to keep the LED on in ms
const unsigned long OffTime   = 50;   // how long to keep the LED off in ms
const unsigned long PauseTime = 1000; // how long between flash sequences

unsigned long msecPeriod;
unsigned long msec0;

int  seqcount = 1;          // # strobe flashes during a sequence

bool strobeOn       = false;
int  ledState;

// -----------------------------------------------------------------------------
void loop ()
{
    unsigned long msec = millis ();

    // -------------------------------------
    // check if timer enable and expired
    if (strobeOn && msec - msec0 >= msecPeriod)  {
        msec0 = msec;

        if (LedOff == ledState)  {
            ledState   = LedOn;
            msecPeriod = OnTime;
        }
        else  {
            ledState   = LedOff;
            msecPeriod = OffTime;
        }

        digitalWrite (LedPin, ledState);
    }

    // -------------------------------------
    // monitor button
    byte but = digitalRead (ButtonPin);

    if (buttonState != but)  {
        buttonState  = but;
        delay (50);                 // debounce

        if (LOW == but)  {
            strobeOn = ! strobeOn;
            Serial.print   ("  button press ");
            Serial.println (strobeOn);

            if (! strobeOn)  {
                ledState = LedOff;
                digitalWrite (LedPin, ledState);
            }
        }
    }
}

// -----------------------------------------------------------------------------
void setup ()
{
    Serial.begin (9600);

    pinMode      (LedPin, OUTPUT);
    digitalWrite (LedPin, LedOff);

    pinMode (ButtonPin, INPUT_PULLUP);
    buttonState = digitalRead (ButtonPin);
}

this version incorporates your pauses in between a sequence of strobes

// flash LEDs controlled by button

const int ButtonPin = 2;     // pin number of pushbutton
const int LedPin    = 13;    // pin number of LED

enum { LedOff = HIGH, LedOn = LOW };    // depends on wiring

int  buttonState;

    // Capitalize Constants
const unsigned long OnTime    = 100;  // how long to keep the LED on in ms
const unsigned long OffTime   = 50;   // how long to keep the LED off in ms
const unsigned long PauseTime = 1000; // how long between flash sequences

unsigned long msecPeriod;
unsigned long msec0;

const int Ncnt = 10;          // # strobe flashes during a sequence
int  cnt;

bool strobeOn       = false;
int  ledState;

// -----------------------------------------------------------------------------
void loop ()
{
    unsigned long msec = millis ();

    // -------------------------------------
    // check if timer enable and expired
    if (strobeOn && msec - msec0 >= msecPeriod)  {
        msec0 = msec;

        if (LedOff == ledState)  {
            ledState   = LedOn;
            msecPeriod = OnTime;
        }
        else  {
            ledState   = LedOff;
            if (Ncnt <= ++cnt)  {
                msecPeriod = PauseTime;
                cnt        = 0;
            }
            else
                msecPeriod = OffTime;
        }

        digitalWrite (LedPin, ledState);
    }

    // -------------------------------------
    // monitor button
    byte but = digitalRead (ButtonPin);

    if (buttonState != but)  {
        buttonState  = but;
        delay (50);                 // debounce

        if (LOW == but)  {
            strobeOn = ! strobeOn;
            Serial.print   ("  button press ");
            Serial.println (strobeOn);

            if (! strobeOn)  {
                cnt      = 0;
                ledState = LedOff;
                digitalWrite (LedPin, ledState);
            }
        }
    }
}

// -----------------------------------------------------------------------------
void setup ()
{
    Serial.begin (9600);

    pinMode      (LedPin, OUTPUT);
    digitalWrite (LedPin, LedOff);

    pinMode (ButtonPin, INPUT_PULLUP);
    buttonState = digitalRead (ButtonPin);
}

knowing the language doesn't mean knowing the concepts common to all languages for using the language

@homerhudson welcome to the forum.

This in your version

  while (strobeOn=1) {

would mean that if you managed to stab or press the button to invoke flashing, flashing would continue indefinitely.

= is for assignment, it is quite different to == which is for a test of equality.

Other than that it looks like it should work, although to stop the flashing will be tricky as you will have to keep your finger on the button and let go at just the right time to cease the flashing.

Increase the delay and make the button test inside your while loop turn off the strobe rather than toggle it. Get your finger off the button when it says to:

    if (buttonState == LOW) {
      strobeOn = false;   // make it stop
     
  Serial.println("OK OK, I'll stop. Get your fat finger off my button."); 

      delay(500);  // plenty of time to release the button
    }

Only changes. Don't mess with the other button handling.

That might make this limp into the air. But you will see the button handling is lame and touchy.

It might be fun to get this working as it is, then promise yourself to read about button debouncing and "state change detection" to handle buttons better.

And look forward to learning about FSMs finite state machines, which technique will allow the flashing to be immediately stopped and started as you press the button even like your grandma presses buttons.

If it still doesn't work, use serial printing to check the values of the variabkes and that the flow through your code is what you think.

HTH

a7

1 Like

The code in #1 works after the suggestions from #7 are applied.

// Firstly, we set the constants.  Constants won't change. They're used here to set pin numbers:
const int buttonPin = 2;  // the number of the pushbutton pin
const int ledPin = 13;    // the number of the LED pin

// variables will change. Here we set the timings of the flashes and which pi
int buttonState = 0;  // variable for reading the pushbutton status
bool strobeOn = LOW; //This allows a pushbutton to act as a switch (True=on, false=off)
int i = 0;       // used in the "for" loop
int ontime = 100; // how long to keep the LED on in ms
int offtime = 50; // how long to keep the LED off in ms
int seqcount = 1; //number of times the strobe flashes during a sequence
int pausetime = 1000; // how long between flash sequences

void setup() {
 
  pinMode(ledPin, OUTPUT); // initialize the LED pin as an output:
  pinMode(buttonPin, INPUT_PULLUP); // initialize the pushbutton pin as an input:
  Serial.begin(9600); 
}

void loop() {
  // First, read the state of the pushbutton value:
  int buttonState = digitalRead(buttonPin);

  // if the button is pressed (ie buttonState is HIGH)
  // then change strobeOn to opposite of current state.
  if (buttonState == LOW) {
    strobeOn = !strobeOn; 
    delay(10);  //to debounces button press
    Serial.print("strobeOn value is: ");
    Serial.println(strobeOn);  
  }
//    else{
//      strobeOn = strobeOn;
//    }


  while (strobeOn == 1) {
    for (int i = 0; i < seqcount; i++) {
      digitalWrite(ledPin, HIGH);
      delay(ontime);                // wait for "delay in ms"
      digitalWrite(ledPin, LOW);    // turn the LED off by making the voltage LOW
      delay(offtime);               // wait for "delay in ms"
      
      digitalWrite(ledPin, HIGH);
      delay(ontime);                // wait for "delay in ms"
      digitalWrite(ledPin, LOW);    // turn the LED off by making the voltage LOW
      delay(offtime);               // wait for "delay in ms"

    }
    delay(pausetime);
    
    int buttonState = digitalRead(buttonPin);

    if (buttonState == LOW) {
      strobeOn = false;   // make it stop
      Serial.println("OK OK, I'll stop. Get your fat finger off my button."); 
      delay(500);  // plenty of time to release the button
    }
  }  
}

a7

1 Like

My two cents. This code corresponds to the fsm diagrams in post #3
No delays used.

// FSM approach to airplane-like LED flashing

// uncomment if you want to debug print. Set monitor baud rate accordingly
// #define PRINT

const int ontime = 150;
const int offtime = 50;
const int pausetime = 1000;
const int strobes = 2;

// button control
unsigned long buttonLastPressed = 0;
const unsigned long buttonDebounceTime = 25;

const int buttonPin = 3;
int previousButtonState, currentButtonState;
boolean buttonPressed;

// two FSM's are defined. "system" and "LED".
// LED fsm ative only when system is in flashing state
enum systemStates {NOT_FLASHING, FLASHING} systemState;
enum LEDstates {LED_ON, LED_OFF, LED_PAUSE} LEDstate;

// LED control
const int LEDpin = 8;
unsigned long lastTimeLED;
int strobeCounter;

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  setsystemState(NOT_FLASHING);

#ifdef PRINT
  Serial.begin(115200);
#endif
}


void loop() {

  buttonPressed = false;

  //deal with button press if we are outside the debounce window
  if (millis() - buttonLastPressed >= buttonDebounceTime) {
    currentButtonState = digitalRead(buttonPin);
    if (currentButtonState == LOW && previousButtonState == HIGH) { // ** depending on how you wired the button**
      buttonPressed = true;
      buttonLastPressed = millis();

#ifdef PRINT
      Serial.println("Button pressed");
#endif

    }

    previousButtonState = currentButtonState;
  }

  // system fsm
  switch (systemState) {
    case NOT_FLASHING:
      if (buttonPressed) {
        setsystemState(FLASHING);
      }
      break;

    case FLASHING:
      if (buttonPressed) {
        setsystemState(NOT_FLASHING);
      }
      break;
  }

  if (systemState == FLASHING) {
    // LED fsm is active
    switch (LEDstate) {

      case LED_ON:
        if (millis() - lastTimeLED >= ontime) { // see if LED has been ON long enough
          strobeCounter++;
          if (strobeCounter == strobes) {
            setLEDstate(LED_PAUSE);
            strobeCounter = 0; // reset strobe counter
          } else {
            setLEDstate(LED_OFF);
          }
        }
        break;

      case LED_OFF:
        if (millis() - lastTimeLED >= offtime) {
          setLEDstate(LED_ON);
        }
        break;

      case LED_PAUSE:
        if (millis() - lastTimeLED >= pausetime) {
          setLEDstate(LED_ON);
        }
        break;
    }
  }
}

// transition LED fsm to a new state
void setLEDstate(LEDstates newState) {
  LEDstate = newState;

  // action to be taken upon entering new state
  switch (LEDstate) {
    case LED_ON:
      digitalWrite(LEDpin, HIGH);
      break;
    case LED_OFF:
      digitalWrite(LEDpin, LOW);
      break;
    case LED_PAUSE:
      digitalWrite(LEDpin, LOW);
      break;
  }
  lastTimeLED = millis(); // record event time
}

// transition system fsm to a new state
void setsystemState(systemStates newState) {
  systemState = newState;

  // action to be taken upon entering new state
  switch (systemState) {
    case FLASHING:
      // wake up: start with LED on
      setLEDstate(LED_ON);
      strobeCounter = 0;
#ifdef PRINT
      Serial.println("Machine flashing");
#endif
      break;
    case NOT_FLASHING:
      // turn lights off before going to bed
      setLEDstate(LED_OFF);
#ifdef PRINT
      Serial.println("Not flashing");
#endif
      break;
  }
}

I built your project. It only functions correctly if I use a button that does not bounce.

I thought it would not.

A nice feature of the wokwi simulator is that it simulates contact bounce on opening and closing the contacts.

Here it is handy because wokwi allows that true-to-life aspect of pushbuttons to be turned off. In this case providing evidence that your button handling is inadequate.

I'll leave it for you to fix. If it works for you as is, you have buttons that work better than you should depend on being the case for all switches, or for the ones you have always.

This is where the problem is

    if (currentButtonState == LOW && previousButtonState == HIGH) {

You are only debouncing the leading edge; real switches need it on both. The common fits-all-switches patttern is

if you haven't looked at the switch for awhile
    if the switch is different to last time
        if the switch is down
            do something

        remember the time
        remember the switch state

a7

1 Like

I focused on the fsm and did not pay attention to bouncing-on-release.

I did several tests with a physical button, which does not make the code failsafe for all scenarios (is there such a thing?).

I changed the code per your suggestion, included a missing pinMode declaration and cleaned it up a little. Moved the button check to a separate function for clarity.

The original code failed the button release in Wokwi. The new code checks.

It was a small, almost invisible change that made all the difference.

Thank you for your comments.

That fix fixed it.

But you changed the logic from your first attempt. I prefer the way you handled the time aspect of solving the problem in that code for this exact circumstance.

There the reaction came immediately the switch went pressed. Your new code reacts in "only" 50 milliseconds, which is getting to the point where some ppl could feel it.

You could use 20 or even 15 milliseconds, which should be good for most switches. I do have crappy arcade switches that bounce for-ever, so for them eliminating the longish wait which would be looking for a stable switch position is useful.

Since pushbuttons do not show a pressed reading unless they are on their way to being fully pressed and stable, nor do they show an unpressed reading unless they are on their way to being fully unpressed and stable, we can react at the beginning of either change in state.

If your buttons don't work that way, get better buttons. :expressionless:

Your original did the time test first, as did the pseudocode I offered and as do a good fraction of button handle libraries, some even have the choice to do one or the other.

There are signals that have glitches, short periods of the appearance of a change that might not come - like closed contacts on a window alarm switch or an RF signal that might be noisy.

Or just cutting the user some slack, let there be the possibility of pressing the button without the missile going off, you really have to mean it and press. The. Button.

In those cases, obvsly, you want to wait until the signal is stable before testing it and acting.

Thanks for posting a link to your simulation. As I said, the bounce or no bounce nature of the simulator pushbuttons is a handy feature. Some ppl, I won't name names, turn off the bouncing if the hole point is something else or they just being lazy. Cough!

a7

1 Like

Hello homerhudson

See below a solution using three timers.

You can customise the sketch to suit your project requirements.

//https://forum.arduino.cc/t/turning-loopy-with-nested-loops/1347812
//https://europe1.discourse-cdn.com/arduino/original/4X/7/e/0/7e0ee1e51f1df32e30893550c85f0dd33244fb0e.jpeg
#define ProjectName "Turning loopy with nested loops"
#define NotesOnRelease "Arduino DUE NANO UNO MEGA tested"
// -- some useful text replacements used because I'm lazy with typing --
#define equ ==
#define nequ !=
#define is ==
// make names
enum TimerEvent {NotExpired, Expired};
enum TimerControl {Halt, Run};
enum OutputAction {Off, On};
enum OutputNames {LedOne};
enum InputNames {Button};
// make variables
uint32_t currentMillis = millis();
constexpr uint8_t OutputPins[] {9};
constexpr uint8_t InputPins[] {A0};
constexpr uint8_t NumberOfFlashes {3};
constexpr uint32_t occurTime {1000};
constexpr uint32_t flashTime {33};
// make structures
struct TIMER
{
  uint32_t interval;
  uint8_t control;
  uint32_t now;
  void make (uint32_t interval_)
  {
    interval = interval_;
  }
  void launch(uint32_t currentMillis)
  {
    control = Run;
    now = currentMillis;
  }
  void halt()
  {
    control = Halt;
  }
  uint8_t expired(uint32_t currentMillis)
  {
    uint8_t timerEvent = currentMillis - now >= interval and control;
    if (timerEvent == Expired) now = currentMillis;
    return timerEvent;
  }
};
//-----------------------------------------
// make objects
TIMER debounce;
TIMER occure;
TIMER flash;
//-----------------------------------------
// make support
void heartBeat(const uint8_t LedPin, uint32_t currentMillis)
{
  static bool setUp = false;
  if (setUp == false) pinMode (LedPin, OUTPUT), setUp = true;
  digitalWrite(LedPin, (currentMillis / 500) % 2);
}
// make application
void setup()
{
  Serial.begin(115200);
  for (uint8_t n = 0; n < 32; n++) Serial.println("");
  Serial.print("Source: "), Serial.println(__FILE__);
  Serial.print(ProjectName), Serial.print(" - "), Serial.println(NotesOnRelease);
  pinMode (InputPins[Button], INPUT_PULLUP);
  pinMode (OutputPins[LedOne], OUTPUT);
  Serial.print("\nled test ..");
  digitalWrite (OutputPins[LedOne], On);
  delay(1000);
  digitalWrite (OutputPins[LedOne], Off);
  delay(1000);
  Serial.println("... done\n");
  // initialize timer
  debounce.make(20);
  debounce.launch(millis());
  occure.make(occurTime);
  flash.make(flashTime);
}
void loop()
{
  currentMillis = millis();
  heartBeat(LED_BUILTIN, currentMillis);
  if (debounce.expired(currentMillis) is Expired)
  {
    static uint8_t stateOld = Off;
    static uint8_t toogleState = Off;
    uint8_t stateNew = digitalRead(InputPins[Button]) ? Off : On;
    if (stateOld nequ stateNew)
    {
      stateOld = stateNew;
      if (stateOld equ On)
      {
        toogleState = toogleState ? Off : On;
        switch (toogleState)
        {
          case On:
            Serial.println("\nFlashing On");
            occure.launch(millis());
            flash.launch(millis());
            flash.control = NumberOfFlashes << 1;
            break;
          case Off:
            Serial.println("\nFlashing Off");
            occure.halt();
            digitalWrite (OutputPins[LedOne], Off);
            break;
        }
      }
    }
  }
  if (occure.expired(currentMillis) is Expired)
  {
    flash.launch(millis());
    flash.control = NumberOfFlashes << 1;
  }
  if (flash.expired(currentMillis) is Expired)
  {
    flash.control--;
    digitalWrite (OutputPins[LedOne], digitalRead (OutputPins[LedOne]) ? Off : On);
  }
}

Have a nice day and enjoy coding in C++.

1 Like

Thanks for that.
When you say once in each loop, do you mean each level? I have it once at the top level loop (to turn it on), then only once in the "while" loop to check if it's been pressed again to turn it off.

Thanks @mancera1979, I did look at that and found it quite interesting (for the future) as I was trying to get tit to work using the basics first. Plus I couldn't see how I could read the button press using states. I thought they were just for assigning values to variables based on a given state.

I will certainly take another look at states, I'm sure I've missed something there.

Thanks @indev2 ,
I only had it in there twice so I could turn it on initially, then scan it within the "while" loop to check if it needs to be turned off.

Thanks also for your edited code, but alas, it did literally nothing - I didn't even get the serial outputs to see if it //should// be on or not.

What's the purpose of
"if (strobeOn == 1) {
strobeOn = 0;" won't that just turn it off each time it's turned on before it gets to do anything?

This appears twice. It is also initialized twice. I am uncertain, but this might be making two variables of the same name with different scope and different values, but which is being used in the program?

1 Like

aren't there just 2 events

Capture

1 Like

Thanks @gcjr, I do appreciate the your help with this!

So just copy and pasting your first code into a new sketch didn't work. After uploading, the LED stays off permanently. The second code fared about the same, except the LED stayed on permanently. Neither of them returned any messages through serial, so I couldn't see which state it thought it should be in.

...so I tinkered, and now find that you've raised so many questions in my mind (so many!), but I'll try to stick to the most pertinent (also to prevent or minimise me looking like too much of a fool here)...

  1. I still haven't read about the time stuff, except to know what millis() is, but I'll assume it works here.

  2. I thought the "void setup" needed to be at the top, but I'll assume I'm wrong since you seem to have way more experience than me.

  3. I have no clue what the "byte but" (teehee) line does. I read about "byte" but couldn't find anything on "but". There are a few buts below that line too. what is it referring to?

there should be a print when the button is pressed to toggle the strobe On/Off. did you turn it on?

so you've learned that the locations of functions is not regimented ... like many things

it is both defining a variable named but to be a single 8-bit byte (since it's either 1/0) and setting it's value to the state of ButtonPin read using digitalRead

would you have understood this if it were?

int but = digitalRead (ButtonPin);

and but is used in the code below that line to determine if the state of the pin has changed and if it is LOW after a delay() to avoid mechanical switch bounce

ContactBounce_ActivationAndDeactivation_FromCurrentSource

1 Like