Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Manufacturing Technology >> Herstellungsprozess

Verwandeln Sie jeden Gleichstrommotor in einen individuellen 360°-Servo – Schritt-für-Schritt-Anleitung

In diesem Tutorial erfahren Sie, wie Sie jeden Gleichstrommotor in einen eigenständigen, kundenspezifischen Servomotor mit vielen Funktionen verwandeln. Im Gegensatz zu normalen Servos, die eine begrenzte Bewegung von 180 oder 270 Grad haben, verfügt dieses über eine unbegrenzte Reichweite von 360 Grad und darüber hinaus haben wir die Möglichkeit, den Rotationsbereich auf jeden gewünschten Wert anzupassen.

Das finde ich ziemlich praktisch, und obendrein können wir sogar den Mittelpunkt des Servos anpassen. So können wir sowohl den Mittelpunkt als auch den Drehbereich gleichzeitig anpassen.

Sie können sich das folgende Video ansehen oder das untenstehende schriftliche Tutorial lesen.

Eine weitere Funktion besteht darin, dass wir die Empfindlichkeit anpassen können oder wie schnell das Servo auf unsere Eingaben reagieren soll. Apropos Eingabe:Wir können drei verschiedene Eingabemodi haben.

Wir können das Servo mit einem analogen Spannungseingang oder mit einem Potentiometer steuern, wir können das Servo mit einem RC-Sender steuern sowie das Servo über eine serielle Schnittstelle steuern, indem wir Winkelwerte über den seriellen Monitor auf unserem PC oder Laptop eingeben.

Wir können das auch gleichzeitig tun, das Servo steuern, indem wir Werte über den seriellen Monitor eingeben und das Servo manuell mit dem RC-Sender bewegen. Der Servomotor kennt jederzeit seine aktuelle Position und kann diese auf dem seriellen Monitor sehen. 

An der Spitze dieser Servomotor-Funktionsliste steht der kontinuierliche Rotationsmodus. Das ist richtig. Selbst in diesem kontinuierlichen Rotationsmodus können wir die Position des Servomotors steuern und verfolgen. Wir können die Servomotorwelle so einstellen, dass sie mit unendlich vielen Umdrehungen in jede beliebige Position geht.  

All dies ist möglich dank des 12-Bit-Encoders, den dieser Servomotor verwendet, des magnetischen Drehpositionssensors AS5600 und der implementierten PID-Regelung für den Antrieb des Gleichstrommotors.

Ich habe diese maßgeschneiderte Servomotor-Controllerplatine hergestellt, die einen eigenen Mikrocontroller und alles andere enthält, um jeden Gleichstrommotor problemlos in einen eigenständigen Servomotor zu verwandeln.

Wir müssen nur die Platine in der Mitte der Abtriebswelle positionieren (einschließlich eines speziellen Magneten auf der Welle), einen Gleichstrommotor beliebiger Größe mit bis zu 3,5 A Nennstrom anschließen, das gesamte System mit 12 V versorgen und schon erhalten wir einen Servomotor aus einem normalen Gleichstrommotor mit all diesen Funktionen.

Jetzt werde ich Sie durch den gesamten Prozess der Herstellung dieses maßgeschneiderten Servomotors führen, damit Sie ihn auch selbst herstellen können. Ich erkläre das Funktionsprinzip eines Servomotors, eines Closed-Loop-Reglers, eines PID-Reglers, wie ich die benutzerdefinierte Leiterplatte dafür und das Getriebe entworfen habe, und erkläre auch den Code dahinter.

Funktionsprinzip des Servomotors

Um das Funktionsprinzip eines Servomotors zu erklären, nehmen wir einen typischen RC-Servomotor auseinander und sehen, was sich darin befindet.

Wir können feststellen, dass es über einen kleinen Gleichstrommotor, eine Controller-Platine, ein Potentiometer und einen dreiadrigen Anschluss verfügt, zwei Drähte für die Stromversorgung und einen für das Eingangssignal. Außerdem gibt es einige Gänge zum Reduzieren der Drehzahl und Erhöhen des Drehmoments des Gleichstrommotors. 

Dies ist ein typisches Setup für die meisten RC- oder Hobby-Servomotoren. Das Potentiometer ist an der Abtriebswelle des Gleichstrommotors angebracht und fungiert als Positionssensor. Es teilt dem Controller die aktuelle Position der Servomotorwelle mit. Die Steuerplatine steuert den Gleichstrommotor basierend auf dem Eingangssignal (der gewünschten Position) und der tatsächlichen Position, die wir als Rückmeldung vom Potentiometer erhalten. Dies stellt ein Regelsystem dar.

Das Eingangssignal bzw. die gewünschte Position wird mit der tatsächlichen Position des Motors verglichen, die wir vom Positionsrückmeldesensor erhalten. Die auftretende Differenz, die als Fehler bezeichnet wird, wird dann in der Steuerung verarbeitet, die dem Motor den Befehl gibt, sich zu bewegen, bis er die gewünschte Position erreicht.

So erstellen Sie einen benutzerdefinierten Servomotor

