Simple Robot - [Teil 1]

Teil 1

Einführung

Hallo liebe Bastler,

in diesem Projekt möchte ich mit Ihnen und für Sie einen einfachen Roboter bauen. Er soll neben den elektronischen Bauteilen aus wenig Material entstehen. Einen 3D-Drucker können Sie verwenden, müssen es aber nicht. Ich habe Holz verwendet, dass ich noch von einem anderen Projekt übrig hatte. Pappe wäre auch eine Alternative.

Meine Überlegung war zu Beginn, wie ich eine Bewegung umsetzen kann, die man sonst so bei z.B. Echsen sieht. Damit meine ich, dass es vier Beine bzw. Füße gibt, von denen immer die zwei diagonal gegenüberliegenden den Boden berühren, während die anderen beiden in der Luft sind und die Vor- oder Rückwärtsbewegung durchführen. Wir werden einen 16-Kanal-Motortreiber und Mikroservos an einem Arduino Nano verwenden.

Im ersten Teil wird es darum gehen, die elektronischen Komponenten anzuschließen und die Servos drehen zu lassen.
Los geht's.

Benötigte Hardware 

Anzahl Bauteil Anmerkung
1 Arduino Nano V3
4 SG90 Mikroservo
1 PCA9685 16 Kanal 12 Bit PWM Servotreiber
1 Verbindungskabel
1 Breadboard
1 Taster
1 Potentiometer (hier 10KOhm)
1 Spannungsversorgung 5V (Labornetzteil oder ähnliches)
PC mit Arduino IDE und Internetverbindung

Bei "Kabelbinder" wird man jetzt mit der Stirn runzeln. Aber wir wollen mit einfachen Mitteln etwas bauen. Sie können auch kleben oder schrauben. Ich konnte damit allerdings ein Problem lösen. Dazu später mehr.

Vorbereitung

Zuerst installieren wir in der Arduino IDE eine passende Bibliothek für das PCA9685 Treiberboard. Dafür starten wir das Programm und wechseln dort in den Bibliotheksverwalter über Werkzeuge und dann Bibliotheken verwalten... oder Strg+Umsch+i. Dort kann man oben den Namen des Boards eingeben. Ich habe die Adafruit PWM Servo Driver Library verwendet. Gibt man das in das Suchfeld ein, sollte das passende Ergebnis angezeigt werden. Anschließend klickt man auf Installieren und kann die Bibliothek dann verwenden. Auf folgendem Bild ist die Installation bereits abgeschlossen.


Eine Sammlung an Bibliotheken finden Sie auch auf der AZ-Delivery Shop Webseite zum besagten Artikel in der Rubrik Wichtige Downloads und Links. Diese können Sie manuell in Ihren Libraries-Ordner der Arduino IDE kopieren. Es sind auch Beispiele für das Einbinden der Bibliothek verfügbar.

Hinweis: Die Pulsweitenmodulation dient nicht nur zur Steuerung von Motoren, sondern auch für das Dimmen von LEDs. Daher ist es theoretisch auch möglich, mit dem gleichen Board die Helligkeit von LEDs zu verändern. In der Bibliothek namens Seeed-PCA9685 ist ein Beispiel für LEDs enthalten. Allerdings ist die Software-seitige Ansteuerung etwas anders.

PCA9585 mit Servos am Arduino Nano

Da wir nun die passende Bibliothek installiert haben, werden wir die elektronischen Komponenten miteinander verbinden. SDA und SCL des Treiberboards stellen die I²C-Verbindung zum Arduino dar und werden am Nano an A4 (SDA) und A5 (SCL) angeschlossen. Außerdem werden Masse (GND), sowie der 5V-Pin des Arduinos mit dem VCC-Pin verbunden.

Hinweis: Man sollte darauf achten, dass man die Servos nicht über den 5V-Pin des Arduinos mit Spannung versorgt. Der zweipolige Connector am PCA9685 an der gegenüberliegenden Seite zu den Servoanschlüssen wird für den Anschluss einer externen Spannungsquelle empfohlen. Es kann auch der zweite V+ Pin an der Pinleiste verwendet werden. Nicht jedoch der VCC-Pin. Dieser sollte nur mit dem 3.3V oder dem 5V-Pin des Arduinos verbunden werden.

Dem Datenblatt der Mikroservos entnehmen wir, dass sie mit einer Spannung von 4,8V bis 5V versorgt werden müssen. Das Treiberboard lässt maximal 5,5V zu. 5V sollte der Wert der idealen Spannungsquelle sein. Wer ein regelbares Labornetzteil sein Eigen nennt, ist hier gut bedient. Es sind auch passende Steckernetzteile im Handel erhältlich.

