Intentionally ignoring a button input till it’s low again... see comments!

Hi!

Basically, I want my strip of LEDs to deviate from their normal routine (e.g rainbow) to carry out another routine (LEDs pulsing once), then go back the routine (aforementioned rainbow) I want them to deviate when I first connect my phone onto a wireless charger. This signal enters the arduino on a digital pin.

If the input was a button, I’d have no issues as the interrupt will only be active whilst the button is high, and when my finger is off the button the input won’t be active. But I want the LEDs to flash once whilst the charger is connected, and then for the arduino to basically forget the input is high. Is there a way to this?

Sure there is. But as you provide no technical information, it's hard to tell ...

Attache block diagram, wiring diagram and code, and do it the way adviced in "How to use Forum" and the other 2-3 advicing topics.
You can't imagine how often a poor way of connecting a button has been the issue.

It sounds like you need a new variable, maybe a bool 'hasFlashed' that is initially false. Once you detect the HIGH signal from your phone being on the charger, you check 'hasFlashed' and if it is false, you do your flash routine and set it true. If it is already true, you do nothing.

If the signal from your phone is low, you reset 'hasFlashed' back to false so it will do it again.

That is not what interrupts are for!

As a beginner, it is incredibly unlikely that interrupts will be useful to you.

A common "newbie" misunderstanding is that an interrupt is a mechanism for altering the flow of a program - to execute an alternate function. Nothing could be further from the truth! :astonished:

An interrupt is a mechanism for performing an action which can be executed in "no time at all" with an urgency that it must be performed immediately or else data - information - will be lost or some harm will occur. It then returns to the main task without disturbing that task in any way though the main task may well check at the appropriate point for a "flag" set by the interrupt.

Now these criteria are in a microprocessor time scale - microseconds. This must not be confused with a human time scale of tens or hundreds of milliseconds or indeed, a couple of seconds. A switch operation is in this latter category and a mechanical operation perhaps several milliseconds; the period of a 6000 RPM shaft rotation is ten milliseconds.

Unless it is a very complex procedure, you would expect the loop() to cycle many times per millisecond. If it does not, there is most likely an error in code planning; while the delay() function is provided for testing purposes, its action goes strictly against effective programming methods. The loop() will be successively testing a number of contingencies as to whether each requires action, only one of which may be whether a particular timing criteria has expired. Unless an action must be executed in the order of microseconds, it will be handled in the loop().


In this case, you need to break up the "rainbow" function into its component parts, and test for your "interrupt" condition regularly during those parts. This has been discussed frequently here, but it is difficult to find the exact discussions. Mike may have a convenient link.


So what sort of actions do require such immediate attention? Well, generally those which result from the computer hardware itself, such as high speed transfer of data in UARTs(, USARTs) or disk controllers.

An alternate use of interrupts, for context switching in RTOSs, is rarely relevant to this category of microprocessors as it is more efficient to write cooperative code as described above.

RE comments about not attaching code - apologies I wasn't sure if it was going to be of any use, I've attached it below in the form of a txt document. I'm fully aware this isn't correct protocol but the code has too many characters to attach to this response properly - I can copy it in two responses if required.

Blh64 - That makes sense, however would that not just repeat the flashing pattern* constantly while the phone is on the charger? I'm after something that runs the flashing pattern* once, then reverts back to standard rainbow* despite the charger still being connected (and hence input = HIGH). So I guess i'm asking for code that sees the HIGH input, leaves it active for a moment (to give the flashing pattern* time to run) then disregards it until it sees it go LOW (charger disconnected) and then back HIGH again (phone reconnected at some point in the future), at which point it re-runs the flashing pattern*

Paul__B - Response much appreciated, thank you! :slight_smile: Referring to your valid point about checking for my interrupts constantly, I've got the loop constantly checking for button changes(which, in my understanding are interrupts in my code(please correct me if i'm wrong!)) which are classed as interrupts as they need to happen in no time at all...

  • = flashing Neopixel pattern once when wireless charger connected
    ** = rainbow pattern is normal operation for the Neopixels

Display_Panel.txt (9.08 KB)

tomg37:
I've got the loop constantly checking for button changes(which, in my understanding are interrupts in my code(please correct me if i'm wrong!)) which are classed as interrupts as they need to happen in no time at all...

Button changes when a human is behind the button do not require instant attention. They are low priority because human attention is sloooooooooooowwwwwww and human speed is dismal. Contact switch buttons also BOUNCE.

If your button is a phototransistor reading beam interrupts or reflections off a fast moving object then you might need an interrupt.

You don't read the button, you read the pin it's connected to. You can use an interrupt to catch it but it's not necessary.

And then there's the gotcha where code to watch a button -and- do something else at the same time is not going to look much like code that can ONLY do one thing at a time.

For the signal reading, look at the state change example in the IDE. You want to do your thing when your signal changes state (becomes high or becomes low).

tomg37:
Blh64 - That makes sense, however would that not just repeat the flashing pattern* constantly while the phone is on the charger? I'm after something that runs the flashing pattern* once, then reverts back to standard rainbow* despite the charger still being connected (and hence input = HIGH). So I guess i'm asking for code that sees the HIGH input, leaves it active for a moment (to give the flashing pattern* time to run) then disregards it until it sees it go LOW (charger disconnected) and then back HIGH again (phone reconnected at some point in the future), at which point it re-runs the flashing pattern*

Look at the State Change Detection example sketch (File->examles->02.Digital->StateChangeDetection) to see how you detect your input CHANGE. That is the time you implement what I had described above. You don't do it every time through loop()