Wenn wir also unseren eigenen Servomotor mit einigen größeren Gleichstrommotoren bauen möchten, als diese typischen RC-Servos verwenden, können wir das gleiche Regelsystem implementieren.

Wir brauchen lediglich einen Positionssensor, der irgendwie an der Abtriebswelle befestigt ist, und einen Mikrocontroller zum Antrieb des Gleichstrommotors.  

Was nun den Positionssensor betrifft, besteht die einfachste Lösung darin, ein einfaches Potentiometer zu verwenden, genau wie wir es bei den RC-Servos gesehen haben. Das Problem bei diesen Potentiometertypen besteht jedoch darin, dass sie einen begrenzten Drehbereich von nur 270 Grad haben, was den Drehbereich des Servomotors direkt einschränkt. Es gibt auch andere Arten von Potentiometern, die mehrere Drehungen ausführen können und eine bessere Reichweite und Auflösung bieten, aber dennoch eine begrenzte Drehung haben.

Wenn der Servomotor einen unbegrenzten Drehbereich haben soll, müssen wir einen Encoder verwenden. Encoder sind elektromechanische Geräte, die die Winkelposition der Welle bei unbegrenzter Drehung verfolgen können. Es gibt viele Arten von Encodern, z. B. inkrementelle oder absolute Encoder oder je nach Sensortechnologie optische, magnetische oder kapazitive Encoder. Natürlich hat jeder von ihnen seine eigenen Vor- und Nachteile.

AS5600 Encoder – Magnetischer Drehpositionssensor

Ich habe mich für die Verwendung eines magnetischen Encoders oder des magnetischen Drehpositionssensors AS5600 entschieden, da es sich um einen sehr kompakten und einfach zu implementierenden Encoder handelt, der eine hohe Präzision und Auflösung bietet. Schauen Sie sich nur an, wie klein dieser Mikrochip ist.

Es verfügt über einen eingebauten Hall-Effekt-Sensor, der Änderungen in der Richtung des Magnetfelds erkennen kann. Wir müssen also nur einen Magneten an der Abtriebswelle des Motors anbringen und ihn in einem Abstand von 0,5 bis 3 mm in der Nähe des Mikrochips positionieren.

Wenn sich nun die Motorwelle und der Magnet drehen, erfasst der Hall-Effekt-Sensor diese Änderungen in der Richtung des Magnetfelds. Mit Hilfe des eingebauten 12-Bit-A/D-Wandlers kann der AS5600-Sensor 4096 Positionen pro Umdrehung oder 360-Grad-Drehung ausgeben.

Das bedeutet, dass Änderungen der Winkelposition bereits ab 0,0878 Grad erfasst werden können. Das ist ziemlich beeindruckend, und angesichts der Tatsache, dass es sehr erschwinglich und leicht zu bekommen ist, ist es die richtige Wahl für einen maßgeschneiderten Servomotor. 

Also gut, was brauchen wir sonst noch, einen Mikrocontroller und einen Treiber für den Gleichstrommotor? Ich habe mich für den DC-Motortreiber DRV8871 entschieden, der bis zu 3,5 Ampere Strom verarbeiten kann, und für den Atmega328-Mikrocontroller.

Ich habe mich für die oberflächenmontierte Version entschieden, da sie viel kompakter ist als die DIP-Version, und mein Ziel war es, eine möglichst kleine benutzerdefinierte Leiterplatte herzustellen, auf der ich alles unterbringen kann, damit das Servo als eigenständiges Gerät arbeiten kann.

Benutzerdefinierter Servomotor-Schaltplan

Hier ist der vollständige Schaltplan dieses speziell angefertigten Servomotors.

Sie können die für dieses Projekt benötigten Komponenten über die folgenden Links erhalten:

Offenlegung:Dies sind Affiliate-Links. Als Amazon-Partner verdiene ich an qualifizierten Käufen.

Wir haben also den Atmega328-Mikrocontroller zusammen mit seiner empfohlenen Minimalschaltung, die einen 16-MHz-Oszillator, einige Kondensatoren und einen Widerstand umfasst.

Für die Stromversorgung des Mikrocontrollers und der anderen Komponenten, die 5 V benötigen, verwenden wir den Spannungsregler AMS1117, der den 12-V-Stromeingang auf 5 V senkt.

Hier ist der AS5600-Positionssensor mit seiner empfohlenen Schaltung, die zwei Kondensatoren und zwei Pull-up-Widerstände für die IC2-Kommunikation enthält.

Der DC-Motortreiber DRV8871 benötigt nur einen Widerstand zur Strombegrenzung und zwei Entkopplungskondensatoren. Dann haben wir zwei Potentiometer, die an die analogen Eingänge des Mikrocontrollers angeschlossen sind, eines zum Einstellen des Drehbereichs und das andere zum Einstellen der Empfindlichkeit des Servos. Der Druckknopf dient zum Einstellen des Mittelpunkts des Servos und der Zwei-Wege-DIP-Schalter zur Auswahl der Arbeitsmodi des Servos. Es gibt eine Stiftleiste für die Eingänge des Servos, entweder einen analogen Spannungseingang oder einen digitalen PWM-Eingang von einem RC-Empfänger, sowie einen 5-V- und einen Erdungsstift. Außerdem gibt es einen Pin-Header zum Programmieren des Mikrocontrollers über das SPI-Protokoll und den seriellen Port. 

