Forum: Mikrocontroller und Digitale Elektronik IRMP mit ESP8266


von Wolfgang S. (ws01)


Angehängte Dateien:

Lesenswert?

Vor ein paar Wochen hatte ich ein Olimex ESP8266-EVB bestellt und bin am 
Wochenende endlich mal tatsächlich dazu gekommen, damit herumzuspielen. 
Als erste Fingerübung habe ich IRMP darauf zum Laufen gebracht. Siehe 
die beiden Anlagen. 1.patch sind die Diffs zu der aktuellen SVN-Version 
von IRMP, user_main.c ist das Hauptprogramm.

Ein Gag am Rande: die sich im Beispieloutput als SAMSG32 meldende 
Fernbedienung taucht in der kürzlichen Umfrage nicht auf. Das liegt 
daran, daß die mit "LG" beschriftete Fernbedienung eines Blu-Ray-Players 
normalerweise zwar in dieser Zunge spricht, aber auf NECisch umschaltet, 
wenn man einen rechts oben mit "TV" beschrifteten Block benutzt.

Noch schlimmer ist eine originale Philips-Fernbedienung einer alten 
Stereoanlage, die schaltet ihre Tasten zwischen verschiedenen Codes um 
(Adresse und Commando) und ggfs. auch ganz ab, je nachdem, welches Gerät 
man einschaltet. Für den Benutzer soll das konsistent aussehen: 
Lautstärke ist Lautstärke und das Radio kann man nicht zurückspulen. :-)

: Bearbeitet durch User
von Konrad S. (maybee)


Lesenswert?

Wolfgang S. schrieb:
> Ein Gag am Rande: die sich im Beispieloutput als SAMSG32 meldende
> Fernbedienung taucht in der kürzlichen Umfrage nicht auf.

Ich hab's nicht aufgeführt, weil Gerät und Fernbedienung ohne IRMP 
funktionieren, aber auf meinem IR-Spion sehe ich das Protokoll.

Ich hatte mal eine Fernbedienung mit abweichendem Protokoll bei der 
On/Off-Taste. Damit rechnet man ja erstmal nicht.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Wolfgang S. schrieb:
> Als erste Fingerübung habe ich IRMP darauf zum Laufen gebracht.

Klasse. Ich werde Deine Änderungen gern in IRMP einbauen.

Planst Du auch noch eine Portierung von IRSND? ;-)

> Das liegt
> daran, daß die mit "LG" beschriftete Fernbedienung eines Blu-Ray-Players
> normalerweise zwar in dieser Zunge spricht, aber auf NECisch umschaltet,
> wenn man einen rechts oben mit "TV" beschrifteten Block benutzt.

Ja, sowas ist mir auch schon mal untergekommen. Ist aber selten.

von Wolfgang S. (ws01)


Lesenswert?

Frank M. schrieb:
> Wolfgang S. schrieb:
>> Als erste Fingerübung habe ich IRMP darauf zum Laufen gebracht.
>
> Klasse. Ich werde Deine Änderungen gern in IRMP einbauen.

Wie ich gerade sehe, hast Du schon. Das ging aber flott. :).

> Planst Du auch noch eine Portierung von IRSND? ;-)

Im Moment brauche ich das zwar nicht, da es aber keine besonderen neuen 
Anforderungen stellt, erledige ich das bei Gelegenheit nebenher.

von Wolfgang S. (ws01)


Angehängte Dateien:

Lesenswert?

Ein kurzer Bericht zum aktuellen Stand. Das Basteln mit dem ESP8266 
gestaltet sich zäher als erwartet, hauptsächlich aufgrund der etwas 
unübersichtlichen Gemengelage aus unterschiedlichen SDK nebst eher 
dürftiger Dokumentation.

Angefangen habe ich mit dem esp_iot_sdk_v1.4.1_pre5_15_10_27.zip

Ziel ist zunächst mal eine kleine Anwendung, die auf bequeme Weise die 
von IRMP verstandenen Tastendrücke auf einem geeigneten Gerät per 
Browser oder App anzeigen kann. Code bereitstellen möchte ich noch 
nicht, da der ganze Aufbau noch zu sehr mit der heißen Nadel gestrickt 
ist, aber schon mal ein paar Zwischenergebnisse diskutieren.

