Projekt 17: Bluetooth-gesteuerter Panzer

(1) Beschreibung:

Im vorherigen Projekt haben wir die Grundkenntnisse über Bluetooth erlernt. In dieser Lektion werden wir Bluetooth verwenden, um das Smart Car zu steuern. Da es Bluetooth betrifft, werden ein Sender und ein Empfänger benötigt. In diesem Projekt verwenden wir das Mobiltelefon als Sender (Master) und das Smart Car mit dem angeschlossenen HM-10 Bluetooth-Modul (Slave) als Empfänger.

Wir haben früher gelernt, dass das Senden eines Bits LEDs steuern kann. Das Prinzip der Steuerung dieses Roboterfahrzeugs ist dasselbe.

Wir verstehen zunächst die Funktion jeder Schaltfläche in der APP und verwenden dann die Schaltflächen der APP, um den Panzer zu steuern.

(2) Hauptfunktionen der APP

Die folgende Tabelle veranschaulicht die Funktionen der entsprechenden Tasten:

TASTEN

FUNKTIONEN

HM-10 Bluetooth-Modul koppeln und verbinden; erneut klicken zum Trennen

Auswahl des zu bedienenden Roboters

Steuerung der Roboterbewegungen über Schaltflächen

Steuerung der Roboterbewegungen über Joystick

Steuerung der Roboterbewegungen über Schwerkraft

Sendet „F“ beim Drücken und „S“ beim Loslassen
Das Auto fährt vorwärts beim Drücken und hält beim Loslassen an

Sendet „L“ beim Drücken und „S“ beim Loslassen
Das Auto dreht links beim Drücken und hält beim Loslassen an

Sendet „R“ beim Drücken und „S“ beim Loslassen
Das Auto dreht rechts beim Drücken und hält beim Loslassen an

Sendet „B“ beim Drücken und „S“ beim Loslassen
Das Auto fährt rückwärts beim Drücken und hält beim Loslassen an

Sendet „u“+Ziffer+„#“ beim Ziehen
Ziehen zum Ändern der Geschwindigkeit des linken Motors

Sendet „v“+Ziffer+„#“ beim Ziehen
Ziehen zum Ändern der Geschwindigkeit des rechten Motors

Auswahl zum Öffnen der Funktionsseite

Sendet „G“ beim Drücken und „S“ beim erneuten Drücken
Hindernisumfahrungsmodus beim Drücken aktivieren, beim erneuten Drücken beenden

Sendet „h“ beim Drücken und „S“ beim erneuten Drücken
Folgemodus beim Drücken aktivieren, beim erneuten Drücken beenden

Sendet „e“ beim Drücken und „S“ beim erneuten Drücken
Linienfolgemodus beim Drücken aktivieren, beim erneuten Drücken beenden

Sendet „f“ beim Drücken und „S“ beim erneuten Drücken
Modus „Bewegung im begrenzten Raum“ beim Drücken aktivieren, beim erneuten Drücken beenden

Sendet „i“ beim Drücken und „S“ beim erneuten Drücken
Lichtfolgemodus beim Drücken aktivieren, beim erneuten Drücken beenden

Sendet „j“ beim Drücken und „S“ beim erneuten Drücken
Feuerlöschmodus beim Drücken aktivieren, beim erneuten Drücken beenden

Auswahl zum Öffnen des Gesichtsausdrucks-Anzeigemodus

Sendet „k“ beim Drücken und „z“ beim erneuten Drücken
Lächelndes Muster beim Klicken anzeigen, Ausdruck beim erneuten Klicken löschen

Sendet „l“ beim Drücken und „z“ beim erneuten Drücken
Ekeliges Muster beim Klicken anzeigen, Ausdruck beim erneuten Klicken löschen

Sendet „m“ beim Drücken und „z“ beim erneuten Drücken
Fröhliches Gesicht beim Klicken anzeigen, Ausdruck beim erneuten Klicken löschen

Sendet „n“ beim Drücken und „z“ beim erneuten Drücken
Trauriges Muster beim Klicken anzeigen, Ausdruck beim erneuten Klicken löschen

Sendet „o“ beim Drücken und „z“ beim erneuten Drücken
Verachtendes Muster beim Klicken anzeigen, Ausdruck beim erneuten Klicken löschen

Sendet „p“ beim Drücken und „z“ beim erneuten Drücken
Herzförmiges Muster beim Klicken anzeigen, Ausdruck beim erneuten Klicken löschen