Hier ist eine Zusammenfassung dieser Schaltung und ihres Arbeitsablaufs. Der Eingang bzw. die gewünschte Winkelposition wird über diese beiden Pins empfangen und kann entweder eine analoge Spannung von einem Potentiometer oder ein digitales PWM-Signal von einem RC-Empfänger sein. Der Eingang geht in den Mikrocontroller, wo er mit der tatsächlichen Winkelposition verglichen wird, die vom Encoder oder dem AS5600-Positionssensor erkannt wird. Dieser Sensor kommuniziert mit dem Mikrocontroller über das IC2-Protokoll.

Dann führt der Mikrocontroller die Berechnung durch, berechnet den Fehler und sendet entsprechend ein PWM-Signal an den DRV8871-Treiber, der den Gleichstrommotor antreibt, bis er die gewünschte Position erreicht. 

Der gesamte Schaltkreis wird mit 12 V versorgt, und der Spannungsregler AS1117 stellt entsprechend 5 V für den Mikrocontroller und die anderen Komponenten bereit.

PCB-Design 

Gemäß dem Schaltplan habe ich versucht, die Platine so klein wie möglich zu gestalten, und am Ende sind es 40 x 40 mm.

Ich positioniere den Encoder an der Unterseite und genau in der Mitte der Platine, so dass er einfach montiert und mit der Abtriebswelle des Servos ausgerichtet werden kann.

Alle anderen Komponenten befinden sich auf der anderen Seite, sodass sie den Encoder und die Abtriebswelle nicht beeinträchtigen.

Ich habe die Platine bei PCBWay bestellt. Hier können wir einfach die Gerber-Datei hochladen, die Eigenschaften unserer Leiterplatte auswählen und sie zu einem günstigen Preis bestellen.

Ich habe die Platine so konzipiert, dass sie 4 Schichten hat, die mittleren sind für GND, was den Preis etwas erhöht. Ich habe keine der Standardeigenschaften geändert, außer der PCB-Farbe, die ich als Weiß ausgewählt habe, und ich kreuze an, dass ich die Änderung der Oberflächenbeschaffenheit zu Immersionsgold, falls zutreffend, ohne Aufpreis akzeptiere.

Sie können den Gerber in der PCBWay-Projektfreigabe-Community finden und herunterladen, über die Sie die Leiterplatte auch direkt bestellen können.

Dennoch kam die Platine nach mehreren Tagen an. Die Qualität der Platine ist super, alles gleicht dem Design und ich habe sie in der Oberflächenveredelung Immersionsgold erhalten.

Also gut, jetzt können wir mit dem Anlöten der Komponenten fortfahren. Ich begann mit den kleineren Komponenten wie dieser Anzeige-LED sowie den Kondensatoren und Widerständen.

Es ist tatsächlich das erste Mal, dass ich diese kleinen SMD-Komponenten löte, und ich war wirklich sehr, sehr schlecht darin. 

Die größte Herausforderung war das Löten des Atmega328-Mikrocontrollers, da die Pins sehr klein und sehr nahe beieinander sind, aber ich habe es irgendwie geschafft.

Der AS5600-Encoder-Mikrochip ließ sich einfach auf die Rückseite der Leiterplatte löten, ebenso wie die größeren Durchgangskomponenten wie der DIP-Schalter, die Potentiometer, die Klemmenblöcke und die Stiftleisten.

Wie auch immer, hier ist das endgültige Erscheinungsbild des Controller-Boards, das meiner Meinung nach immerhin anständig geworden ist.

Jetzt ist es an der Zeit, ein passendes Getriebe für den Gleichstrommotor und diese Steuerplatine herzustellen. 

Benutzerdefiniertes Servo-3D-Modell

Das Getriebe für diesen kundenspezifischen Servomotor habe ich mit Onshape entworfen. Die Ausführung des Getriebes hängt natürlich vom Gleichstrommotor ab. Wie ich bereits erwähnt habe, können wir in Kombination mit der soeben hergestellten Steuerplatine einen Gleichstrommotor jeder Größe verwenden.

Hier verwende ich einen Gleichstrommotor mit 37 mm Durchmesser und einem eingebauten Getriebe, das 50 U/min abgibt. 50 U/min sind eine gute Drehzahl für einen Servomotor, aber ich wollte etwas niedriger gehen, um ein besseres Drehmoment zu erhalten, also habe ich ein Getriebe mit dreifacher Untersetzung gebaut. Zu diesem Zweck habe ich Fischgrätenzahnräder verwendet, da diese effizient und einfach mit einem 3D-Drucker herzustellen sind.

Natürlich haben wir hier die Freiheit, dieses Getriebedesign nach unseren Wünschen zu gestalten, da es davon abhängt, welchen Gleichstrommotor wir verwenden möchten und welche Abtriebsgeschwindigkeiten wir erreichen möchten. 

Ich habe die Steuerplatine auf der Rückseite dieses Getriebes positioniert und sie perfekt in der Mitte der Abtriebswelle ausgerichtet.

Falls wir die Welle des Gleichstrommotors direkt als Abtrieb nutzen möchten, können wir einfach einen 1:1-Zahnradsatz verwenden, damit wir die Position der Welle korrekt verfolgen können. Oder wir könnten in einem solchen Fall auch ein Gurtsystem einsetzen. Wie gesagt, wir haben endlose Möglichkeiten, das Getriebe herzustellen. 

Laden Sie 3D-Modelle und STL-Dateien herunter

Mit Onshape können Sie das 3D-Modell dieses maßgeschneiderten Servomotors direkt in Ihrem Webbrowser ansehen und erkunden. (Dafür benötigen Sie ein Onshape-Konto. Sie können ein kostenloses Konto für die Verwendung zu Hause erstellen.)

Natürlich können Sie hier auch das 3D-Modell sowie die STL-Dateien herunterladen, die Sie für den 3D-Druck der Teile benötigen:

STEP-Datei:

STL-Dateien für den 3D-Druck:

Zusammenbau des benutzerdefinierten Servos

Hier sind die 3D-gedruckten Teile für diesen Bau, damit wir mit dem Zusammenbau des Servomotors beginnen können.

Dazu benötigen wir einige M3-Schrauben und Gewindeeinsätze sowie einige Lager. 

Zuerst habe ich den Gleichstrommotor mit einigen M3-Schrauben mit 8 mm Länge an der Grundplatte befestigt.

Dann können wir die beiden Zahnräder einbauen. Das kleinere Zahnrad geht direkt an die Welle des Gleichstrommotors und das größere Zahnrad dient als Ausgang des Servos. Allerdings besteht die Abtriebswelle des aus zwei Teilen.

Auf beiden Seiten dieses Abtriebswellenteils habe ich Gewindeeinsätze angebracht, auf der einen Seite zum Anschließen des Zahnrads und auf der anderen Seite zum Befestigen von Dingen am Ausgang des Servos. 

Ich habe auch Gewindeeinsätze am kleineren Zahnrad angebracht, die zur Befestigung an der Welle des Gleichstrommotors dienen. Jetzt können wir die gekürzten Zahnräder in ihre Position schieben. Da es sich um Fischgräten-Zahnräder handelt, müssen wir sie beide gleichzeitig an ihren Platz schieben, andernfalls können wir sie nicht koppeln, wenn wir sie einzeln einsetzen.

Mit einer Madenschraube habe ich das kleine Zahnrad an der Welle des Gleichstrommotors befestigt. Ich habe 12 V an den Gleichstrommotor angelegt, um zu prüfen, ob das Getriebe ordnungsgemäß funktioniert. 

Wir können den Zusammenbau des Getriebes abschließen, indem wir die Seitenwand, das Kugellager für die Abtriebswelle und die obere Abdeckung einsetzen.

Ich habe einige M3-Gewindeeinsätze an der Rückplatte angebracht, damit wir die gesamte Baugruppe mit einigen 20 mm langen M3-Schrauben befestigen können. Ich habe das Getriebe noch einmal getestet, es funktioniert super. Wir können sehen, wie sich die Abtriebswelle auf der Rückseite dreht und hier müssen wir den Magneten einfügen, den der AS5600-Encoder verfolgt.

Wir befestigen die Steuerplatine mit einigen M2-Schrauben und -Muttern am Getriebe. Der AS5600-Positionssensor ist jetzt perfekt auf den Magneten ausgerichtet und misst die Änderung des Magnetfelds ordnungsgemäß, wenn sich die Abtriebswelle dreht.

Bitte beachten Sie hierbei, dass die Magnetisierungsrichtung des Permanentmagneten sehr wichtig ist. Je nachdem, ob er axial oder diametral magnetisiert ist, sollten wir den Magneten entweder senkrecht oder parallel zum AS5600-IC positionieren.

Am Ende habe ich die Richtung meines Magneten geändert, da er nicht die richtige Magnetisierung hatte, damit der AS5600-Encoder ihn messen konnte.

Als nächstes habe ich zwei Drähte an den Gleichstrommotor angelötet und den Motor über den Klemmenblock mit der Steuerung verbunden. Für die Stromversorgung habe ich zwei Drähte an die Stromklemmenleiste angeschlossen, die auf der anderen Seite über einen Gleichstromanschluss zum Anschluss einer 12-V-Stromversorgung verfügen. Und fertig, unser maßgeschneiderter Servomotor ist fertig.

Programmierung des Controllers

Jetzt müssen Sie nur noch diesem Servo Leben einhauchen oder den Controller programmieren. Zu diesem Zweck müssen wir zunächst einen Bootloader auf den ATmega328p-Mikrocontroller brennen. Ohne einen Bootloader kann der Mikrocontroller die Sprache oder den Code, den wir an ihn senden, nicht verstehen. 

