Pilotiamo i GPIO della Raspberry Pi con il telecomando della TV!

Home / Blog / Pilotiamo i GPIO della Raspberry Pi con il telecomando della TV!
Pilotiamo i GPIO della Raspberry Pi con il telecomando della TV!

In questo post illustrerò come pilotare i GPIO della raspberry pi utilizzando un normale telecomando infrarosso e la distribuzione Coding For School (CFS).

Adafruit rivende un ricevitore infrarosso perfetto per questo utilizzo, ma con un pizzico di fortuna potete trovare un ricevitore compatibile all’interno di vecchie apparecchiature dismesse dotate di telecomando.

Io ne ho dissaldato uno da un vecchio decoder rotto e funziona perfettamente. 😉

Collegamento del Ricevitore IR alla Raspberry Pi

Il collegamento proposto è il seguente, ma nulla vieta di utilizzare GPIO diversi da quelli illustrati, sarà poi necessario specificarli nei file di configurazione.

Schema dei collegamenti

Sul ricevitore infrarosso abbiamo 3 pin, GND, 3V e output. Colleghiamo l’output del ricevitore al GPIO 1 (18 BCM) e aggiungiamo 3 LED ai GPIO 27,28 e 29 con in serie una resistenza da 270Ω. Il valore della resistenza da utilizzare dipende dal tipo di LED utilizzato. Se non sappiamo che LED abbiamo tra le mani per evitare di bruciarlo è comunque consigliato provare con resistenze di valore maggiore.

Come cavo per il collegamento del ricevitore infrarosso ho utilizzato un cavetto che si usa(va) comunemente per collegare l’uscita audio dei vecchi masterizzatori CD per computer.

Installazione e configurazione LIRC

LIRC è un software che ci permette di decodificare una grande varietà dei più diffusi telecomandi infrarossi. Il programma viene lanciato come demone e una volta ricevuto un segnale infrarosso, tramite l’appropriato driver, decodifica il segnale e invia le informazioni ricevute su di un socket. Sarà poi nostro compito scrivere un programma che tenga monitorato questo socket e reagisca agli eventi adeguatamente.

  1. Su CFS LIRC e le librerie sono già installate nel caso si voglia verificare l’installazione:
     pi@garfield ~ $ sudo apt-get install lirc liblircclient-dev
  2. Per far partire il modulo durante il boot è necessario modificare il file /etc/modules aggiungendo le seguenti righe dove viene specificato il modulo da caricare e il GPIO sul quale è collegato l’output del ricevitore infrarosso:
     lirc_dev
     lirc_rpi gpio_in_pin=18
  3. Modifcare il file /etc/lirc/hardware.conf editando i  seguenti parametri:
     LIRCD_ARGS="--uinput"
     DRIVER="default"
     DEVICE="/dev/lirc0"
     MODULES="lirc_rpi"
  4. Per la Raspberrypi2 è necessario anche modificrae il file /boot/config.txt decommentando il parametro dtoverlay=lirc-rpi  alla fine del file.
  5. Eseguire un reboot del sistema

Test telecomando/ricevitore

Per verificare il corretto funzionamento di LIRC fermiamo il demone e facciamo partire “mode2” che ci mostrerà la corretta ricezione dei segnali infrarossi del nostro ricevitore.

pi@garfield ~ $ sudo /etc/init.d/lirc stop
pi@garfield ~ $ mode2 -d /dev/lirc0

Ad ogni pressione dei tasti sul telecomando sullo scremo avremo un ouput simile a questo:

...
space 900
pulse 887
space 897
pulse 439
space 457
pulse 473
space 416
...

Premere Ctrl-C per terminare l’esecuzione.

Registrazione dei codici del telecomando

Per registrare i codici utilizzati dai tasti del nostro telecomando utilizzeremo irrecord che ci permetterà anche di creare il file lircd.conf usato da LIRC

pi@garfield ~ $ irrecord -d /dev/lirc0 ~/lircd.conf

Seguendo la procedura guidata lanciata da irrecord verrà assegnato un nome ad ogni tasto del telecomando per la lista completa dei nomi assegnabili digitare:

pi@garfield ~ $ irrecord --list-namespace

Più tasti registreremo con irrecord più funzioni potremmo assegnare al programma che creeremo alla fine del tutorial.

A questo punto non ci resta che copiare il file di configurazione nella giusta posizione e riavviare LIRC:

pi@garfield ~ $ sudo cp lircd.conf /etc/lirc/lircd.conf 
pi@garfield ~ $ sudo /etc/init.d/lirc restart

Test configurazione LIRC

Per testare il nuovo file di configurazione appena creato utilizziamo il programma irw.

Questo è l’output premendo i tasti 2 e 5 sul telecomando:

