Test der RGB-LEDs mittels PWM

 Nachdem die Motoren des Roboters erfolgreich mit dem noch recht neuen STM-Board über PWM angesteuert wurden, musste nun noch ein Test mit den RGB-LEDs erfolgen. Hier war nicht die Frage, ob PWM funktioniert, sondern viel mehr, ob die 3,3 Volt Pegel einwandfrei mit den Optokopplern funktionieren. Die Optokoppler sind nämlich hier nötig, da die RGB-LED-Streifen mit 12 Volt angesteuert werden. Das Ergebis war aber erfreulich:

  

Übrigens die im Bild verwendeten Kabel zum Verbinden des STM-Boards habe ich bei Watterott bestellt.

Und wen es interessiert, wie die LED-Streifen angesteuert werden:

Motortest mit STM-Board über die serielle Schnittstelle

 Mittlerweile wurde der Sourcecode vervollständigt, um alle vier Motoren per PWM und mit den jeweiligen Portbits anzusteuern. Hierzu die Fotos wo die Ansteuerung über den seriellen Port erfolgt:

Hier im linken Bild rechts unten sieht man die (rote) Platine, welche die USB-Verbindung zum steuernden Rechner darstellt. Von hier aus werden (gerade in einem Terminal-Programm) die seriellen Befehle gesendet. Das USB-Kabel am STM-Baord dient nur zur Stromversorgung (und zum Flashen):

   

Erste Tests mit dem STM-Board und dem Roboter

 Die Arbeit mit dem STM-Board macht Fortschritte: Beim letzten Update wurde der Code für das ARM-Board derart aktualisiert, dass 2 Bits als Ausgänge definiert wurden. Diese wurden in fliegender Verdrahtung mit einander verbunden, so dass die Eingänge des Motorcontrol-Boards direkt am STM32F4-Board angeschlossen wurden. Interessant ist hierbei, dass das Motor-Board – entgegen den 3,3 Volt des STM-Boards –  5 Volt-Logik aufweist. Das geht jedoch in dieser Richtung, da die 3,3 Volt (HIGH) am Ausgang auch als HIGH vom Motorcontroll-Board akzeptiert werden weil sie innerhalb der Spezifikation liegen. Und so sieht das Ganze dann aus:

Nun wurde das das STM-Board per USB mit dem MacBook verbunden, ein Terminal-Programm gestartet, welches Befehle an das STM-Board sendet:

   

 

 
Und: Es fuktioniert! Der Motor 1 dreht in beide Richtungen entsprechend der seriellen Befehle – wie zuvor mit dem Atmel-Board. Und im Sourcecode wurden lediglich die neuen ARM-Ports angegeben und die Befehle zum Bit-Setzen und -Löschen angepasst. Als nächstes muss geprüft werden, wie bei dem ARM-Board PWM funktioniert, damit z.B. die Motorgeschwindigkeit Richtung Motorcontrol-Board „gesendet“ werden kann.
 
Das Gute an dem Motorcontrolboard: Die benötigte PWM-Spannung Vpwh kommt hier ebenfalls mit 3,3 Volt klar (min. 3,25 Volt). Die Versorgungsspannung des verwendeten Motortreiber ICs VNH2SP30-E benötigt jedoch mindestens 5,5 Volt und maximal 16 Volt – aber diese stehen auf dem Bot ja ohne weiteres zur Verfügung.

Serielle Übertragungen vom STM-Board zum Computer über USB

Es geht voran mit dem STM32F4-Discovery Board!

Um es vorweg zu nehmen: Die folgende serielle Übertragung geschieht nicht über die bereits auf dem STM-Board verbauten USB-Ports. Nach Studium diverser Threads im Internet erwarb ich ein neues IC, welches in der Lage ist, den seriellen Port des ARM-Prozessors (USART) in einen USB-Port zu wandeln. 

Das Ganze ist auf einem sogenannten Breakout-Board von Sparkfun gleich praktisch fertig verlötet, man muss nur noch Stiftleisten hinzufügen. Zum Einsatz kommt hier der Baustein FTDI232R, der keine weiteren Bauteile mehr benötigt und auch gleich mit den 3,3 Volt Logiklevel des STM-Boards klar kommt. Entgegen dem Datenblatt von FTDI müssen bei der Verbindung zwischen dem Breakoutboard drei Leitungen verlötet werden: TX mit RX und RX mit TX und natürlich die gemeinsame Masse, GND. Wer will könnte auch noch gleich zwei Hardware flow control Leitungen mit anschließen – beide Boards unterstützen dieses. So sieht die Testverbindung dann mit den Steckern aus:

 

Hier das Breakout-Board mit dem FTDI-Chip und der USB-Buchse (rechts, mit oranger Schutzfolie) noch einmal im Detail:

  

Und so wird das Ganze dann zum Testen angeschlossen: Das schwarze USB-Kabel, welches zum STM-Board führt, dient hier nur zum flashen des selbigen und zur Stromversorgung. Das transparente USB-Kabel, welches zum FTDI-Board geht, ist das Kabel, welches dann zum PC oder Mac geht. Wird dieses dann angeschlossen, erscheint z.B. unter Linux und Mac OS X ein Device namens /dev/tty.xxxxx bzw. /dev/ttyUSBx. Beim Mac enthält „xxxxx“ gleich eine einmalige Seriennummer. Bestellt hattee ich das Board übrigens bei Watterott (ca. 14 EUR).

  

Hier sind beide Boards dann mal zum Testen am „PC“ des Roboters angeschlossen:

 

Später sollen dann die Daten vom PC des Roboters zum STM-Board (über den FTDI-Chip) und zurück fließen. Diese Aufgabe übernimmt derzeitnoch ein Atmel-Board mit einem Atmega 2560. Tipp: Auf dem STM-Board gibt es diverse USART, wovon aber einige bereits z.B. durch den vorhandenen USB-Port belegt sind! Ich habe mich daher für den noch freien USART2 entschieden.

 

Erstes serielles Testprogramm für das STM-Discovery Board

Nach etwas Suche im Netz fand ich hier und hier Beispiele für serielle Übertragung vom STM-Board. Um es vorweg zu nehmen, das zweite Beispiel verwendet die Open Source Bibliothek libopenmc3. Ich habe mit dem dortigen USART Beispiel lange experimentiert und das Senden war auch erfolgreich. Auch das Empfangen von Daten am STM-Board lieg gut. sobald ich jedoch den TX_RX-Modus aktivierte, ging das Senden nicht mehr. Vielleicht hat jemand eine Lösung – mir gelang es nicht. Ich bin daher wieder zurück auf die Standard-Library von STM gewechselt und mit dem ersten Beispiel dann mit Senden und Empfangen erfolgreich gewesen.

Der folgende Aufbau ist jedoch erst einmal noch „nur Senden“ vom STM-Board Richtung Mac / PC [Update: Auch der Empfang ist mittlerweile (ohne libopenmc) gelöst, hierzu später mehr]

Um hier zu sehen, ob das funktioniert, konnte ich endlich mal meinen Logik Analyser testen. Für alle, die dieser Analyser interessiert, er ist erhältlich bei Saleae und bietet tolle Analysemöglichkeiten. Und das Beste: Die dazugehörige Software läuft unter Linux, Windows und Mac OS!

Das serielle Beispiel sendet nun Zeichen vom STM-Board ausgehend. Die seriellen Signale können dan direkt an einem der Pins abgegriffen werden. Achtung: Die seriellen Ports des STM-Boards dürfen nicht direkt an einen PC angeschlossen werden, da das STM-Board nur mit 3,3 Volt also „logisch HIGH“ arbeitet“. Der PC aber mit 5 oder gar 15 Volt!

Der Versuchsaufbau sah dann wie folgt aus:

 

Hier der entscheidende Ausschnitt des Sourcecodes:

Sehr schön ist hier in der Software des Logic Analysers nun das serielle Protokoll zu erknnen – bzw. die gesendeten Zeichen, die übertragen werden:

 

 

