Roboter Fahrzeug mit Blynk vom Smartphone steuern

Willkommen zu einem neuen Blog aus unserer Reihe über Robot Cars. Diesmal wollen wir unser kleines Auto mit unserem Smartphone steuern. Dafür benutzen wir die App Blynk.

Benötigte Hardware

Fahrzeug Variante 1: Bausatz

Vorteil: Preiswert, alle erforderlichen Teile vorhanden
Nachteil: Schlechter lenkbar, Befestigung von MCU und Sensoren ist mit den vorhandenen Befestigungslöchern nur erschwert möglich.

Anzahl

Bauteil

Anmerkung

1

Bausatz mit 2Rädern

 


Fahrzeug Variante 2: Aus dem 3D Drucker

Vorteil: Dank der Rollkugel als Nachlaufrad, ist die Lenkbarkeit besser. Befestigungslöcher für die MCU und Sensoren sind vorhanden. Es ist auch der Einbau eines Servos für Kamera oder Ultraschall-Sensor vorgesehen.
Nachteil: Ein 3D-Drucker ist erforderlich.

Anzahl

Bauteil

Anmerkung

Anzahl

Bauteil

Anmerkung

1

2 Motoren mit Rädern

 

1

Rollkugel als Nachlaufrad

 

6

Schrauben M3 x 30 mit Mutter

 für Motoren und Rollkugel

2

Schrauben M3 x 12 mit Mutter

 für Powerpack-Halter

1

Chassis aus dem 3D-Drucker

 

1

Powerpack-Halter aus dem 3D-Drucker

 


Als Mikrocontroller benötigen wir wegen der WLAN-Einbindung einen ESP8266 oder besser einen ESP32. Der ESP-32 hat den Vorteil, dass wesentlich mehr I/O Pins zur Verfügung stehen, was bei zukünftigen Projekten mit dem Einsatz von Sensoren wichtig sein wird.

Anzahl

Bauteil

Anmerkung

Anzahl

Bauteil

Anmerkung

1

D1 Board NodeMCU ESP8266MOD-12F

 

oder 1

ESP32 D1 R32 Entwicklungsboard

 

1

4-Kanal L293D Motortreiber Shield

 


Damit das Motortreiber Shield mit den ESP Controllern verwendet werden kann, sind kleine Umbauarbeiten notwendig, da die ESP-Controller mit 3.3 V Versorgungsspannung arbeiten.


Vom Anschluss D7 sollte ein 10kOhm Widerstand an GND angeschlossen werden. Das ist nötig, da am Shield der Pin D7 über einen Pullup Widerstand von 10KOhm mit 5V verbunden ist.

Die Anschlüsse A0 bis A5, sowie die zugehörigen Versorgungsanschlüsse sollten mit Stiftleisten bestückt werden. Damit diese Anschlüsse für Sensoren genutzt werden können, muss außerdem die Versorgungsspannung statt an 5V an 3.3V angeschlossen werden. Das geschieht einfach dadurch, dass  auf der Unterseite die Verbindungsleitung zu den Pins aufgetrennt wird. Anschließend kann man die Pins mit dem 3.3V Pin verbinden.
Auch die Anschlüsse für die Versorgungsspannung sollten bestückt werden.


Zum Anschluss der beiden Motoren werden die Ausgänge M2 und M4 benutzt, da M1 und M3 mit dem ESP8266 Board nicht angesteuert werden können. Die Motoranschlüsse werden mit den entsprechenden Schraubklemmen am Motorshield verbunden werden. Sollte das Fahrzeug über die USB Buchse am Mikrocontroller versorgt werden, muss der Jumper (roter Kreis) entfernt und der Eingang M+ mit dem 5V Anschluss des Mikrocontrollers verbunden werden (grün eingezeichnet).

Das Motorshield wird einfach auf das Mikrocontroller Board aufgesteckt. Weitere Verdrahtungsmaßnahmen sind nicht erforderlich.
Zur mechanischen Befestigung der Boards sind beim Chassis aus dem 3D-Drucker entsprechende Löcher vorhanden, an denen mit Distanzstücken das Mikrocontroller Board festgeschraubt werden kann. Beim Bausatz muss man eventuell geeignete Löcher bohren.

Software

