Pages: [1] 2 3 ... 12   Go Down
Author Topic: Barriera Infrarossi  (Read 10001 times)
0 Members and 1 Guest are viewing this topic.
Lamezia Terme
Offline Offline
Shannon Member
****
Karma: 518
Posts: 12321
Le domande di chi vuol imparare rappresentano la sua sete di sapere
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

NOTA: ci troviamo spesso a consigliare la lettura di questo Topic, le ragioni valide sono diverse:
1 - trovate il codice per generare 38KHz direttamente con i timer dei micro, sia ATmega328 che ATiny85, in modo indipendente dal resto del software, nel caso del 328 addirittura può continuare a lavorare perfino mettendo il micro in stand-by (parziale ovviamente)
2 - trovate info interessanti sul dialogo IR in generale
3 - trovate il codice per mandare in sleep i due micro e per svegliarli mediante interrupt
4 - trovate un sacco di fesserie scritte dal sottoscritto, per farvi due risate, la forte inesperienza di allora, non che ora vada meglio.....


Devo realizzare un controllo tipo barriera infrarossi. Uso un LED IR per la trasmissione ed un TSOP per la ricezione, con questa coppia sono piuttosto immune da disturbi esterni, anche se devo ancora fare prove serie. Il LED devo farlo lavorare, come noto, a 38KHz. Con questo semplice CODE:
Code:
/*
  Controllo trasmissione IR
 */

void setup() {                

  pinMode(3, OUTPUT);    
}

void loop() {
    
   digitalWrite(3, HIGH);   // set the LED on
   delayMicroseconds(8);              // wait for a second
   digitalWrite(3, LOW);    // set the LED off
   delayMicroseconds(9);              // wait for a second
  
}
ottengo una frequenza di 37,78KHz, più che sufficiente, visto che il range di lavoro del TSOP va da 36 a 42KHz circa (sperimentati). Vorrei però riuscire ad ottenere la frequenza esatta, non tanto per questo circuito ma per altre esigenze in generale, ma mi sono reso conto che il delayMicroseconds ignora i valori decimali. Allora mi sono "rivolto" al pwm perché ricordavo di aver visto una sintassi particolare a tre valori, proprio col comando PWM, che però non trovo, e con analogWrite la frequenza è di circa 500Hz e la variazione del duty cicle ovviamente non serve a nulla nel mio caso.
Mi rassegno?
« Last Edit: March 18, 2013, 04:42:26 pm by Michele Menniti » 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

Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 120
Posts: 9168
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Riciclare il codice d'esempio che ti avevo dato per generare i 40kHz per le capsule ultrasoniche ?
Code:
/*
 Generatore di impulsi 40 kHz
 */

byte i,j,stato=0;

void setup()
{
  pinMode(13, OUTPUT);     
  pinMode(2,  OUTPUT);   
  digitalWrite(13, HIGH); 
}

void loop()
{
 for(j=0;j<255;j++)
 {
  stato ^= 1;
  digitalWrite(2,stato);
  for(i=0;i<9;i++)
   {
    asm("nop");
    asm("nop");
    asm("nop");
    asm("nop");
    asm("nop");
    asm("nop");
    asm("nop");
    asm("nop");
    asm("nop");
   }
  }
 
 //delay(25);
}

Agendo sul numero delle nop e dei cicli for puoi ottenere una frequenza di 38 kHz esatti.
Logged

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

 smiley-red, l'unica scusa che riesco ad inventarmi è quella (vera) che non mi sono ancora messo a lavorare con gli ultrasuoni e questo codice era ben conservato nella specifica cartellina.