Bootloader Burn

Um den Bootloader auf den ATmega328p zu brennen, benötigen wir ein Arduino-Board, in meinem Fall verwende ich ein Arduino Nano-Board.

Wir werden die SPI-Kommunikation verwenden, daher müssen wir die passenden SPI-Pins auf dem Arduino-Board und unserem Controller-Board verbinden.

Jetzt müssen wir mit der Arduino IDE die ArduinoISP-Beispielskizze öffnen und auf das Arduino Nano-Board hochladen. Mit diesem Code ist der Arduino Nano nun in der Lage, den Bootloader auf den ATmega328-Mikrocontroller zu brennen. 

Als Nächstes müssen wir als Programmierer im Menü „Extras“ Arduino als ISP auswählen und dann auf Bootloader brennen klicken.

Beim Brennen des Bootloaders sollten wir bemerken, dass die Arduino NANO-Leuchten häufig blinken, was zu einem erfolgreichen Brennen des Bootloaders führt. 

Code-Upload

Sobald wir damit fertig sind, können wir den Code mithilfe eines USB-zu-UART-Schnittstellenmoduls programmieren oder auf die Controllerplatine hochladen.

Die Controller-Platine verfügt über spezielle Pins zum einfachen Anschließen, wie in diesem Schaltplan gezeigt. 

Jetzt können wir den Code für dieses speziell angefertigte Servo, das ich erstellt habe, öffnen und auf den Controller hochladen. Bevor wir das jedoch tun, sollten wir zunächst die Bibliotheken für den AS5600-Sensor und die PID-Regelung installieren. Das können wir ganz einfach über den Arduino IDE Library Manager erledigen. Sobald wir auf die Schaltfläche „Upload“ klicken, wird der Code über das USB-zu-UART-Schnittstellenmodul auf unseren ATmega328-Controller geschrieben.

Und fertig ist unser maßgeschneiderter Servomotor. Jetzt können wir ein Potentiometer daran anschließen, um es zu testen. Bitte beachten Sie, dass der Analogeingang an den „S“-Pin auf der Controllerplatine und nicht an den „A“-Pin geht.

Beim Entwurf der Platine habe ich diese beiden Pins falsch mit dem ATmega328 verbunden. Dann können wir über den DIP-Schalter den analogen Eingangsmodus auswählen und das Servo mit Strom versorgen.

Und hier können wir die Position des Servomotors mithilfe des Analogeingangs vom Potentiometer steuern. Wir haben unseren Gleichstrommotor erfolgreich in einen Servomotor umgewandelt.

Quellcode

Werfen wir nun einen Blick auf den Code dieses speziell angefertigten Servomotors.

/*
 * Custom-built Servo Motor - Arduino Code
 * by Dejan, www.HowToMechatronics.com
 * 
 * Libraries:
 * AS5600 encoder: https://github.com/RobTillaart/AS5600
 * PID conroller: https://github.com/br3ttb/Arduino-PID-Library/blob/master/PID_v1.h
 */
#include "AS5600.h"
#include "Wire.h"
#include <PID_v1.h>
AS5600 as5600; // use default Wire
double Pk1 = 2; //speed it gets there
double Ik1 = 0;
double Dk1 = 0.025;
//Define Variables we'll be connecting to
double Setpoint, Input, Output;
PID myPID(&Input, &Output, &Setpoint, Pk1, Ik1, Dk1, DIRECT);
#define motor_IN1 5
#define motor_IN2 6
#define ch1 2
#define centerSet 7
#define inputSwitch 3
#define modeSwitch 4
int ch1Value;
int encoderValue, inputValue, pwmValue;
String inString = ""; // string to hold input
int centerAngle = 2047; // 180 degrees
int angleDifference = 0;
int angleValue = 0;
int leftLimit = 30;
int rightLimit = 4067;
int rangeAdjustment = 0;
float sensitivityAdjustment = 0;
float angle = 0;
int quadrantNumber = 2;
int previousQuadrantNumber = 3;
int numberOfTurns = 0;
float totalAngle = 0;
int error = 0;
char incomingByte = 0;
int intInput = 0;
void setup() {
 Serial.begin(115200);
 Serial.println(__FILE__);
 Serial.print("AS5600_LIB_VERSION: ");
 Serial.println(AS5600_LIB_VERSION);
 Wire.begin();
 pinMode(motor_IN1, OUTPUT);
 pinMode(motor_IN2, OUTPUT);
 // Activate the Arduino internal pull-up resistors
 pinMode(centerSet, INPUT_PULLUP);
 pinMode(inputSwitch, INPUT_PULLUP);
 pinMode(4, INPUT_PULLUP);
 myPID.SetMode(AUTOMATIC); // PID Setup
 myPID.SetOutputLimits(-255, 255);
 myPID.SetSampleTime(20);
}
void loop() {
 // Read encoder value - current position
 encoderValue = as5600.readAngle();
 // Continuous rotation mode
 if (digitalRead(modeSwitch) == 0) {
 // Enter desired angle for the servo to go to through the serial monitor
 while (Serial.available() > 0) {
 int inChar = Serial.read();
 if (isDigit(inChar)) {
 // convert the incoming byte to a char and add it to the string:
 inString += (char)inChar;
 }
 // if you get a newline, print the string, then the string's value:
 if (inChar == '\n') {
 Setpoint = inString.toInt(); // Setpoint - desired angle
 // clear the string for new input:
 inString = "";
 }
 }
 if (digitalRead(inputSwitch) == 0) { // Potentiometer as input
 inputValue = analogRead(A0);
 if (inputValue < 400) {
 Setpoint = Setpoint - 0.3;
 }
 if (inputValue < 300) {
 Setpoint = Setpoint - 0.3;
 }
 if (inputValue < 200) {
 Setpoint = Setpoint - 0.3;
 }
 if (inputValue > 600) {
 Setpoint = Setpoint + 0.3;
 }
 if (inputValue > 700) {
 Setpoint = Setpoint + 0.3;
 }
 if (inputValue > 800) {
 Setpoint = Setpoint + 0.3;
 }
 }
 else if (digitalRead(inputSwitch) == 1) {
 inputValue = pulseIn(ch1, HIGH, 30000); // RC receiver as input
 if (inputValue < 1450) {
 Setpoint--;
 }
 if (inputValue < 1350) {
 Setpoint--;
 }
 if (inputValue < 1250) {
 Setpoint--;
 }
 if (inputValue < 1150) {
 Setpoint--;
 }
 if (inputValue > 1550) {
 Setpoint++;
 }
 if (inputValue > 1650) {
 Setpoint++;
 }
 if (inputValue > 1750) {
 Setpoint++;
 }
 if (inputValue > 1850) {
 Setpoint++;
 }
 }
 // Convert encoder RAW values into angle value
 angle = encoderValue * 0.087890625;
 // Quadrant 1
 if (angle >= 0 && angle <= 90) {
 quadrantNumber = 1;
 }
 // Quadrant 2
 if (angle >= 90 && angle <= 180) {
 quadrantNumber = 2;
 }
 // Quadrant 3
 if (angle >= 180 && angle <= 270) {
 quadrantNumber = 3;
 }
 // Quadrant 4
 if (angle >= 270 && angle <= 360) {
 quadrantNumber = 4;
 }
 if (quadrantNumber != previousQuadrantNumber) {
 // Transition from 4th to 1st quadrant
 if (quadrantNumber == 1 && previousQuadrantNumber == 4) {
 numberOfTurns++;
 }
 // Transition from 1st to 4th quadrant
 if (quadrantNumber == 4 && previousQuadrantNumber == 1) {
 numberOfTurns--;
 }
 previousQuadrantNumber = quadrantNumber;
 }
 if (totalAngle >= 0) {
 totalAngle = (numberOfTurns * 360) + angle;
 }
 else {
 totalAngle = (numberOfTurns * 360) + angle;
 }
 // Establish Input value for PID
 Input = totalAngle;
 }
 // Limited Rotation Mode
 else if (digitalRead(modeSwitch) == 1) {
 rangeAdjustment = analogRead(A1);
 leftLimit = 0 + 30 + rangeAdjustment;
 rightLimit = 4097 - 30 - rangeAdjustment;
 if (digitalRead(inputSwitch) == 0) { // Analog input - Potentiometer
 // Get value from potentiometer
 inputValue = analogRead(A0);
 if (inputValue < 15) {
 inputValue = 15;
 }
 if (inputValue > 1008) {
 inputValue = 1008;
 }
 Setpoint = map(inputValue, 15, 1008, -255, 255);
 }
 else if (digitalRead(inputSwitch) == 1) { // Digital input - RC transmitter
 inputValue = pulseIn(ch1, HIGH, 30000); // Read RC receiver as input
 Setpoint = map(inputValue, 1000, 2000, -255, 255);
 }
 // Set center angle
 if (digitalRead(centerSet) == LOW) {
 centerAngle = encoderValue;
 angleDifference = 2047 - encoderValue;
 delay(1000);
 }
 // Adjust angle value according to the center point (angleDifference)
 if (centerAngle < 2047) {
 angleValue = encoderValue + angleDifference;
 if (encoderValue < 4097 && encoderValue > (4096 - angleDifference)) {
 angleValue = encoderValue - 4097 + angleDifference;
 }
 }
 if (centerAngle > 2047) {
 angleValue = encoderValue + angleDifference;
 if (encoderValue >= 0 && encoderValue < abs(angleDifference)) {
 angleValue = encoderValue + 4097 + angleDifference;
 }
 }
 else if (centerAngle == 2047) {
 angleValue = encoderValue;
 }
 // Establish Input value for PID
 Input = map(angleValue , leftLimit, rightLimit, -255, 255);
 }
 // Adjusting sensitivity
 Pk1 = analogRead(A2) * 0.002;
 myPID.SetTunings(Pk1, Ik1, Dk1);
 // Run PID process to get Output value
 myPID.Compute();
 // Move right
 if (Output > 1 ) {
 pwmValue = Output;
 if (pwmValue < 30 && pwmValue > 5) {
 pwmValue = pwmValue + 30;
 }
 if (pwmValue <= 5) {
 pwmValue = 0;
 }
 digitalWrite(motor_IN1, LOW);
 analogWrite(motor_IN2, pwmValue);
 }
 // Move left
 else if (Output < 1 ) {
 pwmValue = abs(Output);
 if (pwmValue < 30 && pwmValue > 5) {
 pwmValue = pwmValue + 30;
 }
 if (pwmValue <= 5) {
 pwmValue = 0;
 }
 analogWrite(motor_IN1, pwmValue);
 digitalWrite(motor_IN2, LOW);
 }
 // Do not move
 else if (Output > -1 && Output < 1) {
 pwmValue = 0;
 digitalWrite(motor_IN1, LOW);
 digitalWrite(motor_IN2, LOW);
 }
 //Serial.print(Setpoint);
 //Serial.print("\t");
 //Serial.println(totalAngle);
}Code language: PHP (php)