pi@garfield ~ $ irw
000000037feb6e0c 00 KEY_2 /home/pi/lircd.conf
000000037feb6e0c 01 KEY_2 /home/pi/lircd.conf
000000037feb6e09 00 KEY_5 /home/pi/lircd.conf

Scriviamo il programma per controllare i GPIO

Scriveremo il programma per accendere i nostri 3 LED in C , per fare questo abbiamo bisogno di utilizzare WiringPi già installato di default su CFS, nel caso volessimo comunque reinstallare o aggiornare il programma:

pi@garfield ~ $ git clone git://git.drogon.net/wiringPi
pi@garfield ~ $ cd wiringPi
pi@garfiled ~ $ git pull origin
pi@garfield ~ $ ./build

Il codice

Qui sotto il codice commentato. I pulsanti 1,2,3 del telecomando cambiano lo stato, rispettivamente dei GPIO 27,28,29.

#include <wiringPi.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <lirc/lirc_client.h>
#include <time.h>

void flipLED (int led);

//The WiringPi pin numbers used by our LEDs
#define LED1 27
#define LED2 28
#define LED3 29

#define ON 1
#define OFF 0
int main(int argc, char *argv[])
{
    struct lirc_config *config;
    //Timer for our buttons
    int buttonTimer = millis();
    char *code;
    char *c;
    //Initiate WiringPi and set WiringPi pins 27, 27 & 29 (GPIO 27, 28 & 29) to output. These are the pins the LEDs are connected to.
    if (wiringPiSetup () == -1)
        exit (1) ;
    pinMode (LED1, OUTPUT);
    pinMode (LED2, OUTPUT);
    pinMode (LED3, OUTPUT);
    //Initiate LIRC. Exit on failure
    if(lirc_init("lirc",1)==-1)
        exit(EXIT_FAILURE);
    //Read the default LIRC config at /etc/lirc/lircd.conf This is the config for your remote.
    if(lirc_readconfig(NULL,&config,NULL)==0)
    {
        //Do stuff while LIRC socket is open 0=open -1=closed.
        while(lirc_nextcode(&code)==0)
        {
            //If code = NULL, meaning nothing was returned from LIRC socket,
            //then skip lines below and start while loop again.
            if(code==NULL) continue;{
                //Make sure there is a 400ms gap before detecting button presses.
                if (millis() - buttonTimer > 400){
                    //Check to see if the string "KEY_1" appears anywhere within the string 'code'.
                    if(strstr (code,"KEY_1")){
                        printf("MATCH on KEY_1\n");
                        flipLED(LED1);
                        buttonTimer = millis();
                    }
                    else if(strstr (code,"KEY_2")){
                        printf("MATCH on KEY_2\n");
                        flipLED(LED2);
                        buttonTimer = millis();
                    }
                    else if(strstr (code,"KEY_3")){
                        printf("MATCH on KEY_3\n");
                        flipLED(LED3);
                        buttonTimer = millis();
                    }
                }
            }
            //Need to free up code before the next loop
            free(code);
        }
        //Frees the data structures associated with config.
        lirc_freeconfig(config);
    }
    //lirc_deinit() closes the connection to lircd and does some internal     clean-up stuff.
    lirc_deinit();
    exit(EXIT_SUCCESS);
}
void flipLED (int led)
{
    //If LED is on, turn it off. Otherwise it is off, so thefore we need to turn it on.
    if(digitalRead(led)==ON)
        digitalWrite(led, OFF);
    else
        digitalWrite(led, ON);
}

Supponendo di aver salvato il file col nome 3led_ir_remote.c per compilare il programma dovremmo utilizzare gcc

 pi@garfield ~ $ gcc -o 3led_ir_remote 3led_ir_remote.c -lwiringPi -llirc_client

che produrra il binario 3led_ir_remote, prima di eseguire il programma un ultimo comando per creare un file necessario al funzionamento corretto di LIRC

pi@garfield ~ $ sudo touch /etc/lirc/lircrc

e finalmente l’esecuzione del nostro programma:

pi@garfield ~ $ ./3led_ir_remote

The End 😉

2 thoughts on “Pilotiamo i GPIO della Raspberry Pi con il telecomando della TV!

  1. Salve,
    ho preso realizzato il progetto presentato (molto interessante), funziona tutto. Poi ho incominciato a smanettare… e in una cosa non sono riuscito: non riesco a cambiare l’ingresso. Ho provato con vari GPIO, ovviamente cambiando il GPIO di riferimento nel file /etc/modules, ma nessun risultato. Funziona solo su GPIO18! Ho provato anche a commentare tutto il contenuto del file /etc/modules. Funziona ugualmente. Ovviamente dopo ogni cambiamento ho riavviato. Uso un Raspberry model B+ v1.2. Sono arrivato alla conclusione che il pin 12 GPIO18 è dedicato. E’ giusto?

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *