I’m trying to build a railway mimic board, I have six bi colour LED’s (RED / Green) and six toggle switches.
With a single switch and a single LED the code below if fine, the green light shows when the switch is moved up and the red light when moved down.
The issue comes if I add more switches, and toggle one of them. I have tried to keep the code as simple as possible to ensure that the logic is not flawed.
However, switch 1 on its own is fine, toggle switch 2 a few time and the LED1 goes out.
Here is the program output:
Switch 1 toggled down (Red 1 On)
Switch 2 toggled up (Green 2 On)
Switch 2 toggled down (Red 2 On, Green 2 Off)
Switch 2 Toggled Up (Green 2 On, Red 2 Off)
Switch 2 Toggled Down (Red 1 Off, Red 2 On, Green 2 Off)
const int led1G = 0;
const int led2G = 1;
const int led3G = 2;
const int led4G = 3;
const int led5G = 4;
const int led6G = 5;
const int led7G = 6;
const int led8G = 7;
const int led1R = 15;
const int led2R = 14;
const int led3R = 13;
const int led4R = 12;
const int led5R = 11;
const int led6R = 10;
const int led7R = 9;
const int led8R = 8;
#include <Adafruit_MCP23X17.h>
#define LED_PIN 0 // MCP23XXX pin LED is attached to
const int board1 = 0x20;
const int board2 = 0x21;
Adafruit_MCP23X17 mcp1;
Adafruit_MCP23X17 mcp2;
// Switches
const int sw1U = 5;
const int sw2U = 4;
const int sw3U = 3;
const int sw4U = 2;
const int sw5U = 1;
const int sw6U = 0;
const int sw7U = 7;
const int sw8U = 6;
const int sw1D = 10;
const int sw2D = 11;
const int sw3D = 12;
const int sw4D = 13;
const int sw5D = 14;
const int sw6D = 15;
const int sw7D = 9;
const int sw8D = 8;
// LED's
const int ledPin = 13; // On board
bool sw1ULS = LOW;
bool sw1DLS = LOW;
bool sw2ULS = LOW;
bool sw2DLS = LOW;
bool sw3ULS = LOW;
bool sw3DLS = LOW;
bool sw4ULS = LOW;
bool sw4DLS = LOW;
bool sw5ULS = LOW;
bool sw5DLS = LOW;
bool sw6ULS = LOW;
bool sw6DLS = LOW;
bool sw7ULS = LOW;
bool sw7DLS = LOW;
bool sw8ULS = LOW;
bool sw9DLS = LOW;
void setup() {
Serial.begin(9600);
// Wait for serial to be available
while (!Serial);
Serial.println("Momentry Switch Test");
// Initialize the MCP23017 using I2C
if (!mcp1.begin_I2C(board2)) {
Serial.println("Error.");
while (1);
}
Serial.println("I2C Board 2 Found...");
if (!mcp2.begin_I2C(board1)) {
Serial.println("Error.");
while (1);
}
Serial.println("I2C Board 1 Found...");
// configure board 1 pins for output
for(int pin=0; pin <= 15; pin ++){
mcp1.pinMode(pin, OUTPUT);
}
// configure board 2 pins for input
for(int pin=0; pin <= 15; pin ++){
mcp2.pinMode(pin, INPUT_PULLUP);
}
// Configure onboard LED
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
// Switch off any lit LED's
turnOffLeds();
}
void loop() {
bool sw1UCS = mcp2.digitalRead(sw1U) == LOW;
bool sw1DCS = mcp2.digitalRead(sw1D) == LOW;
bool sw2UCS = mcp2.digitalRead(sw2U) == LOW;
bool sw2DCS = mcp2.digitalRead(sw2D) == LOW;
bool sw3UCS = mcp2.digitalRead(sw3U) == LOW;
bool sw3DCS = mcp2.digitalRead(sw3D) == LOW;
bool sw4UCS = mcp2.digitalRead(sw4U) == LOW;
bool sw4DCS = mcp2.digitalRead(sw4D) == LOW;
bool sw5UCS = mcp2.digitalRead(sw5U) == LOW;
bool sw5DCS = mcp2.digitalRead(sw5D) == LOW;
bool sw6UCS = mcp2.digitalRead(sw6U) == LOW;
bool sw6DCS = mcp2.digitalRead(sw6D) == LOW;
int deBounce = 500;
// Switch 1 Up
if (mcp2.digitalRead(sw1U) == LOW) {
Serial.println("Switch 1 toggled up");
delay(deBounce);
setLED(led1G, led1R);
}
// Switch 1 Down
if (mcp2.digitalRead(sw1D) == LOW) {
Serial.println("Switch 1 toggled down");
delay(deBounce);
setLED(led1R, led1G);
}
// Switch 2 Up
if (mcp2.digitalRead(sw2U) == LOW) {
Serial.println("Switch 2 toggled up");
delay(deBounce);
setLED(led2G, led2R);
}
// Switch 2 Down
if (mcp2.digitalRead(sw2D) == LOW) {
Serial.println("Switch 2 toggled down");
delay(deBounce);
setLED(led2R, led2G);
}
}
void setLED(int ledOn, int ledOff) {
mcp1.digitalWrite(ledOn, HIGH);
mcp1.digitalWrite(ledOff, LOW);
}
void turnOffLeds() {
for (int pin = 0; pin <= 15; pin ++) {
mcp1.digitalWrite(pin, LOW);
mcp2.digitalWrite(pin, LOW);
}
}
An advice - creating fifteenth variables for LED pins, that 15 variables for switches, than 15 bools will force you to create a separate block code for every switch and every LED.
Instead of this it will be better to organize LEDs and switches in arrays; it make possible to work with switches and LEDs in for loops, make your code shorter and better structured.
Since you have a function handy, add serial printing to it to add the notes you did manually.
I don't see anything that would act the way your code and circuit are currently, it might be interesting to see if the function is actually doing the switching or whether it arises from another issue you haven't addressed.
Do you have decoupling capacitors at the power pins on those ICs? They aren't optional, no matter you e never heard of them or used them and have done just fine so far.
Also perhaps not causing your issue, but you should have a series current-limiting resistor for each LED filament. That's four in all. You can use this to your advantage as well, it lets you determine the current for each LED filament independently.
1st, 500 ms to debounce a switch… where 50 is over the top and 20 is average you go delay( 500 )?
I would keep pin numbers (byte not int) in an array, ditto for status. It would shorten the code, reduce the number of places an error can be, save much time.
Each (in an RGB/white) led junction makes/detects certain frequency photons, a model could read a red light from green without an expensive module, 2 analog pins req’d.
Imagine a train layout with light poles with working lights that the trains followed. The light poles might need to sense trains too, to set the red and green apropo.
From a quick look at your code, I’m guessing that you have THREE position switches ? centre off (up, off, and down)
If they’re really only up / down (2-position), then you don’t need to detect separate up and down positions, they can ONLY be up or down, if they’re not up, they’re down - so you can eliminate half your code and logic
I have used a common ground for all the LED’s and the switches.
Due to the number of connections I had opted to use 12C with 2 boards one with LED’s one with switches.
I had created a much more efficient version of this scrip however, in order to identify the issue I stripped it back to 2 very simple routines to show the behaviour, the issue was replicated with more switches added, as they toggled more lights would go out. My thinking was to scale the issue down to two LED’s to hopefully identify the issue with the logic or construction.
I agree 100% there are better ways to achieve.
You are correct the switches do have 3 positions, While I understand the logic of what you say, surly I need to look for the circuit on the up and down.
Or should I add the up and down wires (Red/Green) to a single pin on the Arduino and watch for a change and just toggle that value.
If Switch 1 is moved up then LED1 is set to green, the Red element is turned off.
The reverse happens if the Switch is moved down.
The switches are momentary switches and return to off when they are released.
This works exactly as expected for every switch
That block of code was going to hold the current LED value so I could then toggle the value as necessary, it’s not used in this test bock.
Switches only need servicing once every 50ms or so.
This handles any switch bounce (may not be an issue here).
Switches should be be monitored for a change in state, not their current state.
So we don't have to read back, please repeat what the problem is ?