Diese Woche gibt es Updates…

 So, lange gab es keinen neuen Artikel… Hintergrund ist, das zurzeit an einer sehr umfänglichen Umstrukturierung an der direcs-Software gearbeitet wird. Hierzu wurde extra im Sourcecode-Repository ein separater Branch eröffnet, da die grundsätzliche Arbeitsweise rund um den seriellen Port geändert wird. Ursache waren diverse Probleme in der Vergangenheit mit der Kommunikation zwischen PC / Mac und dem Roboter. Aber dazu in den nächsten Tagen mehr…

coding, coding, coding…

Nachdem es in der Vergangenheit öfter Probleme mit der seriellen Übertragung gab, fiel der Entschluss, alle Übertragungen zwischen dem Atmelboard und dem Computer nicht mehr in Binärform sondern in reinem ASCII zu senden. Dazu wurde im git Repository ein neuer Branch namens AtmelSerialClearText angelegt und seit Mitte August immer mal wieder daran gearbeitet. Nun ist es endlich soweit, nahezu alle Funktionen sind komplett auf die neue Übertragungsmethode umgestellt – sowohl auf Computer, als auch auf Atmel-Seite. Wie man sieht, waren dazu doch einige Änderungen nötig:

Merge made by recursive.

 direcs-avr/adconv.c         |   33 ++

 direcs-avr/adconv.h         |    6 +

 direcs-avr/main.c           | 1040 +++++++++++++++++++++++++++++————–

 direcs-avr/main.h           |   13 +-

 direcs-avr/micromag.c       |    4 +

 direcs-avr/usart.c          |  174 ++++++–

 direcs-avr/usart.h          |   38 ++-

 direcs/direcs.tag           |  193 ++++++–

 direcs/src/circuit.cpp      |  112 ++++-

 direcs/src/circuit.h        |   39 ++-

 direcs/src/direcs.cpp       |  127 +++++-

 direcs/src/direcs.h         |   19 +-

 direcs/src/direcsSerial.cpp |   65 ++–

 direcs/src/direcsSerial.h   |    2 +-

 direcs/src/gui.cpp          |   79 ++++-

 direcs/src/gui.h            |   37 ++-

 direcs/src/interfaceAvr.cpp |   98 ++++

 direcs/src/interfaceAvr.h   |   58 ++-

 direcs/src/mainWindow.ui    |   86 +++-

 direcs/src/motor.cpp        |  792 +++++++++++++++++++++———–

 direcs/src/motor.h          |   46 +-

 direcs/src/plotThread.cpp   |   47 ++-

 direcs/src/plotThread.h     |   14 +-

 direcs/src/sensorThread.cpp |  495 +++++++++++———-

 direcs/src/sensorThread.h   |   27 +-

 25 files changed, 2540 insertions(+), 1104 deletions(-)

Zusätzlich wurde das serielle Verfahren auf dem Atmel ebenfalls vollständig neu geschrieben und arbeitet nun – anstatt in einer Endlosschleife auf den Empfang eines Zeichens zu warten – vollständig interruptbasiert.

Wie aber weiß nun der Atmel, wann eine Übertragung für ihn anfängt oder abgeschlossen ist? ganz einfach: Jede Übertragung muss mit einem ‚*‘ starten und mit einem ‚#‘ enden. Alle anderen Zeichenketten werden ignoriert. Eine Signalisierung über LEDs auf der Platine findet ebenfalls statt: Bei jedem empfangenen Zeichen blinkt die rote LED abwechselnd und sobald das Ende eines Befehls mit # erkannt wurde (und zuvor auch mit * startete!) wird dieses über eine grüne LED angezeigt.

Diese Art der Übertragung hat den Vorteil, dass man sie per Terminalprogramm gut debuggen kann, denn es werden nur ASCII-Zeichen verwendet. Zusätzlich antwortet der Atmel auch immer mit der empfangenen Zeichenkette, die wiederum vom Computer als Antwort überprüft wird. Eine neue Sicherheitsfunktion, die zuvor fehlte. Auch kann man dem Atmel so selbst mit einem Terminalprogramm Befehle senden und „sieht“ was er antwortet. Fragt man einen Wert vom Atmel ab, so antwortet er nur mit diesem Wert und dem Starter und Terminator, also z.B. mit *42#.

