Strumenti Utente

Strumenti Sito


riservata:ir

Questa è una vecchia versione del documento!


Comunicazione a infrarosso

Hardware

ricevitore IR

Un integrato con un fotodiodo e un circuito di condizionamento che si occupa della demodulazione del segnale a 38kHz inviato dal trasmettitore.

Tre piedini: Vcc, GND e segnale.

Segnale in uscita: alto quando non riceve (space), basso quando riceve un segnale IR a 38kHz (mark/burst).

Decodifica: esistono tanti protocolli che codificano 0 e 1 un maniera differente (ma sempre in base alla durata di space e mark). Il protocollo definisce anche cosa viene trasmesso e con che tempi (in genere 8 bit per indirizzo e comando che vengono inviati due volte e un codice per il repeat).

Trasmettitore

Un LED a infrarosso della lunghezza d'onda giusta (compatibile col ricevitore) da pilotare a 38kHz con un microcontrollore.

Idee per progetti

  • video/foto di un telecomando mentre va (si vede col sensore di una camera digitale)
  • reverse engineering di un protocollo IR
  • copiare i dati di un telecomando (usare la libreria) per fare un telecomando con arduino e IRED

Osservazioni

  • perché 38kHz? non confonde il segnale con altro
  • non si riesce a vedere il segnale modulato, il ricevitore dà in uscita un segnale già demodulato

Esempio con decodifica segnale IR

Esiste una libreria molto facile da utilizzare fatta da Ken Shirrif. Il programma seguente invece non usa librerie ed è sufficientemente facile da capire. Prerequisiti:

  • tipi di dati
  • bitwise math (shift, AND)
  • array
  • registri microcontrollori
/* 
 TODO
 - MAXPULSE dice che sono ms ma viene confrontato con 
 variabili che sono us/20
 
 
 RICEVITORE IR
 demodula il segnale di un trasmettitore IR generando
 - livello H per space (trasmettitore off)
 - livello L per mark/burst (impulsi a 38kHz)
 
 LEGGERE I SEGNALI CON I REGISTRI I/O
 l'istruzione digitalRead() è troppo lenta perciò bisogna
 usare l'accesso diretto ai pin con i registri I/O
 PIND è il registro che permette di leggere il valore 
 degli ingressi da 0 a 7 (0 livello L, 1 livello H)
 il terzo bit da destra di PIND è riferito al pin 2
 nel test del ciclo while shifta 1 a sinistra di due
 posizioni (da 00000001 a 00000100) poi fa un AND con gli
 otto bit di PIND; se il risultato è ancora 00000100 
 il segnale è alto
 vedi PortManipulation e BitMath nella Reference 
 
 PROGRAMMA ORIGINALE
 da adafruit modificato nello stile (const invece che define)
 e commentato in italiano
 
 */
 
// pin segnale ricevitore IR
const byte IRpin = 2;
 
// valore massimo di highpulse/lowpulse prima del timeout
// 65000 intervalli da 20us = 1.3 secondi
const unsigned int MAXPULSE = 65000;
 
// risoluzione in us nella lettura degli impulsi
// (gli intervalli saranno multipli di questo valore)
const byte RESOLUTION = 20;
 
// memorizza la durata di H e L per 100 impulsi
unsigned int pulses[100][2];
byte currentpulse = 0; // indice dell'array pulses
 
void setup(void) {
  Serial.begin(9600);
  Serial.println("Attesa sequenza IR!");
}
 
void loop(void) {
  // durata H e L in numero di intervalli di 20us
  unsigned int highpulse, lowpulse;  
  // azzerati a ogni ciclo
  highpulse = lowpulse = 0; 
 
  // se il segnale demodulato è alto (space)
  while (PIND & (1 << IRpin)) {
 
    // incrementa highpulse e aspetta 20 us
    highpulse++;
    delayMicroseconds(RESOLUTION);
 
    // timeout: stampa la sequenza di impulsi, azzera 
    // l'indice e esce da loop (ricominicia da capo)
    if ((highpulse >= MAXPULSE) && (currentpulse != 0)) {
      //printpulses();
      printpulses2();
      currentpulse=0;
      return;
    }
  }
 
  // il segnale diventa L (o timeout)
  // scrivo la durata dell'impulso H
  pulses[currentpulse][0] = highpulse;
 
  // se il segnale è basso (mark)
  while (! (PIND & (1 << IRpin))) {
 
    // incrementa lowpulse e aspetta 20 us
    lowpulse++;
    delayMicroseconds(RESOLUTION);
 
    // timeout: stampa la sequenza di impulsi, azzera 
    // l'indice e esce da loop (ricominicia da capo)
    if ((lowpulse >= MAXPULSE)  && (currentpulse != 0)) {
      //printpulses();
      printpulses2();
      currentpulse=0;
      return;
    }
  }
 
  // il segnale diventa H (o timeout)
  // scrivo la durata dell'impulso L
  pulses[currentpulse][1] = lowpulse;
 
  // passiamo al prossimo impulso (coppia durate H/L)
  currentpulse++;
}
 
void printpulses(void) {
  // \n\r newline + return lascia un linea vuota
  Serial.println("\n\rSequenza impulsi (tempi in microsecondi)");
  Serial.println("space (H)\tmark (L)");
  Serial.println("IR OFF\t\tIR ON");
  for (byte i = 0; i < currentpulse; i++) {
    Serial.print(pulses[i][0] * RESOLUTION, DEC);
    Serial.print("\t\t");
    Serial.println(pulses[i][1] * RESOLUTION, DEC);
  }
}
 
void printpulses2(void) {
  // \n\r newline + return lascia un linea vuota
  Serial.println("\n\rSequenza impulsi (tempi in microsecondi)");
  Serial.println("mark (L)\tspace (H)");
  Serial.println("IR ON\t\tIR OFF");
  Serial.print(pulses[0][1] * RESOLUTION, DEC);
  for (byte i = 1; i < currentpulse; i++) {
    Serial.print("\t\t");
    Serial.println(pulses[i][0] * RESOLUTION, DEC);
    Serial.print(pulses[i][1] * RESOLUTION, DEC);
  }
}

Riferimenti

Questo sito Web utilizza i cookie. Utilizzando il sito Web, l'utente accetta la memorizzazione dei cookie sul proprio computer. Inoltre riconosci di aver letto e compreso la nostra Informativa sulla privacy. Se non sei d'accordo, lascia il sito.Maggiori informazioni sui cookie
riservata/ir.1536946424.txt.gz · Ultima modifica: 2020/07/03 15:59 (modifica esterna)