Re '...several things at the same time'

I've just ran Robin2's comprehensive sketch from the thread, 'Demonstration code for several things at the same time'.
https://forum.arduino.cc/index.php?topic=223286.90

There seem to be no comments in the last six years so I'm therefore posting here instead.

I intend to step through this carefully as a great potential learning exercise asap. But it all appears to work as intended - except for the button.

I'm using the familiar four pin NO breadboard button, which goes low on pressing. It behaves erratically here and I'm wondering if there's a likely explanation I've missed please? The button is physically OK, and has been working fine with other sketches today, although I tried another to be sure.

My code is unaltered from the original apart from pin numbers and a few formating changes. But it takes the post over the site's limit, so I've attached the file:

SeveralThingsCode.ino (9.36 KB)

Please post the file as an attachment. It's hard to imagine, though, how the demonstration code could exceed the limit.

aarg:
Please post the file as an attachment. It's hard to imagine, though, how the demonstration code could exceed the limit.

Duly attached.
I think the message said something like "...exceeds the 9,000 character limit."

void readButton() \\ FUNCTION
{
    // this only reads the button state after the button interval has elapsed
    // this avoids multiple flashes if the button bounces
    // every time the button is pressed it changes buttonLed_State causing the Led to go on or off
    // Notice that there is no need to synchronize this use of millis() with the flashing Leds
    if (millis() - previousButtonMillis >= buttonInterval)
    {
        if (digitalRead(buttonPin) == LOW)
        {
            buttonLed_State = ! buttonLed_State; // this changes it to LOW if it was HIGH
            // and to HIGH if it was LOW
            previousButtonMillis += buttonInterval;
        }
    }
}

what happens if the button is held down for longer than the buttonInterval?

a button action is normally performed when there is a change in button state and it is pressed (i.e. LOW)

void updateOnBoardLedState() \\ FUNCTION Don't do that!

gcjr:

void readButton() \\ FUNCTION

{
    // this only reads the button state after the button interval has elapsed
    // this avoids multiple flashes if the button bounces
    // every time the button is pressed it changes buttonLed_State causing the Led to go on or off
    // Notice that there is no need to synchronize this use of millis() with the flashing Leds
    if (millis() - previousButtonMillis >= buttonInterval)
    {
        if (digitalRead(buttonPin) == LOW)
        {
            buttonLed_State = ! buttonLed_State; // this changes it to LOW if it was HIGH
            // and to HIGH if it was LOW
            previousButtonMillis += buttonInterval;
        }
    }
}




what happens if the button is held down for longer than the buttonInterval?

a button action is normally performed when there is a change in button state and it is pressed (i.e. LOW)

buttonInterval is so long that it would toggle continuously every 300ms. I suppose it's coded simplistically in order to keep the sketch focused on the multitasking aspect...

TheMemberFormerlyKnownAsAWOL:

void updateOnBoardLedState() \\ FUNCTION

Don't do that!

Indeed! Corrected that earlier but then attached the previous draft. Now corrected.

I really don't see any question! What is it?

gcjr:

void readButton() \\ FUNCTION

{
   // this only reads the button state after the button interval has elapsed
   // this avoids multiple flashes if the button bounces
   // every time the button is pressed it changes buttonLed_State causing the Led to go on or off
   // Notice that there is no need to synchronize this use of millis() with the flashing Leds
   if (millis() - previousButtonMillis >= buttonInterval)
   {
       if (digitalRead(buttonPin) == LOW)
       {
           buttonLed_State = ! buttonLed_State; // this changes it to LOW if it was HIGH
           // and to HIGH if it was LOW
           previousButtonMillis += buttonInterval;
       }
   }
}




what happens if the button is held down for longer than the buttonInterval?

It blinks repeatedly.

What is your question?

aarg:
I really don't see any question! What is it?

It's the sentence with the question mark at the end!

Terrypin:
It's the sentence with the question mark at the end!

