Hello World 2

Nach ein paar „Erholungstagen“ habe ich mal wieder ein Experiment mit meinem RN-Control auf dem Weg zum funktionierenden Roboter durchgeführt.
Diesmal hab ich mir vorgenommen, die sehr günstigen LCD-Module HMC16223SG von Pollin (jeweils nur 1,95Euro) zum Laufen bzw. Anzeigen zu bringen.
So sehen die Module aus:

LCD original

Eine grundsätzliche Info zum Start: Die Module sind wirklich sehr klein und wenn man keine sogenannte Flex-Print-Buchsen hat (die Gegenstücke zu den angelöteten Flachbandkabeln), ist das ganze sehr pfriemelig.
Ich hatte keine und habe mich daher dazu entschlossen, eben dieses Kabel zu entfernen – geht mit Entlötlitze recht gut – und statt dessen flexible Leitungen anzulöten.
Das Ergebnis dieser Behandlung sieht man hier recht gut:

LCD angeloetet

In diesem Bild sieht man auch das Poti, welches für die Kontrastregelung zuständig ist. Wie man ein LCD korrekt anschließt ist in diesem Artikel beim mittlerweile oft zitierten „Roboternetz“ zu finden. Es wäre sicher Unsinn, dieses Thema hier ebenfalls erschöpfend zu behandeln.
Das Datenblatt, welches man bei Pollin runterladen kann, gibt im Prinzip folgende Pinbelegung an:

Pin 01 – VSS (GND)
Pin 02 – VDD (+5V z.B. vom RN-Control)
Pin 03 – V0 (Das Datenblatt spricht hier von einer „Stromversorgung für den Flüssig-Kristall Antrieb“, gemeint ist Kontrast)
Pin 04 – RS (Register)
Pin 05 – R/W (Lesen oder schreiben)
Pin 06 – E (Aktivierung)
Pin 07 – DB0 (Datenleitung 1)
Pin 08 – DB1 (Datenleitung 2)

Pin 14 – DB7 (Datenleitung 8 )

Pin 15 und 16 sind beim Pollin nicht von Bedeutung. Hier wäre normalerweise die Beleuchtung anzuschließen.
Prinzipiell kann man zwei verschiedene Betriebsarten beim LCD unterscheiden: Den 4Bit oder den 8Bit-Modus. Dabei benötigt man entweder 4 oder natürlich 8 Datenleitungen. Somit haben wir beim 4-Bit-Modus den Vorteil, nur 4 Leitungen vom Microcontroller zu verbrauchen. Der Nachteil, daß dieser Modus auch um einiges langsamer ist, soll uns jetzt weniger stören.

Um das LCD zum Leben zu erwecken, brauchen wir mindestens die Pins 1, 2, 3, 4, 6, 11, 12, 13 und 14. Die restlichen Pins legen wir auf Masse. Am unten aufgeführten Bascom-Listing kann man sehr gut sehen, welcher Pin des LCD an welchen Pin des Controllers kommt.

Pin 01 – GND
Pin 02 – 5V
Pin 03 – an den Schleifer des Poti (die beiden anderen Beinchen des Poti an 5V bzw. GND)
Pin 04 – Port B0
Pin 05 – GND
Pin 06 – Port B1
Pin 07 – GND
Pin 08 – GND
Pin 09 – GND
Pin 10 – GND
Pin 11 – Port B2
Pin 12 – Port B3
Pin 13 – Port B4
Pin 14 – Port B5

So sieht das ganze angeschlossen aus:

img_2615

Das folgende Listing tut nun nichts anderes, als ein LCD mit 16*2 Zeichen (Config Lcd) mit oben genannter Pinbelegung (Config Lcdpin) im 4-Bit-Modus (Config Lcdbus) zu definieren. Dieses wird gelöscht (Cls – Clear Screen), der Cursor auf Zeile 1, Zeichen 1 (Locate 1,1) gestellt und dann ein Text ausgegeben (Lcd „Hallo Welt“). Auf Zeile 2 steht dann ein anderer Text.
Die Schleife (For i=1 to 999) dürfte ja klar sein. Siehe dazu auch das Bild weiter unten. Hinweis: Der Zeilenumbruch beim „Config Lcdpin“-Befehl ist natürlich zu enfernen.

$regfile = "m32def.dat"
$crystal = 16000000
$baud = 9600
Dim I As Integer
Config Portb = Output
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 ,
                Db7 = Portb.5 , E = Portb.1 , Rs = Portb.0
Config Lcdbus = 4
Config Lcdmode = Port
Cls
Locate 1 , 1
Lcd "Hallo Welt"
Wait 1
Locate 2 , 1
Lcd "99er@wordpress"
Wait 1
For I = 1 To 999
   Cls
   Locate 1 , 1
   Lcd "99er@wordpress"
   Waitms 100
   Locate 2 , 1
   Lcd I
   Waitms 500
Next I
End

So in der Art sollte dann das Ergebnis aussehen: 

img_2614

Experimente – Sharp GP2D120

Heute gibt es ein etwas längeres Bascom-Listing.
Ich werte damit einen Entfernungssensor „Sharp GP2D120“ am Port A0 des Atmega aus. Dies ist wichtig, da mein Roboter später ja „wissen“ muss, ob ihm ein Hindernis im Weg steht.
So sehen die Anschlüsse aus:

Sharp

Wie man sieht, nutze ich die vorhandenen Anschlüsse des RN-Control, um den Sensor mit +5V und GND zu versorgen. Der gelbe Draht des Sensor schließlich wird an der Klemmleiste angeschlossen. Hier wird die Spannung in Abhängigkeit von der Entfernung eines Hindernisses zum Sharp gemessen. Nun aber zum Listing (an den interessanten Stellen hab ich eine Ziffer eingefügt):

$regfile = "m32def.dat"
$crystal = 16000000
$baud = 9600
Config Adc = Single , Prescaler = Auto
Start Adc
Declare Function Messen(byval P As Byte) As Word     '(1)


Ddra = &B00000000
Ddrc = &B11111111
Dim Absli As Word
Dim V As Word
Dim M As Word
Dim I As Byte
Dim J As Word
Sound Portd.7 , 400 , 450

Do
    Absli = Messen(0)                                '(2)
    Print
    Print "Abstand " ; Absli ; " mm"
    Waitms 500
    For I = 0 To 7                                   '(3)
        Portc.i = 1
    Next I
    J = Absli / 100
    If J > 7 Then
        J = 7
   End If
    For I = 0 To J                                    '(4)
        Portc.i = 0
    Next I
  Loop
  End

  Function Messen(byval P As Byte) As Word
   V = Getadc(p)
   M = 25600 / V                                   '(5)
   Messen = M
End Function
 

(1) Hier wird eine Funktion „Messen“ mit einem übergebenen Argument (P / Byte) und einem Rückgabewert (Messen / Word) deklariert.
(2) Die deklarierte Funktion wird mit dem Argument 0 (weil Port 0) aufgerufen, um den Rückgabewert an „Absli“ zuzuweisen.
(3) Die Schleife setzt den gesamten Port C auf 1. Wir erinnern uns – das löscht alle LEDs auf dem RN-Control.
(4) Je nachdem, wie groß „J“ ist (kann maximal 7 sein), werden die Pins des Port C aus- und damit die LEDs angeschaltet.
(5) Die Funktion „Messen“ fragt den Analog-Eingang auf Port A0 ab und berechnet aus diesem Wert den Abstand in mm (25600/V). Diesen komischen Wert hab ich in einem Forumsbeitrag im Netz gefunden und für gut befunden.

Was das ganze Programm macht, dürfte klar sein?!

Experimente – Servo

Ich habe ein paar weitere Experimente gemacht, um mich nach und nach mit den Standardbauteilen vertraut zu machen.
Zunächst habe ich mir ein kleines Programm geschrieben, mit dem ich ganz einfach einen Servo gezielt an eine bestimmte Position drehen kann. Den Servo habe dafür ich an die Stromversorgung  (JP8) und den PWM-Draht  (Pulsweitenmodulation) an den Port A3 des RN-Control angeschlossen.

$regfile = "m32def.dat"
$crystal = 16000000
Dim S As Integer
Config Servos = 1 , Servo1 = Porta.3 , Reload = 10
Config Porta = Output
Enable Interrupts
Do
  Input "Step" , S
  Servo(1) = S
Loop
End

