Pages: [1] 2   Go Down
Author Topic: Primo progetto: contatore IR per una porta  (Read 1083 times)
0 Members and 1 Guest are viewing this topic.
Firenze, Italy
Offline Offline
Full Member
***
Karma: 0
Posts: 104
Dislessia portami via
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao a tutti, come primo progetto ho realizzato un sistema composto da due coppie ricevitore-trasmettitore IR (raggio A e raggio B). I due sensori IR sono montati su una porta (assumo che solo una persona alla volta posso attraversare la porta) ed hanno lo scopo di contare le persone all'interno della stanza. Il codice che ho utilizzato è il seguente:

Code:
/*                                                                                                            *\
Il seguente codice usa due coppie ricevitore-trasmettitore IR a 38Khz
Ha lo scopo di contare le persone che passano da una porta
Gestisce i seguenti casi:
1) Una persona entra nella stanza
2) Una persona esce dalla stanza
3) Una persona sta entrando nella stanza, cambia idea e torna fuori
4) Una persona sta uscendo dalla stanza, cambia idea e torna dentro
5) Una persona inizia ad entrare/uscire si ferma in mezzo ai sensori per un po' e poi completa l'operazione
\*                                                                                                             */


//pin definitions
#define RXA 12 //TSOP A
#define RXB 10 //TSOP B
#define TX 11 //line for both the IR LED  transmitter
#define SX 2 //this LED is ON if there are people in the room
#define SPY 8 //this LED is ON if both the IR beam are not interrupted

//parameter
const int timeOut = 3000;

//variables
int count =0; //people in the room
int timerA = 0; //timer for beam A
int timerB = 0; //timer for beam B

//flag
boolean hitA = true; //this is TRUE if RX A is receiving, this is FALSE if the beam A has been broken
boolean hitB = true; //same as above for beam B

boolean enter= false; //flag for somebody entering the room
boolean leave = false; //flag for somedody leaveing the room

boolean transmitting_IR; //transmission flag
boolean receiving_IR; //receiving flag



//turn_off , turn_on, detect functions come as is from
// http://www.eng.utah.edu/~cs1410/Labs/lab09.html
void turn_off_IR ()
{
  // Instead of just adjusting the output on pin 11, this code also
  //   turns off the timer controlling the PWM output on pin 11
 
  TCCR2A = 0; // Disconnect PWM
  TCCR2B = 0; // Stops the timer
  OCR2A = 0;  // No timer top
  digitalWrite(11, LOW);  // Ensure output is off
 
  transmitting_IR = false;
}

void turn_on_IR ()
{
// Set up Timer2 (which can be connected to pins 3 and 11)
  // For full details, see:
  //   arduino.cc/en/Tutorial/SecretsOfArduinoPWM
  // The syntax here has me baffled, but the patterns of usage
  //   are clear if you look at the ATMega328 diagrams.
  //   _BV appears to stand for 'bit value'
  //   Different bits need to be set to control each timer
  //   Refer to diagrams for clarity

  TCCR2A = _BV(WGM21) | _BV(COM2A0); // This mode toggles output once per timer cycle
  TCCR2B = _BV(CS20);  // Do not scale the clock down - use 16 MHz timer rate.
  OCR2A = 210; // Divide sys. clock by 210, 1/2 cycle = 76 khz, 1 cycle = 38 khz
 
  // Output pin 11 should now be emitting a 38 khz signal.
 
  transmitting_IR = true;
}


void detectIR()
{
  // Determine if we are receiving an IR signal.
  //   if pin RXA is false = receiving
  //   if pin RXA is true = not receiving
 
  if(digitalRead(RXA)){
    //Serial.println("missA");
    hitA = false;
  }else{
    hitA = true;
  }
 
  delay(1);
 
  if(digitalRead(RXB)){
    //Serial.println("missB");
    hitB = false;
  }else{
    hitB = true;
  }
}


void pulseIR(){
  //manage the IR transmitter
  if (transmitting_IR)
    turn_off_IR();
 
  if (!transmitting_IR)
    turn_on_IR();     
}


void checkA(){
  //RX routine
  if(leave == false){ // if nobody is going out
    if(hitA == false && hitB == true){ // and only the INDOOR RX bean has been broken
          if(enter == true){ //if somebody was entering then       
            count ++; // somebody has gone IN
            enter=false;
            updateSx();
            showCount();
          }else{ // if nobody was entering nor leaving then
            leave = true; // somebody is going OUT
            Serial.println("Leaving...");
            timerA=millis() + timeOut;
          }
      }
  }
}


