/*
now use a keypad as additional input
*/
// forum.arduino.cc/t/dart-board-scoreboard-project-led-control/1437125
// https://wokwi.com/projects/459567665471256577
const unsigned long slowBlinkPeriod = 888;
const unsigned long fastBlinkPeriod = 444;
# include <Keypad.h>
const uint8_t ROWS = 4;
const uint8_t COLS = 4;
char keys[ROWS][COLS] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12},
{13, 14, 15, 16}
};
uint8_t colPins[COLS] = {A0, A1, A2, A3};
uint8_t rowPins[ROWS] = {11, 10, 9, 8};
Keypad myKeypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
unsigned long lastSlowBlink;
unsigned long lastFastBlink;
# define K16 16
bool slowBlinkPhase;
bool fastBlinkPhase;
unsigned long now;
enum {
LED_OFF = 0,
LED_SLOW_BLINK,
LED_FAST_BLINK,
LED_ON
};
# include <Adafruit_NeoPixel.h>
# define PIN 7 // the pin
# define NPIXELS 16 // number of LEDs on strip
Adafruit_NeoPixel stab(NPIXELS, PIN, NEO_GRB + NEO_KHZ800);
const unsigned long offColor = 0x202020;
const unsigned long slowColor = 0xff0000;
const unsigned long fastColor = 0xffff00;
const unsigned long onColor = 0x00ff00;
const byte muxOutput = 12; // *input* for COM CD4067 output
# define NT 16 // up to... 16
byte elementState[K16]; // off, slow, fast, on
bool buttonState[K16]; // stable state: true when button down
# define RATE 177
void setup() {
Serial.begin(115200);
Serial.println("hi Mom!");
stab.begin();
stab.setPixelColor(0, 0xff0000);
stab.setPixelColor(1, 0x00ff00);
stab.setPixelColor(NPIXELS - 1, 0x0000ff);
stab.show();
delay(777);
DDRD |= 0x3c; // pni 5 .. 2 outputs PORTD bit5 .. bit2
pinMode(muxOutput, INPUT);
}
void loop() {
now = millis();
// INPUT
static unsigned int lastButtons;
unsigned int buttons = inReaderD(); // read all buttons from mux
unsigned int acts = buttons & ~lastButtons;
lastButtons = buttons;
char key = myKeypad.getKey(); // add any acts from the keypad
if (key != NO_KEY) {
acts |= 1 << (key - 1);
Serial.print((int) key);
Serial.println(" received");
}
// PROCESS
blinker(); // maintains slow and fast phase flags
for (byte ii = 0; ii < K16; ++ii) {
if (acts & 1)
switch (elementState[ii]) {
case LED_OFF :
elementState[ii] = LED_SLOW_BLINK;
break;
case LED_SLOW_BLINK :
elementState[ii] = LED_FAST_BLINK;
break;
case LED_FAST_BLINK :
elementState[ii] = LED_ON;
break;
case LED_ON :
elementState[ii] = LED_OFF;
break;
}
acts >>= 1;
}
// OUTPUT
for (byte ii = 0; ii < K16; ii++)
switch (elementState[ii]) {
case LED_OFF :
stab.setPixelColor(ii, offColor);
break;
case LED_SLOW_BLINK :
stab.setPixelColor(ii, slowBlinkPhase ? offColor : slowColor);
break;
case LED_FAST_BLINK :
stab.setPixelColor(ii, fastBlinkPhase ? offColor : fastColor);
break;
case LED_ON :
stab.setPixelColor(ii, onColor);
break;
}
stab.show();
}
// read 16 bits from the mux
// debounced here by not reading again too soon
unsigned int inReaderC()
{
static unsigned long lastTime;
static unsigned int lastReport;
unsigned int result = 0;
if (now - lastTime < 20) return lastReport;
lastTime = now;
PORTC &= 0xf0;
for (byte ii = 0; ii < NT; ii++) {
result >>= 1;
if (digitalRead(muxOutput) == LOW) result |= 0x8000; // pressed is LOW
PORTC += 1;
}
lastReport = result;
return result;
}
unsigned int inReaderD()
{
static unsigned long lastTime;
static unsigned int lastReport;
unsigned int result = 0;
if (now - lastTime < 20) return lastReport;
lastTime = now;
PORTD &= 0xc3; // mux at 5 .. 2
for (byte ii = 0; ii < NT; ii++) {
result >>= 1;
if (digitalRead(muxOutput) == LOW) result |= 0x8000; // pressed is LOW
PORTD += 0x4;
}
lastReport = result;
return result;
}
// two BWOD blinkers
void blinker()
{
if (now - lastSlowBlink >= slowBlinkPeriod) {
slowBlinkPhase = !slowBlinkPhase;
lastSlowBlink = now;
}
if (now - lastFastBlink >= fastBlinkPeriod) {
fastBlinkPhase = !fastBlinkPhase;
lastFastBlink = now;
}
}
wire address
fix inReader