#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
SR59516 sr16(PIN_CS);
// Istanze di Lanterne Semaforiche Stradali
LSS lss0(sr16, 5, 6, 7); // Nord (ore 12)
LSS lss1(sr16, 10, 11, 12); // Est (ore 3)
LSS lss2(sr16, 2, 3, 4); // Sud (ore 6)
LSS lss3(sr16, 13, 14, 15); // 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();
}
uno:A5.2
uno:A4.2
uno:AREF
uno:GND.1
uno:13
uno:12
uno:11
uno:10
uno:9
uno:8
uno:7
uno:6
uno:5
uno:4
uno:3
uno:2
uno:1
uno:0
uno:IOREF
uno:RESET
uno:3.3V
uno:5V
uno:GND.2
uno:GND.3
uno:VIN
uno:A0
uno:A1
uno:A2
uno:A3
uno:A4
uno:A5
sr1:Q1
sr1:Q2
sr1:Q3
sr1:Q4
sr1:Q5
sr1:Q6
sr1:Q7
sr1:GND
sr1:Q7S
sr1:MR
sr1:SHCP
sr1:STCP
sr1:OE
sr1:DS
sr1:Q0
sr1:VCC
led3:A
led3:C
led4:A
led4:C
led5:A
led5:C
led6:A
led6:C
led7:A
led7:C
led8:A
led8:C
sr2:Q1
sr2:Q2
sr2:Q3
sr2:Q4
sr2:Q5
sr2:Q6
sr2:Q7
sr2:GND
sr2:Q7S
sr2:MR
sr2:SHCP
sr2:STCP
sr2:OE
sr2:DS
sr2:Q0
sr2:VCC
led11:A
led11:C
led12:A
led12:C
led13:A
led13:C
led14:A
led14:C
led15:A
led15:C
led16:A
led16:C
lss0
id=0
lss1
id=1
lss3
id=3
lss2
id=2
10
11
12
2
3
4
13
14
15
5
6
7
pedonale