3. Codice Arduino
Questo è il codice (sketch) da caricare sulla scheda Arduino utilizzando l'IDE Arduino.
Libreria necessaria: Assicurati di aver installato la libreria "Adafruit NeoPixel" dal Gestore Librerie dell'IDE.
/**
* Ruota della Fortuna LED per Bambini
*
* Descrizione:
* Questo codice controlla un anello di LED NeoPixel per simulare una ruota della fortuna.
* Premendo un pulsante, i LED si accendono in sequenza simulando una rotazione
* che rallenta fino a fermarsi su un LED casuale. Un buzzer emette suoni
* durante la rotazione e alla fine.
*
* Hardware Necessario: Vedi sezione Materiali
* Collegamenti: Vedi sezione Assemblaggio
*
* Librerie Necessarie: Adafruit NeoPixel
*
* Creato da: Assistente AI
* Data: 29 Aprile 2025
*/
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
// --- CONFIGURAZIONE ---
const int PIN_NEOPIXEL = 6; // Pin digitale dati NeoPixel
const int NUM_LEDS = 16; // Numero di LED sull'anello (cambia se necessario, es. 12)
const int PIN_PULSANTE = 2; // Pin digitale pulsante
const int PIN_BUZZER = 9; // Pin digitale (PWM) buzzer (opzionale)
const int LUMINOSITA = 50; // Luminosità LED (0-255)
const unsigned long DURATA_MIN_ROT = 3000; // Durata min rotazione (ms)
const unsigned long DURATA_MAX_ROT = 6000; // Durata max rotazione (ms)
const int FREQ_TICK = 1500; // Frequenza suono "tick" (Hz)
const int FREQ_VINCITORE = 2000; // Frequenza suono vincitore (Hz)
const int DURATA_TICK = 50; // Durata suono "tick" (ms)
const int DURATA_VINCITORE = 500; // Durata suono vincitore (ms)
// --- FINE CONFIGURAZIONE ---
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN_NEOPIXEL, NEO_GRB + NEO_KHZ800);
// Variabili globali
bool statoPulsantePrecedente = LOW;
bool ruotaAttiva = false;
unsigned long tempoInizioRotazione = 0;
unsigned long durataRotazioneCasuale = 0;
int ledCorrente = 0;
int ledVincitore = -1;
unsigned long tempoUltimoStep = 0;
int ritardoStep = 50;
void setup() {
Serial.begin(9600); // Per debug
pinMode(PIN_PULSANTE, INPUT);
pinMode(PIN_BUZZER, OUTPUT);
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
clock_prescale_set(clock_div_1);
#endif
strip.begin();
strip.show();
strip.setBrightness(LUMINOSITA);
randomSeed(analogRead(0));
Serial.println("Ruota della Fortuna LED Pronta!");
effettoAvvio();
}
void loop() {
bool statoPulsanteAttuale = digitalRead(PIN_PULSANTE);
if (statoPulsanteAttuale == HIGH && statoPulsantePrecedente == LOW && !ruotaAttiva) {
Serial.println("Pulsante premuto! Avvio rotazione...");
avviaRotazione();
}
statoPulsantePrecedente = statoPulsanteAttuale;
if (ruotaAttiva) {
aggiornaRotazione();
}
}
void avviaRotazione() {
ruotaAttiva = true;
ledVincitore = -1;
spegniTuttiLed();
durataRotazioneCasuale = random(DURATA_MIN_ROT, DURATA_MAX_ROT + 1);
tempoInizioRotazione = millis();
ledCorrente = 0;
ritardoStep = 50;
tempoUltimoStep = millis();
Serial.print("Durata rotazione: ");
Serial.print(durataRotazioneCasuale);
Serial.println(" ms");
}
void aggiornaRotazione() {
unsigned long tempoTrascorso = millis() - tempoInizioRotazione;
if (tempoTrascorso >= durataRotazioneCasuale) {
fermaRotazione();
return;
}
float percentualeCompletamento = (float)tempoTrascorso / durataRotazioneCasuale;
ritardoStep = 50 + (int)(700 * pow(percentualeCompletamento, 4));
if (millis() - tempoUltimoStep >= ritardoStep) {
strip.setPixelColor(ledCorrente, strip.Color(0, 0, 0)); // Spegne precedente
ledCorrente = (ledCorrente + 1) % NUM_LEDS; // Prossimo LED
strip.setPixelColor(ledCorrente, strip.Color(255, 255, 255)); // Accende nuovo (bianco)
strip.show();
suonoTick(); // Suono tick
tempoUltimoStep = millis();
}
}
void fermaRotazione() {
ruotaAttiva = false;
ledVincitore = ledCorrente;
Serial.print("Rotazione terminata! LED vincitore: ");
Serial.println(ledVincitore);
// Lampeggio vincitore
for (int i = 0; i < 5; i++) {
strip.setPixelColor(ledVincitore, strip.Color(0, 255, 0)); // Verde
strip.show();
suonoVincitore();
delay(300);
strip.setPixelColor(ledVincitore, strip.Color(0, 0, 0)); // Spento
strip.show();
delay(200);
}
// Lascia acceso il LED vincitore
strip.setPixelColor(ledVincitore, strip.Color(0, 255, 0)); // Verde fisso
strip.show();
}
// --- FUNZIONI AUSILIARIE ---
void spegniTuttiLed() {
for (int i = 0; i < NUM_LEDS; i++) {
strip.setPixelColor(i, strip.Color(0, 0, 0));
}
strip.show();
}
void effettoAvvio() {
for (int j = 0; j < 256 * 1; j++) {
for (int i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
strip.show();
delay(10);
}
spegniTuttiLed();
}
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if (WheelPos < 85) {
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if (WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
void suonoTick() {
tone(PIN_BUZZER, FREQ_TICK, DURATA_TICK);
}
void suonoVincitore() {
tone(PIN_BUZZER, FREQ_VINCITORE, DURATA_VINCITORE);
}