Raffaele Ilardo
Arduino per rilevare la presenza di un treno sul binario
© La parziale riproduzione dei contenuti di questa pagina è consentita a patto di citare l'indirizzo del sito e l'autore.
Nella pagina Segnalatore di presenza o passaggio treno ho già descritto un circuito che svolge tale funzione, utilizzando due fotocellule che lavorano in modalità differenziale; ho testato a lungo il circuito ed ho potuto concludere che il suo funzionamento è decisamente affidabile, oltre ad essere piuttosto semplice da realizzare.
Chi non disdegna di rivolgersi a soluzioni più avanzate, come per esempio la programmazione di microcontrollori, può sperimentare il progetto che descrivo in questa pagina, sapendo che con una singola scheda Arduino sarà possibile controllare l'evetuale presenza di un treno non su uno, ma su diversi binari contemporaneamente.
Come nella maggior parte dei casi in cui si utilizza una soluzione software, la parte elettronica è ridotta al minimo; vediamo infatti in figura 2 che i componenti utilizzati sono unicamente la fotoresistenza Ftr, il resistore R1, un led e la relativa resistenza limitatrice R2.
figura 2
Le difficoltà da superare per ottenere un funzionamento affidabile vengono risolte via software, dal codice descritto in seguito, e che va naturalmente caricato nella memoria della scheda.
figura 3
Diversamente, quando il programma riscontra un aumento della luminosità, ritiene che il treno non sia più presente e disattiva il led.
Come già ho fatto notare nell'altro progetto, poiché le fotoresistenze hanno caratteristiche diverse l'una dall'altra, potrebbe essere necessario modificare il valore della resistenza R1: il valore previsto è di 39 kΩ, ma potrebbe essere necessario usare un valore inferiore (es.:27 o 33 kΩ) o superiore (47 o 56 kΩ). Lo stesso discorso vale anche per le condizioni di luce ambiente, considerando che la rilevazione della presenza del treno può avvenire in zone molto illuminate, così come in zone in penombra; nel caso di tratti in galleria è senz'altro opportuno collocare una debole sorgente di luce per favorire il corretto funzionamento del dispositivo.
Questo è il codice da caricare, tramite il solito ambiente IDE:
Qualche commento sul codice:
- vengono definite le variabili lum e prevlum, che memorizzano il valore letto con analogRead(0)
- la variabile train, di tipo booleano, memorizza l'informazione "treno presente"
- viene letta la luminosità:
se il valore è inferiore a quello rilevato in precedenza, viene acceso il led e settata a 1 la variabile train
se il valore è superiore a quello rilevato in precedenza, viene spento il led e azzerata la variabile train
il valore attuale di luminosità viene memorizzato in prevlum
- vengono definite le variabili lum e prevlum, che memorizzano il valore letto con analogRead(0)
- la variabile train, di tipo booleano, memorizza l'informazione "treno presente"
- viene letta la luminosità:
se il valore è inferiore a quello rilevato in precedenza, viene acceso il led e settata a 1 la variabile train
se il valore è superiore a quello rilevato in precedenza, viene spento il led e azzerata la variabile train
il valore attuale di luminosità viene memorizzato in prevlum
int lum=0;
int prevlum=0;
bool train=0;
void setup() {
pinMode(13, OUTPUT);
}
void loop() {
lum = analogRead(0);
if ((prevlum-lum)>10){
digitalWrite(13,HIGH);
train=1;
}
if ((lum-prevlum)>10){
digitalWrite(13,LOW);
train=0;
}
prevlum=lum;
delay(10);
}
int prevlum=0;
bool train=0;
void setup() {
pinMode(13, OUTPUT);
}
void loop() {
lum = analogRead(0);
if ((prevlum-lum)>10){
digitalWrite(13,HIGH);
train=1;
}
if ((lum-prevlum)>10){
digitalWrite(13,LOW);
train=0;
}
prevlum=lum;
delay(10);
}
Allo scopo di favorire la scelta del valore di R1 può essere utile aggiungere al codice le istruzioni che stampano sul monitor seriale il valore di lum. Poiché il valore letto con analogRead(0) può andare da 0 a 1023, è opportuno che, in assenza di treno sul binario, si legga un valore compreso fra 700 e 1000; naturalmente, in presenza del treno, tale valore tenderà a calare.
Le istruzioni da aggiungere sono:
Serial.begin(9600); da inserire dopo la linea pinMode(13, OUTPUT);
Serial.println (lum); da inserire dopo la linea delay(10);
Col sistema descritto, usando una sola scheda Arduino, è possibile controllare diversi tratti di binario, modificando opportunamente il codice. Naturalmente sarà necessario usare una fotoresistenza, abbinata al relativo led di segnalazione, per ogni binario controllato, e sarà anche necessario prevedere diverse variabili per memorizzare i valori di luminosità delle varie fotoresistenze.
Come esempio, vediamo di seguito il codice relativo a due tratti distinti di binario:
In questo caso dobbiamo raddoppiare il numero delle variabili:
useremo quindi lum1 e lum2, prevlum1 e prevlum2 e quindi train1 e train2
Per la fotoresistenza n.1, nel tratto di binario n.1, leggeremo la luminosità con lum1 = analogRead(0); a tale fotoresistenza assoceremo il led comandato dal pin 13
Per la fotoresistenza n.2, nel tratto di binario n.2, leggeremo la luminosità con lum2 = analogRead(1); a tale fotoresistenza assoceremo il led comandato dal pin 12
useremo quindi lum1 e lum2, prevlum1 e prevlum2 e quindi train1 e train2
Per la fotoresistenza n.1, nel tratto di binario n.1, leggeremo la luminosità con lum1 = analogRead(0); a tale fotoresistenza assoceremo il led comandato dal pin 13
Per la fotoresistenza n.2, nel tratto di binario n.2, leggeremo la luminosità con lum2 = analogRead(1); a tale fotoresistenza assoceremo il led comandato dal pin 12
int lum1=0;
int lum2=0;
int prevlum1=0;
int prevlum2=0;
bool train1=0;
bool train2=0;
void setup() {
pinMode(13, OUTPUT);
pinMode(12, OUTPUT);
}
void loop() {
lum1 = analogRead(0);
if ((prevlum1-lum1)>10){
digitalWrite(13,HIGH);
train1=1;
}
if ((lum1-prevlum1)>10){
digitalWrite(13,LOW);
train1=0;
}
prevlum1=lum1;
lum2 = analogRead(1);
if ((prevlum2-lum2)>10){
digitalWrite(12,HIGH);
train2=2;
}
if ((lum2-prevlum2)>10){
digitalWrite(12,LOW);
train2=0;
}
prevlum2=lum2;
delay(10);
}
int lum2=0;
int prevlum1=0;
int prevlum2=0;
bool train1=0;
bool train2=0;
void setup() {
pinMode(13, OUTPUT);
pinMode(12, OUTPUT);
}
void loop() {
lum1 = analogRead(0);
if ((prevlum1-lum1)>10){
digitalWrite(13,HIGH);
train1=1;
}
if ((lum1-prevlum1)>10){
digitalWrite(13,LOW);
train1=0;
}
prevlum1=lum1;
lum2 = analogRead(1);
if ((prevlum2-lum2)>10){
digitalWrite(12,HIGH);
train2=2;
}
if ((lum2-prevlum2)>10){
digitalWrite(12,LOW);
train2=0;
}
prevlum2=lum2;
delay(10);
}