#include <SPI.h>
#include "Semafori.h"
#include "sr595.h"
const byte PIN_CS = 4;
// TLCU Traffic Light Control Unit
struct TLCU {
uint8_t *reg; // puntarore a registro condiviso
uint16_t *times; // array di 3 tempi associato a questo registro
};
// tempi specificati in millesimi di secondo
uint16_t lss0_2Times[] = { 5000, 750, 250 };
uint16_t lss1_3Times[] = { 3000, 750, 250 };
// Verde, Giallo, Rosso
// Nota sui tempi:
// il verde di durata meggiore viene solitamente assegnato
// alla strada più trafficata
uint8_t lss0_2 = Color::RED; // registro per lss0 e lss2 (Nord e Sud)
uint8_t lss1_3 = Color::RED; // registro per lss1 e lss3 (Est e Ovest)
uint32_t greenStartTime; // dove salvare millis()
#define TLCU_MAX 2 // Quantità di registri
TLCU tlcu[TLCU_MAX] = {
{ &lss0_2, lss0_2Times },
{ &lss1_3, lss1_3Times }
};
// tlcuIdx è indice di tlcu, inizializzato a 1 per puntare a lss1_3
// che inizia con il verde (vedi funzione allRed())
uint8_t tlcuIdx = 1;
// sr16 è istanza di classe SR59516 per controllare due shift register 595
SR59532 sr32(PIN_CS);
// Istanze di Lanterne Semaforiche Stradali
LSS lss0(sr32, 0, 1, 2); // Nord (ore 12)
LSS lss1(sr32, 3, 4, 5); // Est (ore 3)
LSS lss2(sr32, 6, 7, 8); // Sud (ore 6)
LSS lss3(sr32, 9, 10, 11); // Ovest (ore 9)
void setup() {
Serial.begin(115200);
pinMode(PIN_CS, OUTPUT);
digitalWrite(PIN_CS, HIGH);
SPI.begin();
// ad ogni lanterna è possibile assegnare un ID 0÷255
lss0.setId(0);
lss1.setId(1);
lss2.setId(2);
lss3.setId(3);
// assegna i 2 registri condivisi alle 4 lanterne.
lss0.setRegister(&lss0_2);
lss2.setRegister(&lss0_2);
lss1.setRegister(&lss1_3);
lss3.setRegister(&lss1_3);
}
bool f_allred = true;
// Accende tutti rossi per 2 secondi poi lss1_3 su verde
void allRed() {
static uint8_t startTime = millis();
if (f_allred && millis() - startTime > 2000) {
lss1_3 = Color::GREEN;
greenStartTime = millis();
f_allred = false;
}
}
// Esegue le temporizzazioni
void run() {
Color color = *tlcu[tlcuIdx].reg;
if (millis() - greenStartTime >= tlcu[tlcuIdx].times[color]) {
if (*tlcu[tlcuIdx].reg == Color::RED) {
tlcuIdx++;
tlcuIdx = tlcuIdx % TLCU_MAX;
}
(*tlcu[tlcuIdx].reg)++;
*tlcu[tlcuIdx].reg = *tlcu[tlcuIdx].reg % 3;
greenStartTime = millis();
}
}
void loop() {
// occorre chiamare il metodo show per ogni istanza di lanterna
lss0.show();
lss1.show();
lss2.show();
lss3.show();
// Mantiene accessi tutti rossi per 2 secondi, poi lss1_3 commuta sul verde
allRed();
if (f_allred)
return;
run();
}
lss0
id=0
lss1
id=1
lss3
id=3
lss2
id=2
3
4
5
8
7
6
9
10
11
0
1
2
LS0
LS1
LS2
LS3
LS4
LS5
LS6
LS7
LS8
LS9