Hi
I am having a problem with this switch scanning code. When I press any of the switches (tactile switch) I do not get a response on serial monitor. serial monitor shows the DEBUG option being on or off and also shows if the switch for selecting either brown or grey mapping.
I have triple checked the connections and all the inputs and outputs are wired correctly.
Is the something I'm doing wrong which I can't see.
Thank you
/*
- ATmega2560, 5×12 switch matrix
- Columns float HIGH via INPUT_PULLUP; only driven LOW when scanning
- Rows are inputs with INPUT_PULLUP, so a closed switch pulls the row pin LOW
- OPTION_SW_1 (pin 22) = Grey/Brown mapping
- OPTION_SW_4 (pin 25) = Debug toggle
- SCAN_INTERVAL = 2 ms
- POWER_LED (pin 38) lights at startup
*/
#include <Arduino.h>
// Switch rows (12 inputs, active LOW when pressed)
static const uint8_t switchInputs[12] = {
2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13
};
// Switch columns (5 lines, normally pulled HIGH via INPUT_PULLUP)
static const uint8_t switchOutputs[5] = {
44, 43, 42, 41, 40
};
// Mapping‐select switch: HIGH = Grey, LOW = Brown
#define OPTION_SW_1 22
// Debug‐toggle switch: LOW = Debug ON, HIGH = Debug OFF
#define OPTION_SW_4 25
// Power LED
#define POWER_LED 38
// 2 ms scan interval
#define SCAN_INTERVAL 2
// Track last pressed state for each (col,row)
bool lastPressed[5][12] = { false };
// Timestamp of last scan
unsigned long lastScan = 0;
// Whether Serial debug is currently active
bool serialActive = false;
// Last mapping state (to detect changes)
bool lastMappingGrey = false;
void setup() {
// 1) Turn on the power LED
pinMode(POWER_LED, OUTPUT);
digitalWrite(POWER_LED, HIGH);
// 2) Configure row inputs as INPUT (they read HIGH until pulled LOW by a switch)
for (uint8_t i = 0; i < 12; i++) {
pinMode(switchInputs[i], INPUT_PULLUP);
}
for (uint8_t i = 0; i < 5; i++) {
pinMode(switchOutputs[i], OUTPUT);
}
// 4) Configure mapping and debug switches
pinMode(OPTION_SW_1, INPUT_PULLUP);
pinMode(OPTION_SW_4, INPUT_PULLUP);
// 5) Always start Serial at 115200
Serial.begin(115200);
delay(5);
Serial.println("System initialized.");
// 6) Print initial mapping
bool mappingGrey = (digitalRead(OPTION_SW_1) == HIGH);
lastMappingGrey = mappingGrey;
Serial.print("Mapping: ");
Serial.println(mappingGrey ? "GREY" : "BROWN");
// 7) Check debug switch at startup
if (digitalRead(OPTION_SW_4) == LOW) {
serialActive = true;
Serial.println("Debug enabled (pin 25 LOW).");
} else {
serialActive = false;
Serial.println("Debug disabled (pin 25 HIGH).");
}
}
void loop() {
// 1) Detect mapping switch changes
bool mappingGrey = (digitalRead(OPTION_SW_1) == HIGH);
if (mappingGrey != lastMappingGrey) {
lastMappingGrey = mappingGrey;
if (serialActive) {
Serial.print("Mapping changed: ");
Serial.println(mappingGrey ? "GREY" : "BROWN");
}
}
// 2) Detect debug‐toggle changes
bool nowDebug = (digitalRead(OPTION_SW_4) == LOW);
if (nowDebug && !serialActive) {
serialActive = true;
Serial.println("Debug enabled (pin 25 LOW).");
}
else if (!nowDebug && serialActive) {
Serial.println("Debug disabled (pin 25 HIGH).");
serialActive = false;
}
// 3) Only scan every SCAN_INTERVAL milliseconds
if (millis() - lastScan >= SCAN_INTERVAL) {
lastScan = millis();
scanMatrix();
}
// 4) (Optional) insert checkSafety(); here
}
// Scan a 5×12 matrix using “open-drain” style: columns idle as INPUT_PULLUP (HIGH),
// and are driven LOW only during the brief scan.
void scanMatrix() {
bool isGreyMode = (digitalRead(OPTION_SW_1) == HIGH);
for (uint8_t col = 0; col < 5; col++) {
// 1) Activate this column: switch from INPUT_PULLUP → OUTPUT + LOW
pinMode(switchOutputs[col], OUTPUT);
digitalWrite(switchOutputs[col], LOW);
delayMicroseconds(50); // allow settling time
// 2) Read each of the 12 rows
for (uint8_t row = 0; row < 12; row++) {
bool pressed = (digitalRead(switchInputs[row]) == LOW);
if (pressed != lastPressed[col][row]) {
lastPressed[col][row] = pressed;
if (serialActive) {
Serial.print(pressed ? "Pressed " : "Released ");
Serial.print("Row ");
Serial.print(row + 1);
Serial.print(" Col ");
Serial.print(col + 1);
Serial.print(" → ");
Serial.println(mapToFunction(row, col, isGreyMode));
}
// TODO: Add your relay control here.
}
}
// 3) Deactivate this column: switch back to INPUT_PULLUP
pinMode(switchOutputs[col], INPUT_PULLUP);
}
}
// Returns a two‐ or three‐letter code for a given (row, col) and mapping
String mapToFunction(uint8_t row, uint8_t col, bool isGrey) {
if (isGrey) {
// GREY MAPPING
if (row == 2 && col == 2) return "BRR";
if (row == 7 && col == 2) return "BRF";
if (row == 2 && col == 3) return "FTD";
if (row == 7 && col == 3) return "FTU";
if (row == 5 && col == 2) return "RTD";
if (row == 3 && col == 2) return "RTU";
if (row == 3 && col == 3) return "PF";
if (row == 5 && col == 3) return "PR";
if (row == 8 && col == 0) return "OSR";
if (row == 9 && col == 0) return "OSL";
if (row == 10 && col == 0) return "OSD";
if (row == 11 && col == 0) return "OSU";
if (row == 8 && col == 1) return "NSR";
if (row == 9 && col == 1) return "NSL";
if (row == 10 && col == 1) return "NSD";
if (row == 11 && col == 1) return "NSU";
}
else {
// BROWN MAPPING
if (row == 6 && col == 2) return "BRR";
if (row == 1 && col == 2) return "BRF";
if (row == 2 && col == 3) return "FTD";
if (row == 7 && col == 3) return "FTU";
if (row == 0 && col == 2) return "RTD";
if (row == 4 && col == 2) return "RTU";
if (row == 3 && col == 3) return "PF";
if (row == 5 && col == 3) return "PR";
}
return "Unknown";
}