void checkB(){
  if(enter == false){ //if nobody is entering
    if(hitB == false && hitA == true){ // and only the OUTDOOR RX bean has been broken
          if(leave == true){ //if somebody was leaving
            count --; // somebody has gone OUT
            leave=false;
            updateSx();
            showCount();
          }else{ //if nobody was leaving nor entering then
            enter = true; //somebody is going OUT
            Serial.println("Entering...");
            timerB = millis() + timeOut;
          }
      }
  }
}



void showCount(){
  /*                               *\
  This function will show the count
  \*                               */
  Serial.println(count);
  Serial.println("---------------------------------------------");
  delay(1000);
}

void timeManager(){
 
  int now = millis(); // update current time

  if( (enter == true && now > timerB)  ){ // if enter time out is triggered
      Serial.println("Time Out!");
      if(hitA == false && hitB == false){ // if somobody has stopped between the sensors
        timerB = now + timeOut; // hold the entering state and restart the entering timeOut
        Serial.println("Both blocked!"); 
      }else{
        enter = false;  // the entering beeing has changed is mind and he has come back without entering
      }
  //same for leaving
  }else if( (leave == true && now > timerA)){
     Serial.println("Time Out!");
     if(hitA == false && hitB == false){
        timerA = now + timeOut;
        Serial.println("Both blocked!"); 
     }else{
        leave = false;
     } 
  }

}

void updateSx(){
 if(count > 0){
    digitalWrite(SX,HIGH);
   }else{
    digitalWrite(SX,LOW);
   }
}

void updateSpy(){
  if(hitA && hitB){
    digitalWrite(SPY,HIGH);
   }else{
    digitalWrite(SPY,LOW);
   }
}


void setup(){ 
  pinMode(RXA, INPUT);
  pinMode(TX, OUTPUT);
  pinMode(RXB, INPUT);
  pinMode(SX, OUTPUT);
  pinMode(SPY, OUTPUT);
  digitalWrite(SX, LOW);
  digitalWrite(SPY, LOW);
 
  Serial.begin(9600);
  Serial.println("Ready!");
  pulseIR();
  delay(100);
}

void loop(){
  pulseIR(); // transmit cycle
  detectIR(); // search for IR
  checkA(); // check A IR sensor
  checkB(); // check B IR sensor
  updateSpy(); //upate the spy led
  timeManager(); // check for time out
}

Ho testato il codice su breadboard e pare funzionare bene! Poiché sono nuovo al mondo di Arduino e le mie conoscenze elettroniche sono piuttosto di base, per non parlare della scarsissima esperienza, mi piacerebbe avere i vostri pareri e suggerimenti su come migliorare il progetto o qualunque cosa riteniate utile segnalarmi.

Allego anche uno Fritzing del circuito su cui lavora il codice



* IRcounter.jpg (70.48 KB, 1160x876 - viewed 31 times.)
Logged

The brightest flame burns quickest

BZ (I)
Offline Offline
Brattain Member
*****
Karma: 251
Posts: 21252
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quanto so io la resistenza va sul alimentazione del TSOP e non sull' uscita.
Per aumentare la potenza del IR emanato dai LED IR metterei un transistore NPN.
Ciao Uwe
Logged

Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 110
Posts: 6975
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Progetto interessante.  smiley-lol
Potresti aggiungere una terza coppia, più in alto delle altre due, per discriminare gli adulti dai bambini.
Ricordo che una cosa del genere era stata fatta in un progetto sperimentale sui varchi di accesso alle ZTL per discriminare la auto da camion e furgoni.
Puoi anche prevedere più porte di accesso/uscita alla stanza.

Ciao.
Paolo.

Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Firenze, Italy
Offline Offline
Full Member
***
Karma: 0
Posts: 104
Dislessia portami via
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Grazie mille,
per lo schema di collegamento del TSOP ho fatto riferimento a:
http://www.parallax.com/dl/docs/books/edu/Roboticsv2_2.pdf pag. 252
Anche io pensavo che la resistenza dovesse essere collegata all'alimentazione, però mi sono fidato e funziona. Proverò a cambiare comunque la posizione della resistenza.

Per quanto riguarda il transitore NPN come può aumentare la portata dei led (che è di circa 30 cm) ? Dici di usarlo come amplificatore di corrente?
Logged

The brightest flame burns quickest

