Autovelox con sensori ad infrarosso

Ciao a tutti, qualche giorno fa ho comprato due diodi IR tsus4300: www.vishay.com/docs/81053/tsus4300.pdf e due fototransistor teft4300: www.vishay.com/docs/81549/teft4300.pdf, per realizzare un autovelox. In pratica l'intenzione è di misurare tramite Arduino il tempo che trascorre da quanto viene interrotto il fascio della prima coppia a quando viene interrotto quello della seconda. Sapendo lo spazio, applico la formula velocità=spazio/tempo e così la ottengo. Vorrei poi visualizzarla su display lcd 16x2, ma per il momento mi accontenterei di vederla sul monitor seriale, dove però viene continuamente una velocità di -1 Km/h, indipendentemente se il fascio è interrotto o meno. Potete dirmi dove sbaglio?

autovelox_2.ino (613 Bytes)

Se la distanza massima tra emettitore e ricevitore è una decina di centimetri, è possibile.

Tuttavia avresti qualche problema con l'interferenza della luce del Sole, lampade ad incandescenza ed al neon.

Ti conviene pensare a modulare il fascio con una portante a 38 kHz oppure a 56 kHz ed usare un ricevitore amplificato e filtrato (TSOP4838 oppure TSOP4856).

La mia intenzione è quella di far passare tra i due componenti una macchinina come quelle delle Hot Wheels, larga circa 3 cm, non di più, su una pista, quindi la distanza tra i due non dovrebbe superare i 10 cm.. E nel programma su Arduino c'è qualche errore (penso di si ahahah)? O è quindi dovuto ai componenti (fototransistor in particolare, come detto da te)?
Grazie Luca

Preciso che lo schema con i componenti l'ho preso da questo link: Tu non puoi passare! | Elettronico per caso…, però l'uscita dei due (ovvero tra il fototransistor e la resistenza) l'ho messa su un ingresso digitale, con stato HIGH o LOW... non sono una cima su Arduino ahahah.
Grazie ancora per la risposta

Intanto t1 e t2 dichiarali unsigned long, poi Val1 e Val2 quando il fascio viene interrotto vanno a LOW e non a HIGH

Ciao,
li ho usati anche io , se li vuoi utilizzare alla luce metti un tappino per biro della Bic non quello che copre la punta ma l'altro, per diminuire la luce che rileva il ricevitore (quello nero) come nella foto

Ok grazie Marinaio67! Adesso li correggo!
Vespucci, intendi il tappo nero (se di una biro bic nera) che è all'estremità opposta alla punta? Andrebbe bene anche del semplice nastro isolante, arrotolato per fare un tubino? Grazie mille!

Vespucci, potrei sapere i valori delle due resistenze (per diodo IR e fototransistor) che hai messo? Io ho deciso 47 ohm per il diodo, siccome (5-1,2)V/100 mA=38 ohm, quindi ne ho scelta una leggermente maggiore per avere una corrente che non sia proprio di 100 mA, che è il valore massimo. Per il fototransistor ne ho invece usata una da 1Mohm (mi sono basato sulla schema del circuito che è al sito che ho scritto prima). Non uccidetemi se ho sbagliato ahahah :smiley: grazie!

Il LED può sopportare 100mA ma solo per 20ms altrimenti dura poco: ti conviene usare una corrente di 20mA (180 ohm).

Il fototransistor necessità di una corrente sui 3mA (max 50mA), perciò il resistore deve essere da 1.6k ma anche uno da 1k va bene.

Grazie mille per i consigli! Finalmente ho dei valori precisi per le resistenze!! Allora, per il LED vicino ai 180 ohm ho solo 220 ohm, così facendo otterrei 17 mA (nessun problema quindi, visto che è anche minore), mentre per il fototransistor ho 1k, quindi ok!
Ehm, scusa la domanda stupida forse... Con questi valori di resistenza si riesce a "coprire" una distanza tra i due componenti (LED e fototransistor) di 10 cm (anche meno, circa 5 cm come detto prima)? Lo avevi scritto tu il valore dei 10 cm, ma non si sa mai :smiley: Oppure il problema è nel programma di Arduino (lo allego)... Ho modificato lo schema come mi è stato consigliato precedentemente e ho aggiunto le istruzioni per visualizzare il valore della velocità sul display lcd 16x2 (l'ho anche collegato ovviamente ahahah), però, dopo averlo caricato, sia sul monitor seriale che sul display (quindi almeno quello va bene xD) scrive "inf km/h" continuamente, e se passo davanti al fascio luminoso non dà alcuna risposta (continua a ciclare la stessa scritta). Al momento di luce (del Sole e non) ce n'è ben poca, quindi non credo possa essere quello... Grazie mille ancora per tutto l'aiuto!!!! :smiley:

Dovresti poter coprire i 10 cm, ma se no ci riesci abbassa il valore del resistore del LED in modo da portare la corrente a 40mA (100 ohm).

Per lo sketch dovresti postarlo usando il tag </> in alto a sinistra sopra la prima faccina.

int sens1=9; 
int sens2=8;
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup()
{
  pinMode(sens1,INPUT); 
  pinMode(sens2,INPUT);
  Serial.begin(9600); 
  lcd.begin (16, 2);
  lcd.setCursor(0, 0);
  lcd.print ("VELOCITA': ");
}

void loop() {
 
  double spazio=0.05; // 
  double tempo=0.0;
  double velocita=0.0;
  unsigned long t1=0.0;
  unsigned long t2=0.0;
  int Val1=digitalRead(sens1);
  int Val2=digitalRead(sens2);
  
  if(Val1==LOW)
  {
   t1=millis();
  }
  
  if(Val2==LOW){
        t2=millis(); 
        tempo=(t2-t1)/3600000;  
        velocita=spazio/tempo; 
        Serial.print(velocita);
        Serial.println(" km/h");
        lcd.setCursor(0, 1);
        lcd.print(velocita); 
        lcd.print("Km/h");
      } 
}

a parte l'inizializzazione errata delle due variabili t che è 0 e non 0.0 il problema è la formula
considerando che lo spazio è 0.05(penso km) io lo cambierei in double per forzare il cast e lo trasformarsi in metri ovvero 50.
a questo punto la formula diventa questa

double vel = ( spazio / ( t2 - t1 ) ) * 3600;

ho editato perché mi è scappato lo zero.

Grazie vbextreme per la risposta! Le altre variabili con 0.0 sono giuste invece?
Lo spazio è la distanza che c'è tra una coppia LED-fototransistor e l'altra... Nel programma vorrei scrivere che è uguale a 5 cm, per fare una prova, anche se magari nel progetto finale l'aumento fino a 10 cm circa (da non sbagliarsi, io compreso ahahah, con la distanza tra LED e fototransistor, ovvero dove in mezzo passa l'oggetto da rilevare)... Così ho scritto 0.05 , pensando fosse in metri... L'unità di misura è in Km quindi? Se è così lo dovrei cambiare in 0.00005 penso! Grazie ancora!

