Staubsaugerroboter Neato Botvac D85 intelligenter machen

Einleitung

Neato Botvac mit ESP8266 und einfacher HTML-API.

Inspiriert durch https://github.com/sstadlberger/botvac-wifi, allerdings hat mir die Lösung mit Websockets nicht zugesagt, daher nun als einfache Web-API.

Benötigt wird:

  • ESP8266 (und ggf. ein Programmieradapter)
  • etwas Kabel und Lötzinn
  • Bastelgeschick
  • Arduino IDE sowie die ESP8266 Libraries

ESP-Sketch

Den Sketch mit der Arduino IDE und passendem Adapter auf dem ESP flashen.

Sketch:

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <WiFiClient.h>
#include <ArduinoOTA.h>

#define SSID "<WiFi SSID>"
#define PASSWORT "<WiFi password>"
#define HOSTNAME "botvac"

WiFiClient client;
bool serialReading = false;
String apiRes;
ESP8266WebServer server (80);

void readSerial() {
  serialReading = true;
  String serBuf;
  int count = 0;
  delay(10);
  // wait for serial data available
  while (Serial.available() == 0 && count < 10) {
    delay(10);
    count++;
  }
  count = 0;  
  // read lines from serial, limit to prevent endless loop
  while (Serial.available() > 0 && count < 10) {
    serBuf = Serial.readStringUntil('\x1A');
    if (serBuf.length() > 0) {
      apiRes.concat(serBuf);
    }
    serBuf = "";
    count++;
    delay(10);
  }
  delay(10);
  serialReading = false;
}

void serverIndex() {
  // just a very simple index page
  server.send(200, "text/plain;charset=utf-8", "Welcome to Botvac API!\n\nRunning V1.2.5");
}

void serverError() {
  // just a very simple error page
  server.send(400, "text/plain;charset=utf-8", "Error. Not implemented or wrong syntax.");
}

void serverReboot() {
  // reboot ESP
  server.send(200, "text/plain;charset=utf-8", "Botvac API will reboot in 10 sec!");
  delay(10000);
  ESP.reset();
}

void serverApi() {
  // the actual api, converting http://HOSTNAME.local/api?cmd=<Command> to the actual serial command
  if( ! server.hasArg("cmd") || server.arg("cmd") == NULL) {
    server.send(400, "text/plain;charset=utf-8", "Invalid Request");         // The request is invalid, so send HTTP status 400
  } else {
    String cmd = server.arg("cmd");
    Serial.println(cmd);
    // wait for output from serial, then send reply
    serialReading = true;
    readSerial();
    while (serialReading) {
      delay(10);
    }
    if (apiRes.length() > 0) {
      server.send(200, "text/plain;charset=utf-8", apiRes);  
    } else {
      server.send(200, "text/plain;charset=utf-8", "No Reply.");
    }
    apiRes = "";
  }
}

void setup() {
  // start serial
  // botvac serial console is 115200 baud, 8 data bits, no parity, one stop bit (8N1)
  Serial.begin(115200);

  // start wifi
  WiFi.disconnect();
  WiFi.setPhyMode(WIFI_PHY_MODE_11N);
  WiFi.mode(WIFI_STA);
  WiFi.begin(SSID, PASSWORT);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }
  WiFi.hostname(HOSTNAME);

  ArduinoOTA.setHostname(HOSTNAME);
  ArduinoOTA.setPassword("otapwd"); //set a password for ota here
  ArduinoOTA.begin();

  // start webserver
  server.on("/", serverIndex);
  server.on("/api", serverApi);
  server.on("/reboot", serverReboot);
  server.onNotFound(serverError);
  server.begin();

  // start MDNS
  // this means that the botvac can be reached at http://HOSTNAME.local
  if (!MDNS.begin(HOSTNAME)) {
    while (1) {
      // wait for watchdog timer
      delay(500);
    }
  }
  MDNS.addService("http", "tcp", 80);
}

void loop() {
  ArduinoOTA.handle();
  server.handleClient();
}

Ja, ich weiß, da sind Arduino-spezifische Funktionen drin, was von Puristen gerne verschmäht wird... ;-)

Für meinen Anwendungsfall reichts...

Der ESP ist anschließend übrigens OTA-update-fähig, d.h. weitere Updates können über's WLAN erfolgen, ohne den ESP jedes Mal ausbauen zu müssen.

Hardware / Verkabelung

Der ESP muss an die Wartungs-Pins der seriellen Schnittstelle gelötet werden. Diese findet man, wenn man den Bumper entfernt und anschließend den Deckel über die 8 Torx-Schrauben abnimmt.
Am Besten natürlich mit einem Stecker dazwischen, damit man die Verbindung für Wartungszwecke o.ä. leicht wieder trennen kann.

Die serielle Schnittstelle befindet sich rechts vorne am Mainboard, es sind jeweils 3 Kontake oben und unten:

TX muss am ESP an RX und umgekehrt.

Der ESP kann gut in der kleinen Aussparung hinter dem Bürstenmotor untergebracht werden:

Am Besten mit etwas Schaumstoff o.ä. puffern, damit nichts klappert.

Darauf achten, dass alles gut befestigt ist und auch Lötstellen und Kabel nochmal prüfen. Wir wollen ja nicht, dass sich etwas löst wenn der Botvac durch die Wohnung saust/saugt. wink

Bedienung

Die API kann nun, wenn alles geklappt hat, via http://botvac.local/api?cmd=<Botvac-Kommando> angesprochen werden. Wenn man als Kommando Help eingibt werden die möglichen Kommandos ausgegeben.

Auswertbar wunderbar z.B. per cURL oder auch in einem PHP-Script per file_get_contents().

Quellen