Projekte |
Übertragungsprotokoll RoboInterface -> Extension-Modul
Schon vor langer Zeit hatte
ich die Idee, das RoboInterface mit einigen zusätzlichen
Basteleien auszurüsten, z.B. Einem LC-Display. Von Anfang an bot
sich die Erweiterungsschnittstelle für das Extension-Modul an,
da hier ohne den Verlust von Aus- und Eingängen zusätzliche
Geräte angeschlossen werden können.
Da das Protokoll aus
Zeitgründen nicht direkt von fischertechnik verfügbar war,
habe ich mit einem Logik-Analysator die Datenübertragung
abgehört und anschließend ausgewertet. Freundlicherweise
bekam ich von fischertechnik die Erlaubnis, meine Erkenntnisse zu
veröffentlichen und damit allen Interessierten verfügbar zu
machen.
WARNUNG
Die nun folgenden Informationen habe ich nach bestem Wissen zusammengestellt. Dennoch kann ich nicht für die Fehlerfreiheit garantieren. Falls ein Fehler auftauchen sollte, bin ich natürlich sehr froh über eine Benachrichtigung.
Ich möchte auch darauf hinweisen, dass bei einer derartigen Nutzung der Extension-Schnittstelle immer mit Vorsicht vorzugehen ist. Bei falschem Anschluss oder Kurzschlüssen kann u.U. das Robo-Interface beschädigt werden – die Garantie erlischt beim Anschluss von ft-fremden Geräten. Eine Verwendung der hier offengelegten Daten geschieht auf eigene Gefahr. Für evtl. entstandene Schäden übernehme ich keine Haftung.
Die Schnittstelle wird mit 3,3V betrieben. Auf keinen Fall darf diese Spannung überschritten werden.
Die Hardware
Die Verbindung zwischen Robo-Interface und den Extension-Modulen wird durch ein 10-poliges Kabel hergestellt. Die Schnittstelle selbst wird mit 3,3V betrieben. Die Treiber des RoboInterface sind nur in der Lage, die Ausgänge auf GND zu ziehen (sog. „Open-collector“ - Ausgänge), deshalb sind seitens der Extension Pull-up Widerstände nötig. Im originalen EM werden hierzu Widerstände 22K gegen +3,3V benutzt.
|
|
(Steckeransicht von oben) |
---|---|---|
Die Steckerbelegung:
|
Typ:
(Aus der Sicht des RoboInterface)
|
|
Das Protokoll
Ich habe das Protokoll mit einem selbstgebauten 8-Kanal Logik-Analysator untersucht. Bei der Untersuchung per Oszilloskop kam nicht sehr viel heraus, weil mir dort nur zwei Kanäle zur Verfügung standen und dadurch die Synchronisation mit dem Datenprotokoll nicht funktioniert. Zur Analyse habe ich dann mehrere Kurven mit unterschiedlichen Motordefinitionen untereinander gelegt und dadurch relativ schnell herausgefunden, welcher Teil der Sequenz wofür zuständig ist.
Bild : Diagramm des Protokolls
Kanäle, Linie unten = logisch “0” (GND), Linie oben = logisch “1” (3,3V)
Im obigen Ausschnitt kann man sehen, dass 6 Datenpakete zu je 8 Bit übertragen werden. Die Übertragung beginnt, wenn die Adressleitungen (zur Adressierung später mehr) auf logisch “0” gelegt werden. Nach einer gewissen Wartezeit legt das EM die Leitung “EM Takt-Bestätigung” auf 0, dies veranlasst dann das Robo-Interface, die weiteren Datenpakete zu übertragen. Nach jedem Datenpaket wird die “EM Takt-Bestätigung” kurz auf Logisch “1” gelegt, um dem Robo-Interface den Empfang zu bestätigen. Die Datenpakete sind nach meinen momentanen Erkenntnissen folgendermaßen zugeordnet:
Ausgänge:
Byte Nr. |
Inhalt |
---|---|
1 |
(ziemlich sicher) ein Header, evtl. Für zus. Übertragungsmöglichkeiten (z.B. Seriennummer) |
2 |
8 Bit Ausgangsinformation, 0 = an, 1 = aus. In diesem Beispiel ist O1 an. Die Informationen werden in der Reihenfolge 8,7,...2,1 übertragen. |
3 |
24 Bit Geschwindigkeitsinformation, Byte 1 |
4 |
24 Bit Geschwindigkeitsinformation, Byte 2 |
5 |
24 Bit Geschwindigkeitsinformation, Byte 3 |
6 |
Funktion nicht bekannt. |
Eingänge:
Byte Nr. |
Inhalt |
---|---|
1 |
8 Bit Eingangsinformation (I8 – I1). Auch hier gilt: 0=Eingang ist geschaltet, 1=Eingang ist offen. |
2 |
Analogeingang AX, low-Byte. |
3 |
Analogeingang, low-Byte. |
4 |
Analogeingang, low-Byte. |
5 |
High-Bits der Analog-Eingänge (jeweils 2 Bit) |
6 |
Funktion nicht bekannt. |
Die
Daten sind bei einer steigenden Flanke von “Takt Daten”
gültig.
Die Geschwindigkeitsinformationen sind in 8 Blöcken zu je 3 Bit =24 Bit in Datenpaket
3,4 und 5 hineinkodiert. Hierbei gilt folgende Zuordnung:
O8: Byte 5, Bit 7,6,5
O7: Byte 5, Bit 4,3,2
O6: Byte 5, Bit 1,0 und Byte 4, Bit 7
O5: Byte 4, Bit 6,5,4
O4: Byte 4, Bit 3,2,1
O3: Byte 4, Bit 0 und Byte 3, Bit 7,6
O2: Byte 3, Bit 5,4,3
O1: Byte 3, Bit 2,1,0
Die Geschwindigkeitsinformation ist invertiert, d.h. %000 = max. Geschwindigkeit und %111 = min. Geschwindigkeit.
Das RoboInterface scannt von Zeit zu Zeit den Extension-Bus und beginnt mit der Übertragung der Daten, sobald sich ein EM mit einem Signal auf “EM Takt-Bestätigung” zurückmeldet.
Timing (ungefähre Werte)
Dauer
der Datenübertragung (1 EM) : ca. 1430 µs
Dauer eines Bits: (Takt Daten) : 10µs
Dauer eines Bytes (inkl. Rückmeldung EM): 112 µs
Antwortzeit des EM nach Empfang der Adresse: 700 µs
Aktualisierungsrate: 10 ms
Adressierung
Da mehrere EM (momentan drei, laut Aussagen im Forum bis zu sieben) an den gleichen Übertragungsleitungen angeschlossen sind, müssen Informationen mitübertragen werden, die sicherstellen, dass jedes EM “seine” Übertragung erkennt. Hierzu existieren 3 Adressleitungen. Wenn alle drei Adressleitungen auf logisch “1” liegen, ist der Extension-Bus inaktiv. Vom RoboInterface werden, bei 3 angeschlossen EM, nacheinander die entsprechenden Datenpakete mit der Adresse 0, 1 und 2 übertragen. Jedes EM
reagiert auf die Adresse “0” (=alle Adressleitungen auf “0”), wertet dieses Datenpaket aus, gibt aber die Adressinformationen verändert an der Ext.-OUT – Buchse aus. Indem jedes EM eine “1” von der Adresse subtrahiert, bekommt das nachfolgende EM das Datenpaket, das vorher noch mit Adresse “1” übertragen wurde, mit der Adresse “0” übertragen. Dadurch bestimmt allein die Reihenfolge der Verkabelung die Adresse des EM. Das folgende Bild zeigt vier Diagramme, die mit 3 EM an einem RoboInterface aufgezeichnet wurden:
Messpunkt zwischen RoboInterface und dem ersten EM
Messpunkt zwischen dem ersten und zweiten EM
Messpunkt zwischen dem zweiten und dem dritten EM
Messpunkt nach dem dritten EM
Man kann hier sehr schön sehen, wie sich die Adressierungssignale von Modul zu Modul verändern (jeweils die 4., 7. und 8. Linie von oben), während die Datenpakete selbst unverändert bleiben. Das RoboInterface sendet so viele Datenpakete, wie Module vorhanden sind. Nach dem dritten Modul existiert keine gültige Adresse mehr. Realisiert wird diese Umrechnung der Adressleitungen beim EM mit einem 74HC283, dies ist ein 4-Bit Volladdierer.
Die Realisierung eines eigenen Erweiterungsmoduls
Um nun eigene Basteleien an das RoboInterface anschließen zu können, muss man das Datenprotokoll entsprechend auswerten und die erforderlichen Signale generieren, die das RoboInterface als Antwort vom Extension-Modul erwartet. Ein kleiner Ablaufplan verdeutlicht dies:
Warten, bis die Adresse = 0 ist (A0 = 0, A1 = 0, A2 = 0).
Nach einer Verzögerung von ca. 700µs wird dem RoboInterface eine logische „0“ auf der Leitung „EM Takt Bestätigung“ gesendet. Ohne diese Bestätigung sendet das RoboInterface keine weiteren Daten.
Nun sendet das RoboInterface ein Datenpaket von 8 Bit. Gleichzeitig müssen die Daten der Eingänge an das RoboInterface gesendet werden.
Zur Bestätigung wird die Leitung „EM Takt Bestätigung“ kurz auf logisch „1“ geschaltet, anschließend wieder auf „0“.
Die Punkte 3 und 4 werden so lange wiederholt, bis 6 Datenpakete (= 6 Bytes) übertragen sind, anschließend werden alle Leitungen hochohmig geschaltet.
Ein weiteres Problem ist die Betriebsspannung des RoboInterface und der Extension-Module, die bei 3,3V liegt. Zwar können die meisten µC auch mit 3,3V betrieben werden, aber bei den LC-Displays ist eine Betriebsspannung von 5V noch recht weit verbreitet. Normalerweise arbeitet man dann mit sogenannten Levelshiftern, also ICs, die als Interface zwischen der 3,3V und 5V – Welt arbeiten. Durch die Open-Collector Ausführung der Extension-Schnittstelle lässt sich diese Pegelanpassung aber noch viel einfacher realisieren. Bei dieser Art der Beschaltung wird die Datenleitung durch einen Widerstand (sog. „Pull-Up“) auf den Pegel der Betriebsspannung, in diesem Fall 3,3V, gelegt. Durch einen Transistor kann die Datenleitung bei Bedarf auf Masse geschaltet werden. Damit ist es möglich, auch unterschiedliche Betriebsspannungen unter einen Hut zu bekommen. In unserem speziellen Fall bedeutet dies, dass der genutzte Atmel Mega-8 durchaus mit 5V versorgt werden kann, aber dennoch keine Gefahr für die 3,3V-Schnittstelle darstellt. Mit den eingehenden 3,3V-Pegeln hat der µC kein Problem, diese werden ohne Probleme richtig erkannt. Falls man das komplette Modul in 3,3V-Technik betreiben möchte, ist dies kein Problem und mit dem Weglassen des 7805 und einer Drahtbrücke schnell erledigt. Einzig der Max232 (Schnittstellentreiber für die RS-232-Schnittstelle) ist nicht für 3,3V geeignet, dieser muss gegen einen entsprechenden 3,3V-Typ (Max3232) ausgetauscht werden.
Um weitere Module nach dem Eigenbau anschließen zu können, muss die Adressierung entsprechend den Vorgaben der originalen Adressierung erzeugt werden. Um den µC von diesen lästigen Aufgaben zu entlasten, habe ich einen 4-Bit Volladdierer verwendet, der bei entsprechender Beschaltung auch eine 1 subtrahieren kann (da habe ich – zugegeben – etwas beim Extension-Modul gespickt). Allerdings muss diese Berechnung mit zwei Und-Gattern, die am Carry (Übertrag) Eingang angeschaltet sind, etwas korrigiert werden. Als Abfallprodukt bekommt man am höchstwertigen Ausgang des Addierers ein Signal, wenn das Modul adressiert ist. Prinzipiell könnte man auch den µC diese Aufgaben erledigen lassen, aber hierbei würden 5 weitere Ports verloren gehen.
Schaltplan des Eigenbau-Extension-Moduls (zur Vergrößerung auf das Bild klicken):
Hier ein Schaltplan des Eigenbau-Extension-Moduls als Eagle-Schaltplandatei.
Layout des Eigenbau-Extension-Moduls (zur Vergrößerung auf das Bild klicken):
Hier das Layout als Eagle-Datei.
Die Platine ist zwar nur einseitig geätzt, aber zweiseitig bestückt. Das von mir angefertigte Layout ist so ausgelegt, dass die Steckverbindungen auf der Lötseite angebracht werden. Vor allem bei den Anschlusssteckern für das RoboInterface ist ein Einlöten auf der Bestückungsseite mit diesem Layout nicht möglich, da dann die Pins des Anschlusssteckers gespiegelt sind.
Bei der Auswahl der Bauteile sollte beachtet
werden, dass ich bei den Elektrolyt-Kondensatoren sog.
"Miniaturausführungen" benutzt habe. Das Layout ist für einen max.
Durchmesser von 5 mm ausgelegt. Die 100nF-Stützkondensatoren sollten
Keramikkondensatoren sein.
Das Quarz mit der Frequenz von 7.3728 MHz hört sich zunächst recht
"krumm" an, es ist aber für eine möglichst genaue
Baudratengenerierung ausgelegt. Auch möglich sind 3.6864 MHz, 11.0592 MHz oder
14.7456 MHz. Die Initialisierung der seriellen Schnittstelle muss dann
entsprechend geändert werden. Soll die RS-232-Schnittstelle nicht benutzt
werden, kann auch eine andere Taktfrequenz (z.B. der interne Oszillator des
Mega-8) benutzt werden. Die Programmteile für das RoboInt sind nicht
Frequenzabhängig.
Zur Aktualisierung der Software des Mega-8 nutze ich die serielle Schnittstelle
in Verbindung mit einem Bootloader, deshalb empfehle ich die Bestückung mit dem
7.3728 MHz-Quarz. Eine ISP-Schnittstelle ist auf dem Layout nicht vorgesehen.
Foto der Bestückungsseite Foto der Lötseite
In den
ersten Experimentalversionen der Software habe ich noch jedes Bit
einzeln von der Schnittstelle gelesen, bis mir irgendwann in den Sinn
kam, dass die Datenübertragung doch auch mit der im Atmel
eingebauten SPI-Schnittstelle realisiert werden könnte. Dies
erspart einiges an Programmieraufwand, weil ein komplettes Byte
automatisch gelesen und gleichzeitig geschrieben werden kann. In
einer weiteren Optimierungsstufe habe ich die komplette Kommunikation
mit Interrupts realisiert, so dass die restliche Software im
Hauptprogramm abgearbeitet werden kann. Eine Einschränkung hat
diese Methode jedoch: Um nicht Teile von Daten zu verlieren, sollten
keine weiteren Interrupts verwendet werden, oder mit der
entsprechenden Vorsicht. Seit einigen Monaten habe ich C als
Programmiersprache entdeckt – ein relativ komfortabler
Makro-Assembler, der dem Programmierer einige lästige Dinge
abnimmt, es aber fast mit Assembler aufnehmen kann.
Insgesamt stehen 12 frei programmierbare Ein- und Ausgänge zur Verfügung.
Wenn das Selbstbau-EM mit den Spannungsversorgungsbuchsen nach rechts oben ausgerichtet wird, haben die Portstecker (JP3, JP5) folgende Belegung (jeweils von links nach rechts, s. auch Bild unten):
JP3 | GND | VCC (+5V) | PC0 | PC1 | PC2 | PC3 | PC4 | PC5 | RESET |
JP5 | PB1 | PB0 | PD7 | PD6 | PD5 | PD3 |
Hier die C-Datei (nur die Abfrage der Extension-Schnittstelle).
Ein handelsübliches Punktmatrix-Display mit HD44780-kompatiblem
Controller kann auf zwei Arten angeschlossen werden: Im 8-Bit oder im 4-Bit
Modus. Im 8-Bit-Modus werden inklusive Steuerleitungen insgesamt 11
Portleitungen benötigt. Zwar sind bei diesem Modul 12 Leitungen vorhanden, ich
habe mich aber für den 4-Bit-Anschluß entschieden, da hierbei noch 5
Portleitungen als Reserve verbleiben. Ein weiterer Grund ist, dass die Ports des
Mega-8 durch die Verwendung des Hardware-SPI für den RoboInt-Anschluss
teilweise belegt sind und deshalb kein vollständiger 8-Bit Port übrig ist. Man
müsste die 8 Bits sehr aufwändig auf verschiedenen Ports zusammenstellen. Die
Geschwindigkeit des LCDs wird vom 4-Bit Modus kaum beeinflusst.
Unten ein Beispiel für den Anschluss eines LCD. Achtung! Die Ausrichtung
der Anschlusspins kann, je nach Hersteller, variieren.
EM-Anschluss | LCD | Beschreibung |
JP3, Pin 1 (GND) | 1 | GND (Masse, Minuspol) |
JP3, Pin 2 (VCC) | 2 | Spannungsversorgung (+5V) |
JP3, Pin 3 (PC0) | 11 | D4 |
JP3, Pin 4 (PC1) | 12 | D5 |
JP3, Pin 5 (PC2) | 13 | D6 |
JP3, Pin 6 (PC3) | 14 | D7 |
JP5, Pin 4 (PD6) | 4 | RS (Register-Select) |
JP5, Pin 5 (PD5) | 5 | R/W (Schreib / Lesezugriff) |
JP5, Pin 6 (PD3) | 6 | Enable (Controller - Freigabe) |
An Pin 3 des LCD muss noch ein Potentiometer für den Kontrast angeschlossen werden (siehe hierzu Datenblatt des Display-Herstellers). Bei mir haben bislang alle Displays recht gut funktioniert, wenn ich den Kontrast-Eingang einfach mit Masse (GND) verbunden habe. Die Spannungsversorgung und der Kontrast ist beim nun folgenden Bild nicht mit eingezeichnet. Die Pins 7 - 10 des Displays müssen mit Masse (GND) verbunden werden.
Für erste Experimente habe ich eine Testsoftware geschrieben, die auf einem 16x2 Display in der oberen Zeile den Zustand der Ausgänge ausgibt, in der zweiten Zeile die Geschwindigkeitsinformationen. Die verschiedenen Aufgaben (Datenverkehr mit dem RoboInterface = spi.c und Datenverkehr mit dem LCD = lcd.c) wurden in getrennte Dateien ausgelagert, um die Übersicht etwas zu verbessern. Im ZipFile inklusive ist auch das Makefile, das für eine Compilierung mit dem WinAVR-Paket des AVR-GCC ausgelegt ist (zur Vertiefung der C-Kenntnisse in Verbindung mit dem AVR empfehle ich das AVR-GCC Tutorial auf http://www.mikrocontroller.net).
Nach Start des Controllers zeigt das Display "Not connected" an, sobald Übertragungen vom RoboInterface empfangen werden, werden die Informationen auf dem LCD angezeigt. Zusätzlich zählt das EM die Eingänge und den Analog-Eingang hoch, um auch den umgekehrten Übertragungsweg zu prüfen.
Die C-Files und das fertig compilierte Hex-File können hier heruntergeladen werden.
Zunächst einmal muss man sich Gedanken machen, wie man
aus RoboPro heraus Daten versenden kann. Zur Verfügung stehen uns insgesamt 4
Bytes, 1 Byte repräsentiert den Zustand der Ausgänge und weitere 3 Byte
beinhalten die Geschwindigkeitsinformationen.
Wichtig: Die Geschwindigkeitsinformationen werden aus RoboPro nur dann
übertragen, wenn der zugehörige Ausgang auch eingeschaltet ist. Daraus ergibt
sich, dass die Geschwindigkeitsinformationen nicht verwendet werden können,
wenn man über die Motorausgänge Daten versenden möchte, weil man ja nie
weiß, welcher Ausgang ein- oder ausgeschaltet ist. Deshalb übertrage ich die
Daten folgendermaßen: Der "Datenbus" (=1 Byte) wird über die
Geschwindigkeitsinformationen übertragen, die Ausgänge 1,2,3 müssen
zwangsläufig eingeschaltet sein. Ausgang 8 nutze ich als Signalleitung, um dem
LCD-Modul mitzuteilen, wann neue Daten vorhanden sind.
Die C-Files, das fertig compilierte Hex-File und ein kleines RoboPro - Programm können hier heruntergeladen werden.
Dieses Programm befindet sich noch in der Beta-Phase, ich
möchte noch die einfachere Implemetierung verschiedenster LCD-Größen
vereinfachen, außerdem die Textausgabe noch verfeinern, z.B. die Ausgabe von
vordefinierten Texten (das ist schneller). Die freien Eingänge sollen
noch für eine kleine Tastatur genutzt werden.
Mit dem RoboInterface ist es unmöglich, Servos direkt
anzusteuern, da diese ein sehr präzises Timing benötigen.
Üblicherweise werden Servos mit Impulsen angesteuert, die im Bereich von 1-2ms
liegen. Manche Servos können auch kleinere und größere Impulswerte nutzen und
dadurch größere Stellwege realisieren.
Der Einfachheit halber habe ich zunächst 4 Servos angesteuert, theoretisch
könnte man bis zu 12 Servos anschließen.
Die Impulsleitungen der Servos werden an PC0 ... PC3 angeschlossen (s.
Anschlussbelegung oben)
Die C-Files, das fertig compilierte Hex-File und ein kleines RoboPro - Programm können hier heruntergeladen werden.
Dieses Programm befindet sich noch in der Beta-Phase, ich möchte noch die Parametrisierung der Servos über die serielle Schnittstelle ermöglichen, um für jeden Servo ein eigenes Profil anlegen zu können (Offset und Faktor). Diese Daten sollen dann im EEPROM des Controllers abgespeichert werden.
Es stehen (fast) alle Möglichkeiten offen. Noch in
Planung sind u.a.:
- Schrittmotor-Ansteuerung.
- Ansteuerung von alten Parallel-Interfaces.
- I²C (TWI) - Ansteuerung (wird bereits durch die Hardware des Mega-8
unterstützt)
- Nutzung der Analog-Eingänge des Mega-8 (bis zu 6, je 10 Bit Auflösung)
- Ansteuerung eines Grafik-Displays (T6963-Controller)
Projekte |