Codeübersicht

Also beginnen wir die Schleife, indem wir den Encoderwert oder die aktuelle Position der Welle lesen.

// Read encoder value - current position
 encoderValue = as5600.readAngle();Code language: JavaScript (javascript)

Wenn wir uns dann im kontinuierlichen Rotationsmodus befinden, akzeptieren wir Werte vom seriellen Monitor und verwenden sie als Sollwert oder gewünschten Winkel für den PID-Regler.

// Enter desired angle for the servo to go to through the serial monitor
 while (Serial.available() > 0) {
 int inChar = Serial.read();
 if (isDigit(inChar)) {
 // convert the incoming byte to a char and add it to the string:
 inString += (char)inChar;
 }
 // if you get a newline, print the string, then the string's value:
 if (inChar == '\n') {
 Setpoint = inString.toInt(); // Setpoint - desired angle
 // clear the string for new input:
 inString = "";
 }
 }Code language: JavaScript (javascript)

Wenn der Eingabemodus auf Potentiometer eingestellt ist, lesen wir seinen analogen Eingang aus und korrigieren den Sollwert, je nachdem, wie weit wir ihn drehen.

if (digitalRead(inputSwitch) == 0) { // Potentiometer as input
 inputValue = analogRead(A0);
 if (inputValue < 400) {
 Setpoint = Setpoint - 0.3;
 }
 if (inputValue < 300) {
 Setpoint = Setpoint - 0.3;
 }
 if (inputValue < 200) {
 Setpoint = Setpoint - 0.3;
 }
 if (inputValue > 600) {
 Setpoint = Setpoint + 0.3;
 }
 if (inputValue > 700) {
 Setpoint = Setpoint + 0.3;
 }
 if (inputValue > 800) {
 Setpoint = Setpoint + 0.3;
 }
 }Code language: JavaScript (javascript)

Wir führen die gleiche Sollwertkorrektur durch, wenn der Eingang der RC-Empfänger ist. 

Hier wandeln wir die RAW-Encoderwerte in Winkelwerte um und verfolgen mit diesen if-Anweisungen, in welchem Quadranten sich die aktuelle Position der Welle befindet.

// Convert encoder RAW values into angle value
 angle = encoderValue * 0.087890625;
 // Quadrant 1
 if (angle >= 0 && angle <= 90) {
 quadrantNumber = 1;
 }
 // Quadrant 2
 if (angle >= 90 && angle <= 180) {
 quadrantNumber = 2;
 }
 // Quadrant 3
 if (angle >= 180 && angle <= 270) {
 quadrantNumber = 3;
 }
 // Quadrant 4
 if (angle >= 270 && angle <= 360) {
 quadrantNumber = 4;
 }Code language: HTML, XML (xml)

Mit diesen Informationen können wir verfolgen, wie sich die Welle dreht und wann sie eine volle Umdrehung macht. Der Gesamtwinkel ist der Eingangswert für den PID-Regler.

if (quadrantNumber != previousQuadrantNumber) {
 // Transition from 4th to 1st quadrant
 if (quadrantNumber == 1 && previousQuadrantNumber == 4) {
 numberOfTurns++;
 }
 // Transition from 1st to 4th quadrant
 if (quadrantNumber == 4 && previousQuadrantNumber == 1) {
 numberOfTurns--;
 }
 previousQuadrantNumber = quadrantNumber;
 }
 if (totalAngle >= 0) {
 totalAngle = (numberOfTurns * 360) + angle;
 }
 else {
 totalAngle = (numberOfTurns * 360) + angle;
 }
 // Establish Input value for PID
 Input = totalAngle;Code language: JavaScript (javascript)

Wenn wir uns hingegen im eingeschränkten Rotationsmodus befinden, lesen wir zuerst den Potentiometerwert ab, der zum Einstellen des Rotationsbereichs verwendet wird, und stellen die linke und rechte Grenze der Rotation entsprechend ein.