Zur Fernsteuerung des Fahrzeugs soll die frei erhältliche Software Blynk verwendet werden. Blynk ist ein Kickstarter Projekt, das eine möglichst einfache Steuerung von Mikrocontrollern mit einem Smartphone erlaubt. Wesentliches Element ist die App, mit der über eine Art Baukasten eine Anwendung erstellt werden kann. Alle Informationen zu dieser Anwendung werden im Blynk Server gespeichert. Jede Anwendung erhält eine eindeutige Identifikationsnummer. Auf der Mikrocontroller Seite sorgt eine Bibliothek dafür, dass der Mikrocontroller mit dem Blynk Server kommunizieren, und dass die Anwendung am Smartphone direkt die Pins des Mikrocontrollers lesen oder ansteuern kann. Dazu ist keine weitere Programmierung am Mikrocontroller erforderlich. Die einzige Bedingung ist, dass der Mikrocontroller Zugriff auf den Blynk Server haben muss. Da für die Fernsteuerung des Fahrzeugs aber keine Pins des Mikrocontrollers direkt angesteuert werden können, wird doch ein wenig Programmierung notwendig sein.

Zuerst aber muss die Blynk App am Smartphone installiert werden. Nachdem die App installiert und gestartet wurde, erscheint der Anmeldebildschirm. Damit man Blynk nutzen kann, braucht man einen Account für den Blynk-Server. Dazu sind lediglich eine E-Mail-Adresse und ein beliebiges Passwort erforderlich.

Nachdem Sie einen Account angelegt haben, erscheint eine Nachricht zum Thema Energie. Um ein Blynk-Projekt zu erstellen braucht man für jedes Bildschirmelement eine bestimmte Menge von Energie. Mit einem neuen Account erhält man automatisch 2000 Energiepunkte, mit denen man arbeiten kann. Braucht man für ein Projekt mehr Energiepunkte, kann man solche käuflich erwerben.

Nach diesem Meldungsfenster erscheint der Startbildschirm. Hier kann nun das Robocar Projekt über den folgenden QR-Code geladen werden.


Sie sehen nun das Projektfenster. Wenn Sie auf das Mutternsymbol klicken, öffnen sich die Projekteinstellungen. In den Projekteinstellungen finden Sie den Link „Email all“. Wenn Sie darauf klicken, erhalten Sie eine E-Mail mit dem Key, den Ihr Mikrocontroller Sketch braucht, um mit dem Blynk-Server zu kommunizieren. Mit dem Dreieck-Symbol am Projektfenster oben rechts starten Sie die Anwendung.



Mehr Informationen zu Blynk, finden Sie im Internet oder im Smarthome-Buch.  Im Buch wird auch beschrieben, wie man einen eigenen privaten Blynk-Server auf einem Raspberry Pi installieren kann.

Der Sketch

Außer dem Paket für den ESP32 oder den ESP8266 benötigen Sie die Blynk-Bibliothek, die über die Bibliotheksverwaltung installiert werden kann.

 

#ifdef ESP32
  //Konstante und Include-Dateien für den ESP32
  #include <WiFi.h>
  #include <BlynkSimpleEsp32.h>
  //Pins für das Drehrichtungs Schieberegister 
  #define SHIFT_IN 12       //Dateneingang Arduino D8
  #define SHIFT_CLK 17      //Schiebetackt Arduino D4
  #define LATCH_CLK 19     //Speichertakt Arduino D12
  #define OUT_ENABLE 14    //Mit LOW Ausgang aktivieren Arduino D7
  
  //PWM für Motoren Geschwindigkeit zwischen 0 und 1023
  #define M1PWM 23   //Pin für Motor1 Arduino D11
  #define MRIGHT 25    //Pin für Motor2 Arduino D3
  #define M3PWM  27   //Pin für Motor3 Arduino D6
  #define MLEFT 16   //Pin für Motor4 Arduino D5
  
  //Servo Anschlüsse
  #define SERVO1 5  //Pin für Servo1 D10
  #define SERVO2 13   //Pin für Servo2 D9
#endif

