Programmbeispiele für den ROBOprogy


zur homepage

Mehrere Programme im Speicher – eines davon starten.

Der ROBOcontroller besitzt in der Mitte der Platine einen Start/Stop-Eingang, mit dem man das zuletzt übertragene Programm starten kann. Mehr kann man mit einer einzigen Taste nicht erreichen, da noch Sonderaufgaben erfüllt werden müssen („Tiefschlaf“ bei längerer Betätigungsdauer). Manchmal gibt es aber gute Gründe, zwischen mehreren Programmen umschalten zu können:

Will man also zwischen mehreren Programmen wählen, die in den ROBOprogy geladen wurden, muss man das dem ROBOcontroller über einen Digitaleingang X mitteilen. Man schließt einen weiteren Taster zwischen (beispielsweise) 4in und 0 V an, der innerhalb von jeweils einer Sekunde nach Start/Stop gedrückt werden kann und wählt damit:

Erfahrungsgemäß hat jeder Schalter Wackelkontakte, die bei unvorsichtiger Programmierung Mehrfachbetätigung vortäuschen. Deshalb wird erst eine lange, ununterbrochene Folge von „offener Kontakt“ als „wirklich offen“ akzeptiert. Man konstruiert also eine Wiederholung, in der der Kontakt immer wieder geprüft wird. Jedes Schließen startet den Zähler neu, indem der bisherige Stand durch den Wert 0 ausgetauscht wird. War der Kontakt bei 50 aufeinenderfolgenden Tests offen, wird die Wiederholung beendet. Die folgende Funktion wartet, bis die Tast sicher wieder losgelassen wurde.

: TASTEFREI { --- } 0         \ internen Zähler initialisieren (der Wert bleibt ohne Namen auf dem Stack)
BEGIN 4in             \ Taste frei?
               IF 1+              \ ja, Zähler erhöhen
               ELSE drop 0  \ nein, alten Zählerstand entfernen und wieder bei 0 beginnen
               THEN 1 ms    \ den MEGA32 runterbremsen, Wackelkontakte dauern etwa 20 ms
               dup 50 =         \ war der Kontakt 50 mal nacheinander offen?
UNTIL drop ;        \ ja, dann ist er auch offen! Zähler noch entfernen, Stack sauber halten

Das Programm „Tastefrei“ wird also nach frühestens 50 ms wieder verlassen, das reicht bei Wackelkontakten normalerweise aus. Wenn man besonders prellfreie Schalter verwendet, kann man die Zeit möglicherweise unter 10 ms reduzieren. Das muss man testen.

Nun beginnt das Zählen der Tastenbetätigungen. Die Idee: Das Programm wartet zunächst 1000 ms. War in diesem Zeitraum kein Tastendruck, wird bei Programmende der Wert 0 geliefert. Mit jedem Tastendruck wird der oberste Wert auf dem Stack erhöht und die Uhr beginnt erneut zu laufen. Das Programm wird frühestens eine Sekunde nach Programmstart bzw. dem letzten Tastendruck verlassen. Nebenbei: Wer mindestens 256 Mal auf die Taste drückt, erlebt eine Überraschung J

: P-NR { --- n } 0             \ Dieses Programm liefert einen Wert; diesen initialisieren
10 AT100!                 \ Zeitgeber starten, nach 1000 ms ist die Uhr abgelaufen
BEGIN 4in 0=               \ Taste gedrückt? (gleichen Input wie in „Tastefrei“ verwenden!)
               IF 1+ brumm          \ ja, mitzählen, akustische Rückmeldung
                       Tastefrei          \ Prellen abwarten
                      10 AT100!     \ Zeitgeber beginnt wieder bei 1000 ms; ein internes Programm subtrahiert eine Einheit pro 100 ms.
               THEN
               AT100@ 0=          \ Zeit abgelaufen?
UNTIL ;                        \ Wert auf dem Stack gibt die Anzahl der Tastenbetätigungen an.

Damit sind die Vorbereitungen abgeschlossen, nun müssen die Einzelprogramme entworfen werden, die im Hauptprogramm „Start“ verwendet werden sollen. Zum Testen einige kurze Kostproben (Ihre Programm werden hoffentlich sinnvoller und länger sein):

: P1 beep ;
: P2 beep 100 ms beep ;
: P3 beep 100 ms beep 100 ms beep ;
: P4 P2 100 ms P2 ; \ con variazione J

Nun kommt das Hauptprogramm, das immer zuletzt vom PC an den ROBOprogy übermittelt und mit der Start/Stoptaste gestartet wird. Darin wird – je nach Anzahl der Tastendrucke am Digitalport 4in – eines der Programme P1, P2, P3.... aufgerufen und abgearbeitet:

: START { --- } \ dieses Programm ganz am Schluss übertragen, damit es per Start/Stoptaste gestartet werden kann!
        P-NR dup 0=                  \ kein Tastendruck?
        IF P1                             \ ja, dazugehörendes Programm aufrufen
        ELSE dup 1 =                \ nein, einmal gedrückt?
               IF P2
               ELSE dup 2 =
                       IF P3
                       ELSE dup 3 =
                              IF P4
                              ELSE brumm \ es gibt kein 5. Programm
                              THEN
                       THEN
               THEN
        THEN drop ;                 \ Prog-Kennziffer entfernen

So eintippen und testen – bei mir hat es geklappt.

Dieses letzte Programm lässt sich eleganter mit der Funktion DMODEJUMP schreiben. Das ist ein so genannter "computed jump", die notwendige Kennzahl liefert das Programm P-NR.

: START { --- } \ dieses Programm ganz am Schluss übertragen, damit es per Start/Stoptaste gestartet werden kann!
P-NR dm! \ Nummer holen und in der jump-Variablen speichern
DMODEJUMP P1 P2 P3 P4 JUMPEND ; \ zum gewählten Programm springen, fertig!

Das ist doch erheblich einfacher und übersichtlicher als ineinandergeschachtelte IF-ELSE-THEN-Bedingungen! Testen Sie selbst, was passiert, wenn man öfters als dreimal auf 4in drückt. eine genauere Beschreibung dieser sehr nützlichen Sprungbefehls findet man in der Befehlsliste.

Noch ein letzter Hinweis: Die in diesem Programm benötigte Hilfstaste am Digitalinput 4 kann in anderen Programmteilen sehr gute Dienste leisten, denn nach Ende der eben beschriebenen Programmauswahl, wenn also der Roboter tatsächlich startet, ist diese Taste „arbeitslos“. Ein pfiffiger Konstrukteur hat den Berührungssensor rechts vorn, der bei jedem anständigen Roboter zu finden ist, als Programmwähler „missbraucht“: Er drückt auf die Starttaste und wählt durch Antippen der Stoßstange das Programm. Wenn er sich vertippt, kann er jederzeit durch erneuten Druck auf die Starttaste abbrechen. Sobald der ROBO losfährt, ist die Programmauswahl beendet und ein anderes Programm wird den Stoßstangenkontakt richtig auswerten.

Platzbedarf: 101 Bytes (einschließlich P1..P4). Mit einigen Tricks kann man den Speicherbedarf  vielleicht auf 80 Bytes drücken.


© Herbert Weidner 2006-5

zur homepage