Das aktuelle Demoprogramm realisiert einen Accesspoint, der mit der 
festen SSID irmp432, via WPA2 und einer festen Passphrase einen DHCP- 
und einen Webserver auf der Adresse 192.168.4.1 realisiert und auf 
jeglichen http-Request mit einer Standard-HTML-Seite antwortet, wie sie 
in den ersten beiden Bildern gezeigt wird, einmal auf einem 
Android-Handy, dann im Firefox. Zu diesem Zweck habe ich ein 
Espressif-Beispiel gnadenlos abgespeckt.

Gezeigt werden in umgekehrter chronologischer Reihenfolge die letzten 
maximal vierzig von IRMP erkannten Tastendrücke, die zu diesem Zweck in 
einem Ringpuffer aufgehoben werden. Bei jedem Webrequest wird der 
aktuelle Zustand gerendert, wobei der erneute Abruf der Seite mit einem 
Refresh-Tag getriggert wird, wenn der Browser mitspielt. Primitiv, aber 
wirksam.

Zusätzlich schickt das Programm gleich beim Erkennen eines Tastendrucks 
eine entsprechende Teile an das UART sowie ein UDP-Paket. Eine 
entsprechende App (basierend auf dem hier 
https://play.google.com/store/apps/details?id=de.mystrobl.rechner) 
horcht auf diese Pakete und zeigt sie ohne zeitliche Verzögerung an, 
siehe drittes Bild.  Falls jemand den aktuellen Stand ausprobieren 
möchte und weil das Binary nicht sonderlich groß ist, habe ich es 
ebenfalls hier angehängt. boot_v1.1.bin kann man aus dem SDK nehmen.

Geflasht wird das hier wie folgt:
1
esptool.py --baud=345600 --port=COM9 write_flash 0x00000 boot_v1.1.bin 0x01000 user1.2048.old.3.bin

SSID wie oben genannt, pw ist 0123456789zwotzeL

Abschließend noch zwei WifiAnalyzer-Screenshots.

Inzwischen ist der esp_iot_sdk_v1.5.0 herausgekommnen, wie ich gerade 
gesehen habe. Nächstes Wochenende. :-)

von Wolfgang S. (ws01)


Angehängte Dateien:

Lesenswert?

Statt den im Vorposting gezeigten Entwurf weiter zu polieren, habe ich 
mich darauf beschränkt, diesen i.W. unverändert mit dem IOT-SDK 1.5.0 zu 
übersetzen, dies zusammen mit einem älteren Android-Tablet als 
kabelloses Kontrolldisplay für IR-Codes zu verwenden und erst mal eine 
andere Idee zu verfolgen, nämlich IRMP in die unter dem Namen NodeMCU 
bekannte Lua-Adaption (https://en.wikipedia.org/wiki/NodeMCU) 
einzubauen.

Trotz einiger überraschender Hürden (s.w.u.) war das insgesamt weniger 
Aufwand als erwartet.

http://nodemcu.com/index_en.html vermittelt zunächst den Eindruck einer 
Hardwareplattform. Tatsächlich ist aber die auf GitHub gehostete 
Firmware https://github.com/nodemcu/nodemcu-firmware problemlos mit dem 
ESP-Open-SDK https://github.com/pfalcon/esp-open-sdk übersetzbar und 
läuft dann anstandslos auch auf dem Olimex-Board 
(https://www.olimex.com/Products/IoT/ESP8266-EVB/open-source-hardware). 
So weit, so gut.  Dann fangen die Probleme aber an.

In der mit dem unveränderten Espressif-SDK realisierten IRMP-Adaption 
hatte ich den sog. Hardware-Timer aus der driver_lib verwendet, um 
Timer-Interrupts zuverlässig alle 67 µS (bei 15 kHz) realisieren zu 
können.

Dummerweise fehlt aber NmiTimSetFunc(func) im esp-open-sdk in ets_sys.h 
und das aus gutem Grunde, denn ein dafür wiederum benötigtes externes 
Symbol fehlt in einer der nur als Object-Module verfügbaren Library, die 
im open-sdk verwendet wird. Selbst der auf Minimum 100 µs beschränkte 
Softwaretimer ist nicht verfügbar. Damit fehlt die wesentliche Grundlage 
für den Betrieb der IRMP-ISR.

Es gibt aber einen Ausweg. Es läßt sich nämlich vergleichsweise einfach 
ein Interrupt an die steigende, fallende oder an beide Flanken eines 
Pegelwechsels an einem Pin binden.  Der genaue Zeitpunkt steht über 
einen API-Call µs-genau oder über inline-Assembly sogar taktgenau zur 
Verfügung:
1
#define STORE_CYCLES(r) do { \
2
  __asm__ __volatile__("rsr %0, CCOUNT \n\t" : "=a" (r)); \
3
} while (0);

Zwar besagt das nichts über die zeitliche Genauigkeit des Interrupts 
selber, in der Praxis ist es aber offenbar hinreichend präzise für IRMP.

Zusammen mit einem kleinen Ringpuffer läßt sich so ganz einfach eine 
Pulse-Train mitschreiben. Jedoch ist dies nicht das, was IRMP erwartet. 
Da IRMP allerdings völlig egal ist, wann und wie irmp_ISR() aufgerufen 
wird, lassen sich die Aufrufe ohne weiteres vor dem Aufruf von 
irmp_get_data nachholen. Ein positiver Nebeneffekt dieses Verfahrens 
besteht darin, daß der IR-Empfang nebenläufig und gepuffert erfolgt. 
Der Beispieloutput im Anhang zeigt z.B. das Dekodieren von 29 
IRMP-Telegrammen am Klump aus bereits gepufferten IR-Daten.


Modul irmp mit den drei Funktionen init, get_data und close.
----------

Funktionen
----------

irmp.init(int queuesize) -> 0 (no memory) oder 1 (ok)

queuesize: Gesamtzahl von Pulsen und Lücken, die gepuffert werden. Wie 
viele pro Tastendruck verwendet werden, hängt vom Protokoll ab.

irmp.get_data() ->  protokollname(string) adress(int) command(int) 
flag(int)  oder 0 (nichts) oder -1 (keine queue, closed)

irmp.close() -> Queue wieder freigeben.


Für das Herumprobieren damit war ESPlorer (http://esp8266.ru/esplorer/) 
nützlich.


Lua, das ich mir erst bei der Gelegenheit oberflächlich angeeignet habe, 
hat ein etwas ungewöhnliches Features, das mit der Implementation von 
mehrfachen Rückgabewerten von Funktionen zu tun hat: 
http://www.lua.org/pil/5.1.html und das einige Verrenkungen erfordert, 
wenn man dergl. Listen tatsächlich verwenden möchte.  Zwar ist es 
ziemlich einfach und elegant, mehrere Werte, auch unterschiedlich viele, 
von einem C-Programm aus abzuliefern - man kippt sie einfach 
nacheinander auf dem Stack ab - so einfach das aber ist, so umständlich 
ist es dann wieder in Lua, mit diesen etwas anzufangen. Leider hat eine 
der dafür benötigten Funktionen ("unpack") zwischen 5.1 und 5.3 ihren 
Namen bzw. Ort gewechselt (von globalem Namensraum zu Attribut von 
"tables").  Die einzige simple, auch mit variabel langen Rückgabelisten 
zurechtkommende Verfahrensweise, ein direkt auf einen Funktionsaufruf 
angewandter Table Constructor http://www.lua.org/pil/3.6.html 
funktioniert in der vorliegenden NodeMCU-Version nicht, es kommen nur 
zwei von vier oder mehr Rückgabewerten an. Zum Glück gibt es einen 
Workaround, das Einsammeln der Rückgabewerte läßt sich nachbilden: 
http://www.lua.org/pil/5.2.html.

Dies erklärt die Funktion collect in dem nachfolgenden Schnipsel.
1
require "irmp"
2
function collect(...)
3
   return arg
4
end
5
function irmpg()
6
   local r
7
   repeat
8
      r=collect(irmp.get_data())
9
      if #r>2 then print(string.format("%s(%d): addr=%04x cmd=%04x f=0x%02x  ",unpack(r)))
10
      else break end
11
   until #r==1
12
end
13
print (irmp.init(1000))

Wenn dieses Schnipsel ausgeführt wurde, können nachfolgend alle 
zwischenzeitlich aufgelaufenen Tastendrücke mit einem einfachen Aufruf 
von irmpg() dekodiert und über das UART angezeigt werden. Siehe 
Beispieloutput.

Es wäre schön, wenn IRMP statt per Polling wahlweise auch per 
Pulse-Train mit Input versorgt werden könnte. Wenn ich mich erinnere, 
hattte Frank vor einer Weile mal angedeutet, über so etwas nachdenken zu 
wollen.

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.