Über die Variable S, die in meinem Fall einen Wert von 40 – 190 annehmen kann, steuere ich die Position des Servo (Servo(1)=S). An dieser Stelle wird für mich eine große Schwäche von Bascom deutlich, die eigentlich eine Stärke sein sollte – Bascom ist einfach zu erlernen und nimmt dem Nutzer viel Arbeit ab, aber wie ein Servo wirklich angesteuert wird – das lernt man so natürlich nicht.
An dieser Stelle möchte ich auf die Seiten des Roboternetz hinweisen, auf deren Wiki unter vielen anderen Themen auch die Servoansteuerung umfänglich beschrieben wird.

Ein wichtiger Hinweis: Achtet bitte darauf, die Spielerei mit den Werten nicht zu übertreiben. Ein Motor, der sich nicht drehen kann, zieht viel Strom – und wenn ein Servo an seinem Anschlag angekommen ist weil man einen zu großen bzw. zu kleinen Wert gewählt hat, dann wird das nicht ewig gut gehen. Speziell der Spannungsregler 78S05 (IC2) kann dabei sehr heiß werden und unter Umständen auch durchbrennen.
Zu diesem Thema hab ich übrigens einen interessanten und lustigen Spruch gelesen:

„Elektronik funktioniert mit Rauch. Wenn man den Rauch aus einem Bauteil entweichen lässt, ist es kaputt.“

Ziele braucht das Land

Nachdem ich die ersten Experimente mit den LEDs abgeschlossen habe, werde ich wagemutig. Im Prinzip hab ich ja alles beisammen, was ich brauche. Aber der Spruch „Vor den Erfolg hat der Herr den Schweiß gesetzt“ ist nicht aus der Luft gegriffen und trifft ganz besonders auch für den Bau eines Roboters zu.
Ich stelle selbstkritisch fest, daß ich mit dem Zusammenbau des Chassis bereits den dritten Schritt vor dem ersten und zweiten gemacht habe und gehe nun zwei zurück.

Ich sollte festlegen, was mein Roboter überhaupt tun soll – und vor allem ob diese Zielsetzung realistisch ist. Mittlerweile hab ich schon ein paar Experimente gemacht, um dies abschätzen zu können. Natürlich wäre es schön, einen humaniden Roboter bauen zu können, der mir morgens in die „Puschen“ hilft … aber daran sind selbst die Profis der Branche mit Millionenetats gescheitert.
Also.

Zwei (eigentlich drei) wichtige Punkte sind zu klären und werden durch die von mir gekauften Dinge bereits teilweise vorgegeben.

1. Was soll der Roboter können?
Nun. Erstmal will ich mich mit dem typischen Erstlingwerk eines Roboterbauers „zufrieden geben“. Der Roboter soll, angetrieben durch Elektromotoren, durch die Wohnung fahren und vor Hindernissen ausweichen. Nach meinen ersten gemachten Experimenten scheint mir dies ein anspruchsvolles Ziel zu sein.

2. Wie soll er aufgebaut sein?
Wer den zweiten meiner Artikel gelesen hat, weiß bereits was ich gekauft habe. Diese Teile werden zum Einsatz kommen. Damit ergibt sich auch eine praktische runde Form, die das Hängenbleiben zumindest erschwert. Das Gewicht wird, wenn ich denn das Original RN-Control verwende, bei ca. 750g liegen. Später möchte ich das RN-Control durch eine selbst gelötetete minimalere Schaltung ersetzen, was das Gewicht wieder senken wird.

3. Wann soll das gute Stück fertig sein und wie ist „fertig“ definiert?
Kurz gesagt: Im Sommer soll das unter 1 gesagte fehlerlos möglich sein. Der Roboter soll Anfang August, ohne anzuecken, durch das Wohnzimmer düsen. Dabei soll er vor allem ausweichen, was mindestens 5cm hoch ist. Teppichkanten wird er bis dahin (noch) nicht erkennen.

Gut. Nachdem das geklärt ist, kann es ja weiter gehen.

Hello World

So wie es in vermutlich jeder Programmiersprache ein „Hello World“ gibt, möchte ich auch eins in Bascom schreiben.
Den Kontakt mit der Außenwelt soll in meinem Fall aber keine Textausgabe, sondern das Blinken einer LED symbolisieren. Ich glaube, daß ich diese Grundlagen beherrschen muss, bevor ich mich an größere Aufgaben wage.

Dem Schaltplan des RN-Control kann ich entnehmen, daß die 8 eingebauten LEDs an den Ports PC0 – PC7 des Mega32 hängen. Um eine LED am Port PC3 zum Leuchten zu bringen, müste also folgender Codeauszug reichen: 