Genova
Offline Offline
Faraday Member
**
Karma: 38
Posts: 3255
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ma il fatto che la gente comune ha 2 gambe, ciascuno di noi ha la propria lunghezza del passo, i sensori non vengono ingannati? passo lungo 2 persone - passo corto una persona, il pantalone in fondo oscilla durante la camminata o una gonna smiley
Se con me porto qualcosa dentro la stanza o esco con una scatola o un abito in mano magari lungo, non inganno i sensori?
non è semplice stabilire costantemente quante persone ci sono in una stanza o se è vuota, mi sa che devi resettare spesso il sistema.

ciao  
Logged

no comment

Padova
Offline Offline
Full Member
***
Karma: 0
Posts: 135
Mala tempora currunt
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Non penso che questa cosa dell'altezza funzioni... Mentre per i veicoli i parametri sono standard per le persone vedo qualche difficoltà... Ci sono bambini di 10 anni che sono più alti di me.....  smiley-razz è vero anche il contrario.. Sono io ad essere basso  smiley-eek-blue smiley-lol
Logged

Firenze, Italy
Offline Offline
Full Member
***
Karma: 0
Posts: 104
Dislessia portami via
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ma il fatto che la gente comune ha 2 gambe, ciascuno di noi ha la propria lunghezza del passo, i sensori non vengono ingannati? passo lungo 2 persone - passo corto una persona, il pantalone in fondo oscilla durante la camminata o una gonna smiley
Se con me porto qualcosa dentro la stanza o esco con una scatola o un abito in mano magari lungo, non inganno i sensori?
non è semplice stabilire costantemente quante persone ci sono in una stanza o se è vuota, mi sa che devi resettare spesso il sistema.

Tutti questi casi non sono gestiti certo, i sensori sono facili da ingannare anche se pensavo di piazzarli ad altezza delle spalle di una persona per non soffrire il problema delle 2 gambe smiley-wink

Per il fatto degli oggetti andrebbe testato, ma credo che sia abbastanza robusto da questo punto di vista, dato che il sistema può essere solo in tre stati, qualcosa sta entrando (e non qualcosa sta entrando due volte) e qualcosa sta uscendo, ci sono dei timeOut per il tempo di attraversamento... Però non ci scommetterei la casa! Ripeto lo dovrei testare in situazioni simili.
« Last Edit: April 10, 2012, 06:08:28 am by IngHooch » Logged

The brightest flame burns quickest

BZ (I)
Offline Offline
Brattain Member
*****
Karma: 251
Posts: 21252
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Grazie mille,
per lo schema di collegamento del TSOP ho fatto riferimento a:
http://www.parallax.com/dl/docs/books/edu/Roboticsv2_2.pdf pag. 252
Anche io pensavo che la resistenza dovesse essere collegata all'alimentazione, però mi sono fidato e funziona. Proverò a cambiare comunque la posizione della resistenza.

Per quanto riguarda il transitore NPN come può aumentare la portata dei led (che è di circa 30 cm) ? Dici di usarlo come amplificatore di corrente?

