Dit artikel is beschikbaar in: English Castellano Deutsch Francais Italiano Nederlands Turkce |
door Over de auteur: Ismael Ripoll, afgestudeerd aan de Polytechnische Universiteit van Valencia in 1996. Professor in operating systemen aan de afdeling DISCA. Onderzoeksgebieden omvatten onder andere real- time scheduling en operating systemen. Linux gebruiker vanaf 1994. Hobby's: Trektochten door de Pyreneeën, skiën en hobby-electronica. Elisa Acosta is een computer ingenieur aan de polytechnische school van Valencia. Op dit moment werkt ze voor Indra (een communicatiebedrijf) aan jaar-1900 problemen :-) Dit artikel is gebaseerd op het werk van Elisa Acosta tijdens haar afstudeeropdracht.
|
Kort:
Met behulp van een eenvoudige elektrische schakeling kunnen we RT-Linux opdrachten geven via een infrarode afstandsbediening.
Er was een project met de naam "lirc" (Linux Infra-red Remote Control) gestart door Ralph J.K. Metzler (http://fsinfo.cs.uni-sb.de/~columbus/lirc/) waarbij een infrarode ontvanger werd ontwikkeld met gebruikmaking van de standaard Linux hulpmiddelen. Met "standaard" wordt bedoeld dat het geen gebruik maakte van de RT-Linux real time uitbreidingen. In dit artikel starten we met hetzelfde onderwerp maar gaan we in op oplossingen met behulp van RT-Linux.
De ISU1U60 infrarood ontvanger is een elektronisch wonder; met een 3-pins connector (twee voor voeding en één voor aarde) is het in staat om praktisch alle ontvangst- en conversie werk te doen, waarbij een TTL-signaal wordt aangeboden op de seriële aansluitpin.
Toevallig is de parallelle poort (en ook de seriële poort) te gebruiken als algemene invoer en uitvoer poort. Een hoop randapparaten gebruiken dit om met de PC te communiceren zoals bijvoorbeeld een Iomega ZIP drive.
We zullen de parallelle poort gebruiken voor het ontvangen van de gegevens van de infrarood ontvanger. We hebben hierbij slechts één pin nodig van deze poort omdat de ontvanger ook slechts één data-pin heeft.
Het signaal van de afstandsbediening is heel complex omdat het diverse coderingen en modulaties combineert. Laten we dit signaal eens nader bekijken.
Het medium voor het signaal van de afstandsbediening zijn de lichtgolven in het infrarood spectrum. Dit soort licht is volkomen onschadelijk, in tegenstelling tot ultraviolet licht. Infrarood is niet zichtbaar voor het menselijk oog maar wel voor elektronische halfgeleiders. Infrarode lichtbronnen zijn onder andere: de zon, gloeilampen, LED-diodes enz. Een infrarode LED wordt door de afstandsbediening gebruikt voor het uitzenden van het signaal.
Infra-red light | Visible | ultraviolet light |
Een op die manier geconstrueerde detector is in staat om alle infrarood te detecteren, ongeacht de bron van het licht. Ontwerpers van afstandsbedieningen moesten een codering aan het licht toevoegen om het zo te kunnen onderscheiden van andere lichtbronnen. Het uitgezonden signaal van een afstandsbediening wordt gemoduleerd met frequenties tussen de 32 en 40 KHz, afhankelijk van fabrikant en type. Laten we even aannemen dat de frequentie 38 KHz is omdat dit de meest gebruikte is. Meer als 90% van de apparaten gebruiken deze frequentie of iets wat er veel op lijkt.
De infrarood ontvanger. |
Het gemoduleerde infrarode licht op 38 KHz is het communicatiemedium wat wordt gebruikt tussen de zender (afstandsbediening) en ontvanger (TV, video enz.). Nu moeten we nog bepalen hoe de informatie wordt verzonden oftewel, welke bits komen overeen met welke ingedrukte toets op de afstandsbediening.
De codering van die informatie is afhankelijk van de fabrikant maar gelukkig hoeven we dat in dit project niet te weten, we hoeven de coderingen alleen maar te vergelijken.
Afgaand op de modulatie van het signaal mag het duidelijk zijn dat de informatie serieel wordt verzonden. Bit voor bit en dus hebben we slechts één stroom data aan de ontvangende kant.
De volgende informatie is afkomstig van de technische specificaties van sensor IS1U60 (http://ns14.sharp.co.jp/ecg/unit/is1u60/is1u60-fea.html) en geeft de interne structuur weer. De twee linkerpijlen geven het ontvangen infrarode licht weer wat om wordt gezet in een elektrische stroom via de LED. Het signaal wordt versterkt en het directe signaalgedeelte wordt geëlimineerd, het wordt gefilterd om alleen frequenties vlakbij de 38 KHz door te laten en vervolgens wordt het gecorrigeerd (demodulator plus integrator), en tenslotte wordt het omgezet naar een TTL-signaal.
Op dit moment zijn er op zijn minst twee variaties (ECP, EPP) om de parallelle poort om te toveren tot een algemeen bruikbare communicatiepoort. Ons project heeft slechts bescheiden functionele eisen voor het gebruik van de parallelle poort, daarom zal iedere versie voldoen. Feitelijk hebben we maar één IN datastroom nodig.
Detailering statusregister |
Schrijven in het stuurregister programmeert de poort. Van de 8 bits in het register wordt alleen bit 4 gebruikt. Een "1" in dit bit laat de hardware van de poort een interrupt genereren (meestal nummer 7) indien de ACK datastroom veranderd van hoge spanning (5 volt) naar lage spanning (0 volt).
Het dataregister is de deur die openstaat naar de pinnen van de connector. Data die naar deze poort wordt geschreven verschijnt op pin 2 tot en met 9 van de parallelle connector. Dit is alleen een OUT poort. Omdat we alleen gedetecteerd infrarood moeten aflezen is deze poort niet bruikbaar voor ons. We hebben een invoerpoort nodig. De statuspoort geeft de status van de printer weer. Deze draden worden door de printer aangestuurd (of door een extern apparaat) en de computer leest dit af. Dit zijn dus IN draden. Ook al is het een 8-bit register, alleen de 5 hoogste bits hiervan worden aangesloten en gebruikt, de rest staat altijd op nul. De draden zijn vernoemd naar de functionaliteit die ze hebben wanneer een printer is aangesloten maar feitelijk zijn het gewone digitale draden die je voor van alles kan gebruiken.
Van deze draden is vooral die op pin 10 interessant (bit 6 van het register), omdat het gebruikt wordt als een digitale invoerlijn. Maar hij kan ook worden gebruikt voor het geven van interrupts als de spanning op de lijn wijzigt (van 5 naar 0), zoals boven vermeld.
Schema van chip en verbindingen |
De infrarode ontvanger heeft tussen de 4,7 en 5,3 volt aan spanning nodig. Als de spanning beneden de 4,7 valt dan stopt de ontvanger met functioneren. Deze voeding kan op verschillende manieren worden verkregen:
Verbinden aan de parallelle poort is een kwestie van het aansluiten van ontvanger pin 1 aan poort pin 10 en ontvanger pin 2 aan poort pin 18. Merk op dat de pin GND (ground) op twee plaatsen moet worden aangesloten, de aarde van de voeding en de aarde van de poort.
Voor het maken van deze verbindingen kun je willekeurige kabel gebruiken.
REAL-TIME module |
---|
#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); } |
Het is belangrijk om een precieze meting te krijgen van het signaal van de ontvanger. Sterker nog, het is dé reden voor het inzetten van een real-time systeem. Het interpreteren van de rij metingen die van de real-time taak af komen om te ontdekken welke toets er is ingedrukt is niet tijdsafhankelijk en kan dus worden gedaan door een normaal Linux proces.
Een andere mogelijkheid om metingen te verrichten is het installeren van een interrupt afhandelprogramma voor interrupt 7. Je hebt dan de periodieke taak niet nodig en ook geen nieuwe schedule.
De functie init_module
start de taak. Je hoeft alleen de communicatie-FIFO voor de taak te creëren, de taak zelf en tenslotte deze omzetten naar een periodieke taak. De waarde van de periode (100 RT-tikken is ongeveer 90 micro seconden) is voor testen en foutafhandeling. Hoe korter de periode, des te preciezer de meting maar dit zal meer CPU-tijd verbruiken.
Het volgende programmaatje stuurt de waarden die het afleest van apparaat /dev/rtf0 door naar de standaard uitvoer. Met dit eenvoudige programma kunnen we "zien" wat voor frame er wordt verstuurd van de infrarode zender als een toets wordt ingedrukt.
Programma |
---|
#include #include #include #include #include int main(){ int fd; unsigned long cont; fd=open("/dev/rtf0",O_RDONLY); while(1) { read(fd,&cont,sizeof(cont)); if ( cont > 700) printf("\n"); printf("%d ",cont); fflush(stdout); } return 0; } |
Hoewel de meeste afstandbedieningen een zelfde infrarood signaal gebruiken, hoeft dat zeker niet zo te zijn voor de codering van de toetsen. Het herkennen van toetsen is echter een kwestie van vormanalyse en geen real-time probleem. De beste manier om een programma te maken die concrete commando's herkend is het bekijken van de uitvoer van dit programma om een idee te krijgen hoe de afstandsbediening zijn data verstuurt.
Simpel gesteld, als een toets op de afstandsbediening wordt ingedrukt zal een bepaalde sequentie worden uitgezonden die we op het scherm als een rij nummers zien. Als we de toets ingedrukt houden zal dezelfde sequentie periodiek worden verstuurd (SONY afstandsbedieningen vormen hierop een uitzondering).
Laten we dit eens bekijken (vergeet niet de real-time modules te installeren: FIFO en scheduler):
# 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 11We kunnen zien dat de toets steeds dezelfde sequentie herhaalt als hij ingedrukt blijft. Een ander interessant detail is de meetfout. De getallen van de verschillende frames hebben een variatie van 1, dit is de kwantificatiefout.
Voor het programmeren van herkenningssoftware hoef je alleen een array aan te houden met daarin ieder frame wat door de afstandsbediening kan worden uitgezonden. Wanneer nu een frame is ontvangen kan deze worden vergeleken met de waarden in de array (een verschil van +/- 1 is acceptabel). Dit programma mag de lezer als oefening zelf schrijven.
Sommige afstandsbedieningen zenden steeds een ander frame uit wanneer een toets in wordt gedrukt, zelfs als we steeds dezelfde indrukken. Ze doen dit als volgt: als we een toets indrukken zendt het apparaat een frame die we "frameA" zullen noemen. Als we hem loslaten en wederom indrukken wordt "frameB" uitgezonden. De volgende toetsindruk zend weer frameA enzovoorts. Als we de toets ingedrukt houden zal hetzelfde frame meerdere keren worden verstuurd. Op deze manier kan de ontvanger onderscheidt maken tussen een lange toetsindruk en twee korte. Hoe denk je dat de volgorde 1 1 (elf) wordt gemaakt op nieuwe afstandsbedieningen?
|
Site onderhouden door het LinuxFocus editors team © Ismael Ripoll & Elisa Acosta, FDL LinuxFocus.org Klik hier om een fout te melden of commentaar te geven |
Vertaling info:
|
2001-05-22, generated by lfparser version 2.8