Pilotare diversi dispositivi con il movimento della testa

Progetto IR decode

Come utilizzare Arduino per comandare diversi elettrodomestici col movimento della testa

L'idea di questo progetto nasce per dare una mano alle persone con gravi disfunzioni motorie, utilizzando Arduino (per comandare alcuni sistemi come televisore, condizionatore, lampade e altri dispositivi) e un pc con webcam, per tradurre piccoli movimenti della testa in istruzioni da impartire ad Arduino. Il sistema è un prototipo che non è stato mai provato realmente, ma solo in ambiente simulato, pertanto non mi ritengo responsabile di malfunzionamenti e/o danni causati dal sistema; questo articolo vuole essere un'idea per poter realizzare qualcosa di più serio e sicuro, e spiegare come ho realizzato il prototipo utilizzando diverse tecnologie. Lo schema di funzionamento rappresentato in figura è il frutto dell'unione di elementi già esistenti che permettono di formare il sistema completo.

questo l'elenco dell'hardware e del software impiegato per il prototipo

  • Arduino UNO
  • Classe IRremote
  • PC o Netbook
  • Webcam
  • Software basato su .Net Framework 4.0
  • Software per spostare il mouse con il tracking facciale tramite webcam
  • eventuali circuiti esterni per pilotare carichi

il funzionamento del sistema si divide in due fasi denominate SETUP e OPERATIV. Nella fase di setup (quando il pin4 di Arduino si trova a livello logico alto) è possibile ricevere e decodificare il codice del telecomando e tramite il software sul pc, associarlo ad un pulsante dell'interfaccia grafica. Nella fase operativ (quando il pin4 di Arduino si trova a livello logico basso) il software sul pc permette di inviare ad Arduino il codice, associato ad un pulsante, e di riprodurre il relativo segnale ir.

Lo schema del circuito elettrico è il seguente:

 

La sezione composta da un fototransistor (IR RX) si occupa di acquisire il segnale di un telecomando, mentre il diodo IR TX permette di trasmettere un codice precedentemente memorizzato.
La sezione attuatori è composta da tre diodi led, che permettono di simulare le uscite verso relè o altri circuiti digitali. La sezione scelta modalità permette di eseguire la memorizzazione dei codici dei telecomandi piuttosto che la loro riproduzione.

il codice che gira sull'Arduino è il seguente, i diversi commenti nel codice ne spiegano il funzionamento


#include <IRremote.h>
//pin dove è collegato il fototransistor
int RECV_PIN = 2;

//oggetti per ricevere e trasmettere il segnale IR
IRrecv irrecv(RECV_PIN);
IRsend irsend;

decode_results results;

String DataIR = "";

char dataRX = ' ';
byte buffer = 0;

String codNome = "";
String codCodifica = "";
String codNumBit = "";

void setup()
{
  //pin scelta modalita SETUP-OPERATIV
  pinMode(4, INPUT);

  //inizializzazione seriale e classe ir
  Serial.begin(9600);
  irrecv.enableIRIn();
}

//Funzione per decodificare il segnale ir
void dump(decode_results *results) {

  //se non ci sono bit da decodificare esci
  if(results->bits == 0)
  {
    return;
  }

  //inizio struttura stringa da spedire al pc
  Serial.print("@");

  //restituisci il tipo di codifica
  if (results->decode_type == UNKNOWN) {
    Serial.print("???");
  }
  else
  {
    if (results->decode_type == NEC)
    {
      Serial.print("NEC");
    }
    else if (results->decode_type == SONY)
    {
      Serial.print("SON");
    }
    else if (results->decode_type == RC5)
    {
      Serial.print("RC5");
    }
    else if (results->decode_type == RC6)
    {
      Serial.print("RC6");
    }

    Serial.print("$");
    //invio il codice del telecomando
    Serial.print(results->value, HEX);

    Serial.print("$");
    //invio il numero dei bit
    Serial.print(results->bits, DEC);
  }

  //fine buffer
  Serial.println("#");

}

void loop()
{
  if(digitalRead(4) == HIGH)
  {
    //modalità registrazione segnale ir
    if (irrecv.decode(&results))
    {
      //invia al software tutti i dati
      //sul segnale ir
      dump(&results);
      // Receive the next value
      irrecv.resume();
    }
  }
  else if(digitalRead(4) == LOW)
  {
    //modalità generazione segnale ir in base a comando da pc
    //via porta seriale
    while(Serial.available())
    {
      //leggi dalla seriale il codice
      //e trasmetilo via IR
      dataRX = Serial.read();
      //scarto lil carattere @
      if(dataRX == '@')
        buffer = 0;
      else if (dataRX == '$')
      {
        buffer++;
      }
      else if (dataRX == '#')
      {
        //fine pacchetto trasmetti i dati via ir
        //Serial.println(codNome);
        //Serial.println(codCodifica);
        //Serial.println(codNumBit);

        //converte da stringa a int
        char buf_codCodifica[codCodifica.length() + 1];
        codCodifica.toCharArray(buf_codCodifica, codCodifica.length() + 1);

        char buf_codNumBit[codNumBit.length() + 1];
        codNumBit.toCharArray(buf_codNumBit, codNumBit.length() + 1);

        long lng_codCodifica = atol(buf_codCodifica);
        long lng_codNumBit = atol(buf_codNumBit);

        //Serial.println(lng_codCodifica);
        //Serial.println(lng_codNumBit);

        //trasmette il segnale
        if(codNome == "NEC")
          irsend.sendNEC(lng_codCodifica, lng_codNumBit);
        if(codNome == "SON")
          irsend.sendSony(lng_codCodifica, lng_codNumBit);
        if(codNome == "RC5")
          irsend.sendRC5(lng_codCodifica, lng_codNumBit);
        if(codNome == "RC6")
          irsend.sendRC6(lng_codCodifica, lng_codNumBit);

        //pulisci le variabili per un nuovo comando
        codNome = "";
        codCodifica = "";
        codNumBit = "";
        buffer = 0;
      }
      else
      {
        //accumula i caratteri provenienti dal pc e li dispone
        //nelle relative variabili
        if(buffer == 0)
          codNome += dataRX;

        if(buffer == 1)
          codCodifica += dataRX;

        if(buffer == 2)
          codNumBit += dataRX;
      }
    }
  }
}

L'interfaccia del software che gira sul pc è mostrata in figura

Il pulsante Avvia registrazione permette di ricevere la stringa inviata da Arduino contenente Il nome della codifica, il valore e il numero di bit che la compongono. Una volta acquisito il codice è possibile assegnarlo ad uno dei dodici pulsanti dei comandi, semplicemente cliccando sul numero di pulsante nella lista dei codici assegnati ai pulsanti e cliccando sul pulsante Assegna.
Una volta terminata la fase di registrazione e dopo aver settato il circuito nella modalità Operativ, è possibile inviare il codice del telecomando alla scheda cliccando semplicemente il pulsante relativo.

La fase successiva è quella di impiegare un software per il tracking facciale. Per la prova ho utilizzato Camera Mouse 2012 disponibile gratuitamente per il download. Avviato il software, viene rilevata automaticamente la webcam, tramite il mouse dobbiamo cliccare su un punto del viso da tracciare, ad esempio la punta del naso. Per avviare lo spostamento del mouse tramite movimenti della testa è necessario premere il tasto Ctrl della tastiera. Nella sezione settings del programma è possibile settare molti parametri tra cui la simulazione del click che viene effettuata quando il puntatore del mouse rimane, per un tempo stabilito, fermo sopra un'icona o pulsante. Quindi ritornando alla nostra interfaccia grafica, il click verrà effettuato quando il puntatore del mouse rimarrà fermo sopra un pulsante Comando.

Attualmente il progetto è in fase embrionale, bisogna ancora migliorare le funzionalità del software su pc che deve permettere anche la gestione diretta dei pin digitali della board Arduino.
Anche la gestione dei segnali ir, che attualmente vengono gestiti dalla libreria IRremote, può essere migliorata creando un sistema di acquisizione diretta dei segnali in modo da permettere la gestione di ogni tipo di telecomando, visto che nel prototipo vengono gestite solo le codifiche NEC, SONY RC5 e RC6

Aggiornamenti futuri sul prototipo su www.logicaprogrammabile.it

4 Comments

  1. alexxandro.p 7 maggio 2013
  2. Piero Boccadoro Piero Boccadoro 8 maggio 2013
  3. Emanuele 30 aprile 2012
  4. LoryD 30 aprile 2012

Leave a Reply