di Ismael Ripoll & Elisa Acosta Notizie sull'autore: Ismael Ripoll, Ph.D. al Politecnico dell'Università di Valencia nel 1996. Docente di sistemi operativi al Dipartimento di DISCA. Gli interessi di ricerca includono lo scheduling in tempo reale e i sistemi operativi. Utente Linux dal 1994. Hobby: Trekking nei Pirenei, sci, ed elettronica domestica. Elisa Acosta è un Ingegnere Informatico della Scuola del Politecnico di Valencia. Al momento lavora per Indra (una azienda di comunicazioni) sui problemi dell'anno 1900 :-) Questo articolo si basa sul lavoro di tesi di Elisa Acosta. Contenuto: |
Sommario:
Usando un semplice circuito eletrico, possiamo far si che RT-Linux riceva ordini da un telecomando ad infrarossi.
Per capire questo articolo non sono necessarie conoscenze di elettronica e di hardware, anche se si parlerà di un piccolo componente hardware usato per il telecomando ad infrarossi.
Grazie ad un progetto, chiamato "lirc" (Linux Infra-red Remote Control) è stato avviato da Ralph J. K. Metzler (http://fsinfo.cs.uni-sb.de/~columbus/lirc/), è stato sviluppato un driver per un ricevitore ad infrarossi che usa i servizi "normali" di Linux. Con "normali" si intende che non faceva uso delle estensioni per il tempo reale di RT-Linux. In questo articolo iniziamo con lo stesso argomento, ma ricerchiamo soluzioni basate su RT-Linux.
Nella prima parte del nostro progetto vedremo l'hardware necessario per connettere il ricevitore ad infrarossi al computer. Nella seconda parte vedremo come sia possibile interpretare i segnali dal ricevitore ad infrarossi usando Real-Time Linux. Ci occorre solo un minimo di hardware: un ricevitore ad infrarossi Sharp (IS1U60) e alcuni cavi e connettori.
Il ricevitore ad infrarossi IS1U60 è una meraviglia dell'elettronica: posto in un contenitore a tre piedini (due per l'alimentazione e uno per la terra) è in grado di fare quasi tutto il lavoro di ricezione e conversione, fornendo un signale seriale TTL sul terzo piedino.
I PC hanno un mucchio di connettori nei quali inserire ogni sorta di periferica digitale (modem, stampanti, SCSI, tastiere, monitor, ecc.), ma niente che ci permetta di collegarci a semplici dispositivi elettronici. In altre parole, un PC standard non ha una scheda di acquisizione dati. Una scheda mediante la quale saremmo in grado di leggere il voltaggio di una specifica linea.
Per fortuna, la porta parallela (così come la porta seriale) può essere usata come porta generica di ingresso/uscita. Molte periferiche usano questa caratteristica per comunicare col PC, come ad esempio il drive Iomega ZIP.
Useremo la porta parallela per ricevere dati dal ricevitore ad infrarossi. Ci servirà un solo piedino della porta parallela, in quanto il ricevitore ad infrarossi ha un singolo piedino per i dati.
Come già detto, il ricevitore ad infrarossi IS1U60 è un ricevitore specificamente progettato per costruire ricevitorei per applicazioni domestiche.
Il segnale del telecomando è veramente complesso, in quanto vengono combinate diversi tipi di codifica e di modulazione. Osserviamo questo segnale.
Il supporto fisico che trasporta il segnale del telecomando è un'onda luminosa nello spettro dell'infrarosso. Questo tipo di luce è assolutamente innocua, a differenza della luce ultravioletta. La luce infrarossa è invisibile all'occhio umano ma non ai dispositivi a semiconduttori. Le sorgenti di luce infrarossa sono: il sole, i bulbi a incandescenza, i diodi LED, ecc. Nei telecomandi, per emettere il segnale viene usato un LED ad infrarosso.
Luce infrarossa | Luce visibile | Luce ultravioletta |
|
Ogni dispositivo a semiconduttori e sensibile alla luce (di qualsiasi colore/frequenza). La maggior parte dei semiconduttori viene quindi posta in contenitori di plastica nera per proteggerla dalla luce. Un sensore ad infrarossi è costituito sostanzialmente da un diodo semiconduttore, con del vetro nella parte superiore per consentire alla luce infrarossa di entrarvi.
Un sensore ad infrarossi così fatto sarà in grado di individuare la luce infrarossa, qualsiasi sia la sorgente che la genera. I progettisti di telecomandi hanno dovuto aggiungere una particolare codifica alla luce emessa dai telecomandi per renderla distinguibile dal resto delle sorgenti luminose. Il segnale emesso da un telecomando viene modulato a frequenze tra 32 e 40 KHz, a secondo della marca e del modello. Assumiamo che la frequenza del telecomando sia di 38KHz, che è il valore più comune. Più del 90% dei dispositivi usano questa frequenza o una molto vicina.
Il ricevitore ad infrarossi. |
Occorre ricordare che ogni cosa che viene fatta per emettere il segnale dovrà essere rimossa durante la ricezione. Se emettiamo una luce infrarossa, ci occorre riceverla; se questo segnale viene modulato con una portante di 38KHz, allora questa portante dovrà essere eliminata (filtrata). La demodulazione è fatta in modo analogico con un singolo filtro passa banda (per eliminare ogni frequenza distante da quella di emissione) e un filtro rettificatore/integrale.
La luce infrarossa modulata a 38KHz è supporto di comunicazione usato tra l'emettitore (il telecomando) e il ricevitore (TV, video, ecc.). A questo punto occorre determinare come viene trasmessa l'informazione, che è come dire, quali bit identificano il tasto premuto sul telecomando.
La codifica dell'informazione dipende dal modello; fortunatamente, in questo progetto non ci interessa conoscere questi metodi ma solo confrontarli
Considerando la modulazione del segnale è ovvio che l'informazione viene trasmessa in serie. Un bit dopo l'altro e allo stesso modo ci occorre soltanto un flusso di dati dal lato del ricevitore.
La seguente proviene dalle specifiche tecniche del sensore IS1U60 (http://ns14.sharp.co.jp/ecg/unit/is1u60/is1u60-fea.html), e presenta la struttura interna. Le due frecce a sinistra rappresentano la luce infrarossa convertita in un segnale elettrico tramite il led. Il segnale viene amplificato, vengono eliminate le componenti dirette, viene filtrato per far passare le frequenze vicine a 38KHz, quindi viene corretto (demodulatore+integratore), e infine viene convertito in un segnale TTL compatibile.
La porta parallela è progettata per comunicare con stampanti, ma nel tempo, e per via del fatto che non c'era niente di simile disponibile sui PC, venne usata per connettere tutti i tipi di periferiche.
Al momento, ci sono almento due versioni (ECP, EPP) per trasformare la porta parallela in una vera porta di comunicazioni generica. Il nostro progetto è piuttosto modesto per quel che riguarda le funzioni richieste dalla porta parallela, quindi ogni versione andrà bene. Più precisamente, ci occorre solo un flusso di ingresso.
Dettaglio del registro di stato |
Il PC controlla la porta parallela con tre registri di 8 bit. Ci sono un registro dati (0x378), un registro di stato (0x379) e uno di controllo (0x37A). I valori tra parentesi rappresentano i soliti indirizzi dei registri della prima porta parallela.
Scrivendo nel registro di controllo possiamo comandare la porta. >Degli 8 bit del registro viene usato solo il bit 4.. Scrivendo un "1" in questo bit si comanda all'hardware della porta di generare in'interruzione (di solito la n. 7) quando si individua una transizione di stato della linea ACK che va dal livello alto (5 volt) al livello basso (0 volt).
Il registro dati è una porta aperta verso i piedini del connettore. Ogni dato che scriviamo in questa porta apparirà nei piedini dal 2 al 9 del connettore parallelo. Questa porta è solo di uscita, in quanto non possiamo conoscere il valoree ("0" o "1") dei piedini del connettore leggendo la porta. Dovendo noi leggere i valori forniti dal ricevitore ad infrarossi, questa porta per noi è inutile.
La porta di stato ci informa sullo stato delle linee di controllo della stampante. >Da queste linee la stampante è in grado di informare il computer del proprio stato. Queste linee gestiscono la stampante (o un dispositivo esterno) e il computer le legge; pertanto queste sono linee di ingresso. Anche se si tratta di un registro ad 8 bit, solo i 5 bit più significativi sono collegati a delle linee, gli altri tre bit sono sempre a zero. I numeri delle linee sono denominati in accordo alla funzionalità che hanno nella comunicazione con una stampante, ma queste linee sono a tutti gli effetti linee digitali generiche che possono essere usate per quasi ogni cosa.
Tra queste 5 linee, la più interessante il piedino 10 (bit 6 del registro), in quanto è usato come linea di ingresso digitale, ma può anche generare interruzioni quando lo stato della linea cambia (da 5V a 0V), come detto prima.
Descrizione fisica del chip e collegamento |
Al ricevitore ad infrarossi occorrono tra 4,7 e 5,3 volt. Se il voltaggio va al di sotto di 4,7 il ricevitore smette di funzionare. Questa tensione di alimentazione può essere ottenuta in modi diversi:
usando batterie. In questo caso è meglio usare una batteria da 4,5V in serie con una da 1,5V. Il voltaggio effettivo non sarà 6V ma 5,5V.
Usando un alimentatore (dispositivo che converte corrente alternata in corrente continua di basso voltaggio). Anche se è semplice da costruire, va oltre gli scopi di questo articolo.
Prendendo i 5 volt dal computer. In un computer, ci sono due tipi di cavi: cavi piatti (che portano dati) e cavi spessi di colore rosso, giallo e nero per l'alimentazione. Il cavo rosso è quello dei +5V e quello nero è la terra o 0V.
Per alimentare il ricevitore, collegheremo il cavo nero al piedino 2 del ricevitore e quello rosso (5V) al piedino 3.
La connessione alla porta parallela è semplice: basta connettere il piedino 1 del ricevitore al piedino 10 della porta e il piedino 2 del ricevitore al piedino 18 della porta parallela. Si noti che il piedino GND (terra) deve essere connesso in due posti: terra dell'alimentatore e terra della porta parallela.
Per fare queste connessioni si può usare qualsiasi tipo di cavo.
modulo REAL-TIME |
---|
#define PERIOD 100 #define SIZE 8192 #define FIFO_ZERO 0 #define LP0 0x378 /*Address /dev/lp0*/ #define STS LP0+1 RT_TASK task; //---------- Real time task void Real_Time_Task(){ unsigned short data1, data2=0; unsigned long cont = 0L; while(1){ // Read the port value data1=inb(STS) & 0x40; // If no change.. if ( data2 == data1) { // Increment the counter. cont++; } else { // Send the counter value. rtf_put(FIFO_ZERO, (char *) &cont, sizeof(cont)); cont = 0L; data2 = data1; } rt_task_wait(); } } //------------- Main program int init_module(){ RTIME now = rt_get_time(); // Create communication FIFO with Linux. rtf_create(FIFO_ZERO,SIZE); // Create the real time task. rt_task_init(&task,Real_Time_Task,1,3000,4); // Make it periodic. rt_task_make_periodic(&task,now+3000,PERIOD); return 0; // Everything worked. } //------------- To unload the module void cleanup_module(){ rt_task_delete(&task); rtf_destroy(FIFO_ZERO); } |
Il modo più semplice di misurare lo stato dell piedino ACK della porta parallela è creare un processo periodico che legge il bit di stato. Se individua un cambiamento mentre il piedino mantiene lo stesso stato, viene incrementato il contatore. In questo modo gli scatti del contatore rappresentano il tempo durante il quale il bit è rimasto allo stesso livello. Se si individua un cambiamento del valore, si manda il valore del contatore ad un normale processo di Linux tramite una FIFO. Un processo di Linux deve rimanere in attesa per leggere la FIFO. I valori letti sono equivalenti al tempo che il segnale è rimasto al livello basso e poi al livello alto.
E' fondamentale prendere misure accurate del segnale dato dal ricevitore, e questo è di fatto l'unico motivo per usare un sistema in tempo reale. L'interpretazione della sequenza di valori dati dal processo in tempo reale per individuare il tasto premuto non ha vincoli di tempo e può essere gestito con un normale processo di Linux.
Un altro modo di misurare i cambiamenti nel piedino di ACK è installare un gestore di interruzioni sull'interruzione 7. Con questa soluzione non occorre usare un pianificatore o un processo periodico.
La funzione init_module lancia il processo. Occorre solo: creare la FIFO di comunicazione per il processo, creare il processo stesso e infine convertirlo in uno periodico. Il valore del periodo (100 RT-Ticks, corrispondenti circa a 90 micro secondi) viene usato per le prove e per la gestione degli errori. Più è breve il periodo, più è alta la risoluzione delle misure, ma un ciclo troppo stretto con brevi periodi impegna maggiormente la CPU.
Il seguente programma manda allo standard output quello che legge dal device /dev/rtf0. Con questo semplice programma, possiamo "vedere" il formato di ogni sequenza inviata dall'emettitore di infrarossi quando viene premuto un tasto.
Programma utente |
---|
#include |
Il valore 700 che compare nel programma è un valore stimato e rappresenta il valore minimo di tempo tra due sequenze consecutive.
Sebbene la maggior parte dei telecomandi usi un segnale infrarosso simile, la codifica dei tasti può essere diversa. Riconoscere il tasto premuto è un problema di "riconoscimento di formato" e non uno di "tempo reale". Il miglior modo di far si che un programma riconosca un comando reale è osservare l'uscita di questo programma e farsi un'idea di come il nostro telecomando emetta i dati.
In parole povere, possiamo dire che quando viene premuto un tasto sul telecomando, questo manda una sequenza caratteristica che vediamo sullo schermo come sequenza di numeri. Se teniamo premuto il tasto, il telecomando invierà la stessa sequenza periodicamente (i telecomadi della SONY fanno eccezione).
Osserviamolo (ricordate di installare i necessari moduli del tempo reale: FIFO e planifier):
# modprobe rt_fifo_new # modprobe rt_prio_sched # insmod ir # ir_get 0 126509 13 6 23 7 13 7 12 7 12 7 12 7 12 8 11 8 11 8 11 8 11 8 11 19 11 1081 13 6 23 7 12 7 12 8 11 8 11 8 11 8 12 7 12 8 11 8 11 8 11 19 11 1080 14 6 23 7 12 7 12 7 12 7 12 8 11 8 11 8 11 9 11 7 12 8 11 19 11 1080 13 6 24 6 13 7 12 7 12 7 12 7 12 7 12 8 11 8 11 8 11 8 11 19 11
Possiamo notare che questo comando ripete la stessa sequenza quando viene premuto il tasto. L'altra cosa da notare sono gli errori di misura. Le figure delle diverse sequenze hanno solo una variazione di 1, che rappresenta l'errore di quantizzazione.
Per programmare un software di riconoscimento, occorre solo tenere in un array ogni sequenza inviata dal telecomando, e quindi, quando arriva una nuova sequenza, confrontarla (con uno scarto di ±1) con quelle tenute nell'array di sequenze. Questo programma viene lasciato come esercizio al lettore.
Alcuni telecomandi emettono una sequenza distinta ogni volta che viene premuto un tasto, anche se viene premuto sempre lo stesso. Ecco cosa fanno: quando si preme un tasto, mandano una sequenza che chiamiamo "SeqA"; se lo si rilascia e lo si preme di nuovo, emettono "SeqB"; alla successiva pressione emettono di nuovo "SeqA" e così via. Se si mantiene premuto il tasto, la sequenza viene emessa diverse volte. In questo modo, il ricevitore può vedere la differenza tra una pressione lunga e due pressioni successive. Come pensavate che venisse gestita sui nuovi telecomandi la selezione di 1 1 (undici)?
|
Pagine web mantenute dal Team degli Editori di LinuxFocus
© Ismael Ripoll & Elisa Acosta LinuxFocus.org 2000 Clicca qui per segnalare un errore o per inviare un commento a Linuxfocus |
Informazioni sulla traduzione:
|
2000-04-28, generated by lfparser version 1.5