Servo ansteuern (Arduino, ESP8266, ESP32)

title

Servo ansteuern (Arduino, ESP8266, ESP32)

In diesem Beitrag möchte ich euch zeigen wir Ihr einen Servo mit einem Arduino, ESP8266 (Wemos D1 mini lite) und ESP32 (Wemos Lolin32) betreiben könnt. Das ansteuern des Servos ist beim Arduino und ESP8266 das selbe Prinzip nur beim ESP32 gibt es eine Neuerung.
Für Arduino und ESP8266 wird die Funktion analogWrite() verwendet, die kennen wir alle, doch diese Funktion gibt es mit dem ESP32 nicht mehr. Wen man diese Funktion nutzen möchte muss man nun mit ledcWrite(channel, duty) arbeiten, wie das genau geht zeige ich euch hier.

Was sind Servomotoren?

Servomotoren werden oft im Modellbau eingesetzt, man sagt auch Getriebemotoren dazu. An der Drehachse des Servos ist ein Potentiometer befestigt, mit dem wird die aktuelle Position bestimmt. Servos sind recht Präzise und lassen sich sehr einfach Ansteuern, daher auch gut geeignet in der Robotertechnik. Sie haben im Normalfall einen Bewegungsbereich von 0°-180°, angesteuert werden Sie mit einem Analogen Signal oder auch PWM Signal.

Ich habe mal das Signal von der Ansteuerung mit einem Osziloskop angesehen.
Arduino und ESP8266, standart bei 50 Hz.

0 Grad, Arduino90 Grad, Arduino180 Grad, Arduino

ESP32
Mit der neuen Funktion (ledcWrite) kann die Frequenz selber bestimmt werden, mehr dazu weiter unten im Beitrag.

esp32-0esp32-90esp32-180

Servo mit Arduino Uno ansteuern.

Servo Arduino

Funktion

Mit #include Servo.h wird die Bibliothek in den Sketch eingebunden. Servo servoblau; definiert den Namen des Servos, servoblau.attach(3); hier gibt die 3 den Pin an mit dem der Servo geschalten wird und zu guter letzt servoblau.write(90); damit übergibt man den Winkel in Grad an den Servo, in diesem Fall 90 Grad.

Programmcode

Wo Ihr die Bibliothek U8g2lib bekommt könnt Ihr hier nachlesen.

#include <U8g2lib.h>

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
U8G2_SSD1306_128X64_NONAME_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);

#include <Servo.h>
Servo servoblau;

void setup() {
  servoblau.attach(3);
  u8g2.begin();
  u8g2.enableUTF8Print();
}

void loop() {
  u8g2.setFont(u8g2_font_courB18_tf);
  u8g2.setFontDirection(0);

  servoblau.write(0);
  u8g2.firstPage();
  do {
    u8g2.drawStr(0, 20, "0 Grad");
  } while ( u8g2.nextPage() );
  delay(3000);
  servoblau.write(90);
  u8g2.firstPage();
  do {
    u8g2.drawStr(0, 20, "90 Grad");
  } while ( u8g2.nextPage() );
  delay(3000);
  servoblau.write(180);
  u8g2.firstPage();
  do {
    u8g2.drawStr(0, 20, "180 Grad");
  } while ( u8g2.nextPage() );
  delay(3000);
  servoblau.write(120);
  u8g2.firstPage();
  do {
    u8g2.drawStr(0, 20, "120 Grad");
  } while ( u8g2.nextPage() );
  delay(3000);
  servoblau.write(45);
  u8g2.firstPage();
  do {
    u8g2.drawStr(0, 20, "45 Grad");
  } while ( u8g2.nextPage() );
  delay(3000);
}

Servo ansteuern mit ESP8266 als Web Server (Wemos D1 mini Lite)

Servo ESP8266

Funktion

Die Funktion ist die selbe wie beim Arduino.

Programmcode

Wo Ihr die Bibliothek U8g2lib bekommt könnt Ihr hier nachlesen.
Für die Biliothek ESP8266 habe ich auch schon einen Beitrag gemacht.

#include <Servo.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <U8g2lib.h>

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
U8G2_SSD1306_128X64_NONAME_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);

const char* ssid     = "WLAN NAME";
const char* password = "PASSWORT";
Servo servoblau;
ESP8266WebServer server ( 80 );

void setup()
{
  Serial.begin(9600);
  servoblau.attach(12);
  u8g2.begin();
  u8g2.enableUTF8Print();
  connectWifi();
  beginServer();
  servoblau.write(0);
  u8g2.setFont(u8g2_font_courB18_tf);
  u8g2.setFontDirection(0);
  u8g2.firstPage();
  do {
    u8g2.drawStr(0, 20, "0 Grad");
  } while ( u8g2.nextPage() );
}

void loop() {
  server.handleClient();
  delay(1000);
}