Provo subito, dò per scontato che risolvo (ovviamente!) e quindi sollevo il problema successivo:
Dopo x tempo di NON interruzione del fascio devo mandare in sleep il micro, e fin qui va tutto bene, ma così spengo il LED ed il TSOP va HIGH e mi attiva l'interrupt e riaccende tutto  smiley-eek; non t'inczz, chiarisco subito:
Il micro è attivo e la barriera funziona (TSOPout a LOW)
Quando viene interrotta (TSOPout a HIGH) il micro svolge la sua azione di controllo (p.es. un led, un relé, ecc.).
Cosa vorrei fare ora:
Se non viene interrotta per x tempo il micro si spegne, ma dovrebbe restare attiva la barriera, in modo da riaccendere il micro. Usando un tiny85 non dispongo p.es. della separazione di alimentazione dell'ADC altrimenti pensavo di lasciare accesa questa sezione sperando di usarla.
Allora ho notato questa cosa interessante:
Se alimento il LED a tensione fissa a 5V il TSOP ovviamente resta in HIGH, però se interrompo il fascio, al ripristino il TSOP mi dà un impulso LOW e poi torna su HIGH, come se per un'istante ricevesse la frequenza giusta; potrei invertirmi la logica di questo comportamento, ma il problema è che l'impulso ce l'ho non all'interruzione del fascio ma alla fine, quando ormai tutto è ritornato normale.
Che dici metto un 555 e non se ne parla più? Anche se questo va contro l'idea del risparmio energetico, visto che il 555 in azione mi consuma più del micro, credo.
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

Guidonia
Offline Offline
Full Member
***
Karma: 0
Posts: 214
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Innanzitutto saluto Menniti, Astrobeed e tutti i partecipanti del forum,
sto cercando di capire cosa svolge la routine asm, ma cercando su "san google" sono riuscito a capire che serve per implementare uno straccio di codice in assembly, non riuscendo a spiegarmi cosa centri con la possibilità di avere 40kHz esatte mi chiedevo:

  • asm serve veramente a ad implementare del codice assemly?
  • è una questione di "calcoli" sugli intervalli di tempo?
asm viene ripetuto 2560 volte in un loop
vuol dire che asm impiega 0,015625 hz?
  • perchè proprio da 25?
  • la stringa "nop" è un parametro costante o potevo scriverci anche "abc" ? e "pippo"?

Non dovrebbe interrompersi sul passaggio? (quindi LOW) e se "si vedono" dare un HIGH?
Sto facendo troppe domande smiley?

Marbi

[/list]
Logged

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

Ciao Marbi, mi pare che NOP stia per "not operation", comunque leggi qui
Comunque è un parametro, non puoi scrivere abc.
Tutto quello schetch serve per "tarare" la frequenza sul pin 2 a circa 40KHz
Il TSOP funziona come ho detto: LOW se si vedono e HIGH se non si vedono.
« Last Edit: July 24, 2011, 05:57:11 am by menniti » 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

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

@ astrobeed: secondo le mie misure lo sketch fornisce una frequenza di 39857 Hz, ho fatto un po' di prove e non riesco comunque ad ottenere 40KHz o 38KHz, a questo punto va benissimo qualsiasi valore, siamo vicinissimi alle frequenze richieste ed i sensori hanno buone tolleranze.
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

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

ciao a tutti
@menniti
Non capisco perché vuoi spegnere l' arduino ma tener acceso il led IR.
Se vuoi risparmiare corrente risparmi di piú spegnendo il led.
Non so che barriera IR vuoi fare e cosa vuoi trigherare ma basta un controllo 2 a 10 al secondo per rilevare una persona.
A quel punto:
* fari dei brevi treni di impulsi da 38kHz e rilievi in quel momento il segnale del TSOP
* se vuoi risparmiare ancora di piú metti  il ATmega in sleep vedi libreria Narcoleptic.h http://code.google.com/p/narcoleptic/ oppure programmando direttamente i registri e il timer.
* fare la frequenza con un timer (ma non chiedermi a me come si fa, so che si puó fare ma non so come)
* generare i 38Khz con un oscillatore esterno che puó essere spento.

@Marbi
NOP é un istruzione macchina come scrive menniti e non fa niente. Dura un ciclo di clock che sono a 16Mhz 0,0625 µsecondi.
Si deve fare anche i conti con le altre funzioni tradotte in linguaggio macchina hanno bisogno di tempo per essere interpretati. Alla fine il for insieme ai NOP non é nient altro che un ritardo di 12,5µsecondi.
Un riassunto delle istruzioni li trovi a pagina 427 del http://www.atmel.com/dyn/resources/prod_documents/doc8161.pdf

Ciao Uwe
« Last Edit: July 24, 2011, 06:41:12 am by uwefed » Logged

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