#ifdef ESP8266
  //Konstante und Include-Dateien für den ESP8266
  #include <ESP8266WiFi.h>
  #include <BlynkSimpleEsp8266.h>

  //Pins für das Drehrichtungs Schieberegister 
  #define SHIFT_IN 0       //Dateneingang Arduino D8
  #define SHIFT_CLK 4      //Schiebetackt Arduino D4
  #define LATCH_CLK 12     //Speichertakt Arduino D12
  #define OUT_ENABLE 13    //Mit LOW Ausgang aktivieren Arduino D7
  
  //PWM für Motoren Geschwindigkeit zwischen 0 und 1023
  #define M1PWM 13   //Pin für Motor1 Arduino D11 Doppelbelegung!
  #define MRIGHT 5   //Pin für Motor2 Arduino D3
  #define M3PWM  12  //Pin für Motor3 Arduino D6 Doppelbelegung!
  #define MLEFT 14   //Pin für Motor4 Arduino D5
  
  //Servo Anschlüsse
  #define SERVO1 15  //Pin für Servo1 D10
  #define SERVO2 2   //Pin für Servo2 D9
#endif

//Für Blynk Debug Meldungen
#define BLYNK_PRINT Serial

// Die folgenden Konstanten müssen durch Ihre persönlichen Daten ersetzt werden
// BLYNK authentication key aus dem E-Mail
#define KEY "+++++++++++++++++++++++++++++++++++++"
// SSID des lokalen  WLAN
#define SSID "************************************"
// Passkey für das WLAN
#define PSK "**************************************"
// Adresse eines lokalen Blynk Server oder "" für den öffentlichen 
#define SERVER  ""

//Bits im Schieberegister zu Motor Zuordnung
#define M1A 2   //Motor1 A
#define M1B 3   //Motor1 B
#define M2A 1   //Motor2 A
#define M2B 4   //Motor2 B
#define M3A 5   //Motor3 A
#define M3B 7   //Motor3 B
#define M4A 0   //Motor4 A
#define M4B 6   //Motor4 B


//Motor Zuordnung
#define DRIGHT 2
#define DLEFT  4

//Konstanten für Drehrichtung
#define STOP 0
#define FORWARD 1
#define BACKWARD 2

//Aktueller Inhalt des Richtungs-Schieberegisters
uint32_t directions = 0;

//Maximalgeschwindigkeit
int z;

//Füllt das Schieberegister zur Motorsteuerung
//mit dem Inhalt von directions
void sendDirections() {
  uint8_t i;
  digitalWrite(LATCH_CLK, LOW);  //Speicher sperren
  digitalWrite(SHIFT_IN, LOW);   //Eingang auf 0
  for (i=0; i<8; i++) {
    digitalWrite(SHIFT_CLK, LOW);//Bit für Bit einlesen
    if (directions & bit(7-i)) {
      digitalWrite(SHIFT_IN, HIGH);
    } else {
      digitalWrite(SHIFT_IN, LOW);
    }
    digitalWrite(SHIFT_CLK, HIGH);
  }
  digitalWrite(LATCH_CLK, HIGH); //Mit der positiven Flanke speichern
}

//Die Drehrichtung für einen Motor festlegen
void setDirection(uint8_t motor, uint8_t direction) {
  uint8_t a=0, b=0;
  //Bitnummern für den gewählten Motor bestimmen
  switch (motor) {
    case 1: a=M1A; b=M1B; break;
    case 2: a=M2A; b=M2B; break;
    case 3: a=M3A; b=M3B; break;
    case 4: a=M4A; b=M4B; break;
  }
  //zuerst beide Bits für den Motor auf 0 setzen bedeutet STOP
  directions &= ~ bit(a) & ~ bit(b);

  switch (direction) {
    case FORWARD: directions |= bit(a); break; //Für VORWÄRTS Bit A auf 1
    case BACKWARD: directions |= bit(b); break;//Für RÜCKWÄRTS Bit B auf 1
  }
  //Serial.printf("Directions = %x\n",directions); 
  sendDirections(); //Neue Einstellung ans Schieberegister senden
}


// neutrale Zone für x und y
// Der Joystick muss außerhalb dieses Bereichs sein um einen Motor zu aktivieren
int minRange = 312;
int maxRange = 712;

//Linken und rechten Motor ansteuern.
//Die Parameter left und right enthalten die Geschwindigkeit
//Negative Werte bedeuten rückwärts
void motors(int16_t left, int16_t right) {
  //Serial.printf("Links %i, rechts %i\n",left,right);
  //Richtung
  if (left<0) {
    setDirection(DLEFT,BACKWARD);
  } else if (left == 0){
    setDirection(DLEFT,STOP);
  } else {
    setDirection(DLEFT,FORWARD);
  }
  if (right<0) {
    setDirection(DRIGHT,BACKWARD);
  } else if (right == 0){
    setDirection(DRIGHT,STOP);
  } else {
    setDirection(DRIGHT,FORWARD);
  }
  //PWM Ausgabe ist für ESP32 und ESP8266 unterschiedlich
  #ifdef ESP32
    //Geschwindigkeit
    ledcWrite(DLEFT,abs(left));
    ledcWrite(DRIGHT,abs(right));
  #endif
  #ifdef ESP8266
    //Geschwindigkeit
    analogWrite(MLEFT,abs(left));
    analogWrite(MRIGHT,abs(right));
  #endif
  
}