no non convertirla inutilmente in km lasciala in metri, ora mi spiego:
1km = 1000 metri
1h = 3600000 ms
dunque nella tua formula dovresti dividere un numero di km molto piccolo per poi doverlo moltiplicare per un numero esageratamente grande, ma se tu ti esprimi in metri è come se dividessi già * 1000 il tempo.
Dunque spazio lascialo pure a 0,05 metri e lo moltiplichi * 3600 e non 3600000 come avresti dovuto fare se usavi i km

potresti usare anche i cm :
1m = 100 cm
il codice più preciso diventa

double spazio = 5.0;
...
double vel = ( spazio / ( t2 - t1 ) ) * 36.0;

Okok mi stavo giusto correggendo, avevo capito male :slight_smile: spazio lo lascio così (0.05), benissimo! E uso la tua formula (con 3600), ok! Oppure li cambio, rispettivamente 5.0 e 36.0 .
Io vorrei che, una volta superati i due "blocchi", ricevessi in uscita il valore della velocità... Però appena apro il monitor seriale mi dà continuamente "inf km/h" e se passo davanti al fascio non cambia nulla! Non capisco davvero cosa non vada! Grazie mille per l'aiuto (lo sto ripetendo tutte le volte, spero di non essere noioso ahah)!!

int sens1=9; 
int sens2=8;
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup()
{
  pinMode(sens1,INPUT); 
  pinMode(sens2,INPUT);
  Serial.begin(9600); 
  lcd.begin (16, 2);
  lcd.setCursor(0, 0);
  lcd.print ("VELOCITA': ");
}

void loop() {
 
  double spazio=5.0; // 
  double tempo=0.0;
  double velocita=0.0;
  unsigned long t1=0;
  unsigned long t2=0;
  int Val1=digitalRead(sens1);
  int Val2=digitalRead(sens2);
  
  if(Val1==LOW)
  {
   t1=millis();
    while( digitalRead(sens2) );
       while ( !digitalRead(sens2) );
        t2=millis(); 
        velocita=(spazio / ( t2 - t1 ) ) * 36.0; 
        Serial.print(velocita);
        Serial.println(" km/h");
        lcd.setCursor(0, 1);
        lcd.print(velocita); 
        lcd.print("Km/h");
      } 
}

però sembra che i suddetti sensori diano high quando leggono, ma bisognerebbe vedere il circuito che stai usando, comunque puoi provare con:

int sens1=9; 
int sens2=8;
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup()
{
  pinMode(sens1,INPUT); 
  pinMode(sens2,INPUT);
  Serial.begin(9600); 
  lcd.begin (16, 2);
  lcd.setCursor(0, 0);
  lcd.print ("VELOCITA': ");
}

void loop() {
 
  double spazio=5.0; // 
  double tempo=0.0;
  double velocita=0.0;
  unsigned long t1=0;
  unsigned long t2=0;
  int Val1=digitalRead(sens1);
  int Val2=digitalRead(sens2);
  
  if(Val1==HIGH)
  {
   t1=millis();
    while( !digitalRead(sens2) );
        while ( digitalRead(sens2) );
        t2=millis(); 
        velocita=(spazio / ( t2 - t1 ) ) * 36.0; 
        Serial.print(velocita);
        Serial.println(" km/h");
        lcd.setCursor(0, 1);
        lcd.print(velocita); 
        lcd.print("Km/h");
      } 
}

Scusa se ho indentato male il codice ma sono al phone

while( !digitalRead(sens2) );
while ( digitalRead(sens2) );

E' un errore o è giusto così?

Sto usando lo stesso schema di questa immagine:


E' diverso il mio per il fatto che uso gli ingressi digitali invece di quelli analogici, come è invece nell'immagine.

Con il programma modificato da te ho l'effetto inverso... Non mi da nulla in uscita ahahah nemmeno se ci passo davanti... Spero di non aver rotto i componenti a questo punto...

Togli di mezzo quella resistenza di pull down, che in questo schema veniva sicuramente utilizzata per ricreare un partitore di tensione ma a te non serve.Al massimo potresti metterne una da 100k in caso di falsi positivi.
e usa il primo codice che ti ho postato ( non ti da niente perché non legge niente).

L'emettitore del fototransistor (il piedino più corto) lo porto quindi direttamente a massa? L'uscita, che è in ingresso ai pin digitali di Arduino, non va a zero così facendo?
Se non legge niente significa che c'è qualche problema nei componenti, no?
Grazie, Luca