r2724r16:
It would be REALLY helpful if you tell me how I should program it. Thanks!
This is getting very frustrating. Take three or four hours to study and understand the code in Several Things at a Time. It has all the concepts you need.
Try the program, make changes to it so you can be sure you know how it works.
r2724r16:
Thanks! So I've quickly read over that but there is one problem with making a function for the blinking lights and a function for the button being pressed.
If I wrote a function for the lights to blink, and another function for the button state to be read (and put it in a loop), then the Arduino can't check the state of the button while the lights function is running.
Any ideas?
Yes. get yourself out of blow-off mode and learn something new!
The point of that DEAD SIMPLE CODE is to show how to attend to two or more things independently.
If they're leds then they're leds and if there's a button then that's a task too.
I can turn something on and come back later to turn it off but I NEVER want code execution to stop in between, which is what delay() does.
Nick Gammon has a tutorial with clear commonsense explanation of what it's about, plus code.
Let's look at an analogy. Say you want to cook breakfast. You need to cook:
Put coffee on. Stare at watch until 1 minute has elapsed. Pour coffee.
Cook bacon. Stare at watch until 2 minutes have elapsed. Serve bacon.
Fry eggs. Stare at watch until 3 minutes have elapsed. Serve eggs.
The flaw in this is that whichever way you do it, something is going to be cooked too early (and get cold).
In computer terminology this is blocking. That is, you don't do anything else until the one task at hand is over.
What you are likely to do is this:
Start frying eggs. Look at watch and note the time.
Glance at watch from time to time. When one minute is up then ...
Start cooking bacon. Look at watch and note the time.
Glance at watch from time to time. When another minute is up then ...
Put coffee on. Look at watch and note the time.
When 3 minutes are up, everything is cooked. Serve it all up.
In computer terminology this is non-blocking. That is, keep doing other things while you wait for time to be up.
Note that coffee, bacon and eggs all prepare differently, sort of like how led and button code work differently.
Unless you're dense, replace cook with running a task. There's a led task and there's a button task, the code for each one runs in turn and neither makes the other wait. The tasks are different but the code for each runs which is what you want.
If you learn the basic lesson then this example will be clear to you. Run it and see, you press the button and the blinking starts, press again to stop.
// add-a-sketch_button 2018 by GoForSmoke @ Arduino.cc Forum
// Free for use, Apr 30/2018 by GFS. Compiled on Arduino IDE 1.6.9.
// Update May 6/2018, Aug 11, 2018
/* Button Debounce Example
--- for this example connect a button between pin 7 and GND
--- or stick a jumper in pin 7 and while holding the board steady
--- tap the free end onto the grounded USB port box to press.
--- Press and hold the Button to toggle led13 blinking.
Yes I'm using a 16 bit micros timer to time fractions of millis as micros.
The button reader only reads 1 button per call so as to not block void loop().
Each button has a history byte that holds the last 8 reads with 256 possible
states but only 4 of them being significant.
0 is the button held down
255 is the button left up
127 is the buton changing from up to down, button just released.
128 is the button changing from down to up, button just pressed.
everything else is to be ignored as bounce.
*/
// button vars
byte buttonPin = 7;
byte buttonHistory;
word markButtonTime; // 16-bit micros timers
const word waitButtonTime = 500; // micros
// added sketch task, on-off blinker vars
byte ledState, ledPin = 13; // use byte for small values, int cost 2 bytes
word startBlink, waitBlink; // 16 bit millis is good to time 65.535 seconds
void buttonTask() // yup, this is my new button debounce compromise method.
{ // read twice per milli, bits 0 to 6 all same sets the state
if ( word( micros()) - markButtonTime >= waitButtonTime ) // read occaisoinally
{
buttonHistory <<= 1; // if you don't know <<= look it up in the Arduino Reference
// keep a browser open to that page when you use the IDE.
buttonHistory += digitalRead( buttonPin ); // read history streams through buttonHistory
markButtonTime = micros(); // gets the low 16 bits of micros(), time to 60 ms + margin
}
/* buttonHistory bits read as values:
0 is button held down, 8 reads of 0 in a row
255 is button left up, 8 reads of 1 in a row
127 is buton changing from up to down, 7 1's and 1 0 = just released
128 is button changing from down to up, 7 0's and 1 1 = just pressed.
everything else is to be ignored as bounce.
Understand that 7 same bits in a row counts as pin state stable.
*/
}
void OnOffBlinker() // only blinks if there's a wait time, can be switched on/off
{
if ( waitBlink > 0 ) // this is the on/off switch
{
// word( millis()) gets the low 16 bits of the 32-bit millis() return.
if ( word( millis()) - startBlink >= waitBlink ) // difference in time by subtracting start from end
{
ledState = !ledState; // ! is NOT: not_0/true becomes 0/false else 0 becomes 1.
digitalWrite( ledPin, ledState ); // the led changes state.
startBlink += waitBlink; // next blink starts when it should, where diff > wait.
}
}
else if ( ledState > 0 ) // waitBlink == 0 turns blinking off
{
digitalWrite( ledPin, ledState = LOW ); // make sure the led is OFF
} // yes, you can set a variable during calculation in C, the write here is LOW.
}
void setup()
{
Serial.begin( 115200 );
for ( byte i = 0; i < 66; i++ ) Serial.println();
Serial.println( F( "\n Button Debounce Example, free by GoForSmoke\n" ));
Serial.println( F( "\n-- for this example connect a button between pin 7 and GND" ));
Serial.println( F( "--- or stick a jumper in pin 7 and while holding the board steady" ));
Serial.println( F( "--- tap the free end onto the grounded USB port box to press." ));
pinMode( buttonPin, INPUT_PULLUP );
pinMode( ledPin, OUTPUT );
buttonHistory = 255;
waitBlink = 500;
};
void loop()
{
buttonTask();
/*
0 is the button held down
255 is the button left up
127 is the buton changing from up to down, button just released.
128 is the button changing from down to up, button just pressed.
everything else is to be ignored as bounce.
*/
switch ( buttonHistory )
{
case 128 : // pin is HIGH in bit 7, LOW for 7 reads, up to down detected
buttonHistory = 0; // change detected, make it into no change now
Serial.print( F( "press detected " ));
Serial.println( millis());
if ( waitBlink == 0 ) // toggle action tied to button press
{
waitBlink = 500; // makes the blinking start
startBlink = millis(); // gets the low 16 bits
}
else
{
waitBlink = 0; // makes the blinking stop
}
break;
case 127 : // pin is LOW in bit 7, HIGH for 7 reads, down to up detected
buttonHistory = 255; // change detected, make it into no change now
Serial.print( F( "release detected " ));
Serial.println( millis());
break;
}
OnOffBlinker();
}