rangeAdjustment = analogRead(A1);
 leftLimit = 0 + 30 + rangeAdjustment;
 rightLimit = 4097 - 30 - rangeAdjustment;

Wenn der Eingabemodus das Potentiometer ist, verwenden wir seinen Wert als Sollwert für den PID-Regler.

if (digitalRead(inputSwitch) == 0) { // Analog input - Potentiometer
 // Get value from potentiometer
 inputValue = analogRead(A0);
 if (inputValue < 15) {
 inputValue = 15;
 }
 if (inputValue > 1008) {
 inputValue = 1008;
 }
 Setpoint = map(inputValue, 15, 1008, -255, 255);
 }Code language: HTML, XML (xml)

Wenn der Eingabemodus der RC-Empfänger ist, lesen wir den eingehenden PWM-Wert vom Empfänger und verwenden diesen Wert als Sollwert.

else if (digitalRead(inputSwitch) == 1) { // Digital input - RC transmitter
 inputValue = pulseIn(ch1, HIGH, 30000); // Read RC receiver as input
 Setpoint = map(inputValue, 1000, 2000, -255, 255);
 }Code language: JavaScript (javascript)

Um einen anderen Mittelpunkt festzulegen, prüfen wir, ob wir den Druckknopf gedrückt haben und erfassen diese Position als neuen Mittelpunkt.

// Set center angle
 if (digitalRead(centerSet) == LOW) {
 centerAngle = encoderValue;
 angleDifference = 2047 - encoderValue;
 delay(1000);
 }Code language: JavaScript (javascript)

Demnach müssen wir dann die tatsächlichen Messwerte des Encoders anpassen und um die Winkeldifferenz zwischen dem neuen und dem alten Mittelpunkt verrechnen. Wir verwenden diesen Wert als Eingabewert für den PID-Regler.

if (centerAngle > 2047) {
 angleValue = encoderValue + angleDifference;
 if (encoderValue >= 0 && encoderValue < abs(angleDifference)) {
 angleValue = encoderValue + 4097 + angleDifference;
 }
 }
 else if (centerAngle == 2047) {
 angleValue = encoderValue;
 }
 // Establish Input value for PID
 Input = map(angleValue , leftLimit, rightLimit, -255, 255);Code language: HTML, XML (xml)

Mithilfe des Analogeingangs des anderen Potentiometers stellen wir die Proportionalverstärkung des PID-Reglers ein und führen schließlich den PID-Prozess aus, um einen Ausgangswert zu erhalten.

// Adjusting sensitivity
 Pk1 = analogRead(A2) * 0.002;
 myPID.SetTunings(Pk1, Ik1, Dk1);
 // Run PID process to get Output value
 myPID.Compute();Code language: JavaScript (javascript)

Wir verwenden diesen Ausgangswert zum Antreiben der Gleichstrommotoren mit einem PWM-Signal, links oder rechts, oder in Stillstandsposition, abhängig vom Ausgangswert des PID-Reglers oder abhängig vom Fehler zwischen der gewünschten und der tatsächlichen Position, die der Encoder liest.

// Move right
 if (Output > 1 ) {
 pwmValue = Output;
 if (pwmValue < 30 && pwmValue > 5) {
 pwmValue = pwmValue + 30;
 }
 if (pwmValue <= 5) {
 pwmValue = 0;
 }
 digitalWrite(motor_IN1, LOW);
 analogWrite(motor_IN2, pwmValue);
 }Code language: HTML, XML (xml)

Das wäre also alles für dieses Video. Bitte beachten Sie, dass der Code nicht gut optimiert ist und Raum für Verbesserungen besteht.

Wenn Sie versuchen, dieses Projekt neu zu erstellen, sollten Sie außerdem auf die Fehlerbehebung vorbereitet sein. Besonders beim Löten kleiner SMD-Bauteile kann viel schief gehen.

Ich habe dieses Servo beim ersten Versuch nicht zum Laufen gebracht. Zuerst hatte ich einige falsche Anschlüsse auf der Platine, dann habe ich die Platine mit neuen Updates erneut bestellt, brauchte aber noch ein paar Versuche, bis ich sie zum Laufen brachte. 

Dieser Abschnitt des Artikels befindet sich noch im Aufbau, bitte schauen Sie sich ihn etwas später an ….


Herstellungsprozess

  1. 5-Achsen-Bearbeitung und Multitasking
  2. Wiedererwärmungsöfen und ihre Typen
  3. Wasserrecycling und Prozessoptimierung in Papierfabriken:Effizienz steigern, Kosten senken und die Umwelt schützen
  4. 3 Schlüsselabschnitte im Mikrofonherstellungsprozess
  5. Mechanische Verfahren zur Entzunderung von Stahl
  6. Textteleporter
  7. PERED-Technologie für die Produktion von direkt reduziertem Eisen
  8. Arduino Ant Hexapod-Roboter
  9. Wasserfilter:Aufbau eines Proof-of-Concept-Prototyps
  10. Härte eines Materials verstehen