#include <SPI.h>
// Definizione Pin
const int latchPin = 5;
const int numChips = 5; //Numero di chip
const int numLEDs = 12; //Numero di led
// Liste della spesa: memorizzano l'intensità (0-10) per ogni colore di ogni LED
int intensitaR[numLEDs];
int intensitaG[numLEDs];
int intensitaB[numLEDs];
void setup() {
pinMode(latchPin, OUTPUT);
SPI.begin();
// Alta velocità per evitare sfarfallio (flicker)
SPI.beginTransaction(SPISettings(20000000, MSBFIRST, SPI_MODE0));
}
void loop() {
// MOTORE PWM: Questo ciclo crea le sfumature
// Più è veloce questo loop, più i colori sono stabili
for (int step = 0; step < 10; step++) {
for ( int j = 9 ; j >= 1 ; j-- ){
for ( int k = 0 ; k < 10 ; k++ ){
impostaColore(1,10,0,j);
impostaColore(2,10,0,j);
impostaColore(3,10,0,j);
impostaColore(4,10,0,j);
impostaColore(5,10,0,j);
impostaColore(6,10,0,j);
impostaColore(7,10,0,j);
delay(50);
}
}
// 1. Creiamo una mappa temporanea di 5 byte (40 bit) tutti spenti
byte chip[numChips] = {0, 0, 0, 0, 0};
// 2. Controlliamo ogni LED e costruiamo la mappa di bit
for (int i = 0; i < numLEDs; i++) {
int bitBase = i * 3; // Ogni LED occupa 3 canali consecutivi (R, G, B)
// Se l'intensità è maggiore dello step attuale, "aggiungiamo" il bit con l'OR
if (intensitaR[i] > step) accendiBitInMappa(chip, bitBase + 0);
if (intensitaG[i] > step) accendiBitInMappa(chip, bitBase + 1);
if (intensitaB[i] > step) accendiBitInMappa(chip, bitBase + 2);
}
// 3. Spediamo la mappa ai 5 chip
digitalWrite(latchPin, LOW);
for (int c = numChips - 1; c >= 0; c--) {
SPI.transfer(chip[c]);
}
digitalWrite(latchPin, HIGH);
}
}
// FUNZIONE MAGICA 1: Traduce "LED X" in coordinate di intensità
void impostaColore(int n, int r, int g, int b) {
if (n < 1 || n > numLEDs) return; // Protezione contro numeri LED sbagliati
int i = n - 1;
intensitaR[i] = r;
intensitaG[i] = g;
intensitaB[i] = b;
}
// FUNZIONE MAGICA 2: Trova il chip giusto e accende il bit con l'OR (|)
void accendiBitInMappa(byte mappa[], int bitAssoluto) {
int nChip = bitAssoluto / 8; // Divisione intera per trovare il chip
int nBit = bitAssoluto % 8; // Resto per trovare il bit nel chip
// Usiamo l'OR per non sovrascrivere gli altri LED nello stesso chip
mappa[nChip] |= (1 << nBit);
}