Bionic Spider Controller - Teil 1 - AZ-Delivery

Im Bionic Spider Roboter Kit haben Sie bereits gelernt, wie die bionische Spinne funktioniert und auch schon einige Projekte damit umgesetzt. Zuletzt wurde die Steuerung des Roboters über eine Smartphone-App hinzugefügt.

Da die Steuerung über das Touchdisplay nicht besonders schön ist, soll in diesem Blogbeitrag eine alternative Steuerung mit einem Joystick vorgestellt werden.

 

Hardware

Als Joystick stehen zwei Ausführungen zur Verfügung, zum einen kann das KY-023 Modul verwendet werden. Da hier aber wieder einiges an Verkabelung notwendig wäre, empfiehlt sich das PS2 Joystick Shield, welches direkt auch auf einen Mikrocontroller mit Uno Layout gesteckt werden kann.

Da der Mikrocontroller mit dem Roboter kommunizieren muss, wird ein Mikrocontroller mit WiFi Funktionalität benötigt. Des Weiteren werden zwei ADC für je die X- und Y-Achse benötigt, deswegen muss hier ein ESP32 verwendet werden.

(Der ESP8266 verfügt nur über einen ADC-Eingang.)

 

Für die realisierung des Projekts benötigen Sie:

ESP32 NodeMCU D1 R32

PS2 Joystick Shield

(optional) 9V Blockbatterie + Batterieclip

und natürlich ein Zusammengebautes Bionic Spider Robot Kit

 

Da die Analogeingänge der zwei Joystick Achsen an den GPIO 2 und 4 anliegen, welche mit dem ADC2 verbunden sind, können diese nicht gleichzeitig mit dem WLAN Modul verwendet werden. Die Anschlüsse IO 34 und IO35 (ADC1) liegen aber direkt neben diesen, dadurch kann ganz einfach die Funktionsfähigkeit über eine Drahtbrücke hergestellt werden.

Abbildung 1: Drahtbrücke zwischen den Anschlüssen

Verbinden Sie die Anschlüsse wie oben abgebildet.
Da am GPIO 2 die On-Board LED angeschlossen ist, muss hier der Pin entfernt werden, da die Verbindung ansonsten den Wert der X-Achsen Spannung beeinflussen würde.

Das gleiche gilt für den Pin D12, da dieser den Boot Vorgang stört und somit kein boot mit aufgestecktem Shield möglich wäre. An diesem Anschluss liegt der mittlere Taster des Joysticks, dieser ist dadurch nicht mehr benutzbar. Falls sie diesen trotzdem implementieren wollen, muss dieser wieder mit einem freien Anschluss verbunden werden.

 

Abbildung 2: Shield mit Modifikationen

 

Das Shield kann einfach auf den D1 R32 gesteckt werden. Achten Sie darauf, dass der kleine Schalter in der linken Ecke auf 3v3 gestellt ist, da der ESP32 sonst durch die zu hohe Spannung von 5V beschädigt werden könnte.

Software

Falls Sie das erste Mal einen ESP32/ESP8266 in der Arduino IDE programmieren, kopieren Sie folgende URLs in der Arduino IDE unter: File->Preferences->Additional boards manager URLs :  https://dl.espressif.com/dl/package_esp32_index.json

http://arduino.esp8266.com/stable/package_esp8266com_index.json

 

und installieren Sie in der Boardverwaltung das ESP32 und ESP8266 Paket.

 

 

Für die Übertragung der Daten zwischen den Mikrocontrollern eignet sich das ESPNOW Protokoll, welches durch die integrierte Library einfach zu benutzen ist.

Der Vorteil dieses Protokolls ist, dass die Datenpakete auch ohne Server und WLAN übertragen werden können, somit ist eine Kommunikation an jedem Ort und ohne weitere Hardware möglich.