Der Eingangsstrom des Treiberboards sollte 8A nicht überschreiten. Sollte es für besonders große Servos notwendig sein, sollten diese separat mit Strom versorgt werden. Das Board ist außerdem gegen eine Verpolung geschützt. Das nächste Bild zeigt die schematische Darstellung der Verbindungen.


Tipp:
Die meisten USB-Steckernetzteile, mit denen Sie Ihre Smartphones aufladen, haben ebenfalls eine Ausgangsspannung von 5V. Achten Sie auf die Beschriftung auf den Netzteilen. Sie liefern meistens auch genügend Strom zwischen 1A und 3A. Mit ein bisschen Geschick oder gar Lötarbeit können Sie davon Strom für das Treiberboard abzapfen. Die äußeren beiden Pins eines USB-Typ A Steckers sind immer +5 und GND. Ein Spannungsmessgerät verrät Ihnen, um welchen Pin es sich jeweils handelt.

Haben Sie alles so miteinander verbunden, sollten Sie als nächsten Schritt ein Beispielprogramm aus der Bibliothek auf den Arduino laden. In der Arduino IDE unter dem Menü Datei dann Beispiele finden Sie weiter unten den Punkt Adafruit PWM Servo Driver Library. Darin finden Sie vier Beispiele. Darunter ein Projekt namens Servo. Öffne Sie dieses, laden Sie es auf den Arduino hoch und schauen Sie, ob sich Ihre Servos bewegen.

An dieser Stelle ist es noch nicht wichtig, den Quellcode zu verstehen. Da das Beispiel allerdings für acht Servos vorbereitet ist, können Sie unten die letzte Zeile ändern, um nur vier Servos anzusteuern und die Pause zu vermeiden. Die Bedingung > 3 rührt daher, dass die Pins der Servos bei 0 beginnen und nicht bei 1. Servo 3 ist also das vierte Servo. Ist der Zähler servonum größer als 3, soll er wieder von vorn beginnen.

if (servonum > 3) servonum = 0;

Tipp: Man sieht hier, dass man nach der Stelle suchen muss, die die maximale Anzahl der anzusteuernden Servos angibt. Ratsam wäre es, eine Variable oder Konstante mit eindeutigem Namen zu verwenden, die weiter vorn im Quelltext leichter zu finden und anzupassen wäre.

Die Achsen der Servos sollten sich nun nacheinander in beide Richtungen drehen. Funktioniert das, werden wir nun noch die Endanschläge der Servos ausloten. Wir ändern die Maximalzahl der Servos auf 1, da alle Servos in dem Fall gleich sein sollten. Im oberen Teil des Quellcodes des Servo-Beispiels finden Sie folgende Codezeilen:

#define SERVOMIN  150
#define SERVOMAX  600

Testen Sie mit diesen Werten aus, wie weit sich die Achsen drehen können. Man hört es auch am Klang des Getriebes, wenn der Endanschlag erreicht ist. Das sollte man dann nicht zu oft machen.

Achten Sie dabei darauf, dass man nicht das absolute Maximum einer Servoachse nutzen sollte. Eine kleine Toleranz ist hier zu empfehlen. Ich habe eine prozentuale Toleranz in den Quellcode eingearbeitet. So werden die Maximalpunkte niemals angefahren. Dazu später mehr.

Servos mitteln

Wir wollen nun die Mittelposition der Achsdrehung unserer Servos bestimmen. Diese werden dann auch gleich die Ausgangspositionen sein. Wir benötigen dafür ein Potentiometer. Damit drehen wir die Servoachsen auf die Mittelposition. Die Bewegungen der einzelnen Servos wird dann später immer von diesen Positionen ausgehen. Je nachdem, wie gut oder schlecht wir den Roboter dann zusammenbauen, kann sich der Mittelpunkt auch nochmal verschieben.

Da wir mehrere Servos verwenden und später die Positionen auch einzeln festlegen möchten, müssen wir das entsprechende Servo ansteuern. Dafür nutzen wir einen Taster, mit dem wir durch die Servos durchschalten. Im späteren Verlauf nutzen wir die beiden Komponenten, um die Bewegung des Roboters ein- und auszuschalten und wir können die Bewegungsgeschwindigkeit regulieren. Wir schließen das Potentiometer und den Taster wie im folgenden Bild an den Arduino an:



Wir brauchen nun Quellcode, mit dem wir die Servoachsen drehen und deren Position auslesen können. Wir nutzen einige Teile aus dem Servo-Beispiel für den PCA9685.

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

#define SERVOMIN   68   // 0 bis 4096 - try and error
#define SERVOMAX   510  // 0 bis 4096 - try and error
#define SERVO_FREQ 50   // Analog servos run at ~50 Hz updates  
#define TOLERANZ   10   // Prozent vom Endanschlag

Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); 

Es werden die Wire-Bibliothek für die I²C-Verbindung und die Adafruit Servo Driver-Bibliothek eingebunden. Als Nächstes übernehmen wir die Konstanten SERVOMIN, SERVOMAX und SERVO_FREQ aus dem Servobeispiel. Hier sind nun bereits meine Minimal- und Maximalwerte eingetragen. Zusätzlich erzeugen wir uns eine Konstante für die Toleranz an den Außenanschlägen. Es wird dann noch ein Objekt vom Typen des Servotreibers erzeugt.

Hinweis: Den Kommentaren des Servo-Beispiels kann man entnehmen, dass in die Klammern des Servotreiber-Objektes die I²C-Adresse eingetragen wird. Es ist möglich, mehrere von den Treiberboards seriell zu verbinden, um mehr als 16 Servos anzusteuern. Lässt man die Klammern leer, wird die Standardadresse verwendet. Um die Adresse zu ändern, muss auf dem Board die Lötstelle auf der rechten Seite geschlossen oder geöffnet werden.

Nun werden noch die Variablen deklariert und definiert:

// States      
int state = 0;

// Input
int taster_pin = 8;
bool input = HIGH;
bool input_alt = HIGH; 
int input_analog = 0;

Durch alle Servos zu schalten, realisieren wir mit der state-Variablen. Sie entspricht der servonum-Variable aus dem Servo-Beispiel. Wir recyclen diese Variable später und nutzen sie für andere Funktionen. Der Tasterpin ist D8 und somit hier mit 8 definiert. Für das Entprellen des Tasters brauchen wir den alten und den neuen Zustand. Daher die beiden input-Variablen. Das Potentiometer ist an A0 des Arduinos angeschlossen. Also definieren wir diese Variable mit 0.

 

// Servos
// Berechne Min und Max mit Servotoleranz am Aussenanschlag
const int MAXSERVOS = 4;
int range = SERVOMAX - SERVOMIN;
double temp = (range / 100) * (double)TOLERANZ;
int NEWMIN = SERVOMIN + (int)temp;
int NEWMAX = SERVOMAX - (int)temp;
int i = 0;
int SERVO_MIDDLE[MAXSERVOS] = {275, 334, 317, 284};

Die maximale Anzahl der Servos wird hier mit MAXSERVOS als Ganzzahlkonstante festgelegt. Diese Variable wird im Quellcode öfter verwendet. Ergänzt man den Aufbau durch mehr Servos, muss man nur hier den Wert entsprechend erhöhen. Die Range, also der Bereich, um den sich die Servoachse drehen kann, errechnet sich aus der Subtraktion der beiden Maximalwerte. Um die Toleranz als Prozentwert auf diese beiden Endpunkte aufzurechnen, wird dieses Zwischenergebnis durch 100 geteilt und anschließend mit der Toleranz multipliziert.

Hier werden statt Ganzzahlen kurzzeitig Gleitkommazahlen als Datentyp verwendet. Ist das Zwischenergebnis zuvor eine ungerade Zahl, ist das Ergebnis der Division keine Ganzzahl, sondern eine gebrochene Zahl. Würden wir das mit Ganzzahlen machen, würde die CPU die Kommastellen einfach weglassen und das Ergebnis wäre ungenau. Für die neuen Endpunkte NEWMIN und NEWMAX wird einfach das vorherige Ergebnis zu dem alten Minimalwert dazu addiert, bzw. vom alten Maximalwert subtrahiert.

Hinweis: Die Drehwinkelwerte des Servos sind keine Winkelangaben, sondern Werte aus dem AD-Wandler. Er erzeugt digitale Werte aus dem Potentiometer, dass in dem Servo für die Position der Drehbewegung zuständig ist. Man kann sie auch mit der map()-Funktion so umrechnen lassen, dass sie Winkelangaben entsprechen. Dies ist hier aber nicht notwendig. Wir brauchen diese Funktion dann dennoch, da wir die Drehwinkel der Servos und des Potentiometers synchronisieren wollen.

