#include <Adafruit_NeoPixel.h>
#define MAIN_STRIP_PIN 6
#define EXTRA_LED_PIN 5
#define LED_COUNT 10 // Solo la striscia principale
#define MUX_COM1 8
#define MUX_COM2 7
#define MUX_S0 12
#define MUX_S1 11
#define MUX_S2 10
#define MUX_S3 9
Adafruit_NeoPixel leds(LED_COUNT, MAIN_STRIP_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel extraLed(1, EXTRA_LED_PIN, NEO_GRB + NEO_KHZ800); // LED singolo separato
enum State { IDLE, FASE1, WIN1, FASE2, WIN2, END };
State currentState = IDLE;
unsigned long stateStartTime = 0;
// Fase 1
bool secretCode[LED_COUNT];
// Fase 2
uint32_t buttonColors[8]; // Colori assegnati ai 8 pulsanti
uint8_t currentStep = 0; // Passo corrente nella sequenza
unsigned long lastButtonPress = 0; // Per timeout bianco lampeggiante
bool buttonsPressed[8] = {0};
unsigned long buttonPressTime[8] = {0};
#define SIMULTANEOUS_THRESHOLD 300 // ms per pressione simultanea
void selectMux(uint8_t ch) {
digitalWrite(MUX_S0, ch & 0x01);
digitalWrite(MUX_S1, (ch >> 1) & 0x01);
digitalWrite(MUX_S2, (ch >> 2) & 0x01);
digitalWrite(MUX_S3, (ch >> 3) & 0x01);
}
void setup() {
Serial.begin(9600);
while (!Serial) { ; }
pinMode(MUX_S0, OUTPUT);
pinMode(MUX_S1, OUTPUT);
pinMode(MUX_S2, OUTPUT);
pinMode(MUX_S3, OUTPUT);
pinMode(MUX_COM1, INPUT);
pinMode(MUX_COM2, INPUT);
leds.begin();
extraLed.begin();
leds.setBrightness(80);
extraLed.setBrightness(80);
leds.clear();
extraLed.clear();
leds.show();
extraLed.show();
currentState = FASE1;
initFase1();
}
void loop() {
switch (currentState) {
case IDLE:
leds.clear();
extraLed.clear();
leds.show();
extraLed.show();
break;
case FASE1:
handleFase1();
break;
case WIN1:
handleWinState();
break;
case FASE2:
handleFase2();
break;
case WIN2:
handleWinState();
break;
case END:
leds.clear();
extraLed.clear();
leds.show();
extraLed.show();
Serial.println("*** GIOCO COMPLETATO! ***");
while (true) delay(1000);
}
}
// ====================== FASE 1 ======================
void initFase1() {
randomSeed(analogRead(A0) + millis());
for (uint8_t i = 0; i < LED_COUNT; i++) {
secretCode[i] = random(2);
}
Serial.println("=== FASE 1 ===");
Serial.print("Sequenza numerica: ");
for (uint8_t i = 0; i < LED_COUNT; i++) {
Serial.print(secretCode[i]); Serial.print(" ");
}
Serial.println();
Serial.print("Sequenza colori: ");
for (uint8_t i = 0; i < LED_COUNT; i++) {
uint32_t c = getColorFromCode(i, secretCode[i]);
if (c == leds.Color(255,0,0)) Serial.print("ROSSO");
else if (c == leds.Color(0,0,255)) Serial.print("BLU");
else if (c == leds.Color(255,255,0)) Serial.print("GIALLO");
else Serial.print("VERDE");
Serial.print(" ");
}
Serial.println("\nIndovina con gli switch!");
}
uint32_t getColorFromCode(uint8_t pos, bool right) {
if (pos < 5) return right ? leds.Color(0,0,255) : leds.Color(255,0,0); // Blu / Rosso
else return right ? leds.Color(0,255,0) : leds.Color(255,255,0); // Verde / Giallo
}
void handleFase1() {
bool isMatch = true;
for (uint8_t ch = 0; ch < LED_COUNT; ch++) {
selectMux(ch);
delayMicroseconds(500);
bool left = digitalRead(MUX_COM1);
bool right = digitalRead(MUX_COM2);
uint32_t color;
bool correctPos = (left && !right && !secretCode[ch]) || (!left && right && secretCode[ch]);
if ((left && !right) || (!left && right)) {
color = getColorFromCode(ch, right);
if (!correctPos) isMatch = false;
} else {
color = leds.Color(100, 0, 100);
isMatch = false;
}
leds.setPixelColor(ch, color);
}
leds.show();
extraLed.clear(); // Spento durante Fase 1
extraLed.show();
if (isMatch) {
Serial.println("*** FASE 1 COMPLETATA! ***");
currentState = WIN1;
stateStartTime = millis();
}
delay(100);
}
// ====================== FASE 2 ======================
void initFase2() {
Serial.println("=== FASE 2 ===");
Serial.println("Premi due pulsanti dello stesso colore contemporaneamente");
Serial.println("per riprodurre la sequenza della Fase 1.");
Serial.println();
// Assegna esattamente 2 di ogni colore
uint32_t colors[8] = {
leds.Color(255,0,0), leds.Color(255,0,0),
leds.Color(0,0,255), leds.Color(0,0,255),
leds.Color(255,255,0), leds.Color(255,255,0),
leds.Color(0,255,0), leds.Color(0,255,0)
};
// Mescola casualmente
randomSeed(analogRead(A1) + millis());
for (uint8_t i = 7; i > 0; i--) {
uint8_t j = random(i + 1);
uint32_t temp = colors[i];
colors[i] = colors[j];
colors[j] = temp;
}
memcpy(buttonColors, colors, sizeof(colors));
// Debug seriale
Serial.print("Pulsanti (0-3 mux1 I10-13, 4-7 mux2 I10-13): ");
for (uint8_t i = 0; i < 8; i++) {
uint32_t c = buttonColors[i];
if (c == leds.Color(255,0,0)) Serial.print("ROSSO ");
else if (c == leds.Color(0,0,255)) Serial.print("BLU ");
else if (c == leds.Color(255,255,0)) Serial.print("GIALLO ");
else Serial.print("VERDE ");
}
Serial.println();
currentStep = 0;
lastButtonPress = millis();
memset(buttonsPressed, 0, sizeof(buttonsPressed));
leds.clear();
leds.show();
}
void handleFase2() {
uint8_t pressedCount = 0;
uint8_t pressedButtons[8];
uint32_t candidateColor = 0;
bool foundValidPair = false;
memset(buttonsPressed, 0, sizeof(buttonsPressed)); // Resetta stato precedente
// Ciclo sui 4 canali pulsanti (I10 a I13)
for (uint8_t localCh = 0; localCh < 4; localCh++) {
uint8_t ch = 10 + localCh;
// === Leggi mux1 (btn 0-3) ===
selectMux(ch);
delayMicroseconds(1000); // Tempo di assestamento GENEROSO
bool pressedMux1 = !digitalRead(MUX_COM1);
if (pressedMux1) {
uint8_t btn = localCh; // btn 0-3
lastButtonPress = millis();
if (!buttonsPressed[btn]) buttonPressTime[btn] = millis();
buttonsPressed[btn] = true;
pressedButtons[pressedCount++] = btn;
}
// === Leggi mux2 (btn 4-7) ===
selectMux(ch); // Riconferma canale (ridondante ma sicuro)
delayMicroseconds(1000);
bool pressedMux2 = !digitalRead(MUX_COM2);
if (pressedMux2) {
uint8_t btn = 4 + localCh; // btn 4-7
lastButtonPress = millis();
if (!buttonsPressed[btn]) buttonPressTime[btn] = millis();
buttonsPressed[btn] = true;
pressedButtons[pressedCount++] = btn;
}
}
// === Resto della logica identica ===
if (millis() - lastButtonPress > 10000) {
bool on = (millis() / 1000) % 2;
extraLed.setPixelColor(0, on ? extraLed.Color(255,255,255) : 0);
}
else if (pressedCount == 1) {
extraLed.setPixelColor(0, buttonColors[pressedButtons[0]]);
}
else if (pressedCount >= 2) {
for (uint8_t i = 0; i < pressedCount && !foundValidPair; i++) {
for (uint8_t j = i+1; j < pressedCount; j++) {
uint8_t b1 = pressedButtons[i];
uint8_t b2 = pressedButtons[j];
if (buttonColors[b1] == buttonColors[b2]) {
unsigned long dt = abs((long)(buttonPressTime[b1] - buttonPressTime[b2]));
if (dt <= SIMULTANEOUS_THRESHOLD) {
candidateColor = buttonColors[b1];
foundValidPair = true;
break;
}
}
}
}
if (foundValidPair) {
uint32_t expected = getColorFromCode(currentStep, secretCode[currentStep]);
if (candidateColor == expected) {
leds.setPixelColor(currentStep, candidateColor);
leds.show();
currentStep++;
extraLed.setPixelColor(0, candidateColor); // Vittoria: colore corretto
} else {
extraLed.setPixelColor(0, extraLed.Color(180, 0, 255)); // Sconfitta: viola intenso
}
} else {
extraLed.setPixelColor(0, 0);
}
}
else {
extraLed.setPixelColor(0, 0);
}
extraLed.show();
// Aggiorna striscia principale
for (uint8_t i = 0; i < LED_COUNT; i++) {
leds.setPixelColor(i, i < currentStep ? getColorFromCode(i, secretCode[i]) : 0);
}
leds.show();
if (currentStep >= LED_COUNT) {
Serial.println("*** FASE 2 COMPLETATA! ***");
currentState = WIN2;
stateStartTime = millis();
}
}
// ====================== WIN ======================
void handleWinState() {
unsigned long elapsed = millis() - stateStartTime;
if (elapsed < 5000) {
static int j = 0;
for (uint8_t i = 0; i < LED_COUNT; i++) {
leds.setPixelColor(i, Wheel((i * 256 / LED_COUNT + j) & 255));
}
extraLed.setPixelColor(0, Wheel(j & 255));
leds.show();
extraLed.show();
j = (j + 2) % 256;
delay(20);
} else {
leds.clear();
extraLed.clear();
leds.show();
extraLed.show();
if (currentState == WIN1) {
currentState = FASE2;
initFase2();
} else if (currentState == WIN2) {
currentState = END;
}
}
}
uint32_t Wheel(byte pos) {
pos = 255 - pos;
if (pos < 85) return leds.Color(255 - pos * 3, 0, pos * 3);
if (pos < 170) { pos -= 85; return leds.Color(0, pos * 3, 255 - pos * 3); }
pos -= 170; return leds.Color(pos * 3, 255 - pos * 3, 0);
}Loading
cd74hc4067
cd74hc4067
Loading
cd74hc4067
cd74hc4067