Des Weiteren werden die Pakete einfach, ohne komplizierte Authentifizierung wie bei WLAN, ausgesendet, wodurch auch eine sehr schnelle Übertragung nahezu in Echtzeit realisiert werden kann.

 

Für die Kommunikation werden die Hardware-Adressen, die sogenannten MAC-Adressen (Media-Access-Control) der beiden Geräte benötigt. Diese befinden sich in einem geschützten Teil des Speichers und können eindeutig einem Gerät zugeordnet werden.

Über diese können die Pakete an den richtigen Empfänger gesendet werden.

 

1 Ermitteln der MAC-Adressen

Da sich die Adressen im geschützten Speicher befinden, können diese auch mit einem separaten kurzen Programm ausgelesen werden, da sich diese beim neuen Beschreiben des Speichers nicht ändert.

 

Laden Sie das Programm auf die beiden Mikrocontroller:

#ifdef ESP32
  #
include <WiFi.h>
#
endif
#
ifdef ESP8266
  #
include <ESP8266WiFi.h>
#
endif

void setup() {
 
WiFi.mode(WIFI_STA);
 
Serial.begin(115200);
 
delay(2000);
 
Serial.println();
}

void loop() {
 
Serial.print("Mac Adress:");
 
Serial.println(WiFi.macAddress());
 
delay(5000);
}

 

Den Code können Sie hier herunterladen.

 

Nachdem die Programme auf die Mikrocontroller geladen wurden, wird nun im Seriellen Monitor (Baudrate: 115200) die entsprechende MAC-Adresse angezeigt. Notieren Sie diese für das folgende Programm.

 

2 Code Controller

Das Joystick Modul verfügt über 6 einzelne Taster und einen Joystick mit zwei Achsen und einem integrierten Taster.

Um das Projekt möglichst einfach zu halten, werden nur die Bewegungsrichtung oder die gedrückten Taster als String wie folgt übermittelt:

Joystick nach oben: CMD_FWD

Joystick nach unten: CMD_BWD

Joystick nach rechts: CMD_RGT

Joystick nach links: CMD_LFT

 

Taster A: BTN_A

Taster B: BTN_B

etc. …

 

Damit ein neuer Befehl nur gesendet werden kann, wenn der vorherige ausgeführt wurde, wird vom Empfänger eine Bestätigung übermittelt. Erst wenn diese empfangen wurde, kann ein neuer Befehl gesendet werden.
Damit bei einem Fehler die Kommunikation nicht komplett blockiert wird, ist die Rückmeldung nur nach einer erfolgreichen Datenübermittlung an den Empfänger erforderlich. Außerdem wird der Status nach 10 Sekunden, wenn keine Bestätigung übermittelt wurde, automatisch zurückgesetzt.

 

Code:
Um die Übersichtlichkeit zu wahren, werden hier zur Erklärung nur Ausschnitte gezeigt. Der komplette Code kann am Ende heruntergeladen werden.

#define X 34
#
define Y 35

#
define A 26
#
define B 25
#
define C 17
#
define D 16
#
define E 27
#
define F 14

uint8_t receiverAddress[] = {0xA4, 0xCF, 0x12, 0xDC, 0xCF, 0x3A};

int calibY, calibX;
bool status = true;
long sentTime;

Am Anfang werden die GPIO Pin der jeweiligen Taster/Joystick-Achsen definiert, um diese später im Programm einfacher und übersichtlich verwenden zu können.
Im Anschluss wird die MAC-Adresse des Empfängers definiert, diese muss im gezeigten Hexadezimalformat mit 0x als Prefix vorliegen:
A4:CF:... -> 0xA4, 0xCF,...

Die folgenden Variablen dienen zur Kalibrierung und Regelung, um die Befehle nur zu senden, falls der vorherige bereits ausgeführt wurde.