void connectWifi()
{
  WiFi.enableSTA(true);
  delay(2000);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void beginServer()
{
  server.on ( "/", handleRoot );
  server.begin();
  Serial.println ( "HTTP server started" );
}

void handleRoot() {
  if ( server.hasArg("SERVO") ) {
    handleSubmit();
  } else {
    server.send ( 200, "text/html", getPage() );
  }
}

void handleSubmit() {

  String SERVOValue;
  SERVOValue = server.arg("SERVO");
  Serial.println("Set GPIO ");
  Serial.print(SERVOValue);

  if ( SERVOValue == "0" ) {
    servoblau.write(0);
    server.send ( 200, "text/html", getPage() );
    u8g2.setFont(u8g2_font_courB18_tf);
    u8g2.setFontDirection(0);
    u8g2.firstPage();
    do {
      u8g2.drawStr(0, 20, "0 Grad");
    } while ( u8g2.nextPage() );
  }
  else if ( SERVOValue == "90" )
  {
    servoblau.write(90);
    server.send ( 200, "text/html", getPage() );
    u8g2.setFont(u8g2_font_courB18_tf);
    u8g2.setFontDirection(0);
    u8g2.firstPage();
    do {
      u8g2.drawStr(0, 20, "90 Grad");
    } while ( u8g2.nextPage() );
  }
  else if ( SERVOValue == "180" )
  {
    servoblau.write(180);
    server.send ( 200, "text/html", getPage() );
    u8g2.setFont(u8g2_font_courB18_tf);
    u8g2.setFontDirection(0);
    u8g2.firstPage();
    do {
      u8g2.drawStr(0, 20, "180 Grad");
    } while ( u8g2.nextPage() );
  } else
  {
    Serial.println("Error Servo Value");
  }
}

String getPage() {
  String page = "<lang=en-EN><><http-equiv='refresh' content='60'/>";
  page += "<>arduino-projekte.info</title>";
  page += "<> body { background-color: #fffff; font-family: Arial, Helvetica, Sans-Serif; Color: #000000; }";
  page += ".button {display: inline-block; padding: 15px 15px; font-size: 25px; cursor: pointer; text-align: center; text-decoration: none;";
  page += "outline: none; color: #ffffff; background-color: #4db2ec; border: none; border-radius: 15px;}";
  page += ".button:hover {background-color: #4DCAEC; color:#ffffff;}";
  page += ".button:active {background-color: #4DCAEC; box-shadow: 0 3px #666; transform: translateY(3px); }</style>";
  page += "</head><><> WebServer</h1>";
  page += "<>Servo Test</h3>";
  page += "< action='/' method='POST'>";
  page += "< class='button' type='submit' name='SERVO' value='0'>    ";
  page += "< class='button' type='submit' name='SERVO' value='90'>    ";
  page += "< class='button' type='submit' name='SERVO' value='180'>";

  page += "</body>";
  return page;
}

Servo ansteuern mit einem ESP32 als Web Server (Wemos Lolin32)

servo wemos lolin32

Funktion

Die Funktion ist vom Prinzip die selben wie schon in den ersten beiden Versionen. Doch eine Grundlegende Sache ist anders, wie schon ober beschrieben gibt es die Funktion analogWrite() mit mehr. Die Neue Funktion heißt ledcWrite(channel, duty).

Wie wird ledcWrite(channel, duty) verwendet?

Im Setupteil müssen die Befehle ledcSetup(Kanal, Frequenz, Bit); und ledcAttachPin(Pin, Kanal); eingetragen werden und im Loopteil ledcWrite(Kanal, Zeit);.

ledcSetup(Kanal, Frequenz, Bit);

Kanal: Es git 16 Kanäle die Verwendet werden können. (einstellbar von 0-15)
Frequenz: Die Frequenz kann von 1Hz-40MHz eingestellt werden, das sagt aus wie schnell ein wechsel der Periode (Ein Aus Zustand) dauert. Bei dem Servo hat sich 166Hz als gut gezeigt.
Bit: Gibt die Aufteilung der Periode an, wieviel Schritte Sie hat und das ganze wird so gerechnet. Nehmen wir na wir haben 8 Bit, dann muss man 28-1 rechnen ergibt 255, dass ergibt dann die Zeit oder Teilung für den Befehl ledcWrite(Kanal, Zeit);.

ledcAttachPin(Pin, Kanal);

Hier wird der Kanal an einen Pin übergeben.
Pin: Hier wird der Pin am EPS32 angeben, wo in diesem Fall der Servo angeschlossen ist.
Kanal: Das muss der Selbe sein wie im Befehl ledcSetup.
Beispiel:
Kanal 1 mit 166Hz und 8 Bit, wird an Pin 13 übergeben. Kanal 1 wird mit 127 ausgegeben, das heißt 127 (2,5 Volt am Arduino, 1,6 Volt am EPS32) ist ca. die hälte von den 255. 255 ist quasi das Signal 1 (high) (5 Volt am Arduino, 3,2 Volt am EPS32)
ledcSetup(1, 166, 8);
ledcAttachPin(13, 1);
ledcWrite(1, 127);

Programmcode

Die Bibliothek Webserver bekommt Ihr hier. https://github.com/bbx10/WebServer_tng
Wie Ihr die Bibliothek U8g2lib installiert könnt Ihr hier nachlesen.
Und zu guter Letzt die Bibliothek um den Wemos Lolin32(ESP32) zu installieren, findet Ihr hier.

#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <U8g2lib.h>

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
U8G2_SSD1306_128X64_NONAME_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);
const char* ssid     = "WLAN NAME";
const char* password = "PASSWORT";