Auswahl zum Öffnen der benutzerdefinierten Funktionsoberfläche; es gibt sechs Tasten 1,2,3,4,5,6; mit diesen Tasten können Sie selbst einige Funktionen erweitern

Klicken zum Senden von „w“
Klicken zur Anzeige des analogen Wertes des linken Fotowiderstands

Klicken zum Senden von „y“
Klicken zur Anzeige des analogen Wertes des rechten Fotowiderstands

Klicken zum Senden von „x“
Klicken zur Anzeige der vom Ultraschallsensor erkannten Entfernung (Einheit: cm)

Klicken zum Senden von „c“, erneut klicken zum Senden von „d“
Drücken zum Einschalten des Lüfters, erneut drücken zum Ausschalten

(3) Flussdiagramm:

(4) Schaltplan:

GND, VCC, SDA und SCL der 8x16 LED-Punktmatrix sind jeweils mit -(GND), +(VCC), SDA, SCL der Erweiterungsplatine verbunden;

Die STATE- und BRK-Pins des Bluetooth-Moduls müssen nicht angeschlossen werden.

(5) Testcode:

(Hinweis: Beim Hochladen des Codes muss das Bluetooth-Modul getrennt sein. Bluetooth kann nach dem Hochladevorgang wieder verbunden werden. Andernfalls kann der Code möglicherweise nicht erfolgreich hochgeladen werden.)

/*
  Keyestudio Mini Tank Robot V3 (Popular Edition)
  lesson 17.
  bluetooth Control tank
  http://www.keyestudio.com
*/

