Forum: Mikrocontroller und Digitale Elektronik IR Signal decodierung


von David K. (davider)


Angehängte Dateien:

Lesenswert?

Hallo,

ich bin aktuell dabei für ein Projekt einen IR-Reciever an meinem "TI 
F28379D Launchpad" einzubinden.
Ich habe hierzu das Signal mit meinem Oszilloskop ausgelesen und konnte 
die verschiedenen Tasten den Verläufen zuordnen, also quasi auf dem 
Papier decodieren (siehe Anhang).
Woran ich nun scheitere ist an der Implementierung in meinen Code. Ich 
habe 2 Ansätze: Einen Externen Interrupt verwenden oder das 
"eCAP-Modul".


Ansatz 1:
-> ISR im Anhang
Bei steigender Flanke soll ein Interrupt gesetzt werden und über 
verschiedene delays wird ermittelt, ob es sich um das Startsignal oder 
die Bits handelt.
Die ISR wird ausgeführt und in meiner "zahl" wird etwas geschrieben, 
jedoch nicht das Richtige ^^...
Ich vermute, dass durch die Delays einige Flanken übersehen werden, da 
"anzahl_bits" nicht bis auf 0 runterzählt, sondern bei ~16 aufhört.
Die Zeiten für meine Verzögerungen hab ich mir aus dem Signalmuster 
überlegt (siehe Anhang).

Weiß jemand, ob das grundsätzlich so funktionieren kann oder gibt es da 
einen viel "einfacheren" Weg?

Ansatz 2:
Ich bin mir nicht sicher wie üblich ein eCAP-Modul ist oder ob das etwas 
TI exklusives ist, bzw. ob hier damit jemand Erfahrung hat. Gedacht ist 
es für die Zeitmessung zwischen Flanken. Bei der Registerkonfigurierung 
bin ich mir jedoch unschlüssig. Lässt sich das eCap auch nur mit CAP1 
und CAP2 im  "continuous-capture mode" verwenden oder muss ich CAP3 & 4 
auch immer mit einbeziehen?

Schon einmal vielen Dank für eure Antworten! Bitte seit nachsichtig, ich 
bin ein relativer Neuling ;-)

LG David

von Joachim B. (jar)


Lesenswert?

David K. schrieb:
> Bitte seit nachsichtig, ich
> bin ein relativer Neuling ;-)

schon IRMP gefunden und gelesen?
https://www.mikrocontroller.net/articles/IRMP
Beitrag "IRMP - Infrared Multi Protocol Decoder"

: Bearbeitet durch User
von David K. (davider)


Lesenswert?

Joachim B. schrieb:

> schon IRMP gefunden und gelesen?
> https://www.mikrocontroller.net/articles/IRMP
> 
Beitrag "IRMP - Infrared Multi Protocol Decoder"

Nein, noch nicht. Danke für den Link! :)
Ich schau gleich mal rein.

von W.S. (Gast)


Lesenswert?

David K. schrieb:
> Ansatz 1:...

Eigentlich ist das recht einfach: Lasse auf jede Flanke einen Interrupt 
erzeugen. Zusätzlich brauchst du einen Timer, den du im Interrupthandler 
mit jeder Flanke ausliest, den Wert merkst und ihn dann wieder startest. 
Je nachdem, wie dein IR-Code gestaltet ist, müßtest du nun eine der 
beiden Flanken ignorieren oder auch nicht. Jedenfalls vergleichst du die 
ausgelesene Zeit vom Timer mit einem Wert, der sauber zwischen beiden 
Informations-Längen liegt, bei deinem Beispiel also die High-Zeit 
zwischen 0.6 ms und 1.7 ms, macht als vergleichswert so etwa 1.1 ms. 
Alles was darunter ist, ergibt ne 0 und was darüber ist ergibt ne 1. 
Dieses Bit schiebst du nun in eine ausreichend breite Variable hinein.

Der Timer sollte so eingerichtet sein, daß er den länsten Zeitabschnitt 
(hier etwa 9 ms) noch problemlos zählen kann. Dann bedeutet nämlich 
dessen Überlauf, daß die ganze IR-Sendung erledigt ist. Dann kannst du 
das zuvor in deine o.g. Variable geschobene IR-Kommando hernehmen und 
auswerten.

Sowas ist als Assembler- oder C-Quelle ziemlich kurz, das sollte für 
dich keinerlei Problem sein. Sowas wie IRMP ist hingegen ziemlich 
umfänglich, weil es eben eine Riesenmenge an verschiedenen 
IR-Protokollen abdecken soll.

W.S.

von Axel S. (a-za-z0-9)


Lesenswert?

David K. schrieb:
> Joachim B. schrieb:
>
>> schon IRMP gefunden und gelesen?
>> https://www.mikrocontroller.net/articles/IRMP
>>
> 
Beitrag "IRMP - Infrared Multi Protocol Decoder"
>
> Nein, noch nicht. Danke für den Link! :)
> Ich schau gleich mal rein.

Was du da hast, sieht schwer nach dem NEC Protokoll aus.

von Jacko (Gast)


Lesenswert?

Was du da erfasst hast ist NEC-Code.

* Startsequenz: 9,0 ms On 4,5 ms Off
* Bit = 0:  0,6 ms On 0,6 ms Off
* Bit = 1:  0,6 ms On 1,6 ms Off
* Abschluss: 0,6 ms On und > 10 ms Off
* Reihenfolge: LSB first.
* 16 Bit Adresse : 8 Bit Adresse und 8 Bit Adresse invertiert
  (Oder:  8 Bit Adresse-Hi + 8 Bit Adresse-Lo)
