Elektronik und Roboterbau
AVR, avr-gcc, CAN, CPLD, Elektronik, Mikrocontroller, MSP430, PIC, Roboter, Schaltungen, Sensoren, Software, Testboards
Tags: AVR,
Software
Stand: 25. Oktober 2006, 17:03
19 Kommentar(e)
Wie der Name schon andeutet wurde der Servocontroller auf Basis der RS232 Version von RNKC10 jetzt um die Möglichkeit auch I/O-Pins zu steuern erweitert. Geplant ist außerdem S8IO auch um eine I2C Version zu erweitern, allerdings fehlt mir im Moment die Zeit dazu.
Es hat sich gezeigt, dass niemand einen Servocontroller gleichzeitig per RS232 und I2C ansteuern will. Warum auch? Der logische Schritt war also diese Funktionalität zu trennen und dafür die einzelnen Versionen zu überarbeiten. Außerdem kam der Wunsch auf, auch I/O-Pins steuern zu können. Das Ergebnis daraus ist also S8IO.
Wie man sieht wurde der Funktionsumfang des RNKC10 gehörig aufgestockt. Dafür ist der AVR jetzt auch zu fast 97% Prozent belegt wenn man alle Funktionen aktiviert. An- und abschalten lassen sich diese im Quelltext per einfachen #defines
.
Als Quarzfrequenzen für Q1 werden 4, 7.3728 und 8 MHz unterstüzt. Bei niedrigen Baudraten und Verwendung des ATTiny2313 ist es möglich dessen internen Oszillator mit 8 MHz zu benutzen und damit den Quarz komplett wegzulassen. Bis zu welcher Baudrate das funktioniert hängt vom dem jeweiligen AVR ab und müsste selbst ausprobiert werden. Alles bis 19,2k Baud sollte aber mit Einschränkungen möglich sein darstellen.
Bei der Wahl des Quarzes sollte man vor allem überlegen welche Baudraten man verwenden will (siehe Baudraten Tabelle).
Die Baudrate beträgt in der Grundeinstellung 9600 Baud, kann aber im Betrieb bzw. beim neu kompilieren geändert werden.
Die Übertragung beginnt immer mit einem Synchronisationsbyte, in diesem Fall das Raute Zeichen (#
, 0x23 als ASCII-Zeichen), gefolgt von einem Byte das die Funktion auswählt. Folgende Zeichen können genutzt werden:
Zeichen | Hex-Wert | Funktion |
---|---|---|
S | 0x53 | Servoposition setzten |
s | 0x73 | Servoposition auslesen |
O | 0x4F | IO-Pins als Ausgang setzten |
I | 0x49 | Zustände der Eingangspins lesen |
C | 0x43 | erweiterte Konfiguration |
‘#S’ + Nummer + Position des Servos
Es wird als zuerst die Adresse des Servos gesendet. Die Adressen von 0 bis 7 stellen dabei den normalen Drehbereich der Servos dar, über die Nummern 8 bis 15 erreicht man die gleichen Servos, allerdings im erweiterten Drehbereich.
Servo Adresse 0 und 8 sprechen also beide das Servo an PORTB.0 an.
Danach wird in einem Byte die Soll-Position des Servos gesendet.
Um das Servo 2 auf Position 10 (0x0a) zu bringen müsste man folgendes senden:
0x23 0x53 0x02 0x0a
‘#s’ + Nummer des Servos
Auch hier muss noch die Servo-Adresse gesendet werden. Man bekommt daraufhin ein Byte mit der aktuellen Position zurück.
‘#O’ + Maske + Zustand
Um auch nur einzelnen Pins als Ausgangs setzen zu können wird hier mit Masken gearbeitet. Es wird also zuerst eine Maske gesendet in der alle Pins die als Ausgang gesetzt werden sollen markiert sind, und erst dann die jeweiligen Zuständen der Pins.
Es werden somit auch nur die Pins die in der Maske gesetzt waren wirklich als Ausgänge geschaltet, alle andere behalten ihre aktuelle Funktion.
In der folgenden Tabelle ist der Zusammenhang zwischen den Bytes und dem Ergebnis dargestellt:
Maske.n | Zustand.n | Pin.n |
---|---|---|
0 | x | vorherige Funktion |
1 | 0 | Ausgang mit Low-Pegel |
1 | 1 | Ausgang mit High-Pegel |
Bit.3 (= 0x08 als Maske) auf High-Pegel setzen:
0x23 0x4F 0x08 0x08
Zusätzlich Bit.6 auf High-Pegel und Bit.2 auf Low-Pegel:
0x23 0x4F 0x4C 0x48
weitere Beispiele:
IO_2 (Pin 6) Ein : 0x23 0x4F 0x04 0x04
IO_2 (Pin 6) Aus : 0x23 0x4F 0x04 0x00
IO_3 (Pin 7) Ein : 0x23 0x4F 0x08 0x08
IO_3 (Pin 7) Aus : 0x23 0x4F 0x08 0x00
IO_4 (Pin 8) Ein : 0x23 0x4F 0x10 0x10
IO_4 (Pin 8) Aus : 0x23 0x4F 0x10 0x00
... ...
‘#I’ + Maske
Auch hier muss zuerst eine Maske gesendet werden die angibt welche Pins als Eingang geschaltet werden sollen. Daraufhin bekommt man ein Byte mit dem aktuellen Zustand der Eingangspins zurück. Alle Bits die in der Maske nicht gesetzt werden waren sind auch in diesem Byte nicht gesetzt.
Zustand von Bit.2 und Bit.4 lesen:
0x23 0x49 0x14
=> sendet (Eingangswert & 0x14) zurück
Hier sind wiederum folgende Funktionen möglich:
Zeichen | Hex-Wert | Funktion |
---|---|---|
V | 0x56 | Version anzeigen |
S | 0x53 | erweiterten Drehbereich einstellen |
s | 0x73 | aktuelle Servopositionen im EEprom speichern |
o | 0x6F | aktuellen Zustand der IO-Pins speichern |
O | 0x4F | Servo Offset einstellen |
B | 0x42 | Baudrate einstellen |
‘#CV’
Liefert zwei Bytes mit der aktuellen Version des Codes zurück. Das erste Byte gibt dabei die Stelle vor dem Komma an, das zweite dementsprechend die Stelle hinter dem Komma.
Aktuell ist “1.0”.
‘#CS’ + Nummer des Servos + Min. Wert (2 Byte) + Max. Wert (2 Byte)
Über dieses Kommando kann man direkt die mimalen und maximalen Timerwerte, die zur Erzeugung der Servoimpulse benutzt werden, setzen.
ACHTUNG: Wird ein zu großer Bereich gewählt kann dies dazu führen das das Servo in den Endanschlag fährt und somit beschädigt wird. Wenn man also den größtmöglichen Drehbereich braucht sollte man sich langsam an diesen herantasten!
Die Syntax ist dabei immer ‘#CS’ + Nummer des Servos + Min. Wert (2 Byte) + Max. Wert (2 Byte). Die passenden Werte für den Minimal und den Maximal Wert lassen sich zum Beispiel per AVRClac berechnen.
Verwendet wird Timer 1 im Overflow-Interrupt-Modus mit einem Prescaler von Eins. Damit ergeben sich zum Beispiel folgende Werte:
Impulslänge | 4 MHz | 7,3728 MHz | 8 MHz |
---|---|---|---|
0,5 ms | 0xf830 | 0xf19a | 0xf060 |
0,8 ms | 0xf380 | 0xe8f6 | 0xe700 |
1,0 ms | 0xf060 | 0xe334 | 0xe0c0 |
1,5 ms | 0xe890 | 0xd4cd | 0xd120 |
2,0 ms | 0xe0c0 | 0xc667 | 0xc180 |
2,2 ms | 0xdda0 | 0xc0a4 | 0xbb40 |
2,5 ms | 0xd8f0 | 0xb800 | 0xb1e0 |
Die neu gesetzten Werte sind erst nach einem Reset des Mikrocontrollers aktiv, bleiben aber auch ohne Spannung erhalten!
Sobald man als einen der Werte 0xffff sendet werden bei nächsten Reset wieder die Default-Werte für das Servo (0,8 bis 2,2 ms) gesetzt.
Um den Drehbereich auf 0,5 bis 2,5 ms auszudehnen muss folgendes gesendet werden (bei 4 MHz):
0x23 0x43 0x53 0x00 0xd8 0xf0 0xf8 0x30
‘#Cs’
Speichert alle Servopositionen im EEprom und stellt sie bei einem Rest des Mikrocontrollers wieder her.
‘#Co’
Macht das gleiche wie das Servopositionen speichern, nur für die IO-Pins.
‘#CO’ + Nummer + Offset
Ermöglicht einen Offset im Bereich von -128 bis 127 zu definieren, der jeweils auf die Servoposition addiert wird. Somit lässt sich zum Beispiel die Nullposition noch genau justieren.
ACHTUNG: Größere Werte sollten eher durch das Umsetzen des Servohebels erreicht werden, da sich ansonsten der mögliche Drehbereich einschränkt.
‘#CB’ + Baudrate
Hier muss noch ein Byte gesendet werden das die einzustellende Baudrate definiert. Folgende Tabelle zeigt die Möglichkeiten:
Byte | Baudrate | Verfügbar bei | ||
---|---|---|---|---|
4 MHz | 7,3728 MHz | 8 MHz | ||
0 | 2400 | ja | ja | ja |
1 | 4800 | ja | ja | ja |
2 | 9600 | ja | ja | ja |
3 | 14,4k | ja | ja | |
4 | 19,2k | ja | ja | ja |
5 | 28,8k | ja | ||
6 | 38,4k | ja | ja | |
7 | 57,6k | ja | ||
8 | 115,2k | ja |
Folgender Befehl ändert die Baudrate auf 19,2k Baud:
0x23 0x43 0x42 0x04
Der Quelltext zu S8IO steht unter der GNU General Public License (GPL). Eine Kopie der GPL liegt dem Projekt bei.
Kommentare
# Rainer Poisel meinte am 2. November 2006, 23:12 dazu:
Servus,
Danke für diese Informative und gut aufgebaute Seite!! Der Servocontroller hat auf Anhieb auch auf meinem Atmega8 funktioniert. Hab nur ein paar Ports geändert, damit ich meinen externen Quartz weiterverwenden kann.
Hier gibts das: s8io_atmega8.zip
Das .hex-File im Archiv ist direkt für den Atmega8. Kompiliert hab’ ich’s mit avr-gcc-3.4.6.
MfG und Danke,
Rainer
# Hunibert meinte am 29. Januar 2007, 19:15 dazu:
Hallo, welches Programm verwendest Du zum Senden der Hex-Codes?
Gruß
# Fabian Greif meinte am 29. Januar 2007, 20:54 dazu:
Zum Testen verwende ich unter Windows HTerm und unter Linux kleine selbstgeschriebene Python-Scripte.
# Herbert meinte am 6. März 2007, 09:03 dazu:
Auch Sehr zu Empfehlen unter Windows ist Docklight. Docklight ist ein Test-, Analyse- und Simulations-Werkzeug für serielle Kommunikationsprotokolle (RS232, RS485/422 und andere www.docklight.de/index_de.htm Gruß Herbert
# Criss meinte am 18. Juni 2007, 20:25 dazu:
Ich habe bis jetzt alles ausprobiert aber der µC Reagiert nicht ich habe sowohl einen AT90S2313 als auch einen ATtiny2313 getestet mit 7,68628MHz aber weder auf das Kommando den Servo auf eine Position x zu fahren noch nur einfach eine Versionsantwort von dem µC zu erhalten (#CV) zeigen Ergebnisse. Die Schnittstelle an sich geht, da ich Testweise ein anderes Programm auf den µC laufen lies. Daher meine Frage was mache ich Falsch?
# Fabian Greif meinte am 18. Juni 2007, 21:15 dazu:
Warum den einen 7,68628 MHz Quarz? Ich hab den Wert mal in die Baudraten-Tabelle aufgenommen. Mit 19,2k und kleiner 9600 Baud sollte eine Verbindung machbar sein.
Hast du den Wert entsprechend im Makefile geändert und neu compiliert? Du kannst ja probehalber ein
uart_putc('a')
oder so ans Ende der Initialisierung (hinter dassei();
) schreiben und schauen ob du das Zeichen richtig empfängst.# Criss meinte am 18. Juni 2007, 22:29 dazu:
Super geht alles. Danke
# Jörg meinte am 15. Juli 2007, 18:42 dazu:
Vollgeil ! Funzt auf Anhieb ! Danke !!
# Max Matteo meinte am 31. Juli 2007, 22:04 dazu:
Super tolle Seite.
Muss man bei mehreren Positionierungen das ?#? auch mehrmals senden?
Grüße Max
# Herbert meinte am 11. August 2007, 10:01 dazu:
Suche C++ Programmierer, Wir arbeiten derzeit an einer Serverbasierenden Software, die den S8IO in all seinen Funktionen unterstützen soll. Mehr Info: http://robotrack.dyndns.org/phpkit/004_s8io.htm
Gruß Herbert
# Herbert meinte am 16. August 2007, 18:33 dazu:
Super tolle Seite, aber wie soll man sich
Austauschen
wenn kein Forum da ist..?? Bitte mach da was?!Gruß Herbert
# Fabian Greif meinte am 16. August 2007, 22:26 dazu:
Ich hab testweise mal ein Forum auf den Webserver geworfen, zu erreichen unter: http://forum.kreatives-chaos.com/.
# Dennis meinte am 28. Oktober 2007, 11:51 dazu:
Hallo erstmal,
finde die Erklärung hier echt spitze Daumen hoch. Ich bau mir grade auch zwangsweise ne kleine Servosteuerung zusammen (2 Servos und ein Relais)
So nu komm ich zu meiner frage ;). Läuft das ganze auch auf einem RNS1 Controller bzw wo bekomme ich einen RNKC10 her? Das ist der einzigste den ich im I-Net gefunden habe. Die Google Ergebnisse zum RNKC10 sind nicht sonderlich ergiebeig :( Mein Problem ist, dass ich im selben Programm später auch noch ein Relais schalten will. Daher ist die Funktion mit den IO Pins mehr als perfekt.
So und nun noch eine letzte Frage. Ist es auch möglich mit dem Controller ein Pulsweitensignal auszugeben von 0 - 100%?.
Gruß Dennis
# Fabian Greif meinte am 30. Oktober 2007, 11:24 dazu:
RNS1 und RNKC10 sind keine realen Mikrocontroller, sondern lediglich die Bezeichnungen für die Software die auf einem AT90S2313 läuft. Daher ist es ein Problem die RNS1 Software durch die S8IO Software zu ersetzen. Einfach den entsprechenden Mikrocontroller neu programmieren.
Zu der Frage ob PWM möglich ist:
Mit dem Mikrocontroller, ja. Allerdings ist die Software akutell nicht dafür ausgelegt. Außerdem liegt der Hardware-PWM fähige Pin dummerweise auf PB3 und damit genau im Bereich der Servos.
# Maximilian meinte am 24. November 2007, 01:02 dazu:
Nabend zusammen!
Für meinen Robotor benötige ich mehr als nur 8 Servos! Ich habe die Idee mehrere Servocontroller und Relaisplatinen auf einen rs 232 Bus zu hängen!
Meine Frage ist, wie man die Startadresse ändern kann? Habe bisher nur ein wenig mit Basic programmiert und komme hier nicht mehr weiter!
Danke für die Hilfe!
Maximilian
# Andreas W meinte am 11. Januar 2010, 00:41 dazu:
Hi,
habe vor deine Schaltung für die Steuerung eines Roboterarms einzusetzen, hab soweit auch alles fertig, aber nun ist folgendes.. Wenn ich die hex datei einspiele klappt das wunderbar, will ich aber die mitgelieferten Dateien mit AVR Studio 4 compilieren und dann einspielen meckert er, dass das Programm 133,4% des Programmspeichers benötigen würde, Fehler und Warnungen zeigt er keine. Habe 8000000MHz eingestellt und Optimierung -Os.
Hast du eine Ahnung woran dies liegt? Grüße
# marcel meinte am 25. Juli 2010, 23:48 dazu:
hallo ich wolte mal fragen ob es mitlerweile eine I2C version besteht
mfg Marcel
# Fabian Greif meinte am 26. Juli 2010, 03:15 dazu:
@Marcel
Nein, ich habe an dem Projekt nicht mehr wirklich weiter gearbeitet, von daher gibt es von mir bisher keine I2C Version.
Grüße Fabian
# Fabian Greif meinte am 23. März 2014, 14:37 dazu:
Kommentare wegen zu viel SPAM geschlossen. Weitere Fragen & Anregungen bitte per E-Mail.