// Array, zum Speichern von Bilddaten, kann selbst berechnet oder mit einem Modulwerkzeug ermittelt werden
unsigned char start01[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
unsigned char front[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x12, 0x09, 0x12, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned char back[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x48, 0x90, 0x48, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned char left[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x28, 0x10, 0x44, 0x28, 0x10, 0x44, 0x28, 0x10, 0x00};
unsigned char right[] = {0x00, 0x10, 0x28, 0x44, 0x10, 0x28, 0x44, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned char STOP01[] = {0x2E, 0x2A, 0x3A, 0x00, 0x02, 0x3E, 0x02, 0x00, 0x3E, 0x22, 0x3E, 0x00, 0x3E, 0x0A, 0x0E, 0x00};
unsigned char clear[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
#define SCL_Pin  A5  // Taktpin als A5 festlegen
#define SDA_Pin  A4  // Datenpin als A4 festlegen

#define ML_Ctrl 4  // Richtungssteuerungspin des linken Motors definieren
#define ML_PWM 6   // PWM-Steuerungspin des linken Motors definieren
#define MR_Ctrl 2  // Richtungssteuerungspin des rechten Motors definieren
#define MR_PWM 5   // PWM-Steuerungspin des rechten Motors definieren
char ble_val;      // Zum Speichern des über Bluetooth empfangenen Wertes

void setup() 
{
  Serial.begin(9600);

  pinMode(ML_Ctrl, OUTPUT);
  pinMode(ML_PWM, OUTPUT);
  pinMode(MR_Ctrl, OUTPUT);
  pinMode(MR_PWM, OUTPUT);

  pinMode(SCL_Pin, OUTPUT);
  pinMode(SDA_Pin, OUTPUT);
  matrix_display(clear); // Bildschirm löschen
  matrix_display(start01);  // Startbild anzeigen
}

void loop() 
{
  if (Serial.available())
  {
    ble_val = Serial.read();
    Serial.println(ble_val);
  }
  switch (ble_val)
  {
    case 'F':  // Befehl zum Vorwärtsfahren
      Car_front();
      break;
    case 'B':  // Befehl zum Rückwärtsfahren
      Car_back();
      break;
    case 'L':  // Befehl zum Linksdrehen
      Car_left();
      break;
    case 'R':  // Befehl zum Rechtsdrehen
      Car_right();
      break;
    case 'S':  // Befehl zum Anhalten
      Car_Stop();
      break;
  }
}

/***************Funktion zum Betrieb des Motors***************/
void Car_back() 
{
  digitalWrite(MR_Ctrl, LOW);
  analogWrite(MR_PWM, 200);
  digitalWrite(ML_Ctrl, LOW);
  analogWrite(ML_PWM, 200);
  matrix_display(back);  // Rückwärtsfahren
}

void Car_front() 
{
  digitalWrite(MR_Ctrl, HIGH);
  analogWrite(MR_PWM, 55);
  digitalWrite(ML_Ctrl, HIGH);
  analogWrite(ML_PWM, 55);
  matrix_display(front);  // Bild für Vorwärtsfahren anzeigen
}

void Car_left() 
{
  digitalWrite(MR_Ctrl, HIGH);
  analogWrite(MR_PWM, 55);
  digitalWrite(ML_Ctrl, LOW);
  analogWrite(ML_PWM, 200);
  matrix_display(left);  // Bild für Linksdrehen anzeigen
}

void Car_right() 
{
  digitalWrite(MR_Ctrl, LOW);
  analogWrite(MR_PWM, 200);
  digitalWrite(ML_Ctrl, HIGH);
  analogWrite(ML_PWM, 55);
  matrix_display(right);  // Bild für Rechtsdrehen anzeigen
}

void Car_Stop() 
{
  digitalWrite(MR_Ctrl, LOW);
  analogWrite(MR_PWM, 0);
  digitalWrite(ML_Ctrl, LOW);
  analogWrite(ML_PWM, 0);
  matrix_display(STOP01);  // Bild für Anhalten anzeigen
}

// Diese Funktion wird zur Anzeige auf der Punktmatrixanzeige verwendet
void matrix_display(unsigned char matrix_value[])
{
  IIC_start();  // Funktion zum Aufrufen der Startbedingung der Datenübertragung
  IIC_send(0xc0);  // Adresse auswählen
  for (int i = 0; i < 16; i++) // Musterdaten haben 16 Bytes
  {
    IIC_send(matrix_value[i]); // Musterdaten übertragen
  }
  IIC_end();   // Musterdatenübertragung beenden
  IIC_start();
  IIC_send(0x8A);  // Anzeigesteuerung, Impulsbreite als 4/16 auswählen
  IIC_end();
}

// Bedingungen für den Start der Datenübertragung
void IIC_start()
{
  digitalWrite(SDA_Pin, HIGH);
  digitalWrite(SCL_Pin, HIGH);
  delayMicroseconds(3);
  digitalWrite(SDA_Pin, LOW);
  delayMicroseconds(3);
  digitalWrite(SCL_Pin, LOW);
}

// Zeichen für das Ende der Datenübertragung
void IIC_end()
{
  digitalWrite(SCL_Pin, LOW);
  digitalWrite(SDA_Pin, LOW);
  delayMicroseconds(3);
  digitalWrite(SCL_Pin, HIGH);
  delayMicroseconds(3);
  digitalWrite(SDA_Pin, HIGH);
  delayMicroseconds(3);
}

// Daten übertragen
void IIC_send(unsigned char send_data)
{
  for (byte mask = 0x01; mask != 0; mask <<= 1) // Jedes Zeichen hat 8 Stellen, die einzeln geprüft werden
  {
    if (send_data & mask)  // Hohe oder niedrige Pegel entsprechend jedem Bit (0 oder 1) setzen
    {
      digitalWrite(SDA_Pin, HIGH);
    } 
    else 
    {
      digitalWrite(SDA_Pin, LOW);
    }
    delayMicroseconds(3);
    digitalWrite(SCL_Pin, HIGH); // Taktpin SCL_Pin hochziehen, um Datenübertragung zu stoppen
    delayMicroseconds(3);
    digitalWrite(SCL_Pin, LOW); // Taktpin SCL_Pin herunterziehen, um SDA-Signale zu ändern
  }
}

(6) Testergebnis:

Nach dem Hochladen des Codes verbinden Sie den Roboter mit dem Bluetooth-Modul und koppeln Sie die Bluetooth-APP. Schalten Sie den Netzschalter des Motorantriebsschields ein. Stellen Sie den Roboter auf den Boden und Sie können diese Schaltflächen der Bluetooth-App verwenden, um den Roboter zu steuern.

  1. Die Pfeile nach oben, unten, links und rechts steuern den Roboter, um ihn vorwärts, rückwärts, links und rechts zu bewegen.

  1. Klicken Sie auf die Joystick-Schaltfläche und ziehen Sie die Richtung des schwarzen Punktes im weißen Kreis, um die Bewegungsrichtung des Roboters zu steuern.

  1. Klicken Sie auf die Schwerkraft-Schaltfläche und neigen Sie das Telefon in die Vorwärts-, Rückwärts-, Links- und Rechtsrichtungen. Der Roboter bewegt sich in die Richtung, in die das Telefon geneigt ist.