Periodimetro su segnale in uscita da TSOP IR.

Ciao a tutti,
nel procedere al mio progetto (ed al relativo apprendimento) mi vedo costretto ad acquisire dei codici di telecomando in un formato chiamato CCF (Pronto Hex Raw string) dove i periodi di ON e di OFF del fotodiodo emettitore vengono codificati in una serie di numeri esadecimali che ne indicano il numero di cicli del carrier.
Consideriamo una frequenza classica di 38 KHz, corrispondenti alla durata di un carrier di 26 uS, un burst di ON della durata di 208 uS corrisponderà ad uno 0x0008 (8 cicli nel periodo di ON).
Per velocizzare l'operazione di acquisizione (con l'oscilloscopio è stato utile per impratichirmi ma muovere continuamente i cursori nell'asse delle x iniziava a diventare fastidioso :slight_smile: ) vorrei utilizzare un arduino, collegarvi un TSOP38238 (alimentando quest'ultimo a +5Vcc con relativo resistore e condensatore come da schema di circuito consigliato nel datasheet) ed usarlo per demodulare il segnale PWM in arrivo al suo fotodiodo ricevente.
Una volta uscito dal TSOP il segnale sarà un TTL con periodi temporali di LOW e di HIGH corrispondenti all'on ed all'off del codice modulato a 38 KHz (od invertiti, dipende se normalmente l'uscita è HIGH o LOW, non ho ancora guardato).
Vorrei quindi, tramite l'uso di un interrupt, identificare la variazione di stato per identificare un inizio trasmissione, andare a controllare ogni 26 uS lo stato del segnale (se HIGH o LOW), auto incrementare un contatore che si riazzererà al cambio di stato e ripartirà da capo, terminata la trasmissione chiamare detachInterrupt e rimettersi in "listening".
In modo da avere con un input simile:
8 on 6 off 5 on 9 off
un output così codificato:
0x0008 0x0006 0x0005 0x0009.
Praticamente la realizzazione di un periodimetro digitale specializzato in questo specifico compito.
Il ragionamento è corretto?
Datemi qualche consiglio! :slight_smile:

Quello che vuoi fare non funziona.
http://www.vishay.com/docs/82491/tsop382.pdf pagina 5 in basso
Il TSOP38238 ha bisogno di un minimo di numeri di impulsi perche un treno di impulsi venga risconosciuto come HIGH. Questo é dato dal filtro usato internamente. Le sequenze di impulsi devono essere piú lunghi. al minimo 10 impulsi e poi una pausa della durata di almeno 10 Impulsi.

Ciao Uwe

uwefed:
Quello che vuoi fare non funziona.
http://www.vishay.com/docs/82491/tsop382.pdf pagina 5 in basso
Il TSOP38238 ha bisogno di un minimo di numeri di impulsi perche un treno di impulsi venga risconosciuto come HIGH. Questo é dato dal filtro usato internamente. Le sequenze di impulsi devono essere piú lunghi. al minimo 10 impulsi e poi una pausa della durata di almeno 10 Impulsi.

Ciao Uwe

Ma i dati trasmessi dal telecomando sono un treno di impulsi, io ho riassunto con un esempio di 4 burst ma in realtà sono ben di più (almeno 18).
Essendo così secondo te funziona o mi manca qualche altro dato per realizzare?

Ho fatto un minicircuitino su breadboard con condensatore e resistore come da specifiche del datasheet del TSOP38238.
Con l'oscilloscopio sono andato a misurare l'out e, sorpresa, i periodi TTL non coincidono perfettamente con quelli del burst infrarosso.
Il burst infrarosso di ON era lungo 8 carrier da 26 uS l'uno per un totale di 208 uS, il segnale TTL invece si attesta su 232 uS.
Qualche idea del perchè?

Spero sia utile

#include <IRremote.h>
int buttonState[3];

const int buttonPin[8] = { 9, 11, 10, 4, 6, 5, 8, 7}; // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin

unsigned int AmpPower[] = { 3350, 1800, 400, 450, 350, 1350, 400, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 1350, 400, 450, 400, 450, 400, 450, 400, 450, 400, 450, 400, 450, 400, 500, 350, 1350, 350, 500, 350, 1350, 400, 450, 400, 450, 400, 450, 400, 450, 400, 500, 350, 500, 350, 500, 350, 500, 350, 1350, 350, 500, 350, 1350, 400, 1350, 350, 1350, 350, 1400, 350, 500, 300, 550, 300, 1400, 350, 500, 350, 1350, 350, 1400, 350, 1350, 350, 500, 350, 500, 350, 1400, 350};
unsigned int AmpVolUp[] = { 3350, 1800, 400, 500, 300, 1400, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 1400, 350, 500, 300, 550, 300, 550, 350, 500, 350, 500, 350, 500, 350, 500, 350, 1350, 400, 450, 350, 1400, 300, 550, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 1400, 350, 500, 300, 550, 300, 550, 300, 550, 300, 550, 350, 500, 350, 500, 350, 500, 350, 500, 350, 1350, 350};
unsigned int AmpVolDown[] = { 3350, 1850, 300, 550, 300, 1400, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 550, 300, 550, 300, 1400, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 1400, 300, 550, 300, 1400, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 1400, 300, 550, 300, 550, 300, 550, 300, 550, 350, 1350, 350, 500, 350, 500, 350, 1400, 300, 550, 300, 550, 300, 550, 300, 550, 350, 500, 350, 500, 350, 1350, 350};
unsigned int AmpAux[] = { 3350, 1800, 400, 450, 400, 1350, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 500, 350, 1400, 350, 500, 350, 500, 300, 550, 300, 550, 300, 550, 300, 550, 300, 550, 300, 1400, 350, 500, 350, 1400, 300, 550, 300, 550, 300, 550, 300, 550, 300, 550, 300, 550, 350, 500, 350, 500, 350, 500, 350, 1350, 350, 500, 350, 1400, 300, 1400, 350, 500, 350, 500, 350, 1400, 300, 550, 300, 1400, 350, 500, 350, 1350, 350, 1400, 350, 1350, 350, 500, 350, 500, 350};
unsigned int DVBPower = 0x807FC03F;
unsigned int DVBVolUp = 0x807F00FF;
unsigned int DVBVolDown = 0x807F38C7;
unsigned int DVBChUp = 0x807F10EF;
unsigned int DVBChDown = 0x807F08F7;


IRsend irsend;

void setup()
{
Serial.begin(9600);

for(int i = 0; i < 8; i++)
{
pinMode(buttonPin[i], INPUT);
}
pinMode(ledPin, OUTPUT);

}

void loop()
{
for(int i = 0; i < 8; i++)
{

// read the state of the pushbutton value:
buttonState[i] = digitalRead(buttonPin[i]);

// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
if (buttonState[i] == HIGH)
{
// turn LED on:
digitalWrite(ledPin, HIGH);

switch (i)

{

case 2:
//Philips TV + DTV Power on/off
irsend.sendRC5(0xC, 12);
delay(40);
irsend.sendRC5(0x80C, 12);
delay(200);
irsend.sendNEC(0x807FC03F, 32);
delay(40);
Serial.println("case 1");
break;
case 0:
//DTV Vol +
irsend.sendNEC(0x807F00FF, 32);
delay(40);
Serial.println("case 2");
break;
case 1:
//DTV Vol -
irsend.sendNEC(0x807F38C7, 32);
delay(40);
Serial.println("case 3");
break;
case 6:
//DTV Ch +
irsend.sendNEC(0x807F10EF, 32);
delay(40);
Serial.println("case 4");
break;
case 7:
//DTV Ch -
irsend.sendNEC(0x807F08F7, 32);
delay(40);
Serial.println("case 5");
break;
case 3:
//Panasonic Amp Power + Aux
irsend.sendRaw(AmpPower, 99, 38);
delay(500);
irsend.sendRaw(AmpAux, 99, 38);
delay(40);
Serial.println("case 6");
break;
case 4:
//Panasonic AmpVolUP
irsend.sendRaw(AmpVolUp, 99, 38);
delay(40);
Serial.println("case 7");
break;
case 5:
//Panasonic AmpVolDown
irsend.sendRaw(AmpVolDown, 99, 38);
delay(40);
Serial.println("case 8");
break;

}

}
else
{
// turn LED off:
digitalWrite(ledPin, LOW);
}
}

}