If you mean the remark about the button behaviour, that's been answered... in reply #3 and #5.

aarg:
If you mean the remark about the button behaviour, that's been answered... in reply #3 and #5.

I don't think either of those explain the erratic behaviour I get. As I said in my #8 reply to Greg, it does blink if I hold the button down. But with a normal brief press/release its action is unpredictable. I note that Robin used a simple wire...
Has anyone tried it?

Terrypin:
I'm using the familiar four pin NO breadboard button, which goes low on pressing. It behaves erratically here and I'm wondering if there's a likely explanation I've missed please? The button is physically OK, and has been working fine with other sketches today, although I tried another to be sure.

My code is unaltered from the original apart from pin numbers and a few formating changes. But it takes the post over the site's limit, so I've attached the file:

Please list the lines on which you made changes - it is much easier to help if you limit your changes to those that are unaviodable.

Please also explain what you mean by "behaves erratically"

...R

Terrypin:
I don't think either of those explain the erratic behaviour I get. As I said in my #8 reply to Greg, it does blink if I hold the button down. But with a normal brief press/release its action is unpredictable. I note that Robin used a simple wire...
Has anyone tried it?

shouldn't it only toggle if the button is pressed? then check for a change in state, not simply that the button is LOW

int lastswitchstate = HIGH;
int ledPin          = 13;
int switchpin       = A1;

// -----------------------------------------------------------------------------
void setup () {
    Serial.begin (9600);
    pinMode (ledPin, OUTPUT);
    pinMode (switchpin, INPUT);
}

// -----------------------------------------------------------------------------
void loop () {
    int reading = digitalRead (switchpin);

    if (reading != lastswitchstate){
        lastswitchstate = reading;

        if (LOW == reading)
            digitalWrite (ledPin, ! digitalRead (ledPin));
        
        delay (10);
    }
}

Robin2:
Please list the lines on which you made changes - it is much easier to help if you limit your changes to those that are unaviodable.

Please also explain what you mean by "behaves erratically"

...R

As I said, the changes were trivial: pin numbers and some formatting. I just changed my pin numbers back to yours and ran your sketch and obviously I got the same behaviour from the button.

Not sure what I can add to 'erratic' and 'unpredictable'! IOW, sometimes a press does nothing, sometimes it toggles, sometimes it appears to flash very briefly twice on one press. Etc.

Can you confirm that you get clean toggling please?

Terrypin:
As I said, the changes were trivial: pin numbers and some formatting. I just changed my pin numbers back to yours and ran your sketch and obviously I got the same behaviour from the button.

Not sure what I can add to 'erratic' and 'unpredictable'! IOW, sometimes a press does nothing, sometimes it toggles, sometimes it appears to flash very briefly twice on one press. Etc.

Can you confirm that you get clean toggling please?

Thinking about that code:

The button is only checked once every 300mS. It's entirely possible you would press the button and release it between checks:

                  V-check        V-check ...
CHECKS:     ------|--------------|--------------|--------------|--------------|--- time in mS
PRESSES:             *--------* <-- missed

Not sure why you might see very brief double flashes. I think the idea for the demo is that you press and hold the button for 2 or 5 or whatever seconds, not just for a quick blip.

If you want to toggle the LED using that method you need to change the buttonRead code to look for a change of state and read it much more often (like every 50mS, for example.)

he's not checking for a press. he's checking if the button is LOW

gcjr:
he's not checking for a press. he's checking if the button is LOW

Yes, once every 300mS so a press has to be long and deliberate to demonstrate the blinking timing.

Blackfin:
Yes, once every 300mS so a press has to be long and deliberate to demonstrate the blinking timing.

It's a long time since I wrote and tested the Tutorial code. I don't recall needing to hold the button press for long but it might be a good idea to change

const int buttonInterval = 300; // number of millisecs between button readings

to

const int buttonInterval = 50;

...R