Ciao,
sto cercando di integrare il mio vecchio allarme di casa basato sul micro ST6 e corredato di quadro sinottico a LED basato sul'M5450 con dei "sinottici" un po' più evoluti.
(Sì, lo so dovrei rifare tutto con un sistema un po' più moderno, ma sono vecchio anch'io ... un passo alla volta! )
In sintesi si tratta di simulare un display a LED basato su un M5450: inserire un Arduino al posto del display per poterne prima catturare e poi elaborare opportunamente lo stato dei Led pilotati che formano il "sinottico" dei sensori perimetrali e volumetrici.
La comunicazione con l'M5450 prevede 36 cicli di clock su un filo corrispondenti a 1 start Bit e 35 Bit dati su un secondo filo.
nessun controllo di flusso ne hw ne sw:
|--| |---| |---| |---| |---| |---| |----|
Clock:| 1 || 2 || 3 || 4 || 5 || 6 |...| 36 |____
|----| |--------------| |-------|
Dati | || |___.......ecc........ | |
| START | Bit1 | Bit2 | Bit3 | Bit4 ........... | Bit35 |
I due segnali /fili Data e Clock che ricevo in ingresso nell'Arduino dall'ST6 (a dire il vero è infrapposto un "pilota" 74LS244) un sono "belli" puliti: a titolo di esempio il clock nell'immagine allegata.
Speravo di riuscire a leggere con Arduino correttamente le informazioni del sinottico con un codice più o meno così :
#define LcdDATA 11
#define LcdCLOCK 13
int OKDati;
int Sinottico_Spento;
int Dati_Nuovi[36];
unsigned long PrecedenteMillis = 0;
void setup() {
// Configuro l'interrupt
attachInterrupt(digitalPinToInterrupt(LcdCLOCK), LeggiLED, RISING); // all'arrivo del primo fronte di salita del Clock lancio la sub "LeggiLED"
}
void LeggiLED(){
detachInterrupt(digitalPinToInterrupt(LcdCLOCK));
// disabilito l'interupt (non so se serva ma vorrei evitare che ogni fronte di salita chiami nuovamente l'interrupt)
PrecedenteMillis = millis();
OKDati=1;
Sinottico_Spento=0;
for (int i=1; i <= 36; i++)
{
Dati_Nuovi[i]= digitalRead(LcdDATA); memorizzo il bit
while(digitalRead(LcdCLOCK)== HIGH) {if (millis()- PrecedenteMillis >200){ OKDati=0;break;}}
// attendo la discesa del Clock
while(digitalRead(LcdCLOCK)== LOW) {if (millis()- PrecedenteMillis >200){ OKDati=0;break;}}
// attendo la salitadel Clock e ripeto il ciclo partendo dalla lettura del pin Dati
}
for (int i=1; i <= 36; i++)
{
Sinottico_Spento += Dati_Nuovi[i];
}
if ((OKDati == 1) and (Sinottico_Spento!=0) and (Sinottico_Spento!=36))
{
Serial.print("Dati Validati!");
// DATI RICEVUTI CORRETTAMENTE PROCEDO ALLA VALIDAZIONE
}
attachInterrupt(digitalPinToInterrupt(LcdCLOCK), LeggiLED, RISING); // rimetto a posto l'interrupt
}
void loop() {
}
(Soprassedendo sul sistema di uscita dai while che dovrebbe essere inutile se la sequenza dati non ha disturbi o errori)
In realtà però le info lette sono quasi "casuali"
A vostro avviso potrebbe essere un problema di temporizzazione del segnale?
Troppo veloce la comunicazione e troppo lento Arduino a leggere[ digitalRead(LcdDATA); ] ?
come vedete in allegato dovrei riuscire a completare un ciclo di lettura in meno di un millisecondo... troppo poco?
Nel caso sia un problema di velocità sapete se è possibile l'utilizzo della SPI per letture "bovine" configurando Arduino come "SLAVE" di una sequenza di 36 bit?
(forse modificando qualche libreria?)
Grazie fin d'ora di ogni spunto o consiglio!