Secondo me fa fede lo datasheet. Visto che non so che modello é il Tuo TSOP non so dirlo con certezza. Ho usato un TSOP31238 e lí il datasheet prevede una resistenza tra 33 Ohm e 1kOhm (application circuit sulla prima pagina in basso a destra di http://www.vishay.com/docs/81745/tsop312.pdf )

Con un transistore puoi dare piú corrente e il IRLED da piú luce. I IRLED a secondo il modello sopportano anche 100mA e se li metti una alternata con duty cycle 50% puoi raddoppiare tale corrente. percui 200mA. Un uscita Arduino può dare 40mA e percui 20mA per IRLED.

Ciao Uwe
Logged

Firenze, Italy
Offline Offline
Full Member
***
Karma: 0
Posts: 104
Dislessia portami via
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Grazie della dritta!
Mi procurerò il necessario  per fornire più corrente ai LED e vedo che portate ottengo.

Per il futuro farò riferimento al datasheet piuttosto che a generici schemi trovati in giro!
Grazie ancora.
Logged

The brightest flame burns quickest

Firenze, Italy
Offline Offline
Full Member
***
Karma: 0
Posts: 104
Dislessia portami via
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ho una domanda, esistono degli interruttori (cose tipo relè immagino) controllabili con Arduino (insomma con le uscite generabili da Arduino). Per esempio se volessi controllare un interruttore delle lampade di casa (220 V) con un consenso di Arduino (5 V) che cosa mi servirebbe?
Logged

The brightest flame burns quickest

Lamezia Terme
Offline Offline
Shannon Member
****
Karma: 515
Posts: 12317
Le domande di chi vuol imparare rappresentano la sua sete di sapere
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ho una domanda, esistono degli interruttori (cose tipo relè immagino) controllabili con Arduino (insomma con le uscite generabili da Arduino). Per esempio se volessi controllare un interruttore delle lampade di casa (220 V) con un consenso di Arduino (5 V) che cosa mi servirebbe?
esistono i relé reed che consumano abbastanza poco da essere pilotabili direttamente con Arduino ma non vanno bene per carichi 220, o almeno quelli che ho io riportano 110V, e comunque sopportano carichi bassi; la cosa più corretta sarebbe usare, per ogni comando da pilotare, un fotoaccoppiatore ed un rele comune oppure meglio ancora sarebbe un relé a stato solido o più semplicemente un TRIAC; insomma soluzioni ce ne stanno tante, si tratta anche di capire cosa devi fare esattamente, che carichi devi pilotare e per quanto tempo, ecc.
Logged

Guida alla programmazione ISP e seriale dei micro ATMEL (Caricare bootloader e sketch):
http://www.michelemenniti.it/Arduino_burn_bootloader.php
Guida alla Programmazione ATmega328 noP:
http://www.michelemenniti.it/atmega328nop.html
Articoli su Elettronica In:
http://www.michelemenniti.it/elettronica_in.html

Firenze, Italy
Offline Offline
Full Member
***
Karma: 0
Posts: 104
Dislessia portami via
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Grazie, la domanda era sorta nella remota ipotesi che il contatore sulla porta funzioni in maniera robusta, potrei spegnere (il generale luci?) le luci della stanza quando nessuno è dentro e riaccenderle quando entra qualcuno.
Ci tengo a precisare che (almeno per il momento) non intendo usare il progetto per questo scopo, era giusto una curiosità per capire le potenzialità di Arduino.
Logged

The brightest flame burns quickest

Lamezia Terme
Offline Offline
Shannon Member
****
Karma: 515
Posts: 12317
Le domande di chi vuol imparare rappresentano la sua sete di sapere
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Grazie, la domanda era sorta nella remota ipotesi che il contatore sulla porta funzioni in maniera robusta, potrei spegnere (il generale luci?) le luci della stanza quando nessuno è dentro e riaccenderle quando entra qualcuno.
Ci tengo a precisare che (almeno per il momento) non intendo usare il progetto per questo scopo, era giusto una curiosità per capire le potenzialità di Arduino.
Spegnere il generale luci significherebbe montare il componente in serie al magnetotermico, se ti riferisci all'intero appartamento, mi pare un po' complessa come soluzione, dal punto di vista realizzativo; se invece parli della famosa stanza allora ti basta interrompere il filo che va al lampadario, ma così il controllo sarebbe totale da parte del tuo circuito, oppure dovresti realizzare uno schema a doppio interruttore (hai presente il corridoio che ti permette di accendere e spegnere una lampadina con due o più intetturroi separati?) di cui uno sarebbe quello originale della stanza e l'altro il tuo componente, mi sembra più elegante.
Logged

Guida alla programmazione ISP e seriale dei micro ATMEL (Caricare bootloader e sketch):
http://www.michelemenniti.it/Arduino_burn_bootloader.php
Guida alla Programmazione ATmega328 noP:
http://www.michelemenniti.it/atmega328nop.html
Articoli su Elettronica In:
http://www.michelemenniti.it/elettronica_in.html

Firenze, Italy
Offline Offline
Full Member
***
Karma: 0
Posts: 104
Dislessia portami via
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

oppure dovresti realizzare uno schema a doppio interruttore (hai presente il corridoio che ti permette di accendere e spegnere una lampadina con due o più intetturroi separati?) di cui uno sarebbe quello originale della stanza e l'altro il tuo componente, mi sembra più elegante.

Mi piace questa soluzione, posso realizzarla con un TRIAC?
Logged

The brightest flame burns quickest

Deep south of Italy
Offline Offline
Faraday Member
**
Karma: 8
Posts: 2955
The quieter you become, the more you can hear
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

si, il circuitino è semplice, tipo questo:

questo però è optoaccoppiato
« Last Edit: April 10, 2012, 09:01:13 am by BrainBooster » Logged

Pages: [1] 2   Go Up
Jump to: