Forum: Projekte & Code RGB Moodlight mit STM8


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


Angehängte Dateien:

Lesenswert?

Moin,

hier kommt ein Follow-Up zu meinem Beitrag [0]. Weil ich seit kurzem mit 
STM8 Controllern herumspiele, dachte ich mir es wäre doch ganz nett, 
dieses Projekt vom AVR auf den STM8 zu portieren. Was soll ich sagen: 
das ging viel leichter als erwartet. Das liegt sicher auch daran, daß 
der STM8 genügend PWM-Kanäle hat, um die PWM komplett in Hardware zu 
machen.

Schaltbild:

1
  TSOP                  STM8S103F3
2
  34136                 Evalboard
3
 .-----.              .------------.
4
 |    3|----+-[100R]--|3.3V      5V|-------------.
5
 |    2|-.  |         |            |             |
6
 |    1|-)--)---------|PA1      PD4|--|<--[150R]-+ red
7
 '-----' |  |         |            |             |
8
         |  = 100nF   |         PD3|--|<--[220R]-+ green
9
         |  |         |            |             |
10
         '--+---------|GND      PA3|--|<--[150R]-' blue
11
                      '------------'

Das Evalboard ist bei mir ebay Nummer 171907337886, die LED sind 5mm 
Typen von Pollin, dito der TSOP34136. Der ganze Krempel steckt derzeit 
auf einem Breadboard, als Programmer dient ebay Nummer 121507212413. 
Aber auch ein STLINK V1 von einem STM8 Discovery funktionierte.

Die Hardware ist ziemlich geradezu. Der TSOP wird aus der auf 3.3V 
stabilisierten Betriebsspannung des STM8 versorgt (auf dem Evalboard ist 
dafür ein LT1117-3.3 verbaut). Die LED werden L-aktiv gegen 5V 
getrieben, das hauptsächlich deswegen weil dann die Wahl der 
Vorwiderstände (für 10mA) etwas entspannter abläuft als gegen 3.3V.

An Software braucht man den SDCC [1]. Bei mir in Version 3.5.0 (ab 3.4.0 
wird der STM8 unterstützt, allerdings offenbarte ein Blick auf den von 
3.4.0 generierten Assemblercode gar grausliches; ich empfehle also 
dringend den SDCC 3.5.0+ zu verwenden, der geht gut). Ferner braucht man 
stm8flash [2], make und (optional, zur Neu-Erzeugung der PWM-Tabelle) 
Perl. Linux-Nutzer haben das alles an Bord bzw. können es über das 
System-Packagemanagement nachinstallieren.

Die beigelegte stm8s.h wurde aus der STM8S Standard Peripheral Library 
von ST in Verbindung mit [3] erzeugt (plus ein paar manuelle Edits). Für 
die prinzipielle Funktion verweise ich auf den Vorgängerthread [0].

Noch ein paar Notizen:

- beim Eintritt und Verlassen der irmp_ISR() schalte ich die User-LED 
auf dem Board (PB5) ein bzw. aus. Damit kriegt man einen ungefähren 
Eindruck, wieviel Zeit der µC im Interrupt-Handler verbringt.

- im Prinzip würde die Sache auch mit 8MHz Systemtakt funktionieren. 
Allerdings kann der STM8 jetzt 250 Helligkeitsstufen (statt 208 beim 
AVR) auflösen. Und damit die Lichtprogramme auch schnell ablaufen 
können, habe ich einfach den Systemtakt auf das Maximum von 16MHz 
gestellt, was dann gut 240Hz PWM-Frequenz ergibt. Wer hat, der kann ;)

- die notwendigen Änderungen an IRMP habe ich als separates diff File 
angehängt. Falls der Patch wegen Zeilenendungen nicht applied - sorry, 
aber DOS Zeilenendungen nerven einfach. Deswegen ist das eine meiner 
ersten Aktionen, das gerade zu rücken.

- der gesamte Code belegt 3333 Byte von 8KB Flash und 57 Bytes von 1KB 
RAM. Da ist also noch Luft. Es erstaunt mich etwas, daß der STM8 damit 
kaum mehr Programmspeicher verbraucht als der ATmega8. Obwohl der STM8 
vergleichsweise spartanisch ausgestattet ist. Und der SDCC ein viel 
minimalistischerer Compiler ist als der (avr-)gcc.

Happy Hacking!


[0] Beitrag "noch ein AVR Moodlight"
[1] http://sdcc.sourceforge.net/
[2] https://github.com/vdudouyt/stm8flash
[3] https://github.com/gicking/SPL_2.2.0_SDCC_patch

: Bearbeitet durch User
von Joerg W. (joergwolfram)


Lesenswert?

Danke für den Hinweis auf den SDCC 3.5.0, den werde ich bei mir gleich 
mal aktualisieren.

Jörg

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


Angehängte Dateien:

Lesenswert?

Hallo,

hier kommt eine neue Software-Version. Was hat sich geändert:

- das Makefile wurde mächtig aufgebohrt und kann jetzt 'make depend'
- es wird nur noch ein Timer-Interrupt verwendet
- Master-Clock und CPU-Clock wurden verringert auf das nötige Minimum
- man kann jetzt zur Compilezeit zwischen zwei Fernbedienungen wählen
- Unmengen Bugfixes

Auch die Änderungen an IRMP habe ich nochmal überarbeitet. Die sind 
jetzt final (wenn Frank nicht noch was auszusetzen hat ;)

Außerdem habe ich noch ein kleines Tool dazugepackt (lirc2irmp.zip) mit 
dem man eine Fernbedienung die man in LIRC (http://www.lirc.org/) erfaßt 
hat auch für IRMP verwenden kann:

1
lirc2irmp.pl xyz.lirc >xyz.h

funktioniert zwar nur für das NEC Protokoll, aber etwas anderes brauchte 
ich bisher auch nicht.

Für alle Anwender von SDCC noch eine Warnung: der Code wird vom derzeit 
neuesten SDCC Release (3.5.0) nur dann korrekt übersetzt, wenn man mit 
"--max-allocs-per-node 1000" übersetzt. Sonst verhakelt sich SDCC in der 
Schachtelung aus case/if/if in moodlight_remote(). Sobald ich einen 
kurzen Testcase gefunden habe der das Problem demonstriert, werde ich 
einen Bug reporten. Ehrlich gesagt steige ich durch den von SDCC 
generierten Assemblercode noch nicht durch. Ich kann aber sehen daß er 
nicht funktioniert.

Ich will an dem Projekt noch ein bißchen feilen. Z.B. will ich die 
Fernbedienungscodes aus dem Programm werfen und im EEPROM speichern. 
Dann kann man die Fernbedienung wechseln ohne das Programm neu zu 
compilieren. Und man soll auch mehrere Fernbedienungen verwenden können 
sollen. Dazu suche ich noch Feedback: 
Beitrag "Umfrage: welche IR-Protokolle nutzt ihr mit IRMP?"

von Wolfgang S. (ws01)


Lesenswert?

Axel S. schrieb:
> Ich will an dem Projekt noch ein bißchen feilen. Z.B. will ich die
> Fernbedienungscodes aus dem Programm werfen und im EEPROM speichern.
> Dann kann man die Fernbedienung wechseln ohne das Programm neu zu
> compilieren. Und man soll auch mehrere Fernbedienungen verwenden können
> sollen. Dazu suche ich noch Feedback:
> Beitrag "Umfrage: welche IR-Protokolle nutzt ihr mit IRMP?"

Da würde mich schon mal vorab das Design interessieren. Das ist manchmal 
spannender als Details der Implementierung.

Ich habe in einer Neuauflage von
http://www.mystrobl.de/Plone/basteleien/weitere-bulls-and-cows-mastermind-implementationen/mm-v1821/mastermind-solver-mit-led-streifen-und-ir-fernbedienung 
, in der die Fernbedienungscodes auch noch hart verdrahtet waren, das so 
gelöst, daß die drei Knöpfe, die ich da brauche (+,-,ENTER) in der Form 
protocol, address, command im EEPROM gespeichert werden.  Es gibt zwar 
eine Vorbelegung, jedoch läßt sich jede Fernbedienung, deren Protokoll 
enabled ist, anlernen, indem zunächst irgend eine Taste zwölf mal 
hintereinander gedrückt wird (ohne Wiederholungsflag) und dann die 
nächsten drei Tastendrücke mit passendem Protokoll und passender Adresse 
als die o.a. Funktionen im EEPROM gespeichert werden.  Funktioniert 
erstaunlich gut, jedenfalls besser als vorherige Versuche mit 
Tastenfolgen.

Die wesentliche Idee dabei war, nach dem Triggern durch genügend viele 
gleiche Tastendrücke zunächst sofort zu signalisieren "hab's gemerkt", 
dann aber eine Totzeit von ca. 1 s einzulegen und erst dann "warte auf 
ersten Tastendruck" usw. zu signalisieren.   Auf diese Weise kommt es 
auf das Abzählen der Tastendrücke nicht an, man morst einfach so lange, 
bis eine Reaktion kommt und wartet dann auf die Aufforderung zum ersten 
Tastendruck usw.

Mehrere Fernbedienungen zu unterstützen wirft die Frage auf, wie man 
alte angelernte wieder los wird, ohne das zu kompliziert zu machen. 
Eine Tastenkombination "vergiss mich" erfordert, daß die zu vergessende 
Fernbedienung noch verfügbar ist.  Dann lieber Verwaltung in einem 
Ringpuffer (älteste werden jeweils überschrieben) und eine Kombination 
"alles vergessen".

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Hi Axel,

Axel S. schrieb:
> hier kommt ein Follow-Up zu meinem Beitrag [0]. Weil ich seit kurzem mit
> STM8 Controllern herumspiele, dachte ich mir es wäre doch ganz nett,
> dieses Projekt vom AVR auf den STM8 zu portieren.

Vielen Dank für den IRMP-Port auf STM8 - und danke für das diff-File :-)
Sehr schön gemacht: das passt perfekt. Ich habe Deine Änderungen 
eingearbeitet und als IRMP-Version 2.9.6 hochgeladen. Den IRMP-Artikel 
habe ich aktualisiert.

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

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