Quote
ciao a tutti
@menniti
Non capisco perché vuoi spegnere l' arduino ma tener acceso il led IR.
Se vuoi risparmiare corrente risparmi di piú spegnendo il led.
Ciao Uwe, lo scopo è didattico, quindi non devo risparmiare corrente in assoluto ma solo far vedere che il micro si può spegnere e riattivare all’occorrenza; il circuito sarà alimentato tramite alimentatore.
Quote
Non so che barriera IR vuoi fare e cosa vuoi trigherare ma basta un controllo 2 a 10 al secondo per rilevare una persona.
A quel punto:
* fari dei brevi treni di impulsi da 38kHz e rilievi in quel momento il segnale del TSOP
Questa è un’ottima idea, 5-6 controlli al secondo mi stanno bene, oltretutto così implemento facilmente il controllo dello stato del TSOP
Quote
* se vuoi risparmiare ancora di piú metti  il ATmega in sleep vedi libreria Narcoleptic.h http://code.google.com/p/narcoleptic/ oppure programmando direttamente i registri e il timer.
Io uso la sleep.h con ottimi risultati, cos’ha questa libreria di particolare? E’ migliore?
Quote
* fare la frequenza con un timer (ma non chiedermi a me come si fa, so che si puó fare ma non so come)
* generare i 38Khz con un oscillatore esterno che puó essere spento.
Alla prima soluzione avevo pensato ma nemmeno io so come si fa; ne parlarono Leo e Astrobeed ed altri in un Topic sull'RTC ma uscì fuori solo che non era precisa (ma nel mio caso andrebbe bene lo stesso).
La seconda è quella che dicevo col 555, ripeto lo scopo è didattico, quindi il problema del consumo reale non si pone, vorrei però fare tutto col micro (un tiny85 in stand-alone)
Ciò che devo fare in pratica è spegnere il micro e le utenze che controlla, per poi riattivarlo quando la barriera viene interrotta; se la barriera la controllo col micro mi sa che non posso fare quello che vorrei, perché si spegne anche l’uscita a 38KHz e il TSOP si comporta come se fosse stata interrotta.
Grazie.
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

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

Intanto che tornate da fuori porta vado avanti  smiley
Code:
/*
  Controllo barriera IR
 */

#define TX 6
//#define RX 2
#define LV 8
#define LR 9

void setup()
{               
  pinMode(TX, OUTPUT);     
  //pinMode(RX, INPUT);
  pinMode(LV, OUTPUT);
  pinMode(LR, OUTPUT);
  //digitalWrite(RX, HIGH);
  attachInterrupt(0, Passaggio, RISING); 
}

void loop()
{
  /*Le seguenti quattro righe generano sul pin un'onda quadra
    di circa 38KHz */
   digitalWrite(TX, HIGH);  // setta il pin su HIGH
   delayMicroseconds(9);    // pausa di 8 µsec
   digitalWrite(TX, LOW);   // setta il pin su LOW
   delayMicroseconds(8);    // pausa di 9 µsec
   
}
void Passaggio()        // interruzione barriera
{
  digitalWrite(LR, HIGH); // accende il LED per 1 secondo
  delay(1000);
  digitalWrite(LR,LOW);
  detachInterrupt(0);      //disattiva l'interrupt
 
}
Nelle mie misere intenzioni volevo attivare l'interrupt al passaggio del pin 2 (interrupt 0) da LOW ad HIGH (RISING). Quando lancio lo sketch tutto funziona apparentemente, se interrompo in modo stabile la barriera, la sola prima volta il led fa un rapido lampeggio, poi più niente.
L'altra cosa strana è che in altri schetch avevo definito il pin 2 (INT0) con una costante (p.es. RX) e poi avevo usato la costante per l'interrupt, in questo caso la ignora, devo proprio usare "0" altrimenti non fa nemmeno il lampeggio. Idee?

EDIT: specifico che per ora sto lavorando col 328 di Arduino, il passaggio al tiny85 verrà solo quando funziona tutto.
« Last Edit: July 24, 2011, 09:38:11 am by menniti » 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

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Il tuo codice è un PWM a tutti gli effetti  smiley
Cmq per fare temporizzazioni precise devi impostare un timer interno collegato ad un interrut. Imposti il timer, poi al raggiungimento del valore massimo il contatore viene resettato: questa operazione genera un interrupt. Intercetti l'interrupt e spedisci il tuo segnale:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1167000525