void onDataRecv(const esp_now_recv_info_t *info, const uint8_t *data, int data_len) {
 
char dataTemp[data_len];
  memcpy(dataTemp, data, data_len);
//Copy data bytes in char Array
 
Serial.println(dataTemp);

 
if(String(dataTemp).indexOf("RDY") >= 0) {//data contains RDY
   
Serial.println("RST");
    status = true;
  }
}

void onDataSent(const wifi_tx_info_t *tx_info, esp_now_send_status_t sendStatus)
{
   
Serial.print("Sendestatus: ");
   
Serial.println(sendStatus == ESP_NOW_SEND_SUCCESS ? "Success" : "Error");
   
if(sendStatus == ESP_NOW_SEND_SUCCESS) {
      status = false;
//marking sent
      sentTime =
millis(); //store time for limitation
    }
}

Bei diesen beiden Methoden handelt es sich um die Callback Methoden für den Empfang und das Senden über ESPNOW.

Die erhaltenen Daten der Empfangsfunktion werden zunächst in ein char Array kopiert, um im Anschluss den Inhalt auf das Schlüsselwort zu überprüfen. Ist dieses erhalten, so wird der Status wieder auf true gesetzt und es können wieder Befehle gesendet werden.

Die sende-Callback Funktion überprüft den Status des Versandes und setzt die Statusvariable auf false, damit nicht direkt im Anschluss ein Befehl erneut gesendet wird. Zudem wird noch die aktuelle Programmlaufzeit über die millis() Funktion zwischengespeichert, da der Status nach 10 Sekunden wieder zurückgesetzt werden soll.

 

Im setup() werden nur die Konfigurations Befehle der ESPNOW Library aufgerufen, gefolgt von der Kalibrierung der Joystick-Achsen und der GPIO Konfiguration.

Im loop() werden die Werte der Joystick-Achsen gemessen und der Status nach 10 Sekunden wieder zurückgesetzt.

Die folgende Logik wertet die Position der Joystick Achsen aus:

if(status) {
   
if(valX < -50 || valY < -50 || valX > 50 || valY > 50) {
     
Serial.println("trig");
     
if(abs(valX) > abs(valY)) {
       
if(valX < 0) {
         
Serial.println("LEFT");
         
String msg = "CMD_LFT";
          esp_now_send(receiverAddress, (uint8_t *)msg.c_str(), msg.length());
        }
       
else {
         
Serial.println("Right");
         
String msg = "CMD_RGT";
          esp_now_send(receiverAddress, (uint8_t *)msg.c_str(), msg.length());
        }
      }
     
else {
       
if(valY < 0) {
         
Serial.println("BWD");
         
String msg = "CMD_BWD";
          esp_now_send(receiverAddress, (uint8_t *)msg.c_str(), msg.length());
        }
       
else {
         
Serial.println("FWD");
         
String msg = "CMD_FWD";
          esp_now_send(receiverAddress, (uint8_t *)msg.c_str(), msg.length());
        }
      }
    }

Zuerst wird überprüft, ob die Werte der Achsen einen Grenzwert von 50 überschreiten, dies ist notwendig, da sowohl die Potentiometer, über welche die Position der Achsen ausgelesen wird als auch die Analog-Digital-Wandler (ADC) sich auch in der Nullposition minimal um den Nullwert bewegen (sog. driften).

Befindet sich eine Achse über dem Schwellwert, so werden die Werte des Betrags der beiden Achsen miteinander verglichen. So kann die Achse ermittelt werden, die am stärksten bewegt wurde und somit richtungsweisend ist.

Im Anschluss zu dieser Auswahl der Achse muss nur noch geprüft werden, ob der Wert positiv oder negativ ist, um die genaue Richtungsanweisung über ESPNOW senden zu können.

 

Das komplette Programm können Sie hier herunterladen und unter Auswahl des Richtigen Boards und Port auf den ESP32 laden.

3 Code Roboter

Der grundsätzliche Aufbau und insbesondere die ESPNOW Callback Methoden sind nahezu äquivalent zum vorherigen Controller Programm.
Der wesentliche Unterschied ist hier, dass in der Empfangs Callback Methode die Daten nicht direkt verglichen werden sondern in einem String gespeichert werden

cmd = String(dataTemp);

und dann im loop() ausgewertet werden.

 

Im setup() werden zusätzlich noch die Servomotoren initialisiert und in die Nullposition versetzt.

 

Im loop() folgt dann die Auswertung des cmd Strings:

if(cmd.length() > 0) {
   
if(cmd.indexOf("CMD_FWD") >= 0) {
     
Serial.println("FWD");
      forward();
    }
   
else if(cmd.indexOf("CMD_BWD") >= 0) {
     
Serial.println("BWD");
      back();
    }
   
else if(cmd.indexOf("CMD_RGT") >= 0) {
     
Serial.println("RGT");
      rightmove();
    }
   
else if(cmd.indexOf("CMD_LFT") >= 0) {
     
Serial.println("LFT");
      leftmove();
    }

   
else if(cmd.indexOf("BTN_A") >= 0) {
     
Serial.println("A");
      dance1();
    }
   
else if(cmd.indexOf("BTN_B") >= 0) {
     
Serial.println("B");
      dance2();
    }
   
else if(cmd.indexOf("BTN_C") >= 0) {
     
Serial.println("C");
      hello();
    }
   
else if(cmd.indexOf("BTN_D") >= 0) {
     
Serial.println("D");
      pushup();
    }
   
else if(cmd.indexOf("BTN_E") >= 0) {
     
Serial.println("D");
      turnright();
    }
   
else if(cmd.indexOf("BTN_F") >= 0) {
     
Serial.println("D");
      turnleft();
    }
   

    cmd =
"";
   
const char* ack = "RDY";
    esp_now_send(senderAddress, (uint8_t*)ack, strlen(ack));
   
Serial.println("ACK gesendet");
  }

Falls die Länge des Strings größer als 0 ist, bedeutet dies, dass in den String ein neuer Befehl geschrieben wurde. Daraufhin wird wieder der Inhalt mit dem jeweiligen Befehl verglichen und die zugehörige Funktion des Roboters ausgeführt.

Nach der Auswertung wird die Bestätigung an den Controller zurückgesendet.

 

Insbesondere die Funktionen der 6 Tasten können mit beliebigen Funktionen des Roboters belegt werden.

 

Die Methoden der Bewegungen des bionischen Roboters befinden sich in einer separaten Datei aus der letzten Roboter Lektion. Diese können Sie hier herunterladen und im Anschluss in das Projektverzeichnis kopieren.

 

Das komplette Programm können Sie hier herunterladen und unter Auswahl des Richtigen Boards und Port auf den ESP8266 laden. Vergessen Sie nicht die oben genannte Datei mit den Roboterbewegungen in das Verzeichnis zu kopieren

 

Fazit

In diesem Blogbeitrag wurde aus dem Joystick-Shield und einem ESP32 D1 R32 ein voll funktionsfähiger Controller für die Bionic Spider gebaut, welcher über WiFi mit ESPNOW dem Roboter die Befehle übermitteln kann.

Das Projekt lässt auch noch viel Potential zur eigenen Umgestaltung offen, zum Beispiel können andere Befehle durch die einzelnen Tasten ausgeführt werden, aber auch programmierte Bewegungsmuster bei Knopfdruck ausgeführt werden.

Viel Spass beim Nachbauen :)

Esp32Esp8266Projekte für anfänger

Kommentar hinterlassen

Alle Kommentare werden von einem Moderator vor der Veröffentlichung überprüft

Empfohlene Blogbeiträge

  1. ESP32 jetzt über den Boardverwalter installieren - AZ-Delivery
  2. Internet-Radio mit dem ESP32 - UPDATE - AZ-Delivery
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1 - AZ-Delivery
  4. ESP32 - das Multitalent - AZ-Delivery