Lesenswert?

Frank M. schrieb:
> Vielen Dank für den IRMP-Port auf STM8 - und danke für das diff-File :-)

Nichts zu danken. Ich bin froh, daß ich etwas zurückgeben konnte für 
dein schnuckeliges IRMP Projekt :D

> Sehr schön gemacht: das passt perfekt. Ich habe Deine Änderungen
> eingearbeitet und als IRMP-Version 2.9.6 hochgeladen. Den IRMP-Artikel
> habe ich aktualisiert.

Ich habe noch zwei kleine Anmerkungen zu meinem Patch.

1
--- irmp.orig/irmp.c  2015-10-28 16:43:43.357458450 +0100
2
+++ irmp/irmp.c  2015-10-28 00:27:05.000000000 +0100
3
@@ -2013,6 +2013,9 @@
4
      ROM_GPIOPadConfigSet(IRMP_PORT_BASE, IRMP_PORT_PIN,
5
                           GPIO_STRENGTH_2MA,
6
                           GPIO_PIN_TYPE_STD_WPU);
7
+#elif defined(SDCC_STM8)
8
+    IRMP_GPIO_STRUCT->CR1 |= (1<<IRMP_BIT);   // activate pullup
9
+    IRMP_GPIO_STRUCT->DDR &= ~(1<<IRMP_BIT);  // pin is input
10
 #else                                                                   // AVR
11
     IRMP_PORT &= ~(1<<IRMP_BIT);                                        // deactivate pullup
12
     IRMP_DDR &= ~(1<<IRMP_BIT);                                         // set pin to input

Hier sollte man vielleicht die Reihenfolge der Operationen umkehren. 
Also den Pin erst als Eingang setzen und dann den Pullup einschalten. 
Denn sonst kann es unter ungünstigen Umständen dazu kommen daß der Pin 
für ein paar Dutzend Nanosekunden als Ausgang einen H-Pegel treibt. OK, 
dazu muß der Benutzer ihn erst manuell als Ausgang konfiguriert haben. 
Default nach Reset ist Input.

1
--- irmp.orig/irmpsystem.h  2015-10-28 16:43:43.361458349 +0100
2
+++ irmp/irmpsystem.h  2015-10-28 00:27:06.000000000 +0100
3
@@ -116,6 +118,15 @@
4
 #  define PROGMEM
5
 #  define memcpy_P                      memcpy
6
 
7
+#elif defined(SDCC_STM8)
8
+
9
+#  include "stm8s.h"
10
...

Das ist leider nicht so generisch wie es sein könnte. Das Headerfile 
heißt nur für die STM8Sxxx und STM8AFxxx so. Für die STM8Lxxx und 
STM8ALxxx heißt es "stm8l15x.h". Der Name ist dämlich gewählt, weil der 
STM8L Port der Standard Periperal Library keineswegs nur für STM8L15x 
paßt, sondern auch für STM8L05x und weitere. Viel besser wäre "stm8l.h" 
gewesen ...

Auf jeden Fall hat man etwas extra Arbeit, wenn man einen STM8L 
verwenden will. Am einfachsten kopiert man wohl die stm8l15x.h unter dem 
Namen stm8s.h in sein Projekt.

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

Nicht in den nächsten Tagen. Aber man soll niemals nie sagen :)

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Axel S. schrieb:
> Hier sollte man vielleicht die Reihenfolge der Operationen umkehren.
> Also den Pin erst als Eingang setzen und dann den Pullup einschalten.