Non credo tu possa usare un RTC per farti generare un segnale di clock da usare perché un DS1307 o un PCF8563 generano un clock massimo di 32768 Hz (lo stesso del quarzo), troppo basso per i tuoi 38 kHz.
Logged


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

Non ho un problema di temporizzazioni precise, riguardo la frequenza esterna ho detto che eventualmente userei un 555 e con quello non ho problemi di sicuro; il riferimento all'RTC era perché volevo capire come far uscire da un pin del micro una frequenza di riferimento di 38KHz, usando quindi il timer interno, ma non ho idea di come si possa fare. Comunque, nel periodo non collegato ho capito perché il code non andava: il Reference spiega  smiley-sweat che lanciando una routine tramite interrupt i delay & Co & timer non funzionano, quindi ho aggirato il problema.
Code:
/*
  Controllo barriera IR
 */

#define TX 6
#define LV 8
#define LR 9
volatile int stato = LOW;

void setup()
{               
  pinMode(TX, OUTPUT);     
  pinMode(LV, OUTPUT);
  pinMode(LR, OUTPUT);
  attachInterrupt(0, Passaggio, RISING);  // se il pin INT0 (PD2) passa da LOW ad HIGH esegue la routine Passaggio()
  digitalWrite(LR, LOW);
  digitalWrite(LV, HIGH);
}

void loop()
{
  /*Le seguenti quattro righe generano sul pin un'onda quadra
    di circa 38KHz */
   digitalWrite(TX, HIGH);  // setta il pin su HIGH
   delayMicroseconds(8);    // pausa di 8 µsec
   digitalWrite(TX, LOW);   // setta il pin su LOW
   delayMicroseconds(8);    // pausa di 8 µsec
   
   if(stato==HIGH)
     {
       digitalWrite(LR, HIGH);   // accende il LED R per 10 secondi
       digitalWrite(LV, LOW);
       delay(10000);
       stato = !stato;
       digitalWrite(LR, LOW);
       digitalWrite(LV, HIGH);  // accende il LED V fino a nuovo interrupt
     } 
}
void Passaggio()            // interruzione barriera
{
    stato = !stato;
}
Ora mi succede questo: quando si interrompe la barriera per dieci secondi si inverte lo stato dei led, ma se la barriera resta interrotta oltre i 10 secondi c'è comunque un istante in cui i led cambiano di nuovo stato; questa cosa mi crea notevoli problemi: un eventuale meccanismo di sicurezza per un istante non funzionerebbe. Che logica potrei usare per risolvere?

Due domande OT:
1 - c'è una combinazione di tasti per far uscire le due parentesi graffe nell'editazione?
2 - come si fa a far apparire lo sketch con i colori originali dell'IDE?
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

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

Io uso la sleep.h con ottimi risultati, cos’ha questa libreria di particolare? E’ migliore?
Non so perché non conosco la sleep.h .

Ciao Uwe
Logged

Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 120
Posts: 9168
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

1 - c'è una combinazione di tasti per far uscire le due parentesi graffe nell'editazione?

Shift + alt graph + [ per la {
Shift + alt graph + ] per la }

Logged

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

@ Uwe: nessun problema  smiley-lol

@ astrobeed: ottimo, mi ero scocciato di fare ogni volta copincolla delle graffe smiley-lol
hai letto i vari post dopo il tuo ultimo intervento? Qualche idea in proposito?
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

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

Quote
1 - c'è una combinazione di tasti per far uscire le due parentesi graffe nell'editazione?
Usa la tastiera tedesca; li si arriva con
alt graph + 7 per {
alt graph + 0 per }  smiley-wink smiley-wink smiley-wink

La differnza tra sleep.h e Narcoleptic.h dovrebbe essere che Narcoleptic.h ha piú funzionalitá nel senso piú trigger di risveglio rispetto la sleep.h. Non avendo usata ne l' una ne l' altra non sono sicuro in questo.

Ciao Uwe
Logged

Pages: [1] 2 3 ... 12   Go Up
Jump to: