Overview
Principes
OverviewPrincipesPrincipesPrincipesPrincipesPrincipes
  Cronios-Fernsteuerung
  
Konzept

Fernsteuerung von Cronios-LED-Basic Controllern
Konzept, Hard- und Software

Die Firma LEDgenial ist u.a. Anbieter von LED-Produken. Dazu gehören progrmmiebaren Controllermodule zur Ansteuerung von WS2812-LED-Streifen, für diese wurde eine spezielle, kostenlose Programmierumgebung und -sprache LED-Basic entwickelt.

Eine sehr attraktive Anwendung sind die Cronixie-Uhren, die nach dem Flutlichprinzip (Lightguide Display) funktionieren:

Das aktuelle LED-Basic (15.1.5) hat leider keine direkte Input-Funktion. Außerdem verfügt das für die Cronixie-Uhren genutzte Cronios-Controllerboard über keine frei verfügbaren externen Schnittstellen, so daß sich Geräte auf dessen Basis nicht ohne Weiteres von außen steuern lassen.

Ich habe nun eine Möglichkeit entwickelt, dieses Manko zumindest eingermaßen befriedigend zu umgehen:

LED-Basic unterstützt zwar die Abfrage von Tastendrücken oder statische Pegel an einigen Eingängen (je nach Modul). Aber eine komfortable und vor allem schnelle Dateneingabe (z.B. von externen Controllern) ist nicht ohne Weiteres möglich, da eine zyklische Abfrage von Eingangsports einige Probleme macht:

1. ein Eingangspegel muß während laufender Programme mindestens 40 ms anliegen, da ungünstigenfalles eine gerade laufende LED.show-Anzeige-Routine abgewartet werden muß.
2. Selbst wenn in einer Abfrageschleife keine LED.show-Routine aufgerufen wird, kann ein Portwechsel erst nach längerer Zeit festgestellt werden (insbesondere Tastendrücke verzögern sich um bis zu 40 ms).

Damit wäre eine Dateneingabe sehr langsam, aber nicht unmöglich:

Ein Input kann mit Mitteln der LED-Basic-Programmierung folgendermaßen implementiert werden und bedarf nur eines Eingangsportes. Selbst ein Cronios-Modul ist somit steuerbar, wenn der Drehimpulsgeber-Tastenkonatkt extern an Masse gelegt wird, so daß dessen Input-Port zur Eingabe verwendet wird! Durch geschicktes Timing bleibt der Kontakt auch weiterhin manuell bedienbar.

Port Status „Passiv“, Wert 0, Taste nicht gedrückt
Port Status „Aktiv“, Wert 1, Taste gedrückt bzw. extern an Masse gelegt.

Timing für externe Dateneingabe:

1. Start-„Aktiv“ > 50 ms,
um ggf. aus einem laufenden Programm einschl. eventueller LED.show-Routine auszuspringen,
in vorgeschlagener Lösung 60 ms, längerer Aktiv-Zustand wird als manueller Tastendruck gedeutet und springt zurück in die ursprüngliche Tastenabfrage.

2. Datum als Ziffern-„Passiv“,
zusammengesetzt aus 50 ms Mindest-Verarbeitungszeit plus (30 ms * Ziffernwert), also
0 = 50 ms, 1 = 80 ms, 2 = 110 ms, 3 = 140 ms, … , 9 = 330 ms

3a. Trenn-„Aktiv“ mit 50 ms, daraufhin können weitere Ziffern-Passivs folgen, oder
3b. Ende-„Aktiv“ mit 80 ms, damit wird die Eingabe insgesamt beendet und zurück in das ursprüngliche Programm gesprungen.

Mindestdauer Input einer Null:             190 ms
Maximaldauer Ziffernfolge "9999999": 3,13 s
Die Datenübertragung ist zwar extrem langsam, aber mit diesem Timing sehr zuverlässig!
Zusätzliche Timeouts prüfen die Warteschleifen auf Überschreitung der Maximalzeiten. Um ein Blockieren des Hauptprogrammes zu vermeiden, kann z.B. ein "Aktiv"-Zustand länger als 100 ms als manueller Tastendruck gewertet werden.

Ein Eingabebeispiel (/=aktiv, \=passiv):
Input der Ziffer   3: /60\140/80\
Input der Zahl 123: /60\80/50\110/50\140/80\ (s. Abb.)


Der Startimpuls 60 ms wird im Oszillogramm etwas verkürzt dargestellt!
Weiter: EREL-Cronios-Fernsteuerung

Anhang:         LED-Basic Routinen für die INPUT-Emulation:

' ------ Hauptrogramm -----

100:
  ...                        '(Hauptprogramm)

  k = IO.getkey()
  if k > 0 then gosub 20000  'Aufruf INPUT-Fersteuerung

  ...                        '(Hauptprogramm)
    goto 100                         '

 

 

' ===== Routine INPUT Fernsteuerung empfangen =====
'
' IN: nach IO.GETKEY>0 in Hauptprogramm-Schleife
' VAR: i: Aktiv-Timer

20000:                       'Einsprung
  i = 0                      'Aktiv-Timer reset

20100:                       'warte auf Impulspause 
   delay 1                   '(Start) Empfangsbereitschaft...
   i = i + 1
   k = IO.keystate()         'Port-Abfrage
   if i > 100 then retun    'max. 100 ms Wartezeit (sonst manueller Tastendruck)
   if k = 1 then goto 20100  'Startimpuls noch aktiv...

20200:
   gosub 20900                'SUB: ZIFFER EMPFANGEN -> n
   if s = 0 then return       'Fehler-Aussprung!
'  +++++++++++++++++++++++++++++++
'  + hier Ziffer "n" verarbeiten +
'  +++++++++++++++++++++++++++++++
   if s = 1 then goto 20200   'weitere Ziffer folgt...

return                     'fertig


 

' ------ Subroutine einzelne Ziffer empfangen -----
'
' OUT: n: Ziffer
'      o: Anzahl empfangene Ziffern
'      s: Schlußzeichen 0=Überlauf/Fehler,
'                       1=weitere Ziffer folgt,
'                       2=letzte Ziffer
' VAR: j: Passiv-Timer
'      i: Aktiv-Timer
'      k: Keystatus

20900:                      'einzelne Ziffer lesen... -> n
   o = o + 1                'Reset Anzahl Ziffern
   j = 0                    'Reset Impulspausenzähler
   n = -1                   'n<0: Ziffer zunächst ungültig
   s = 0                    's=0: Fehler

20910:                      '--- Passiv-Schleife ---
   delay 1                  'Zeitbasis 1 ms
   j = j + 1                'Zeitmessung Impulspause ("passiv")
   k = IO.keystate()        'warte auf Impuls...
   if j > 350 then return   'max. 350 ms Gesamtwartezeit ->
                            'Abbruch (S=0: Fehler)
   if k = 0 then goto 20910 '-> Passiv-Schleife

   i = 0                    'Aktiv: Reset Impulslängenzähler

20920:                      '--- Aktiv-Schleife ---
   delay 1                  'Zeitbasis 1 ms
   i = i + 1                'Zeitmessung Impulslänge ("aktiv")
   k = IO.keystate()        'warte auf Impulspause...
   if i > 180 then return   'max. 150 ms Gesamtwartezeit ->
                            'Abbruch (S=0: Fehler)
   if k = 1 then goto 20920 'noch aktiv...

20950:                      'Passiv-Länge -> Ziffernwert bestimmen   n = 0                    
   if j > 50 then n = 1     '(Werte experimentell ermittelt)
   if j > 80 then n = 2
   if j > 105 then n = 3
   if j > 135 then n = 4
   if j > 160 then n = 5
   if j > 180 then n = 6
   if j > 210 then n = 7
   if j > 240 then n = 8
   if j > 265 then n = 9
   if j > 290 then n = 10

20990:
   s = 1                    'Impuls kurz   s=1: weitere Ziffer folgt
   if i > 55 then s = 2     'Impuls mittel s=2: letzte Ziffer (Schlußzeichen)
   if i > 150 then s = 0    'Impuls lang   s=0: Überlauf
   o = o + 1                'Anzahl Ziffern zählen
   i = 0                    'Ausstieg

return


663