Es folgt nun noch die Variable i, die als Zähler verwendet wird. Als Nächstes erstellen wir ein Array, in das wir die manuell ermittelten Mittelwerte eintragen können, da wir sie später brauchen werden. Die Anzahl der Servos muss mit der Anzahl der vordefinierten Werte übereinstimmen. Die nächsten Variablen sind für das Entprellen auf Softwarebasis gedacht:

// Timer
unsigned long prell_delay = 100;
unsigned long alte_zeit = 0;

Das Prelldelay ist die Zeit, die der Taster braucht, um sich zu "beruhigen". Die alte Zeit ist der vorherige Zeitstempel, mit dem die aktuelle Zeit verglichen wird. Damit wird sichergestellt, dass der Taster erst wieder verwendet wird, wenn die vorgegebene Prellzeit abgelaufen ist.

Kommen wir nun zur setup()-Funktion:

void setup() {
    Serial.begin(115200);
    Wire.begin();
    pinMode(taster_pin, INPUT_PULLUP);
    pwm.begin();
    pwm.setOscillatorFrequency(27000000);  // The int.osc. is closer to 27MHz  
    pwm.setPWMFreq(SERVO_FREQ);  // Analog servos run at ~50 Hz updates
    delay(500);
}

Wir nutzen mit Serial den seriellen Monitor, um die Werte des Potis anzuzeigen. Der Wert in der Klammer muss mit der Baudrate im seriellen Monitor übereinstimmen. Wire.begin() initialisiert die Kommunikation der I²C-Schnittstelle. Danach wird der Modus des Tasterpins eingerichtet. Wir verwenden den internen Pull-up-Widerstand.

Dabei ist zu beachten, dass der Pin dann low-active funktioniert. Also LOW ist AN und HIGH ist AUS. Für uns ist das nicht wichtig, da wir nur die Änderung des Tasters untersuchen, nicht den Zustand selbst. Anschließend wird die Pulsweitenmodulation des Treiberboards gestartet. Der Oszillator wird auf 27MHz und die PWM-Frequenz auf 50Hz eingestellt. Das sind Standardwerte für die meisten Servos dieser Art.

Es folgt die loop()-Funktion. Wir müssen den Tasterpin untersuchen, die Werte des Potentiometers und diese auf die Servos geben:

void loop() {   
    // Input lesen und anpassen
    input = digitalRead(taster_pin);
    input_analog = analogRead(A0);
    input_analog = map(input_analog, 0, 1023, NEWMIN, NEWMAX);  
    // Entprellen
    // wenn Taster jetzt AN und vorher AUS und aktuelle Zeit minus alte Zeit groesser, als vorgegebenes Delay
    if (input == LOW && input_alt == HIGH && millis() - alte_zeit > prell_delay) {
        state++;
        // States eingrenzen auf Anzahl der Servos
        if (state > MAXSERVOS) {
            state = 0;
        }
        alte_zeit = millis();
    }
    input_alt = input;
    
    //Bildschirmausgabe
    Serial.print("Servo Nr: ");
    Serial.print(state);
    Serial.print(" Position Input: ");
    Serial.println(input_analog);
    
    //Servo positionieren
    pwm.setPWM(state, 0, input_analog);
}

Gehen wir zeilenweise durch den Code. Wir lesen mit digitalRead() den Zustand des Tasterpins ein und speichern ihn vorläufig. Danach holen wir mit analogRead() den aktuellen Wert des Potentiometers.

Im nächsten Schritt synchronisieren wir den Drehwinkel des Potentiometers mit dem des Servos. Die map()-Funktion führt diese Verhältnisrechnung durch. Die Parameter sind die Variable mit dem Quellwert, dann die Minimal- und Maximalwerte des Potentiometers als Quellbereich und anschließend unsere berechneten neuen Minimal- und Maximalwerte des Zielbereiches für das Servo.

Ich habe es für Sie in der folgenden Abbildung einmal grafisch dargestellt und auch gleich die Endanschläge mit eingefügt:


Die Werte des analogen Eingangs, an dem das Potentiometer angeschlossen ist, haben einen Wertebereich von 0 bis 1023. Das entspricht je nach Bauform des Potis einem Winkel von ca. 270 Grad. 

Der Wertebereich des Servos ist in meinem Fall 68 bis 510. Da wird dann noch jeweils die 15%-Toleranz dazugerechnet. Diese Werte müssen nun so zusammenpassen, dass die beiden Endanschläge die Achse des Servos bis zu unseren neuen Minimal- und Maximalwerten drehen lässt. Das nennt man Mappen und nutzt dafür die besagte map()-Funktion.

