
Franzis Roboter Erweiterungen
Teil 2 - Fernsteuerung
von Martin
Müller
Mit einem weiteren Steckbrett, einem Raspberry Pi Pico W und einigen
weiteren elektronischen Bauteilen kann man den Roboter fernsteuern.
Um die beiden Motoren anzusteuern, wird ein Motortreiber benötigt.
Dafür werden insgesamt 4 Transistoren vom Typ BC327-25 und 8
Transistoren BC337-25 verbaut. Der Motortreiber wird mit 4,5 V
betrieben und kann mit den 3,3 V-Signalen des Pico W angesteuert
werden. Die beiden Schottkydioden verhindern, dass beide Stränge der
H-Brücke gleichzeitig durchschalten können.
Programmiert wird der Pico W mit der Arduino-IDE. Die GPIOs 14- 17
werden zur Ansteuerung der Motoren verwendet. Der Pico W stellt ein
eigenes Netzwerk (SSID: ROBOT, PWD: 12345678) zur Verfügung und ist
über die IP-Adresse 192.168.42.1 per Browser mit jedem WLAN-fähigen
Smartphone, Tablet oder Laptop erreichbar. Ist der Roboter
betriebsbereit, leuchtet die LED auf der Platine.
//RobotPicoW.ino
#include <AsyncWebServer_RP2040W.h>
#include "WebPage.h"
AsyncWebServer server(80);
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_AP);
WiFi.softAP("ROBOT", "12345678");
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
pinMode(14, OUTPUT);//rechts zurück
pinMode(15, OUTPUT);//rechts vor
pinMode(16, OUTPUT);//links vor
pinMode(17, OUTPUT);//links zurück
Serial.println(WiFi.softAPIP());
server.on("/", [](AsyncWebServerRequest * request) {webpage(); request->send(200, "text/html", webpageCont);});
server.on("/vor", [](AsyncWebServerRequest * request) {vor(); webpage(); request->send(200, "text/html", webpageCont);});
server.on("/sta", [](AsyncWebServerRequest * request) {stand(); webpage(); request->send(200, "text/html", webpageCont);});
server.on("/zur", [](AsyncWebServerRequest * request) {ruck(); webpage(); request->send(200, "text/html", webpageCont);});
server.on("/lin", [](AsyncWebServerRequest * request) {links();
delay(400); stand(); webpage();request->send(200, "text/html",
webpageCont);});
server.on("/rec", [](AsyncWebServerRequest * request) {rechts();
delay(400); stand(); webpage(); request->send(200, "text/html",
webpageCont);});
server.begin();
}
void loop() {}
void stand(){analogWrite(14, 0); analogWrite(15, 0); analogWrite(16, 0); analogWrite(17, 0); delay(500);}
void vor(){stand(); analogWrite(14, 0); analogWrite(15, 250); analogWrite(16, 255); analogWrite(17, 0);}
void ruck(){stand(); analogWrite(14, 255); analogWrite(15, 0); analogWrite(16, 0); analogWrite(17, 255);}
void rechts(){stand(); analogWrite(14, 255); analogWrite(15, 0); analogWrite(16, 255); analogWrite(17, 0);}
void links(){stand(); analogWrite(14, 0); analogWrite(15, 255); analogWrite(16, 0);analogWrite(17, 255);}
Der Webserver wird mit der AsyncWebServer_RP2040W-Library erstellt. Sie
muss in der Arduino-IDE installiert sein. Über einen einfachen
HTTP-Request werden die Steuerbefehle übertragen.
//WebPage.h
String webpageCont;
void webpage(){
webpageCont = "<!DOCTYPE HTML>";
webpageCont += "<html>";
webpageCont += "<title>Pico W</title>";
// CSS
webpageCont += "<style>";
webpageCont += "h1 {font-size: 40px; color: blue; text-align: center;}";
webpageCont += "h2 {font-size: 25px; color: red; text-align: center;}";
webpageCont += ".button {background-color: lime; border: none; color:
white; width: 6em; height: 4em; text-align: center; font-size: 20px;
cursor: pointer;}";
webpageCont += ".button1 {background-color: green; color: black; position:absolute; top:7em; left:50%; margin-left: -3em;}";
webpageCont += ".button2 {background-color: red; position:absolute; top:12em; left:50%; margin-left: -3em;}";
webpageCont += ".button3 {background-color: blue; position:absolute; top:17em; left:50%; margin-left: -3em;}";
webpageCont += ".button4 {background-color: violet; position:absolute; top:12em; left:30%; margin-left: -3em;}";
webpageCont += ".button5 {background-color: orangered; position:absolute; top:12em; left:70%; margin-left: -3em;}";
webpageCont += "</style>";
// HTML
webpageCont += "<body>";
webpageCont += "<h1>PicoW - Robot</h1>";
webpageCont += R"~(<h2 id="klistat">bereit<h2>)~";
webpageCont += R"~(<button class="button button1" id="btn1" onclick="vor()">VOR</button>)~";
webpageCont += R"~(<button class="button button2" id="btn2" onclick="sta()">STOP</button>)~";
webpageCont += R"~(<button class="button button3" id="btn3" onclick="zur()">ZURUECK</button>)~";
webpageCont += R"~(<button class="button button4" id="btn4" onclick="lin()">LINKS</button>)~";
webpageCont += R"~(<button class="button button5" id="btn5" onclick="rec()">RECHTS</button>)~";
webpageCont += "</body>";
// JavaScript
webpageCont += "<script>";
webpageCont += R"~(function vor(){ButtonDisable(); window.location.href = "/vor";})~";
webpageCont += R"~(function sta(){ButtonDisable(); window.location.href = "/sta";})~";
webpageCont += R"~(function zur(){ButtonDisable(); window.location.href = "/zur";})~";
webpageCont += R"~(function lin(){ButtonDisable(); window.location.href = "/lin";})~";
webpageCont += R"~(function rec(){ButtonDisable(); window.location.href = "/rec";})~";
webpageCont += R"~(function ButtonDisable(){document.getElementById('klistat').innerHTML = "Bitte warten";)~";
webpageCont += R"~(document.getElementById("btn1").disabled =
true; document.getElementById("btn2").disabled = true;
document.getElementById("btn3").disabled =
true;document.getElementById("btn4").disabled =
true;document.getElementById("btn5").disabled = true;})~";
webpageCont += "</script>";
webpageCont += "</html>";
}
Download: RobotPicoW.zip
Der Inhalt der Webseite ist in die Datei WebPage.h ausgelagert. Sie
muss sich im gleichen Verzeichnis wie RobotPicoW.ino befinden. Die
Übertragung der Steuersignale ist mit einer gewissen zeitlichen Latenz
behaftet. Dies ist der recht einfachen einsteigerfreundlichen Art und
Weise der Programmierung geschuldet.