// Auswertung der Joystick Daten
void moveControl(int x, int y) {

// move forward

  if(y >= maxRange && x >= minRange && x <= maxRange) { //forward
    motors(z,z);
  } else if(x <= minRange && y >= maxRange ) { //move forward right
    motors(0.7*z,0.3*z);
  } else if(x >= maxRange && y >= minRange && y<=maxRange) { //move right
    motors(z,-z);
  } else if(x <= minRange && y >= maxRange ) { // move forward LEFT
    motors(0.3*z,0.7*z);
  } else if(x <= minRange && y >= minRange && y <= maxRange) { //move left
    motors(-z,z);
 } else if(y < maxRange && y > minRange && x < maxRange && x > minRange) {// neutral zone
    motors(0,0);
 } else if(y <= minRange && x >= minRange && x <= maxRange) { // move back
    motors(-z,-z);
 } else if(y <= minRange && x <= minRange) { // move back and right
    motors(-0.7*z,-0.3*z);
 } else if(y <= minRange && x >= maxRange) { // move back and left
    motors(-0.3*z,-0.7*z);
 } 
}

//Setup
void setup() {
  Serial.begin(115200);
  Serial.println();
  Serial.println("Initialisierung");
  //Alle verwendeten Pins als OUTPUT setzen
  pinMode(SHIFT_IN,OUTPUT);
  pinMode(SHIFT_CLK,OUTPUT);
  pinMode(LATCH_CLK,OUTPUT);
  pinMode(OUT_ENABLE,OUTPUT);
  //PWM für ESP32 
  #ifdef ESP32
    //PWM für ESP32 
    //ledCSetup(Kanal, Frequenz, Auflösung Bit)
    ledcSetup(DLEFT, 100, 10);
    ledcSetup(DRIGHT,100, 10);
    //Motor Pins den Kanälen zuweisen
    ledcAttachPin(MLEFT,DLEFT);
    ledcAttachPin(MRIGHT,DRIGHT);  
  #endif
  #ifdef ESP8266
    //ESP8266 Motor Pins einfach auf Ausgang
    pinMode(MLEFT,OUTPUT);
    pinMode(MRIGHT,OUTPUT);
  #endif
  //Alle Motoren STOP
  directions = 0;
  sendDirections();  //Ans Schieberegister senden
  digitalWrite(OUT_ENABLE,0); //Ausgänge des Schieberegisters freigeben
  

  Serial.println("Starte BLYNK");
  //Je nach öffentlicher oder eigener Server
  //unterschiedlicher Start für Blynk
  if (SERVER=="") {
    Blynk.begin(KEY, SSID, PSK);
  } else {
    Blynk.begin(KEY, SSID, PSK, SERVER, 8080);
  }
}

void loop() {  
  //hier erfolgt die Kommunikation mit dem Blynk Server
  Blynk.run(); 
}

//Virtueller Pin V1 hat Daten erhalten
BLYNK_WRITE(V1)
  //Werte vom Joystick lesen und auswerten
  { int x = param[0].asInt();
  int y = param[1].asInt();
  moveControl(x,y); }

  //Virtueller Pin V2 hat Daten erhalten
BLYNK_WRITE(V2) 
  { 
    //Wert lesen und Maximalgeschwindigkeit setzen
    z = param[0].asInt(); 
  }

 Sketch zum Herunterladen


Chassis aus dem 3D-Drucker


Datei für das Chassis

Datei für den Akkupack-Halter





 

Beitrag als PDF

Viel Spaß mit dem Roboter Car

 

AmateurfunkEsp-32Esp-8266Projekte für anfänger

Einen Kommentar hinterlassen

Alle Kommentare werden vor der Veröffentlichung moderiert

Empfohlene Blogbeiträge

  1. ESP32 jetzt über den Boardverwalter installieren
  2. Lüftersteuerung Raspberry Pi
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1
  4. ESP32 - das Multitalent
  5. OTA - Over the Air - ESP Programmieren über WLAN