Salve!
Dovrei creare un'onda quadra a 36kHz e allo stesso tempo verificare la presenza di un segnale digitale su un pin (il classico led emettitore con ricevitore TSOP)
E' possibile rilevare la presenza mentre il segnale portante è in LOW? ce la fa arduino con le tempistiche?
Immagino di dover usare il port manipulating con i registri giusto?
Potreste postarmi una bozza del codice?
Grazie in anticipo!
PS: non posso usare gli interrupt perchè il segnale va ricevuto da più di un sensore.
Cerca semplicemente infrarossi qui sul Forum e ti escono un centinaio di Topic, in almeno la metà è riportato il codice che ti serve, ti basta variare opportunamente il valore originale, che è 210 per ottenere 38kHz, lo standard IR; se te ne servono 36kHz lo devi diminuire di qualche unità.
Hai ragione ne ho trovati molti.
Però non mi funzionano, ad esempio questo:
#define RXTSOP 8 //Pin TSOP
#define TXIR 11 //LED IR
#define LED13 13 //LED on pin 13
//flag
boolean transmitting_IR; //transmission 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(TXIR, 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 = 221; // 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()
{
if(digitalRead(RXTSOP)){
digitalWrite(LED13 ,LOW);
}else{
digitalWrite(LED13 ,HIGH);
}
}
void setup(){
Serial.begin(9600);
pinMode(TXIR, OUTPUT);
pinMode(RXTSOP, INPUT);
turn_on_IR();
delay(100);
}
void loop(){
detectIR(); // search for IR
Serial.println(digitalRead(RXTSOP));
delay(50);
}
mi stampa indifferentemente "1" se non per la frazione di secondo dopo aver connesso il led (tramite transistor).
Ho provato anche altri codici ma niente. Qualche consiglio?
questo dovrebbe andare. Prova a guardare il LED IR col cellulare o con una fotocamera, durante il funzionamento lo dovresti vedere sempre acceso. Hai messo una R da 100 ohm in serie al led IR? Cosa intendi per "indifferentemente"? cioè cosa fai per voler vedere cambiare lo stato dell'ingresso?
Si il LED è acceso e la resistenza è presente. Inoltre se provo ad irraggiare il TSOP con il telecomando vedo sulla seriale degli zero quindi il sensore funziona.
Con "indifferentemente" intendo che la seriale stampa sempre "1" anche se disconnetto fisicamente il LED. poi riconnettendolo stampa una decina di zero e poi nuovamente "1". Ho provato anche a schermare il TSOP e disconnettere e riconnettere il LED... la seriale stampa sempre una serie di "0" subito dopo la connessione e poi stampa solo "1".. quindi la serie di 0 iniziali non indicano un rilevamento del segnale da parte del TSOP ma chissà cos'altro...
Ma come mistero? La cosa è assolutamente NORMALE, sempre se ho capito il comportamento che stai descrivendo, visto che la prova di una barriera ad infrarossi si fa semplicemente frapponendo tra LED e RX qualcosa che blocchi sicuramente gli infrarossi e non di sicuro scollegando il LED cme dici di fare. Il Ricevitore che stai usando è di tipo "impulsivo": resta costantemente su "1" fintanto che riceve il fascio a 36kHz, nel momento in cui interrompi il fascio (p.es. con un libro, certamente NON con una carta di credito) il ricevitore dà un impulso di durata fissa verso "0" e poi si rimette ad "1", a prescindere dallo stato attuale del fascio; solo alla successiva interruzione del fascio ottieni un nuovo impulso; in alcuni casi il comportamento impulsivo è esattamente l'opposto di quello che ti ho descritto. Poi ci sono i Ricevitori che invece sono sempre su "0" quando ricevono il fascio e passano ad "1" per l'intera durata del'interruzione, per tornare su "0" quando ritorna il fascio. Entrambi questi comportamenti sono chiaramente descritti nei datasheet.
La prova che devi fare è: ignorare il comportamento iniziale, vedere cosa ti dà mentre tx e rx si "vedono" tra loro, vedere cosa succede nel momento in cui interrompi per 10 secondi questa visuale con un oggetto spesso e non trasparente, quale appunto un libro (nelle mie prove usavo una card completamente rivestita di nastro telato nero). Se normalmente vedi "1" (o "0") e nel momento dell'interruzione vedi un cambio di stato (che dura pochi istanti o tutti i 10 secondi, secondo il tipo di rx che hai) allora ti sta funzionando tutto, se invece l'interruzione viene completamente ignorata probabilmente il ricevitore è guasto oppure non lavora correttamente a 36kHz.
Altra cosa importante: la R da 100ohm deve essere presente anche in serie al V+ del ricevitore, mentre tra V+ e GND, proprio sui suoi pin, devi collegare un C elettrolitico da 4,7-47µF, anche questi componenti sono richiesti dai datasheet.
hai proprio ragione! funziona.. Ho sempre sperimentato con i TSOP in cui se c'è il segnale rimandano 0 e se non c'è rimandano 1 (in modo continuo) e non sapevo che ce ne fossero di diversi (questo l'ho preso da un gioco cinese e non ha alcuna scritta stampata sopra quindi non potevo neanche risalire al datasheet)
Grazie! Non sembra ma mi hai risolto un grosso problema!
Figurati, le due versioni esistono per fini differenti: in genere quello che hai tu si usa per dare un singolo impulso a sistemi di controllo ed allarme, dove è necessario che succeda qualcosa appena il fascio si interrompe, senza che abbia importanza il seguito (una volta che il ladro è entrato poco importa se sta lì o se va avanti ed indietro....); gli altri invece servono per controllare proprio tutta la fase di interruzione del fascio, diciamo che sono più "analogici"; quest'ultimo tipo l'ho usato per il controllo elettronico di un passaggio a livello per ferromodellisti: il sensore mi avvertiva non solo del passaggio del treno ma anche dell'intera durata di tale passaggio.