WebServer server ( 80 );

void setup()
{
  ledcSetup(1, 166, 8);
  ledcAttachPin(13, 1);
  Serial.begin(9600);
  u8g2.begin();
  u8g2.enableUTF8Print();
  connectWifi();
  beginServer();
  servoblau.write(0);
  u8g2.setFont(u8g2_font_courB18_tf);
  u8g2.setFontDirection(0);
  u8g2.firstPage();
  do {
    u8g2.drawStr(0, 20, "0 Grad");
  } while ( u8g2.nextPage() );
}

void loop() {
  server.handleClient();
  delay(1000);
}

void connectWifi()
{
  WiFi.enableSTA(true);
  delay(2000);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void beginServer()
{
  server.on ( "/", handleRoot );
  server.begin();
  Serial.println ( "HTTP server started" );
}

void handleRoot() {
  if ( server.hasArg("SERVO") ) {
    handleSubmit();
  } else {
    server.send ( 200, "text/html", getPage() );
  }
}

void handleSubmit() {

  String SERVOValue;
  SERVOValue = server.arg("SERVO");
  Serial.println("Set GPIO ");
  Serial.print(SERVOValue);

  if ( SERVOValue == "0" ) {
    ledcWrite(1, 2);
    server.send ( 200, "text/html", getPage() );
    u8g2.setFont(u8g2_font_courB18_tf);
    u8g2.setFontDirection(0);
    u8g2.firstPage();
    do {
      u8g2.drawStr(0, 20, "0 Grad");
    } while ( u8g2.nextPage() );
  }
  else if ( SERVOValue == "90" )
  {
    ledcWrite(1, 60);
    server.send ( 200, "text/html", getPage() );
    u8g2.setFont(u8g2_font_courB18_tf);
    u8g2.setFontDirection(0);
    u8g2.firstPage();
    do {
      u8g2.drawStr(0, 20, "90 Grad");
    } while ( u8g2.nextPage() );
  }
  else if ( SERVOValue == "180" )
  {
    ledcWrite(1, 125);
    server.send ( 200, "text/html", getPage() );
    u8g2.setFont(u8g2_font_courB18_tf);
    u8g2.setFontDirection(0);
    u8g2.firstPage();
    do {
      u8g2.drawStr(0, 20, "180 Grad");
    } while ( u8g2.nextPage() );
  } else
  {
    Serial.println("Error Servo Value");
  }
}

String getPage() {
  String page = "< lang=en-EN><>< http-equiv='refresh' content='60'/>";
  page += "<>arduino-projekte.info</title>";
  page += "<> body { background-color: #fffff; font-family: Arial, Helvetica, Sans-Serif; Color: #000000; }";
  page += ".button {display: inline-block; padding: 15px 15px; font-size: 25px; cursor: pointer; text-align: center; text-decoration: none;";
  page += "outline: none; color: #ffffff; background-color: #4db2ec; border: none; border-radius: 15px;}";
  page += ".button:hover {background-color: #4DCAEC; color:#ffffff;}";
  page += ".button:active {background-color: #4DCAEC; box-shadow: 0 3px #666; transform: translateY(3px); }</style>";
  page += "</head><><> WebServer</h1>";
  page += "<>Servo Test</h3>";
  page += "< action='/' method='POST'>";
  page += "< class='button' type='submit' name='SERVO' value='0'>    ";
  page += "< class='button' type='submit' name='SERVO' value='90'>    ";
  page += "< class='button' type='submit' name='SERVO' value='180'>";

  page += "</body›";
  return page;
}

Folgende Bauteile wurden verwendet:


1x Wemos Lolin32 https://amzn.to/2DAV8Mg *
1x Wemos D1 mini lite https://amzn.to/2vMkOF4 *
1x Servo http://amzn.to/2BijqHC *
1x Oled Display 0,96 Zoll http://amzn.to/2ic44AC *

Letzte Aktualisierung am 13.07.2020 / Affiliate Links / Bilder von der Amazon Product Advertising API