* 16 Bit Kommando: 8 Bit Kommando und 8 Bit Kommando invertiert

Was das "eCAP-Modul" liefert, weiß ich nicht.

Ansonsten - wenn du es selber machen willst, mein Ansatz:

- Ein freilaufender Zähler mit passender Frequenz.
- Ein Speicherfeld von passender Länge.

- Jede Flanke löst einen Interrupt aus!

- Negative Flanke: Zählerstand an folgender gerader Stelle des
  Speicherfelds notieren. Zähler = Null
- Positive Flanke: Zählerstand an der folgenden ungeraden Stelle des
  Speicherfelds notieren. Zähler = Null

- Time-Out bei langer Pause (Überlauf des freilaufenden Zählers):
  Auswertung der empfangenen Sequenz.
  Adressierung des Speicherfelds = Null.

Wenn du es noch genauer machen willst, wertest du das Signal
einer Fotodiode (Sender in 5...20 cm Entfernung) aus.
Damit hast du gleich die Modulationsfrequenz - musst aber nicht
mehr ON-OFF, sondern PULSGRUPPE-PAUSE auseinanderhalten.
Lässt sich aber auch ohne Hexenwerk machen.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Axel S. schrieb:
> Was du da hast, sieht schwer nach dem NEC Protokoll aus.

Ja, ist NEC, kann ich bestätigen. Und IRMP wird das ebenso sehen ;-)

von David K. (davider)


Angehängte Dateien:

Lesenswert?

Danke für eure ganzen Antworten!

Ich finde die Idee mit dem Timer & Interrupts ganz gut, das werde ich 
heute probieren. Im Prinzip entspricht die Vorgehensweise dem Aufbau des 
"eCAP-Moduls", bloß dass es hier eben wieder eigene Register gibt die 
man einstellen kann/muss.

Bezüglich NEC:
Das habe ich mir beim durchlesen des IRMP-Beitrags auch gedacht. Nur bei 
der Geschichte mit dem MSB/LSB bin ich mir noch unsicher. So wie ich es 
aktuell ausgelesen & verstanden habe, kommt bei mir das MSB zuerst (?):
Zur Zuordnung (siehe Bilder) habe ich mir den Beispielcode meines 
Arduinos genommen und mir die Taste "1" herausgesucht. Laut dem Code 
entspricht die "1" = 0xFF30CF (bzw. 0x00FF30CF).
Danach habe ich mir das Signal der Taste 1 am Oszilloskop angesehen. 
Zuerst kommt 8x0 und 8x1 (bei jeder Taste), danach das sich verändernde 
Bitmuster.
Somit käme doch das MSB zuerst?

LG David

von Frank M. (ukw) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

David K. schrieb:
> Somit käme doch das MSB zuerst?

NEC ist definitiv LSB First. Aber es gibt natürlich Decoder, die das 
andersherum sehen: Sie interpretieren das Signal als MSB First. Dann 
kommt natürlich ein anderer Code raus. So wird das bei Arduino wohl 
sein. Viele Decoder interpretieren grundsätzlich alles mit MSB first - 
ohne dass sich die Programmierer dabei irgendwas gedacht haben. Kann man 
machen, die Codes bleiben ja eindeutig - egal ob man sie "vorwärts" oder 
"rückwärts" liest.

Es aber zig NEC-kompatible Fernbedienungen, bei denen man sehr gut 
erkennt, dass NEC LSB first benutzt, nämlich wenn man die Nummerntasten 
1...9 drückt. Diese ergeben aufeinanderfolgende Codes wie 0x11... 0x19, 
wenn man die Bitfolge als LSB first liest. Andersherum nicht.

Das ist aber nicht bei allen NEC-FBs so, manche verwenden Codes, welche 
die Matrix der FB-Tastatur wiederspiegeln. Aber auch hier zeigen die 
Codes nur sinnvolle Werte, welche auf die Matrix schließen lassen, wenn 
man sie LSB first interpretiert.

EDIT:

Das kann man auch alles nochmal hier nachlesen:

https://www.sbprojects.net/knowledge/ir/nec.php

: Bearbeitet durch Moderator
von David K. (davider)


Angehängte Dateien:

Lesenswert?

Kleines Update, falls jemand mal über den Thread stolpert:

Ich habe es jetzt mit dem "eCAP"-Modul realisiert. Falls jemand einen 
TI-Controller verwendet der das unterstützt, hilft der Auszug im Anhang 
vielleicht. Angehängt sind die Registerkonfiguration sowie die ISR.

Wie bereits kurz erwähnt ist das Modul quasi ein 32bit-Timer + 
Flankenabhängigen Interrupts. In CAP 1 & 2 werden jeweils die 
Zeitstempel gespeichert. Sobald CAP2 (fallende Flanke) getriggert wird 
löst die ISR aus, die beiden Werte werden von einander abgezogen und 
anhand des Ergebnisses zugeordnet ob es sich um das Startbit, 0 oder 1 
handelt.
Ich habe das Signal als MSB first eingelesen! Also abweichend vom 
NEC-Protokoll! Hat besser zu den Informationen gepasst die ich bereits 
zur Fernbedienung hatte.

Die ganze Geschichte sollte sich auf die selbe Weise mit einem ext. 
Interrupt und einem Timer bzw. der IRMP realisieren lassen (wie weiter 
oben beschrieben).

Danke für die ganzen Beiträge! ;)

LG David

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.