#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Button.h>
int latchPin = 3;//Pin connected to ST_CP of each shift register
int clockPin = 4; //Pin connected to SH_CP of each shift register
int dataPin = 2; //Pin connected to DS of first shift register
// Connect Q7S of the first shift register to DS of the next register(s)
#define clk A0
#define dt A1
Button btn(A2); // Create button instance
#define led A3
LiquidCrystal_I2C lcd(0x27, 16, 2);
String opciones[] = {"DOPAMINE BOX", "POMODORO", "TIME FLOW","TEST-1","TEST-2","ZaphodUB40"};
int max_opciones = sizeof(opciones) / sizeof(opciones[0]);
int state_clk_old;
int state_btn_old;
int count = 0;
bool hz_1 = false;
bool mono = false;
unsigned long tiempo_actual = 0;
unsigned long tiempo_actual2 = 0;
byte button[] = {5, 6, 7, 8, 9, 10, 11, 12};
// Pins connected to switches - MUST be 8 even if you are not using them
// Can even use non-existing pins, just so long as there are 8 of them
byte vals[] = {128, 64, 32, 16, 8, 4, 2, 1};
// DEC values used to create the appropriate binary values for ths shift registers
// Stateful placeholders
int oldState;
int newState;
int swState; // Holds the sum of the value of the switch read function
int lockFlag = 0; // Prevents a change of menu if set to 1
int lastMenu = 0; // Last menu item index prior to the current index
void setup() {
Serial.begin(9600);
lcd.init();
lcd.backlight();
pinMode(led, OUTPUT);
pinMode(clk, INPUT);
pinMode(dt, INPUT);
btn.begin(); // Starts the button object watch for button states, also handles debounce
state_clk_old = digitalRead(clk);
//state_btn_old = digitalRead(btn); // No need for this since the button library is handling this
mostrar_menu();
for (int i = 0; i < sizeof(button); i++) {
pinMode(button[i], INPUT_PULLUP);
}
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
dopamine_box();
}
void loop() {
dopamine_box();
encoder();
if (btn.pressed()) {
checkSwitch(); // Make sure all switches are down (OFF) before unlocking
if(swState == 255){lockFlag = 0;digitalWrite(led,LOW);} // If all off, then unlock
//run_option();
}
/*
if (millis() >= tiempo_actual + 500) {
tiempo_actual = millis();
if (hz_1) digitalWrite(led, !digitalRead(led));
}
if (millis() >= tiempo_actual2 + 6000) {
if (mono) digitalWrite(led, LOW);
}
*/
}
void run_option() {
switch (count) {
case 1:
digitalWrite(led, LOW);
break;
case 2:
hz_1 = !hz_1;
break;
case 3:
digitalWrite(led, HIGH);
tiempo_actual2 = millis();
mono = !mono;
break;
}
}
void encoder() {
if(lockFlag == 1){return;} // If lockflag is 1, exit this function
int state_clk = digitalRead(clk);
int state_dt = digitalRead(dt);
if (state_clk_old == HIGH && state_clk == LOW) {
lastMenu = count; // Track which menu item index we are at
count = (state_dt == LOW)? count-1 : count+1; // Slightly different way to do if..else
count = (count == max_opciones)? 0 : count; // Keep the counter in range of the menu array
count = (count == -1)? max_opciones-1 : count;
if(lastMenu > 0 && count == 0){
checkSwitch();
if(swState != 255){
lockFlag = 1;// If we went from any menu back to 0, then lock it
digitalWrite(led,HIGH);
}
}
mostrar_menu();
}
delay(5);
state_clk_old = state_clk;
}
void mostrar_menu() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Menu:");
lcd.setCursor(0, 1);
lcd.print(opciones[count]);
}
// Check the current switch states for unlocking
void checkSwitch(){
swState = 0;
for (int i = 0; i < sizeof(button); i++) {
swState += digitalRead(button[i]) * vals[i];
}
}
void dopamine_box() {
newState = 0; // Reset the state to 0 (clean)
for (int i = 0; i < sizeof(button); i++) {
// Loop through the button states, multiply the state by the value index of the loop count
// Add them up the the total will be the value to send to the shift registers
newState += digitalRead(button[i]) * vals[i];
}
if(count != 0){newState = 255;} // If we are not on menu item 2, treat all switches as OFF
if (newState != oldState) { // If anything has changed since the last read, update the LEDs
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, newState); // All the greens value 254, normal = 1 -> OFF
shiftOut(dataPin, clockPin, LSBFIRST, ~newState); // All the reds value 254, inverted = 0 -> ON
digitalWrite(latchPin, HIGH);
oldState = newState;
//Serial.println(newState); // For debug only
}
}