Stand
08.07.2020
-
Dr.-Ing. Erhard Henkes
(Update
des ursprünglichen Beitrages von 2010)
Foto: Dr. Erhard Henkes "Nibo bei
Nacht" (Digitalkameras "sehen" die IR-LEDs (violett,
liegend vorne) im Gegensatz zum menschlichen Auge)
Der auf Erfahrungen mit ASURO, c't-Bot und Fußballrobotern
basierende Roboterbausatz Nibo ist seit Juli 2007 bei nicai-systems
erhältlich. Seit Juli.2007 steht die erste C/C++-Bibliothek
für Nibo zum Download bereit, deren Dokumentation man hier
findet. Ich erachte den Roboterbausatz Nibo als empfehlenswertes
Upgrade, wenn man bereits Erfahrungen mit ASURO gemacht hat. Er hat
ein vergleichbares Antriebssystem aber deutlich mehr Möglichkeiten.
Inzwischen wird der Nibo2 als Nachfolgermodell angeboten. Die
Nibo-Bibliothek enthält jedoch noch Files für den
ursprünglichen Nibo, den man als Nibo1 bezeichnen könnte.
Meine Beschreibungen beziehen sich hier auf Nibo1, der immer noch
bestens funktioniert.
Der Nibo besitzt ein eigenwilliges
Design, das bezüglich des Antriebes vom ASURO beeinflusst ist,
und durch die Räder an einen "truck" oder durch die
Form an einen "Traktor" erinnert. Den ASURO schlägt er
in Punkto Stabilität und Aufbau um Längen. Der berühmte
halbe Tischtennisball wurde z.B. durch einen Teflongleiter ersetzt,
der auf eine Holzscheibe (großer Dame-/Mühlestein?)
geklebt wird. Der Holzstein wird in der Mitte der Platine von oben in
ein vorgebohrtes Loch sauber verschraubt. Das ist wirklich
professionell. Die Gleiteinrichtung ist damit leicht abnehm- bzw.
austauschbar.
Foto: Dr. Erhard Henkes (Nibo's Unterseite,
Teflongleiter, fünf IR-Sensoren, vier CNY70, 25:1-Getriebe)
Der
ATmega128 - via I²C flankiert durch seine beiden Helfer ATtiny44
- bietet viel Raum, auch für nicht optimierte Programme. Rechts
oben auf der Platine erkennt man den 6-Pin-ISP-Anschluss für die
Programmierung z.B. mit einem STK500 und AVR Studio. Der
20-Pin-Anschluss ist für ein optionales Grafik-Display (siehe
Bild oben), das sich unbedingt empfiehlt, vorgesehen. Ein
10-Pin-Anschluss (oben neben dem leeren Sockel) kombiniert die beiden
fünfadrigen Kabel, die zu den beiden Odometriesensorplatinen
führen. Ein weiterer 10-Pin-Anschluss (unten neben dem ATtiny44)
dient als Erweiterungsport. Der freie Sockel nimmt den Motortreiber
L293D auf. Ein 16 MHz Quarz (unten rechts) gibt den maximalen Takt
für den ATmega128 vor, der damit auch zuverlässige 400 kHz
am I²C-Bus ermöglicht.
Foto: E. Henkes (Antrieb ohne
Odometriesensorenplatinen)
Der Antrieb des Nibo1 erfolgt
mit zwei Motoren vom Typ 2025-02 (IGARASHI) mit 3-12 Volt
Gleichspannung, 0,001 Nm max. Drehmoment und einer
Getriebeuntersetzung von 25:1 (analog ASURO). Der geschraubte
Aluminiumrahmen beeindruckt durch solide Professionalität. Die
Getriebezahnräder besitzen vier Innenlöcher für die
Odometrie.
Man sieht hier auch sehr gut die
empfehlenswerte Abdeckung für die Odometrie des Nibo, die 20
Zähler pro Radumdrehung liefert.
Ich rate dringend
zum Einsatz des Grafikdisplays,
denn dieses bietet mit 64*128 Pixel Platz für 8 Zeilen Text mit
jeweils 21 Zeichen. Nibo's C-Bibliothek enthält bereits fertige
- allerdings noch nicht optimierte - Routinen, die zumindest die
Ausgabe von Text auf dem Display zum Kinderspiel machen.
Reizvoll
an Nibo ist das Zusammenspiel der drei Microcontroller (Nibo2 hat auf
zwei µC rationalisiert) von Anfang an.
Für den Nibo gibt es eine Bibliothek für C/C++ und Java. Aufsteiger vom ASURO zum Nibo werden wohl im gewohnten C programmieren wollen. Dafür steht eine ordentlich strukturierte C-Bibliothek zur Verfügung, die es rasch erlaubt, eigene Programme auf hohem Niveau zu entwickelen. Dafür sorgt der vorbildlich aufgebaute Header iodefs.h und die weitere Unterteilung in Low Level und High Level Routinen sowie die Routinen für den Motorcontroller und IR-Controller (fünf Abstandssensoren).
Programmiert wird der Nibo z.B. über die
Standard-6-Pin-ISP-Schnittstelle, z.B. mit dem Atmel STK500 Starter
Kit und der kostenlosen Software AVR Studio (ebenfalls von Atmel,
aktuelle Version 7 (kostenlos im Internet). Das AVR Studio
bietet vor allem einen brauchbaren Debugger, mit dem man Programme
schrittweise durchgehen und dabei detailliert die einzelnen Zustände
des Microcontrollers analysieren kann. In Version 7 muss man die
Toolchain (leider umständlich) umstellen auf das uralte WinAVR
2010 („WinAVR-20100110-install.exe“), das man im Netz
findet. Ansonsten läuft man in hässliche, unlösbare
Fehler!
Die Steckerbelegung für das ISP-Kabel des
Atmel STK500 findet man hier.
Foto: E. Henkes (Sechsadrige ISP-Verbindung zwischen
Atmel STK500 Starter Kit und Nibo)
Fangen wir mit
einigen einfachen Sourcecodes zur Demonstration der Möglichkeiten
des Nibo an.
Foto: E. Henkes (Nibo besitzt sechs Duo-LEDs. Rot plus
Grün ergibt Orange)
Hier folgt als Beispiel der Sourcecode in der Programmiersprache C
für das bei einem Display obligatorische "Hallo
Welt!"-Programm (siehe Bild):
#include
<avr/interrupt.h> |
Man erkennt,
auf welch einfache Weise man Text auf dem für diese
Roboterklasse herrlich großen LC-Grafik-Display (64*128 Pixel)
ausgeben kann. Dies ist ein wichtiger Vorteil, und zwar nicht nur für
Einsteiger in die Programmierung von Microcontrollern.
Als
nächstes kümmern wir uns um die Anzeige der
Versorgungsspannung:
#include
<avr/interrupt.h> |
Foto: E. Henkes (Versorgungsspannung)
Mit
acht Akkus (8*1,2 V = 9,6 V) besitzt Nibo ein gewaltiges Kraftpaket,
das er aber auch benötigt. Man sollte sich einen zweiten oder
gar dritten Akkusatz besorgen, wenn man nicht auf dem Trockenen
sitzen will. Nibo ist ein echter Stromfresser, dafür aber auch
ein tolles Kraftpaket.
Als nächstes wenden wir uns der Steuerung der beiden Motoren
zu. Folgende Variablen und Funktionen findet man in der
C/C++-Bibliothek des Nibo:
/*!
*
Aktuelle Geschwindigkeit des linken Rades
*/
extern
int16_t motco_speed_l;
/*!
*
Aktuelle Geschwindigkeit des rechten Rades
*/
extern
int16_t motco_speed_r;
/*!
*
Aktuelle Inkrements des linken Rades
*/
extern
int16_t motco_ticks_l;
/*!
*
Aktuelle Inkrements des rechten Rades
*/
extern
int16_t motco_ticks_r;
/*!
*
Aktualisiert alle Daten
*/
uint8_t
motco_update();
/*!
*
Motoren anhalten
*/
uint8_t
motco_stop();
/*!
*
PWM Werte für die beiden Motoren setzen. Die PWM Werte sind bei
idealisierter
* Mechanik und Elektonik proportional zum
Drehmoment.
* @param left Wert für linkes Rad (-1024
... +1024)
* @param right Wert für rechets Rad (-1024
... +1024)
*/
uint8_t
motco_setPWM(int16_t
left, int16_t right);
/*!
*
Geschwindigkeit für die beiden Motoren setzen. Die Werte werden
in Ticks/Sekunde
* angegeben. Zwanzig Ticks entsprechen
einer Radumdrehung.
* @param left Sollwert für linkes
Rad
* @param right Sollwert für rechets
Rad
*/
uint8_t
motco_setSpeed(int16_t
left, int16_t right);
/*!
*
Regelungsparameter setzen. Weitere Infos im Wiki unter
*
http://nibo.editthis.info/wiki/Motorcontroller-Firmware
*
@param ki Integralanteil
* @param kp Proportionalanteil
*
@param kd Differentialanteil
*/
uint8_t
motco_setParameters(int8_t
ki, int8_t kp, int8_t kd);
/*!
*
Odometriewerte auf angegebene Werte zurücksetzen
*
@param left Wert für linkes Rad
* @param right Wert
für rechets Rad
*/
uint8_t
motco_resetOdometry(int16_t
left, int16_t right);
Hier
ein erstes Programm, das den Nibo mittels einer Funktion
Go(distance,speed) geradeaus vorwärts bewegt. Das Programm ist
noch im Experimentierstadium:
#include
<avr/interrupt.h> |
Hier das zum Programm zugehörige
Video.
Die C/C++-Bibliothek des Nibo bietet momentan folgende Variablen
und Funktionen:
/*!
*
Aktueller Modus des IR-Controllers
*/
extern
uint8_t irco_mode;
/*!
*
Aktuelle Reflexionswerte der Distanzsensoren
*/
extern
uint8_t irco_distance[5];
/*!
*
Zuletzt empfangenes RC5 Kommando
*/
extern
uint16_t irco_rc5_cmd;
/*!
*
Daten des IRCO aktualisieren
*/
uint8_t
irco_update();
/*!
*
Aussenden von IR-Licht stoppen, nur Empfang
*/
uint8_t
irco_stop();
/*!
*
Reflexionsmessung starten
*/
uint8_t
irco_startMeasure();
/*!
*
RC5 Code übertragen
*
@param rc5 RC5 Code
*/
uint8_t
irco_transmitRC5(uint16_t
rc5);
Wir
testen die Möglichkeiten der Abstandsmessung mit den fünf
IR-Sensoren:
#include
<stdlib.h> |
Das Raumgefühl des Nibo, dass man durch den Einsatz von fünf IR-Sensoren erreicht, hat seinen Vorteil. Hier finden Sie ein Programm, das einen gewichteten Sensorschwerpunkt (Summe der Sensorwerte mal zehn mal Einheitsvektoren mal Gewichtungsfaktor) berechnet und darauf sehr einfach reagiert:
/******************************************** |
Damit kann Nibo bereits Hindernissen ausweichen und sich auf
diese Art prinzipiell ungerichtet im Raum bewegen. Die Reaktionen auf
den "gewichteten Sensorschwerpunkt" und die Grenzwerte
(absolut oder relativ) kann man selbstverständlich weiter
optimieren. Dies ist lediglich eine erste Demonstration der
prinzipiellen Möglichkeiten des Nibo.
Eine der Herausforderungen besteht darin
RC5-Code
an den Nibo zu senden und mit diesem zu empfangen. Dafür
benötigt man zunächst eine Fernbedienung, die den
sogenannten RC5-Code
ausstrahlt. Bei mir war es so, dass keine im Haushalt
funktionierte, auch eine Philips-Fernbedienung nicht! Ich habe mir
daraufhin eine kostengünstige Universalfernbedienung
vom Typ SupportPlus 8in1 SP-URC-81-ME besorgt. Folgende Einstellungen
führten beim Nibo zum Erfolg:
1) Auf SET und TV1
gleichzeitig drücken und sofort(!) loslassen, wenn die rote LED
aufleuchtet.
2) 0 2 3 eingeben (einer der vielen Codes für
Philips, 001 und 004 funktionierten nicht!). Die rote LED
erlischt.
3) RC5-Code austrahlen. Funktioniert bei ca. 5 Meter
noch sicher.
Testen kann man dies beim Nibo mit
der Initializer.hex, die den empfangenen RC5-Code im Grafikdisplay
anzeigt.
Die Nibo-Bibliothek ist auf den Empfang und auf das
Senden von RC5-Codes bereits vorbereitet.
/*!
*
Zuletzt empfangenes RC5 Kommando
*/
extern
uint16_t irco_rc5_cmd;
/*!
*
RC5 Code übertragen
*
@param rc5 RC5 Code
*/
uint8_t
irco_transmitRC5(uint16_t
rc5);
#include
<stdlib.h> |
Mit
diesem einfachen Programm kann Nibo bereits RC5-Code empfangen. Damit
ist eine Fernsteuerung bzw. Kommunikation auf diesem Wege über
Entfernungen von einigen Metern möglich. Wie man sieht, kann man
sich damit auf einfache Weise eigene Test- bzw. Steuerprogramme
schreiben. Gerade für die Optimierung von Navigationsprogrammen
ist dies sehr hilfreich! Denken Sie auch an das Togglen, da man damit
einen RC5-Code als On/Off-Schalter verwenden kann. Will
man im Zahlenblock zweistellige Eingaben verwenden, so nimmt man noch
das HIGHBYTE hinzu. Erste Ziffer: 0x38, zweite Ziffer: 0x30. Einfach
austesten und in der switch/case-Auswertung entsprechend reagieren.
Die 4096 Bytes SRAM des ATmega128 bieten ausreichend Platz für die in C++ typischen dynamischen Speicheranforderungen. Allerdings werden new/delete bzw. new[]/delete[] vom aktuellen WinAVR noch nicht unterstützt. Bei abstrakten Klassen kommt es zu Problemen mit "pure virtual". Beide Punkte lassen sich aber leicht umgehen:
//
Hilfskonstruktionen |
Die C++-Schlüsselwörter new/delete werden durch
das klassische malloc/free aus C ersetzt und für den ins Leere
führenden Aufruf der Funktion __cxa_pure_virtual()schafft
man eine Sprungmarke mit einem leeren Rumpf.
Etwas
schwierig gestaltet sich die Erstellung eines C++-Programms mit AVR
Studio und WinAVR, denn ersteres ist nicht wirklich für C++
eingerichtet.
Das beginnt mit der nicht aufgeführten Endung
cpp
und
hört damit auf, dass man das Makefile erst exportieren, dann
manipulieren und als externes Makefile verwenden muss. Dies bedeutet,
dass man das Makefile manuell selbst bei weiteren Änderungen
pflegen muss. Ohne Kenntnis der elementaren Syntax des Makefiles
kommt man also hier nicht weiter. Das hat aber auch seine Vorteile,
weil man sich detailliert mit der Entstehung des Binärprogramms
beschäftigt.
Bezüglich der
Gestaltung des Makefile findet man hier eine Übersicht:
http://www.mikrocontroller.net/arti.....utorial#Exkurs:_Makefiles
Ein Makefile ist nichts anderes als eine Sammlung von
"Steueranweisungen" für Compiler, Assembler,
Linker/Locator, Konverter und ggf. Flashprogramm. Hinzu kommen können
Kopier- und Löschbefehle.
Man sollte den
Gesamtprozess des Erstellens eines Maschinenprogramms in Ruhe
analysieren. Hier findet man einige Links:
http://www.roboternetz.de/wissen/index.php/Bild:Avr-gcc-1.png
http://www.roboternetz.de/wissen/in.....blauf_der_Codegenerierung
Verfolgt man den Weg vom C/C++ Sourcecode (Quellcode) bis
zum Programm im Flash-Speicher, so findet man folgenden
"Reaktionspfad":
C/C++
-> Assembler -> Objektcode -> elf-Datei (ELF = Executable
and Linking
Format)
-> hex-Datei -> Binäres Programm im Flash-Speicher
Der Linker/Locator verbindet mehrere
Objektdateien (o) und Archivdateien (a) zu einer einzigen Datei,
replaziert ihre Daten und verbindet ihre Symbolreferenzen.
C/C++ -> Assembler |
Compiler |
C:\WinAVR\bin\avr-gcc.exe
|
Assembler -> Objektcode |
Assembler |
C:\WinAVR\bin\avr-as.exe |
Objektcode -> elf-Datei |
Linker / Locator |
C:\WinAVR\bin\ld.exe |
elf-Datei -> hex-Datei |
Konverter |
C:\WinAVR\bin\avr-objcopy.exe |
hex-Datei "flashen" |
Flash-Programm |
C:\WinAVR\bin\avrdude.exe |
Den gesamten Prozess kann man im Makefile nachvollziehen.
Nachfolgend finden Sie das Makefile eines Projektes in C++ im Rahmen
einer ersten Bewegungsprogrammierung mit Hilfe des "state
pattern design":
############################################################################### |
Hier sind die im Makefile aufgeführten Source-Dateien
dieses Projektes:
#ifndef
NIBO_H |
#ifndef
ROBOTER_H |
#ifndef
STATE_H |
#ifndef
STATE_FREE_H |
#ifndef
STATE_OBSTACLEFRONT_H |
#ifndef
STATE_OBSTACLELEFT_H |
#ifndef
STATE_OBSTACLERIGHT_H |
#ifndef
UTIL_H |
//Roboter.cpp |
//StateFree.cpp |
//StateObstacleFront.cpp |
//StateObstacleLeft.cpp |
//StateObstacleRight.cpp |
//test.c |
Inzwischen wird der
Nachfolger Nibo2
angeboten. Nachfolgend finden Sie eine interessante Bachelor-Arbeit:
Bachelor-Arbeit