// https://forum.arduino.cc/t/issue-with-matrix-keypad-vs-pull-up-buttons-in-the-code/1239164
// https://wokwi.com/projects/393248438299541505
# include <EEPROM.h>
# include <Keypad.h>
// hack it to use a strip of neopixels
//
# define NINE 8 // # of LEDs to handle (lose status LED at 13)
# define BASE 5 // base. pins must++
# include <Adafruit_NeoPixel.h>
# define LED_PIN A0
# define LED_COUNT NINE
Adafruit_NeoPixel disaply(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
void myDigitalWrite(int theLED, int theValue)
{
unsigned long was = disaply.getPixelColor(theLED - BASE);
disaply.setPixelColor(theLED - BASE, theValue ? 0xff0000 : 0x202020);
disaply.show();
return; // rest is for
if (was == disaply.getPixelColor(theLED - BASE)) Serial.println(" work to do");
Serial.print(theLED);
Serial.print(" + ");
bool any = false;
for (int ii = 0; ii < 9; ii++)
any |= disaply.getPixelColor(ii) == 0xff0000;
// if (any) {
{
for (int ii = 0; ii < 9; ii++)
Serial.print(disaply.getPixelColor(ii) == 0xff0000 ? "X" : ".");
Serial.println("");
}
}
# define digitalWrite myDigitalWrite
//
// end of hack. sue me, I said it was a hack
// the rest is mostly untouched original
const byte ROWS = 2;
const byte COLS = 3;
const byte key [ROWS][COLS] =
{
{1,2,3},
{4,5,6}
};
const String ButtonPress[6] = {"Stop", "Warn", "Change", "Left", "Center", "Right"};
byte rowPins[ROWS] = {3, 2};
byte colPins[COLS] = {A2, A3, A4};
bool gotKey = false;
byte pressedKey;
Keypad keypad = Keypad(makeKeymap(key),rowPins, colPins, ROWS, COLS);
int statuslight = 13;
int LEDleft[] = {5, 6, 7, 8, 9, 10, 11, 12};
int LEDright[] = {12, 11, 10, 9, 8, 7, 6, 5};
int centerleft[] = {9, 10, 11, 12};
int centerright[] = {8, 7, 6, 5};
int light = 0;
int counter = 1;
int pattern_count = 0;
int warning_count = EEPROM.read(0);
long lasttimer = 0;
static long timer = 100;
static long timer2 = 200;
#define LEFTside 0x0
#define RIGHTside 0x1
byte whichLED = LEFTside;
byte LEFT_state = LOW;
byte RIGHT_state = LOW;
byte arrow_state = HIGH;
unsigned long strobeDelay = 75;
unsigned long switchDelay = 500;
unsigned long switchDelay2 = 1000;
unsigned long switchDelay3 = 450;
unsigned long strobeWait = strobeDelay;
unsigned long waitUntilSwitch = switchDelay;
unsigned long sequenceStartTime;
unsigned long sequenceStartTime2;
void setup() {
Serial.begin(9600);
disaply.begin();
disaply.setPixelColor(1, 0xff40c0);
disaply.show();
delay(777);
disaply.clear();
disaply.show();
pinMode(statuslight, OUTPUT);
pinMode(12, OUTPUT);
pinMode(11, OUTPUT);
pinMode(10, OUTPUT);
pinMode(9, OUTPUT);
pinMode(8, OUTPUT);
pinMode(7, OUTPUT);
pinMode(6, OUTPUT);
pinMode(5, OUTPUT);
}
void loop() {
// digitalWrite(statuslight, HIGH);
byte key = (byte)keypad.getKey();
if (key) {
Serial.print("\n$raw key "); Serial.print(key);
gotKey = true;
pressedKey = key - 1;
key = 0;
}
if (gotKey == true) {
Serial.print(" "); Serial.print("now key "); Serial.println(pressedKey); Serial.print(" $ ");
Serial.println(ButtonPress[pressedKey]);
gotKey = false;
/*}
if (0) {*/
if (1) // hand control this outlier
if (ButtonPress[pressedKey] == "Change") {
delay(500);
warning_count++;
if (warning_count >= 18) {
warning_count = 1;
}
// already is boss gotKey = false;
}
if (ButtonPress[pressedKey] == "Right") {
delay(50);
pattern_count = 1;
}
if (ButtonPress[pressedKey] == "Center") {
delay(50);
pattern_count = 2;
}
if (ButtonPress[pressedKey] == "Left") {
delay(50);
pattern_count = 3;
}
if (ButtonPress[pressedKey] == "Warn") {
delay(50);
pattern_count = 4;
}
if (ButtonPress[pressedKey] == "Stop") {
delay(50);
pattern_count = 0;
EEPROM.update(0, warning_count);
}
}
static int lastPattern = -1;
if (pattern_count != lastPattern) {
Serial.print("pattern_count case "); Serial.println(pattern_count);
lastPattern = pattern_count;
}
if (1)
switch (pattern_count) {
case 0:
pattern_off();
break;
case 1:
traffic_left();
Serial.println(" traffic_left");
break;
case 2:
traffic_center();
break;
case 3:
traffic_right();
break;
case 4:
traffic_warning();
break;
}
}
void pattern_off() {
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
}
void traffic_left() {
long time = millis() - sequenceStartTime;
if (time < 16000)
{
left_arrow();
}
else if (time < 18000)
{
half_half_flash();
}
else sequenceStartTime = millis();
}
void traffic_center() {
long time = millis() - sequenceStartTime;
if (time < 16000)
{
center_arrow();
}
else if (time < 18000)
{
half_half_flash();
}
else sequenceStartTime = millis();
}
void traffic_right() {
long time = millis() - sequenceStartTime;
if (time < 16000)
{
right_arrow();
}
else if (time < 18000)
{
half_half_flash();
}
else sequenceStartTime = millis();
}
void traffic_warning() {
switch (warning_count) {
case 1:
even_odd();
break;
case 2:
even_odd_flash();
break;
case 3:
half_half();
break;
case 4:
half_half_flash();
break;
case 5:
two_by_two();
break;
case 6:
tow_by_two_flash();
break;
case 7:
two_by_two_parallel();
break;
case 8:
two_by_two_parallel_flash();
break;
case 9:
three_by_one();
break;
case 10:
three_by_one_flash();
break;
case 11:
outboard();
break;
case 12:
outboard_flash();
break;
case 13:
inboard_6();
break;
case 14:
inboard_6_flash();
break;
case 15:
solid();
break;
case 16:
solid_flash();
break;
case 17:
solid_flash_pause();
break;
case 18:
multi_pattern();
break;
}
}
void even_odd() {
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
long time = millis() - sequenceStartTime;
if (time < 300)
{
digitalWrite(12, HIGH);
digitalWrite(11, LOW);
digitalWrite(10, HIGH);
digitalWrite(9, LOW);
digitalWrite(8, HIGH);
digitalWrite(7, LOW);
digitalWrite(6, HIGH);
digitalWrite(5, LOW);
}
else if (time < 600)
{
digitalWrite(12, LOW);
digitalWrite(11, HIGH);
digitalWrite(10, LOW);
digitalWrite(9, HIGH);
digitalWrite(8, LOW);
digitalWrite(7, HIGH);
digitalWrite(6, LOW);
digitalWrite(5, HIGH);
}
else sequenceStartTime = millis();
}
void even_odd_flash() {
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
digitalWrite(12, LEFT_state);
digitalWrite(11, RIGHT_state);
digitalWrite(10, LEFT_state);
digitalWrite(9, RIGHT_state);
digitalWrite(8, LEFT_state);
digitalWrite(7, RIGHT_state);
digitalWrite(6, LEFT_state);
digitalWrite(5, RIGHT_state);
if ((long)(millis() - waitUntilSwitch) >= 0) {
LEFT_state = LOW;
RIGHT_state = LOW;
whichLED = !whichLED;
waitUntilSwitch += switchDelay;
}
if ((long)(millis() - strobeWait) >= 0) {
if (whichLED == LEFTside)
LEFT_state = !LEFT_state;
if (whichLED == RIGHTside)
RIGHT_state = !RIGHT_state;
strobeWait += strobeDelay;
}
}
void half_half() {
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
long time = millis() - sequenceStartTime;
if (time < 250)
{
digitalWrite(12, HIGH);
digitalWrite(11, HIGH);
digitalWrite(10, HIGH);
digitalWrite(9, HIGH);
digitalWrite(8, LOW);
digitalWrite(7, LOW);
digitalWrite(6, LOW);
digitalWrite(5, LOW);
}
else if (time < 500)
{
digitalWrite(12, LOW);
digitalWrite(11, LOW);
digitalWrite(10, LOW);
digitalWrite(9, LOW);
digitalWrite(8, HIGH);
digitalWrite(7, HIGH);
digitalWrite(6, HIGH);
digitalWrite(5, HIGH);
}
else sequenceStartTime = millis();
}
void half_half_flash() {
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
digitalWrite(12, LEFT_state);
digitalWrite(11, LEFT_state);
digitalWrite(10, LEFT_state);
digitalWrite(9, LEFT_state);
digitalWrite(8, RIGHT_state);
digitalWrite(7, RIGHT_state);
digitalWrite(6, RIGHT_state);
digitalWrite(5, RIGHT_state);
if ((long)(millis() - waitUntilSwitch) >= 0) {
LEFT_state = LOW;
RIGHT_state = LOW;
whichLED = !whichLED;
waitUntilSwitch += switchDelay;
}
if ((long)(millis() - strobeWait) >= 0) {
if (whichLED == LEFTside)
LEFT_state = !LEFT_state;
if (whichLED == RIGHTside)
RIGHT_state = !RIGHT_state;
strobeWait += strobeDelay;
}
}
void two_by_two() {
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
long time = millis() - sequenceStartTime;
if (time < 150)
{
digitalWrite(12, HIGH);
digitalWrite(11, HIGH);
digitalWrite(10, LOW);
digitalWrite(9, LOW);
digitalWrite(8, LOW);
digitalWrite(7, LOW);
digitalWrite(6, HIGH);
digitalWrite(5, HIGH);
}
else if (time < 300)
{
digitalWrite(12, LOW);
digitalWrite(11, LOW);
digitalWrite(10, HIGH);
digitalWrite(9, HIGH);
digitalWrite(8, HIGH);
digitalWrite(7, HIGH);
digitalWrite(6, LOW);
digitalWrite(5, LOW);
}
else sequenceStartTime = millis();
}
void tow_by_two_flash() {
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
digitalWrite(12, LEFT_state);
digitalWrite(11, LEFT_state);
digitalWrite(10, RIGHT_state);
digitalWrite(9, RIGHT_state);
digitalWrite(8, RIGHT_state);
digitalWrite(7, RIGHT_state);
digitalWrite(6, LEFT_state);
digitalWrite(5, LEFT_state);
if ((long)(millis() - waitUntilSwitch) >= 0) {
LEFT_state = LOW;
RIGHT_state = LOW;
whichLED = !whichLED;
waitUntilSwitch += switchDelay;
}
if ((long)(millis() - strobeWait) >= 0) {
if (whichLED == LEFTside)
LEFT_state = !LEFT_state;
if (whichLED == RIGHTside)
RIGHT_state = !RIGHT_state;
strobeWait += strobeDelay;
}
}
void three_by_one() {
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
long time = millis() - sequenceStartTime;
if (time < 400)
{
digitalWrite(12, HIGH);
digitalWrite(11, HIGH);
digitalWrite(10, HIGH);
digitalWrite(9, LOW);
digitalWrite(8, HIGH);
digitalWrite(7, LOW);
digitalWrite(6, LOW);
digitalWrite(5, LOW);
}
else if (time < 800)
{
digitalWrite(12, LOW);
digitalWrite(11, LOW);
digitalWrite(10, LOW);
digitalWrite(9, HIGH);
digitalWrite(8, LOW);
digitalWrite(7, HIGH);
digitalWrite(6, HIGH);
digitalWrite(5, HIGH);
}
else sequenceStartTime = millis();
}
void three_by_one_flash() {
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
digitalWrite(12, RIGHT_state);
digitalWrite(11, RIGHT_state);
digitalWrite(10, RIGHT_state);
digitalWrite(8, RIGHT_state);
digitalWrite(9, LEFT_state);
digitalWrite(7, LEFT_state);
digitalWrite(6, LEFT_state);
digitalWrite(5, LEFT_state);
if ((long)(millis() - waitUntilSwitch) >= 0) {
LEFT_state = LOW;
RIGHT_state = LOW;
whichLED = !whichLED;
waitUntilSwitch += switchDelay;
}
if ((long)(millis() - strobeWait) >= 0) {
if (whichLED == LEFTside)
LEFT_state = !LEFT_state;
if (whichLED == RIGHTside)
RIGHT_state = !RIGHT_state;
strobeWait += strobeDelay;
}
}
void two_by_two_parallel() {
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
long time = millis() - sequenceStartTime;
if (time < 150)
{
digitalWrite(12, HIGH);
digitalWrite(11, HIGH);
digitalWrite(10, LOW);
digitalWrite(9, LOW);
digitalWrite(8, HIGH);
digitalWrite(7, HIGH);
digitalWrite(6, LOW);
digitalWrite(5, LOW);
}
else if (time < 300)
{
digitalWrite(12, LOW);
digitalWrite(11, LOW);
digitalWrite(10, HIGH);
digitalWrite(9, HIGH);
digitalWrite(8, LOW);
digitalWrite(7, LOW);
digitalWrite(6, HIGH);
digitalWrite(5, HIGH);
}
else sequenceStartTime = millis();
}
void two_by_two_parallel_flash() {
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
digitalWrite(12, LEFT_state);
digitalWrite(11, LEFT_state);
digitalWrite(10, RIGHT_state);
digitalWrite(9, RIGHT_state);
digitalWrite(8, LEFT_state);
digitalWrite(7, LEFT_state);
digitalWrite(6, RIGHT_state);
digitalWrite(5, RIGHT_state);
if ((long)(millis() - waitUntilSwitch) >= 0) {
LEFT_state = LOW;
RIGHT_state = LOW;
whichLED = !whichLED;
waitUntilSwitch += switchDelay;
}
if ((long)(millis() - strobeWait) >= 0) {
if (whichLED == LEFTside)
LEFT_state = !LEFT_state;
if (whichLED == RIGHTside)
RIGHT_state = !RIGHT_state;
strobeWait += strobeDelay;
}
}
void outboard() {
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
long time = millis() - sequenceStartTime;
if (time < 300)
{
digitalWrite(12, HIGH);
digitalWrite(11, HIGH);
digitalWrite(10, LOW);
digitalWrite(9, LOW);
digitalWrite(8, LOW);
digitalWrite(7, LOW);
digitalWrite(6, LOW);
digitalWrite(5, LOW);
}
else if (time < 600)
{
digitalWrite(12, LOW);
digitalWrite(11, LOW);
digitalWrite(10, LOW);
digitalWrite(9, LOW);
digitalWrite(8, LOW);
digitalWrite(7, LOW);
digitalWrite(6, HIGH);
digitalWrite(5, HIGH);
}
else sequenceStartTime = millis();
}
void outboard_flash() {
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
digitalWrite(12, RIGHT_state);
digitalWrite(11, RIGHT_state);
digitalWrite(6, LEFT_state);
digitalWrite(5, LEFT_state);
if ((long)(millis() - waitUntilSwitch) >= 0) {
LEFT_state = LOW;
RIGHT_state = LOW;
whichLED = !whichLED;
waitUntilSwitch += switchDelay;
}
if ((long)(millis() - strobeWait) >= 0) {
if (whichLED == LEFTside)
LEFT_state = !LEFT_state;
if (whichLED == RIGHTside)
RIGHT_state = !RIGHT_state;
strobeWait += strobeDelay;
}
}
void inboard_6() {
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
long time = millis() - sequenceStartTime;
if (time < 200)
{
digitalWrite(11, HIGH);
digitalWrite(10, HIGH);
digitalWrite(9, LOW);
digitalWrite(8, LOW);
digitalWrite(7, HIGH);
digitalWrite(6, HIGH);
}
else if (time < 400)
{
digitalWrite(11, LOW);
digitalWrite(10, LOW);
digitalWrite(9, HIGH);
digitalWrite(8, HIGH);
digitalWrite(7, LOW);
digitalWrite(6, LOW);
}
else sequenceStartTime = millis();
}
void inboard_6_flash() {
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
digitalWrite(11, LEFT_state);
digitalWrite(10, LEFT_state);
digitalWrite(9, RIGHT_state);
digitalWrite(8, RIGHT_state);
digitalWrite(7, LEFT_state);
digitalWrite(6, LEFT_state);
if ((long)(millis() - waitUntilSwitch) >= 0) {
LEFT_state = LOW;
RIGHT_state = LOW;
whichLED = !whichLED;
waitUntilSwitch += switchDelay;
}
if ((long)(millis() - strobeWait) >= 0) {
if (whichLED == LEFTside)
LEFT_state = !LEFT_state;
if (whichLED == RIGHTside)
RIGHT_state = !RIGHT_state;
strobeWait += strobeDelay;
}
}
void solid() {
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
long time = millis() - sequenceStartTime;
if (time < 800)
{
digitalWrite(12, HIGH);
digitalWrite(11, HIGH);
digitalWrite(10, HIGH);
digitalWrite(9, HIGH);
digitalWrite(8, HIGH);
digitalWrite(7, HIGH);
digitalWrite(6, HIGH);
digitalWrite(5, HIGH);
}
else if (time < 1600)
{
digitalWrite(12, LOW);
digitalWrite(11, LOW);
digitalWrite(10, LOW);
digitalWrite(9, LOW);
digitalWrite(8, LOW);
digitalWrite(7, LOW);
digitalWrite(6, LOW);
digitalWrite(5, LOW);
}
else sequenceStartTime = millis();
}
void solid_flash() {
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
long time = millis() - sequenceStartTime;
if (time < 200)
{
digitalWrite(12, HIGH);
digitalWrite(11, HIGH);
digitalWrite(10, HIGH);
digitalWrite(9, HIGH);
digitalWrite(8, HIGH);
digitalWrite(7, HIGH);
digitalWrite(6, HIGH);
digitalWrite(5, HIGH);
}
else if (time < 400)
{
digitalWrite(12, LOW);
digitalWrite(11, LOW);
digitalWrite(10, LOW);
digitalWrite(9, LOW);
digitalWrite(8, LOW);
digitalWrite(7, LOW);
digitalWrite(6, LOW);
digitalWrite(5, LOW);
}
else sequenceStartTime = millis();
}
void solid_flash_pause() {
for (int i = 0; i <= 7; i++) {
digitalWrite(LEDright[i], LOW);
}
digitalWrite(12, LEFT_state);
digitalWrite(11, LEFT_state);
digitalWrite(10, LEFT_state);
digitalWrite(9, LEFT_state);
digitalWrite(8, LEFT_state);
digitalWrite(7, LEFT_state);
digitalWrite(6, LEFT_state);
digitalWrite(5, LEFT_state);
if ((long)(millis() - waitUntilSwitch) >= 0) {
LEFT_state = LOW;
RIGHT_state = LOW;
whichLED = !whichLED;
waitUntilSwitch += switchDelay3;
}
if ((long)(millis() - strobeWait) >= 0) {
if (whichLED == LEFTside)
LEFT_state = !LEFT_state;
if (whichLED == RIGHTside)
RIGHT_state = !RIGHT_state;
strobeWait += strobeDelay;
}
}
void left_arrow() {
unsigned long currenttimer = millis();
if (currenttimer - lasttimer >= timer) {
lasttimer = currenttimer;
for (int i = 0; i <= 7; i++) {
}
light = light + counter;
if (light > 7) {
arrow_state = !arrow_state;
light = 0;
counter = 1;
}
if (arrow_state == HIGH) {
digitalWrite(LEDleft[light], HIGH);
}
else if (arrow_state == LOW) {
digitalWrite(LEDleft[light], LOW);
}
}
}
void right_arrow() {
unsigned long currenttimer = millis();
if (currenttimer - lasttimer >= timer) {
lasttimer = currenttimer;
for (int i = 0; i <= 7; i++) {
}
light = light + counter;
if (light > 7) {
arrow_state = !arrow_state;
light = 0;
counter = 1;
}
if (arrow_state == HIGH) {
digitalWrite(LEDright[light], HIGH);
}
else if (arrow_state == LOW) {
digitalWrite(LEDright[light], LOW);
}
}
}
void center_arrow() {
unsigned long currenttimer = millis();
if (currenttimer - lasttimer >= timer2) {
lasttimer = currenttimer;
for (int i = 0; i <= 7; i++) {
}
light = light + counter;
if (light > 3) {
arrow_state = !arrow_state;
light = 0;
counter = 1;
}
if (arrow_state == HIGH) {
digitalWrite(centerright[light], HIGH);
digitalWrite(centerleft[light], HIGH);
}
if (arrow_state == LOW) {
digitalWrite(centerright[light], LOW);
digitalWrite(centerleft[light], LOW);
}
}
}
void multi_pattern(){
long time = millis() - sequenceStartTime2;
if (time < 4000)
{
half_half_flash();
}
else if (time < 8000)
{
outboard();
}
else if (time < 12000)
{
two_by_two_parallel_flash();
}
else if (time < 16000)
{
solid_flash_pause();
}
else if (time < 20000)
{
outboard_flash();
}
else if (time < 24000)
{
tow_by_two_flash();
}
else if (time < 28000)
{
half_half();
}
else if (time < 32000)
{
two_by_two_parallel();
}
else sequenceStartTime2 = millis();
}