...
PORTC.3 = 1
...

Aber Moment! Damit bleibt die LED dunkel. Warum?
Der Befehl PORTC.3 = 1 setzt den Ausgang C3 auf High – sprich, es liegen 5V an. Über Widerstände an der Katode der LEDs liegen an diesen 5V an. Ich muss also den Port auf Low, also 0V, setzen damit die LEDs leuchten.
Der korrekte Code inklusive Blinkfunktion sieht nun so aus:

$regfile = "m32def.dat"
$crystal = 16000000
Config Pinc.3 = Output
Dim I As Integer
For I = 1 To 100
   'LED 3 aus
   Portc.3 = 1
   Wait 1
   'LED 3 an
   Portc.3 = 0
   Wait 1
Next
End

Der Code ist schnell erklärt.
Die erste Zeile macht dem Compiler quasi den Mikrocontroller bekannt. Für einen Mega16 müsste man hier z.B. „m16def.dat“ schreiben. In Bascom kann man sich übrigens unter „Options“ -> „Compiler“ -> „Chip“ alle unterstützten Controller plus zugehörigem Regfile anzeigen lassen.
Die zweite Zeile lässt den Controller das 16MHz-Quarz auf dem RN-Control nutzen. 
„Config Pinc.3 = Output“ ist ein wichtiger Befehl, denn er definiert den Port C3 als Ausgang. Mittels „Dim“ wird I als Integer (kann Zahlenwerte von 0-65535 aufnehmen) deklariert.
Dann wird einfach 100 mal eine Schleife mit „For Next“ durchlaufen, in welcher mittels „Portc.3 = 1“ die LED aus und mit „Portc.3 = 0“ angeschaltet wird. „Wait 1“ lässt den Programmablauf für eine Sekunde anhalten und „End“ beendet schließlich das Programm.

Einfach, oder?

Zurück auf die Schulbank – Elektronik

Obwohl man mit dem RN-Control auch ohne weiterführende Kenntnisse recht schnell brauchbare Ergebnisse erzielen kann – ich möchte schon auch verstehen, was da passiert…
Also zurück auf die Schulbank.
Sollten dem geneigten Leser Sachen wie Ohmsches Gesetz oder Kirchhoffsche Regeln unbekannt vorkommen, wird es Zeit sich damit auseinanderzusetzen. Ich werde nun nicht den Fehler machen, mich in diesem kleinen Blog mit diesen Themen zu befassen. Dafür gibt es sehr gute und umfangreiche Quellen im Internet. Eine davon (und für meine Belange bereits ausreichende) ist das Elektronik-Kompendium.
Unbedingt zu empfehlen ist auch das Studium der Datenblätter für die Mikrocontroller. Es ist zwar sicher möglich, auch ohne diese Kenntnisse auszukommen. Wenn man aber auch mal eine eigene Idee umsetzen will, kommt man nicht ohne sie aus.

Die ersten Schritte

Gut. Mittlerweile sind die Komponenten zusammengebaut und schon ist der erste kleine Patzer passiert. Aber erst mal das Ergebnis:

Chassis zusammengebaut

Ich hab mich gewundert, warum die Räder an der Platine schleifen, wenn ich die vorgefertigten Löcher benutze…
Nun. Das Getriebe mit den Motoren lässt sich für 2 verschiedene Übersetzungen (58:1 und 200:1) nutzen und es gibt 3 verschiedene Arten für den Zusammenbau. Auf dem nächsten Foto kann man ganz gut die drei möglichen Positionen für die Achse erkennen:

img_1868
Bei mir befindet sich die Radachse im Loch A (200:1). Für Loch C (ganz vorn im Bild) ist jedoch das Chassis vorbereitet. Das hab ich dummerweise erst bemerkt, als das Getriebe bereits zusammen gebaut war…
Ich hab mir zwei zusätzliche Löcher in das Chassis gebohrt und nun passt es. Ob nunmehr die Räder zu schnell drehen, werden wir dann sehen. Im schlimmsten Fall muss ich dann das Getriebe noch mal neu zusammensetzen.
Wie man auf dem ersten Foto auch erkennen kann, hab ich schonmal ein paar Anschlussdrähte an die Motoren angelötet. Getestet hab ich damit auch ein wenig. Dazu aber dann später mehr… …