I want to continue this type of pattern where each button press will result in two or three of the LEDs changing their effective state.
I'll assume there are nLED LEDs and buttons, and that the buttons are momentary buttons and need debouncing. I presume you have one button beneath each LED, numbered say 0 to nLED-1, and that the two or three LEDs that will change when button k is pressed have numbers k, k+1, and possibly k+2.
To simplify the coding, create an array (or a bit map), say Lsts, with nLED entries, to represent the current state of LEDs, and a similar array, say Bsts for button statuses, and an array of bytes bounce to track debouncing status.
On each pass through loop()
, use a for
loop to read each eligible switch. A switch with a nonzero bounce entry is debouncing and doesn't get read. If a switch is read and it changes, update the LED statuses in Lsts and at ports. For example:
enum { nLED=5, debouncePasses=50 };
byte Lsts[nLED]={0}, Bsts[nLED]={1,1,1,1,1}, bounce[nLED]={0};
const byte Lpins[nLED] = { 3,4,5,6,7 };
const byte Bpins[nLED] = { 8,9,10,11,12 };
//... etc
void setup() {
for (byte i=0; i<nLED; ++i) {
pinMode(Lpins[i], OUTPUT);
// Buttons will have negative logic, hi for open, lo for pressed
pinMode(Bpins[i], INPUT_PULLUP);
}
// ... any other initialization ...
}
void loop() {
for (byte i=0; i<nLED; ++i) {
// See if button is eligible for reading, and if it changed
if (bounce[i]) {
--bounce[i]; // Decrease bounce pass counter
} else {
if (digitalRead(Bpins[i]) != Bsts[i]){
// Yes, it's eligible and it changed
bounce[i] = debouncePasses; // Set button's debounce counter
if (Bsts[i]) { // Test if switch was pressed vs released
// Toggle the button's light and the next one or two lights
for (int j=i; j<nLED && j<i+3; ++j) {
Lsts[j] = !Lsts[j];
digitalWrite(Lpins[j], Lsts[j]);
}
}
Bsts[i] = !Bsts[i]; // Toggle button state
}
}
}
// ... any other stuff
delayMicroseconds(500); // Delay for bounce-pass timing
// alternately, instead of delayMicroseconds, sleep until timer tick
}
Edit 1: If there are more LEDs than buttons, then use separate constants for the counts, adjust the initializations, etc. For example:
enum { nButton=5, nLED=6, debouncePasses=50 };
byte Lsts[nLED] ={1,0,1,0,1,0};
byte Bsts[nButton]={1,1,1,1,1}, bounce[nLED]={0};
//... etc
void setup() {
for (byte i=0; i<nLED; ++i) {
pinMode(Lpins[i], OUTPUT);
digitalWrite(Lpins[i], Lsts[i]);
}
// Buttons will have negative logic, hi for open, lo for pressed
for (byte i=0; i<nButton; ++i) {
pinMode(Bpins[i], INPUT_PULLUP);
}
// ... any other initialization ...
}
In loop()
, change the initial for
from for (byte i=0; i<nLED; ++i)
to for (byte i=0; i<nButton; ++i)
. This will work ok if there is an extra LEDs after the LEDs that line up with buttons.
Edit 2:
Why when using an array doesn't the arduino recognize the HIGH or LOW state of an led? I tried adding this simple code:
if (42 && 44 && 46 && 48 && 50 == HIGH){
digitalWrite (ledWin, LOW); } else {digitalWrite (ledWin, HIGH);}
Evidently you want to test if all the LEDs are on, and apparently the numbers 42, 44, ... 50 are supposed to somehow represent LED states.
However, numbers like 42, 44, ... are constant values and cannot properly represent the value of something that varies. The condition in that if
statement will always evaluate to the same value, false, as follows.
According to the C/C++ standard, a condition like 42 && 44 && 46 && 48 && 50 == HIGH
consisting of a series of terms separated by &&
operators will be evaluated left to right until either one is false (making the whole expression false) or all are true (making it true). (For example, see the Remarks section of Logical AND Operator: &&.)
In this case, 42 is non-zero, hence true. Next, 44 is true, 46 is true, and 48 is true. But 50 == HIGH
is false – the value of HIGH
is 1, and 50 is not equal to 1. Therefore the whole expression is false.
A better approach to finding out if all the LEDs are on or off is to test the values of Lsts[]
entries. For example, you could add them up, and then see if the sum is equal to 0 (all off) or equal to nLED
(all on):
byte nOn = 0;
for (byte i=0; i<nLED; ++i) nOn += Lsts[i];
digitalWrite (ledWin, nOn < nLED);
That will set the ledWin
pin if not all of the LEDs are on, else will clear it.