Und das sind die derzeitigen Befehle:

re = reset

s1 = get value from sensor 1

s8 = get value from sensor 8

s16 = get value from sensor 16

cc = check if compass module is connected. ‚ok‘ or ‚er‘

cx = get value from compass axis x

cy = get value from compass axis y

cz = get value from compass axis z

ms1 = get value from motor sensor 1

ms4 = get value from motor sensor 4

dd1 = get driven distance 1

..

dd4 = get driven distance 4

id1 = init distance 1

id4 = init distance 4

mp1of = motor power 1 off

mp4of = motor power 4 off

md1cw = motor direction 1 clockwise

md4cw = motor direction 4 clockwise

md1cc = motor direction 1 counterclockwise

md4cc = motor direction 4 counterclockwise

mv1nnn = set motor velocity 1 to nnn (0-255)

mv4nnn = set motor velocity 4 to nnn (0-255)

mv0nnn = set motor velocity for all motors to nnn (0-255)

bdf = bot drive forward

bdb = bot drive backward

bdl = bot drive left

bdr = bot drive right

btl = bot turn left

btr = bot turn right

bgo = bot go

bst = bot stop

bwa = bot wait

Serielle Probleme gelöst (Mac und Linux)

Lange hat sich nichts getan, da berufliche Dinge vorgehen (und damit auch Freizeit ohne Arbeit am Mac nötig waren).

In der Zwischenzeit wurden endlich alle(?) seriellen Probleme gelöst: Der neue Laserscanner S300 funktioniert nun am Mac (mit einem Standard-USB-Wandler) und unter Linux (Debian). Letzteres jedoch nur mit dem Original USB-Wandler von Keyspan! Ein Vorteil bei dem vielen Debuggen: Der Sourcecode für das öffnen, lesen und schreiben am Mac und unter Linux sind nun endlich wieder identisch! Keine unschönen #ifdefs mit Ausnahmen oder ähnlichem (openAtmelPort). Das Ganze funktioniert ebenfalls alles auch mit dem Atmel-Board.

Serieller Port für Atmel-Board nun Mac OS X-Ready

Geschafft! Nach vielen Versuchen konnte der Code zum Ansprechen des seriellen Ports für Mac OS X (10.6, Snow Leopard) so angepasst werden, dass er dort läuft. Zuvor "hing" das Programm immer beim write() Befehl. Interessanterweise trat das gleiche auch dem Original-Code "Device File Access Guide  for Serial Devices" aus dem Mac Dev Center von Apple auf. Benötigt wird dieser Teil im Programm um vom Mac oder PC Daten über die seriellen Schnittstelle zum Roboter (Atmel-Board) zu schreiben und von ihm zu lesen.

Das aus MacPorts installierte Programm minicom brachte dann die Lösung: Mit diesem konnte über zwei USB-to-Serial-Wandlern (PL2303-Chip) und einem Cross-Cable jeweils Daten gesendet und empfangen werden. Dank Open Source, konnte nun verglichen werden, warum dieses Programm einwandfrei funktioniert, der Apple Code aber nicht.

Ursache war die Kontroll-Option "CLOCAL", die für den seriellen Port gesetzt werden musste! :-) Geholfen hat auch Beschreibung auf dieser Seite. Denn es wurde nicht der Original-Treiber des Hersteller Prolific zum Testen (mit minicom) verwendet, sondern der hier beschriebene Open Source-Treiber!

Nach ein "paar" Änderungen im Code läuft der Bot nun auch unter Mac OS X:

 Als nächster Schritt wird nun der Code für den altern Laserscanner angepasst, da er ein ähnliches Verhalten aufweist.

Support für SICK Laser PLS101-312 und Atmelboard wiederhergestellt

Nach vielen Tests mit dem seriellen Port konnte nun der Support für beide seriellen Zugriffe wiederhergestellt werden. Ursache war ein Bit namens CLOCAL, welches beim Öffnen unter Mac OS gesetzt werden muss! Leider ist dieses auch mit keinem Wort auf Apples Mac Dev Center Seiten erwähnt!

 

Linux verhielt sich hier offenbar anders. Wie man sieht, alles wieder "heil":