/*
Forum: https://forum.arduino.cc/t/einstieg-arduino/1333397/4?u=ec2021
Wokwi: https://wokwi.com/projects/417649916925208577
Matrix keyboard for 4 rows x 4 columns = 16 keys
requires one Pin per row and one per column = 8 pins in this case
And a 16 pixel Neopixel ring
Press the red key to start a game
Press the button that corresponds to the blue pixel (changes the color to green)
If a "black pixel" button was pressed the black pixel changes to red
If all blue pixels have been changed to green the game ends and
can be restarted with the red button
2024/03/25 by ec2021
Modified for "Dart Board Occupancy Display"
2024/12/18 by ec2021
*/
#include <Adafruit_NeoPixel.h>
#define PIN_NEO_PIXEL 8 // Arduino pin that connects to NeoPixel
#define NUM_PIXELS 16 // The number of LEDs (pixels) on NeoPixel
Adafruit_NeoPixel NeoPixel(NUM_PIXELS, PIN_NEO_PIXEL, NEO_GRB + NEO_KHZ800);
byte pixelColReference[NUM_PIXELS];
const byte clBlack = 0;
const byte clGreen = 1;
const byte clRed = 2;
// key matrix
int row[] = {2, 3, 4, 5};
int column[] = {13, 12, 11, 10};
int col_scan;
int last_scan = -1;
constexpr int noOfRows = sizeof(row) / sizeof(row[0]);
constexpr int noOfColumns = sizeof(column) / sizeof(column[0]);
boolean blueModus = false;
int greenPixels = 0;
int redPixels = 0;
void setup()
{
Serial.begin(115200);
NeoPixel.begin();
NeoPixel.clear();
for (int i = 0; i < noOfRows; i++)
{
//Initialization of row pins
pinMode(row[i], OUTPUT);
}
for (int i = 0; i < noOfColumns; i++)
{
//Initialization of column pins
pinMode(column[i], INPUT);
digitalWrite(column[i], HIGH);
}
setAllTo(clBlack);
delay(1000);
setAllTo(clGreen);
delay(1000);
setAllTo(clRed);
}
int aRow;
int aColumn;
void loop()
{
if (buttonPressed(aRow, aColumn)) {
action(aRow, aColumn);
}
}
void setAllTo(byte aColor) {
for (int i = 0; i < NUM_PIXELS; i++) {
pixelColReference[i] = aColor;
}
updateNeoPixels();
}
void updateNeoPixels() {
for (int pixel = 0; pixel < NUM_PIXELS; pixel++) {
switch (pixelColReference[pixel]) {
case clBlack: NeoPixel.setPixelColor(pixel, NeoPixel.Color(0, 0, 0));
break;
case clGreen : NeoPixel.setPixelColor(pixel, NeoPixel.Color(0, 255, 0));
break;
case clRed: NeoPixel.setPixelColor(pixel, NeoPixel.Color(255, 0, 0));
break;
}
}
NeoPixel.show();
}
boolean buttonPressed(int &aRow, int &aColumn) {
//Check for pressed buttons
static boolean pressed = false;
static unsigned long lastPressTime = 0;
if (pressed && millis() - lastPressTime < 300) { // The 300 ms avoid bouncing and
// quick key repetitions
return false;
}
pressed = false;
for (int i = 0; i < noOfRows; i++)
{
if (pressed) break;
for (int j = 0; j < noOfRows; j++) {
digitalWrite(row[j], HIGH);
}
digitalWrite(row[i], LOW);
for (int j = 0; j < noOfColumns; j++)
{
col_scan = digitalRead(column[j]);
if (col_scan == LOW)
{
lastPressTime = millis();
pressed = true;
aRow = i;
aColumn = j;
break;
}
}
}
return pressed;
}
void action(int i, int j)
{
int keyNo = i * noOfColumns + j + 1;
switch (keyNo) {
case 1 ... NUM_PIXELS :
changeColor(keyNo - 1);
break;
default: // and all others here ...
Serial.println("No action implemented yet ....");
}
}
void changeColor(byte pixel) {
byte color = pixelColReference[pixel];
switch (color) {
case clRed: color = clGreen;
break;
case clGreen: color = clRed;
break;
}
pixelColReference[pixel] = color;
updateNeoPixels();
}