Gehen wir weiter im Quellcode. Als Nächstes entprellen wir den Taster. Das heißt in dem Fall, dass wir die abgelaufenen Millisekunden berechnen. Wir subtrahieren die aktuelle Zeit mit einer zuvor gespeicherten Zeit. Ist das Ergebnis größer, als unser zuvor definiertes Prelldelay, dann können wir fortfahren.

Die erste Bedingung ist natürlich, dass der Taster überhaupt gedrückt wurde. Hier wird ebenfalls der neue Zustand mit dem alten verglichen. Damit verhindern wir, dass der Taster gedrückt bleiben kann. Er muss zuerst losgelassen werden, bevor auf ihn wieder reagiert wird.

Sind diese Bedingungen erfüllt, wird die state-Variable weiter gezählt. Da sie wie gesagt unserer Servonummer entspricht, schalten wir damit auf das nächste Servo. Wir setzen diese Variable auf 0 zurück, wenn wir die maximale Anzahl an Servos erreicht haben. Anschließend müssen wir noch die aktuelle Zeit speichern, um sie im nächsten Durchlauf bei einem Tastendruck wieder mit der neuen Zeit zu vergleichen. Auch der Zustand des Tasterpins wird gespeichert.

Als letztes folgt dann die Ausgabe der Werte des Potis auf dem seriellen Monitor. Außerdem wird natürlich der angepasste Wert des Potis auf das aktuell eingestellte Servo gegeben. Mit pwm.setPWM() setzen wir die absolute Drehwinkelposition des Servos. Der erste Parameter ist die Servonummer in der Reihenfolge, wie sie am Treiberboard angeschlossen sind. Der dritte Parameter ist die Pulslänge der PWM und sorgt für die Position.

Eine genaue Beschreibung der Parameter findet Ihr auf der Webseite von Adafruit. Wir benötigen nur den ersten und dritten Parameter. Der zweite Parameter bleibt 0.

Laden wir das gesamte Programm nun auf den Arduino und öffnen den seriellen Monitor, sehen wir den Wert des Potis, den wir auf das Servo geben. Für die bessere Sichtbarkeit der Achsdrehung ist es ratsam, auf die Achse des Servos einen Servoarm aufzustecken. Später befestigen wir daran unsere Bauteile. Man sieht dann, wo sich die Mittenposition der Servoachse befindet. Wir notieren uns den Wert, den wir als Mitte einstellen, in dem dafür vorbereiteten Array und schalten dann durch die einzelnen Servos. Sie können damit auch testen, ob die Schaltung ordnungsgemäß aufgebaut wurde.

Eventuell fragen Sie sich, warum wir für vier Servos ein Treiberboard mit 16 Anschlüssen verwenden. Eventuell kommen weitere Servos hinzu. Das ergibt sich im Laufe der Entwicklung des Roboters.

Hier nun noch der finale Quellcode: 

/*  Servopositionen einstellen 
 *  von Andreas Wolter 
 *  fuer AZ-Delivery.de 
 *   
 *  Version: 1.0 
 *   
 *  Funktion: 
 *  Mit einem Potentiometer die Achsen der Servos einstellen. 
 *  Dabei die Positionswerte aus dem seriellen Monitor ablesen. 
 *  Mit einem Taster durch die Servos schalten. 
 *   
 *  Verwendete Hardware: 
 *    - Arduino Nano V3 
 *    - SG90 Mikroservos (4x) 
 *    - PCA9685 16 Kanal 12 Bit PWM Servotreiber 
 *    - Taster 
 *    - Potentiometer (hier 10KOhm) 
 *    - externe Spannungsversorgung 5V 
 *   
 *  Verwendete Bibliotheken: 
 *    - wire 
 *    - Adafruit PWM Servo Driver Library 
 *   
 *  Beispielquelle aus der Adafruit PWM Servo Driver Library: servo 
 *   
 ***************************************************  
  This is an example for our Adafruit 16-channel PWM & Servo driver 
  Servo test - this will drive 8 servos, one after the other on the 
  first 8 pins of the PCA9685 
 
  Pick one up today in the adafruit shop! 
  ------> http://www.adafruit.com/products/815 
   
  These drivers use I2C to communicate, 2 pins are required to   
  interface. 
 
  Adafruit invests time and resources providing this open source code,  
  please support Adafruit and open-source hardware by purchasing  
  products from Adafruit! 
 
  Written by Limor Fried/Ladyada for Adafruit Industries.   
  BSD license, all text above must be included in any redistribution 
 **************************************************** 
 *   
 *  Pinout: 
 *   
 *  Arduino Nano  |   Servo Treiber   |   Externe Spannungsquelle       
 *  ------------------------------------------------------------- 
 *      GND       |         GND       | 
 *      5V        |         VCC       | 
 *      A4        |         SDA       | 
 *      A5        |         SCL       | 
 *                |     Connector V+  |      +5V 
 *                |     Connector GND |      GND 
 *   
 *  Arduino Nano  |   Input 
 *  ------------------------------------------------------------- 
 *      D8        |   Taster Pin 1 
 *      A0        |   Potentiometer Mitte (Schleifer Pin) 
 *      5V        |   Potentiometer Außen 1 
 *      GND       |   Potentiometer Außen 2 
 *      GND       |   Taster Pin 2 
 */ 
 
#include <Wire.h> 
#include <Adafruit_PWMServoDriver.h> 
 
#define SERVOMIN   68   // 0 bis 4096 - try and error 
#define SERVOMAX   510  // 0 bis 4096 - try and error 
#define SERVO_FREQ 50   // Analog servos run at ~50 Hz updates   
#define TOLERANZ   10   // Prozent vom Endanschlag 
 
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); 
 
// States       
int state = 0; 
 
// Input 
int taster_pin = 8; 
bool input = HIGH; 
bool input_alt = HIGH;  
int input_analog = 0; 
 
// Servos 
// Berechne Min und Max mit Servotoleranz am Aussenanschlag 
const int MAXSERVOS = 4; 
int range = SERVOMAX - SERVOMIN; 
double temp = (range / 100) * (double)TOLERANZ; 
int NEWMIN = SERVOMIN + (int)temp; 
int NEWMAX = SERVOMAX - (int)temp; 
int i = 0; 
int SERVO_MIDDLE[MAXSERVOS] = {275, 334, 317, 284}; 
 
// Timer 
unsigned long prell_delay = 100; 
unsigned long alte_zeit = 0; 
 
void setup() { 
  Serial.begin(115200); 
  Wire.begin(); 
  pinMode(taster_pin, INPUT_PULLUP); 
  pwm.begin(); 
  pwm.setOscillatorFrequency(27000000);   // The int.osc. is closer to 27MHz   
  pwm.setPWMFreq(SERVO_FREQ);             // Analog servos run at ~50 Hz updates 
  delay(500); 
} 
 
void loop() { 
  // Input lesen und anpassen 
  input = digitalRead(taster_pin); 
  input_analog = analogRead(A0); 
  input_analog = map(input_analog, 0, 1023, NEWMIN, NEWMAX); 
 
  // Entprellen 
  // wenn Taster jetzt AN und vorher AUS und aktuelle Zeit minus alte Zeit groesser, als vorgegebenes Delay 
  if (input == LOW && input_alt == HIGH && millis() - alte_zeit > prell_delay) { 
    state++; 
    // States eingrenzen auf Anzahl der Servos 
    if (state > MAXSERVOS) { 
      state = 0; 
    } 
    alte_zeit = millis(); 
  } 
  input_alt = input; 
 
  //Bildschirmausgabe 
  Serial.print("Servo Nr: "); 
  Serial.print(state); 
  Serial.print(" Position Input: "); 
  Serial.println(input_analog); 
 
  //Servo positionieren 
  pwm.setPWM(state, 0, input_analog); 
}


Vorschau

Im nächsten Teil bauen wir den Roboter zusammen und legen die Grundposition fest. Anschließend werden wir eine Laufbewegung programmieren, in dem wir die Servos zur richtigen Zeit in die richtige Richtung drehen.

Bis dahin!

Andreas Wolter
für AZ-Delivery Blog

 

2 Kommentare

Dirk

Dirk

Ein großes Lob, sehr ausführlich beschrieben den ich auch nachbauen werde. Bitte weiterhin so schreiben das es auch ein Anfänger versteht. Schön wäre es allerdings einen Link zu erhalten für die Artikel die man nicht über euch beziehen kann.

Arnim

Arnim

Hallo zusammen! Eine tolle Idee, aber ein Bauvorschlag zu einem derzeit nicht lieferbaren Board ist vielleicht doch nicht die beste Werbung?

Einen Kommentar hinterlassen

Alle Kommentare werden vor der Veröffentlichung moderiert