Okay, habe ich geändert. Kommt dann aber erst mit der nächsten Version, 
da ich diese "Unschönheit" als unkritisch ansehe.

> Das ist leider nicht so generisch wie es sein könnte. Das Headerfile
> heißt nur für die STM8Sxxx und STM8AFxxx so. Für die STM8Lxxx und
> STM8ALxxx heißt es "stm8l15x.h".

Das ist schade. Gibt's da keine Preprozessor-Konstante, die man abfragen 
könnte, um den genauen Typ des Prozessors abzufragen?

>> Planst Du auch noch eine Portierung von IRSND? ;-))
> Nicht in den nächsten Tagen. Aber man soll niemals nie sagen :)

Klar. So etwas macht man erst, wenn man es selbst auch braucht.

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


Lesenswert?

Frank M. schrieb:
> Axel S. schrieb:
...
>> Das ist leider nicht so generisch wie es sein könnte. Das Headerfile
>> heißt nur für die STM8Sxxx und STM8AFxxx so. Für die STM8Lxxx und
>> STM8ALxxx heißt es "stm8l15x.h".
>
> Das ist schade. Gibt's da keine Preprozessor-Konstante, die man abfragen
> könnte, um den genauen Typ des Prozessors abzufragen?

Jein. Die SPL erfordert, daß man ein #define mit dem genauen Typ der MCU 
anlegt, weil sie abhängig davon die SFR structs an der für jene MCU 
gültigen Adresse plaziert.

Man könnte jetzt also die komplette Liste der MCU abfragen die in 
stm8s.h respektive stm8l15x.h abgehandelt werden. ca. so:

1
#if defined (STM8S208) || defined (STM8S207) || defined (STM8S105) || \
2
    defined (STM8S103) || defined (STM8S903) || defined (STM8AF52Ax) || \
3
    defined (STM8AF62Ax) || defined (STM8AF626x) || defined (STM8S007) || \
4
    defined (STM8S003) || defined (STM8S005) || defined (STM8AF622x)
5
6
#  include "stm8s.h"
7
8
#elif defined (STM8L15X_MD) || defined (STM8L15X_MDP) || defined (STM8L15X_HD)
9
10
#  include "stm8l15x.h"
11
12
#else
13
#  error "unknown STM8 mcu!"
14
#endif

Finde ich allerdings ziemlich häßlich. Und falls(?) ST irgendwann mal 
eine neue MCU in die STM8 Familie aufnimmt, paßt es natürlich nicht 
mehr.

: Bearbeitet durch User
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Axel S. schrieb:
> Finde ich allerdings ziemlich häßlich.

Wenn man sich die ganzen Preprocessor-Statements im IRMP-Source näher 
anschaut, dann ist das sowieso schon hässlich[1]. Also ich hätte nichts 
dagegen, das genau so einzubauen.

[1]
1
grep '#' irmp.c          | wc -l -> 1281
2
grep '#' irsnd.c         | wc -l ->  753
3
grep '#' irmpprotocols.h | wc -l ->  645
4
5
grep '#' ir*.[ch]        | wc -l -> 3264

: Bearbeitet durch Moderator
von Axel S. (a-za-z0-9)


Lesenswert?

Frank M. schrieb:
> Wenn man sich die ganzen Preprocessor-Statements im IRMP-Source näher
> anschaut, dann ist das sowieso schon hässlich[1]. Also ich hätte nichts
> dagegen, das genau so einzubauen.

[x] make it so!

Wobei, warte mal noch bis ich das eingebaut habe und bestätigen kann daß 
es durch den Compiler läuft.

von google (Gast)


Angehängte Dateien:

Lesenswert?

Kurzbericht:

Ein STM8S103-board von Pollin mit einer RGB-LED zusammengesteckt, das 
ganze Projekt in die kostenlose, aber begrenzte IAR-workbench gezogen, 
alle IRMP-Bezüge entfernt, weil kein IR-Empfänger zur Hand, beim ersten 
Compilieren über die Binärdarstellung ("0b00001010") gestolpert, IAR 
kennt diese nicht, in Hex ("0x0A") umgeschrieben ... läuft sofort.

von google (Gast)



Lesenswert?

Nach Fertigstellung eines STM8S103 mit dieser Technologie:

Beitrag "~1€ ARM-Cortex-M0 (STM32)-Bord selbstgestrickt"

wollte ich noch mein moodlight-Galerie zeigen, siehe angehängte Fotos. 
Leider ist heute das Licht ganz schlecht ...

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.