Project 23: Brandblussende Robot Meerdere Functies

(1)Beschrijving:

De slimme auto heeft in elk vorig project een enkele functie uitgevoerd.

Kan hij meerdere functies tegelijk weergeven? Ja.

In dit laatste grote project willen we een volledige code gebruiken om de slimme auto te bedienen zodat alle functies die in eerdere projecten zijn besproken worden getoond. We gebruiken de knoppen op de Bluetooth-app om automatisch tussen verschillende functies te wisselen, heel eenvoudig en handig.

(2)Stroomdiagram:

Raadpleeg Project 16 voor het installeren en configureren van de Bluetooth-app

(3)Aansluitschema:

1. GND, VCC, SDA, en SCL van het 8x16-bord zijn verbonden met G (GND), + (VCC), A4, en A5 van het uitbreidingsbord.

2. VCC, IN+, IN-, en Gnd van de ventilatormodule zijn verbonden met 5V (V), 12 (S), 13 (S), en Gnd (G).

3. De bruine draad, rode draad, en oranje draad van de servo zijn verbonden met Gnd (G), 5v (V), en D10.

4. RXD, TXD, GND, en VCC van de BT-module zijn verbonden met TX, RX, G (GND), en 5V (VCC). STATE en BRK hoeven niet te worden aangesloten.

5. De pinnen “G”, “V”, en A van de linker vlamsensor zijn verbonden met respectievelijk G (GND), V (VCC), en A1; De rechter vlamsensor is verbonden met G (GND), V (VCC), en A2.

6. De distale poorten van de lijnvolgensor zijn 11, 7, en 8.

(4)Testcode:

(Opmerking: Sluit de Bluetooth-module niet aan voordat u de code uploadt, omdat het uploaden van de code ook gebruik maakt van seriële communicatie, en er kunnen conflicten ontstaan met de Bluetooth seriële communicatie, waardoor het uploaden kan mislukken.)

/*
  Keyestudio Mini Tank Robot V3 (Popular Edition)
  lesson 23
  Fire Extinguishing Robot Multiple Functions
  http://www.keyestudio.com
*/
#include <IRremote.h>
IRrecv irrecv(3);  //
decode_results results;
long ir_rec;  // gebruikt om de IR-waarde op te slaan

/***********/
#define USE_FAN_FUNCTION   1

// Array, gebruikt om gegevens van afbeeldingen op te slaan, kan zelf berekend worden of verkregen via modulustool
unsigned char start01[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
unsigned char STOP01[] = {0x2E, 0x2A, 0x3A, 0x00, 0x02, 0x3E, 0x02, 0x00, 0x3E, 0x22, 0x3E, 0x00, 0x3E, 0x0A, 0x0E, 0x00};
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 Smile[] = {0x00, 0x00, 0x1c, 0x02, 0x02, 0x02, 0x5c, 0x40, 0x40, 0x5c, 0x02, 0x02, 0x02, 0x1c, 0x00, 0x00};
unsigned char Disgust[] = {0x00, 0x00, 0x02, 0x02, 0x02, 0x12, 0x08, 0x04, 0x08, 0x12, 0x22, 0x02, 0x02, 0x00, 0x00, 0x00};
unsigned char Happy[] = {0x02, 0x02, 0x02, 0x02, 0x08, 0x18, 0x28, 0x48, 0x28, 0x18, 0x08, 0x02, 0x02, 0x02, 0x02, 0x00};
unsigned char Squint[] = {0x00, 0x00, 0x00, 0x41, 0x22, 0x14, 0x48, 0x40, 0x40, 0x48, 0x14, 0x22, 0x41, 0x00, 0x00, 0x00};
unsigned char Despise[] = {0x00, 0x00, 0x06, 0x04, 0x04, 0x04, 0x24, 0x20, 0x20, 0x26, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00};
unsigned char Heart[] = {0x00, 0x00, 0x0C, 0x1E, 0x3F, 0x7F, 0xFE, 0xFC, 0xFE, 0x7F, 0x3F, 0x1E, 0x0C, 0x00, 0x00, 0x00};

unsigned char clear[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

#define SCL_Pin  A5  // stel de pin van de klok in op A5
#define SDA_Pin  A4  // stel de datapen in op A4

#define ML_Ctrl 4  // definieer de richtingsbesturingspin van de linkermotor als 4
#define ML_PWM 6   // definieer de PWM-besturingspin van de linkermotor
#define MR_Ctrl 2  // definieer de richtingsbesturingspin van de rechtersensor
#define MR_PWM 5   // definieer de PWM-besturingspin van de rechtermotor
char ble_val;      // gebruikt om de Bluetooth-waarde op te slaan
byte speeds_L = 200; // de beginsnelheid van de linkermotor is 200
byte speeds_R = 200; // de beginsnelheid van de rechtermotor is 200
String speeds_l, speeds_r; // ontvang PWM-tekens en converteer ze naar PWM-waarde

// bedrading van de lijnvolgensor
#define L_pin  11  // links
#define M_pin  7  // midden
#define R_pin  8  // rechts
int L_val, M_val, R_val;

#if USE_FAN_FUNCTION  /****gebruik ventilator*******/
int flame_L = A1; // definieer de analoge poort van de linker vlamsensor als A1
int flame_R = A2; // definieer de analoge poort van de rechter vlamsensor als A2
int flame_valL, flame_valR;

// de pin van de 130-motor
int INA = 12;
int INB = 13;

#else /****gebruik de ultrasone sensor*******/
#define servoPin    10  // servo Pin
#define light_L_Pin A1   // definieer de pin van de linker lichtgevoelige weerstand
#define light_R_Pin A2   // definieer de pin van de rechter lichtgevoelige weerstand
int left_light;
int right_light;

#define Trig 12
#define Echo 13
float distance;// Sla de afstandswaarden op die door ultrasoon worden gedetecteerd voor volgfunctie

// Sla de afstandswaarden op die door ultrasoon worden gedetecteerd voor hindernisontwijking
int a;
int a1;
int a2;

#endif

bool flag;  // vlag variabele, gebruikt om een modus te betreden en te verlaten

void setup() 
{
  Serial.begin(9600);
  irrecv.enableIRIn();  // Initialiseer de bibliotheek van de IR-afstandsbediening

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

  pinMode(L_pin, INPUT); // definieer de pinnen van sensoren als INPUT
  pinMode(M_pin, INPUT);
  pinMode(R_pin, INPUT);

  matrix_display(clear);    // scherm wissen
  matrix_display(start01);  // start tonen

#if USE_FAN_FUNCTION/****gebruik de ventilator*******/
  pinMode(INA, OUTPUT);// stel INA in als OUTPUT
  pinMode(INB, OUTPUT);// stel INB in als OUTPUT

  // definieer ingangen van de vlamsensor
  pinMode(flame_L, INPUT);
  pinMode(flame_R, INPUT);
#else/****gebruik de ultrasone sensor*******/
  pinMode(servoPin, OUTPUT);
  pinMode(light_L_Pin, INPUT);
  pinMode(light_R_Pin, INPUT);

  pinMode(Trig, OUTPUT);
  pinMode(Echo, INPUT);
  procedure(90); // stel de hoek van de servo in op 90°
#endif
}

void loop() 
{
  if (Serial.available()) // als er gegevens in de seriële buffer zijn
  {
    ble_val = Serial.read();
    Serial.println(ble_val);
    switch (ble_val) 
    {
      case 'F': Car_front(); break; // het commando om vooruit te gaan

      case 'B': Car_back(); break;  // het commando om achteruit te gaan

      case 'L': Car_left(); break;  // het commando om links af te slaan

      case 'R': Car_right(); break; // het commando om rechts af te slaan

      case 'S': Car_Stop();  break; // stoppen

      case 'e': Tracking();  break; // de lijnvolgmodus activeren

      case 'f': Confinement(); break;  // de inperkingsmodus activeren

#if USE_FAN_FUNCTION/****gebruik ventilator*******/
      case 'j': Fire(); break;  // brandblussingsmodus inschakelen

      case 'c': fan_begin(); break;  // de ventilator inschakelen

      case 'd': fan_stop();  break;  // de ventilator uitschakelen

#else/****gebruik de ultrasone sensor*******/
      case 'g': Avoid(); break;  // hindernisontwijkingsmodus activeren

      case 'h': Follow(); break;  // volgmodus activeren

      case 'i': Light_following();  break;  // lichtvolg modus activeren
#endif
      case 'u': 
        speeds_l = Serial.readStringUntil('#'); 
        speeds_L = String(speeds_l).toInt(); 
        break; // begin met ontvangen van u, eindig met ontvangen van tekens # en converteer naar het geheel getal

      case 'v': 
        speeds_r = Serial.readStringUntil('#');
        speeds_R = String(speeds_r).toInt(); 
        break; // begin met ontvangen van u, eindig met ontvangen van tekens # en converteer naar het geheel getal

      case 'k': matrix_display(Smile);    break;  // toon "glimlach" gezicht
      case 'l': matrix_display(Disgust);  break;  // toon "walging" gezicht
      case 'm': matrix_display(Happy);    break;  // toon "blij" gezicht
      case 'n': matrix_display(Squint);   break;  // toon "verdrietig" gezicht
      case 'o': matrix_display(Despise);  break;  // toon "minachting" gezicht
      case 'p': matrix_display(Heart);    break;  // toon de hartslag afbeelding
      case 'z': matrix_display(clear);    break;  // afbeeldingen wissen

      default: break;
    }
  }

#if (USE_FAN_FUNCTION != 1)/****de functie om de ventilator niet te gebruiken*******/
  // De volgende drie signalen worden voornamelijk gebruikt voor cyclisch afdrukken
  if (ble_val == 'x') 
  {
    distance = checkdistance(); Serial.println(distance);
    delay(50);
  } 
  else if (ble_val == 'w') 
  {
    left_light = analogRead(light_L_Pin);
    Serial.println(left_light);
    delay(50);
  } 
  else if (ble_val == 'y') 
  {
    right_light = analogRead(light_R_Pin);
    Serial.println(right_light);
    delay(50);
  }
#endif

  if (irrecv.decode(&results))  // Infrarood afstandsbedieningswaarde ontvangen
  {
    ir_rec = results.value;
    Serial.println(ir_rec, HEX);
    switch (ir_rec) 
    {
      case 0xFF629D: Car_front();   break;   // vooruit gaan
      case 0xFFA857: Car_back();    break;   // achteruit gaan
      case 0xFF22DD: Car_left();    break;   // naar links draaien
      case 0xFFC23D: Car_right();   break;   // naar rechts draaien
      case 0xFF02FD: Car_Stop();    break;   // stoppen
      default: break;
    }
    irrecv.resume();
  }
}

#if (USE_FAN_FUNCTION != 1)/****gebruik de ultrasone sensor*******/

// Bedien de ultrasone sensor
float checkdistance() 
{
  float distance;
  digitalWrite(Trig, LOW);
  delayMicroseconds(2);
  digitalWrite(Trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(Trig, LOW);
  distance = pulseIn(Echo, HIGH) / 58.20;  //
  delay(10);
  return distance;
}


// de functie om de servo te bedienen
void procedure(int myangle) 
{
  int pulsewidth;
  pulsewidth = map(myangle, 0, 180, 500, 2000);  // Bereken de pulsbreedtewaarde, dit moet de afbeeldingswaarde zijn van 500 tot 2500. Rekening houdend met de invloed van de infraroodbibliotheek wordt hier 500~2000 gebruikt.
  for (int i = 0; i < 5; i++) 
  {
    digitalWrite(servoPin, HIGH);
    delayMicroseconds(pulsewidth);   // De duur van het hoge niveau is de pulsbreedte
    digitalWrite(servoPin, LOW);
    delay((20 - pulsewidth / 1000));  // De periode is 20ms, dus het lage niveau duurt de rest van de tijd
  }
}

/*****************hindernisontwijking******************/
void Avoid()
{
  flag = 0;
  while (flag == 0)
  {
    a = checkdistance();  // de voorste afstand wordt ingesteld op a
    if (a < 20) // Wanneer de afstand voor minder dan 20cm is
    {
      Car_Stop();  // stoppen
      delay(500); // vertraging van 500ms
      procedure(180);  // servo draait naar links
      delay(500); // vertraging van 500ms
      a1 = checkdistance();  // de linkerafstand wordt ingesteld op a1
      delay(100); // waarde lezen

      procedure(0); // servo draait naar rechts
      delay(500); // vertraging van 500ms
      a2 = checkdistance(); // de rechterafstand wordt ingesteld op a2
      delay(100); // waarde lezen

      procedure(90);  // terug naar 90°
      delay(500);
      if (a1 > a2)  // Wanneer de afstand links groter is dan de afstand rechts
      {
        Car_left();  // de robot draait naar links
        delay(700);  // draai 700ms naar links
      } 
      else 
      {
        Car_right(); // naar rechts draaien
        delay(700);
      }
    }
    else  // als de voorste afstand ≥20cm is, gaat de robot vooruit
    {
      Car_front(); // vooruit gaan
    }
    // ontvang de Bluetooth-waarde om de lus te verlaten
    if (Serial.available())
    {
      ble_val = Serial.read();
      if (ble_val == 'S')  // ontvang S
      {
        flag = 1;  // Stel vlag in op 1 om de lus te verlaten
        Car_Stop();
      }
    }
  }
}

/*******************volgen***************/
void Follow() 
{
  flag = 0;
  while (flag == 0) 
  {
    distance = checkdistance();  // stel de afstandswaarde in op distance
    if (distance >= 20 && distance <= 60) // vooruit gaan
    {
      Car_front();
    }
    else if (distance > 10 && distance < 20)  // stoppen
    {
      Car_Stop();
    }
    else if (distance <= 10)  // achteruit gaan
    {
      Car_back();
    }
    else  // stoppen
    {
      Car_Stop();
    }
    if (Serial.available())
    {
      ble_val = Serial.read();
      if (ble_val == 'S')
      {
        flag = 1;  // verlaat de lus
        Car_Stop();
      }
    }
  }
}

/****************licht volgen******************/
void Light_following() 
{
  flag = 0;
  while (flag == 0) 
  {
    left_light = analogRead(light_L_Pin);
    right_light = analogRead(light_R_Pin);
    if (left_light > 650 && right_light > 650) // vooruit gaan
    {
      Car_front();
    }
    else if (left_light > 650 && right_light <= 650)  // naar links draaien
    {
      Car_left();
    }
    else if (left_light <= 650 && right_light > 650) // naar rechts draaien
    {
      Car_right();
    }
    else  // anders, stoppen
    {
      Car_Stop();
    }
    if (Serial.available())
    {
      ble_val = Serial.read();
      if (ble_val == 'S') 
      {
        flag = 1;
        Car_Stop();
      }
    }
  }
}

#else/****gebruik de ventilator*******/
/***************ventilator inschakelen*****************/
void fan_begin() 
{
  digitalWrite(INA, LOW);
  digitalWrite(INB, HIGH);
}

/***************ventilator stoppen*****************/
void fan_stop() 
{
  digitalWrite(INA, LOW);
  digitalWrite(INB, LOW);
}

/***************brand blussen****************/
void Fire() 
{
  flag = 0;
  while (flag == 0) 
  {
    // Lees de analoge waarde van de vlamsensor
    flame_valL = analogRead(flame_L);
    flame_valR = analogRead(flame_R);
    if (flame_valL <= 700 || flame_valR <= 700) 
    {
      Car_Stop();
      fan_begin();
    } 
    else 
    {
      fan_stop();
      L_val = digitalRead(L_pin); // Lees de waarde van de linker sensor
      M_val = digitalRead(M_pin); // Lees de waarde van de linker sensor
      R_val = digitalRead(R_pin); // Lees de waarde van de rechter sensor
      if (M_val == 1)  //de middelste detecteert zwarte lijnen
      {
        if (L_val == 1 && R_val == 0)  //Als een zwarte lijn links wordt gedetecteerd, maar niet rechts, draai links
        {
          Car_left();
        }
        else if (L_val == 0 && R_val == 1)  //Als een zwarte lijn rechts wordt gedetecteerd, niet links, draai rechts
        {
          Car_right();
        }
        else //ga vooruit
        { 
          Car_front();
        }
      }
      else //de middelste detecteert zwarte lijnen
      { 
        if (L_val == 1 && R_val == 0) //Als een zwarte lijn links wordt gedetecteerd, maar niet rechts, draai links
        { 
          Car_left();
        }
        else if (L_val == 0 && R_val == 1) //Als een zwarte lijn rechts wordt gedetecteerd, niet links, draai rechts
        { 
          Car_right();
        }
        else //anders stoppen
        { 
          Car_Stop();
        }
      }
    }
    if (Serial.available())
    {
      ble_val = Serial.read();
      if (ble_val == 'S') 
      {
        flag = 1;
        Car_Stop();
      }
    }
  }
}

#endif

/***************lijnvolgen*****************/
void Tracking() 
{
  flag = 0;
  while (flag == 0) 
  {
    L_val = digitalRead(L_pin); //Lees de waarde van de linkersensor
    M_val = digitalRead(M_pin); //Lees de waarde van de middelste sensor
    R_val = digitalRead(R_pin); //Lees de waarde van de rechtssensor
    if (M_val == 1)  //de middelste detecteert zwarte lijnen
    {
      if (L_val == 1 && R_val == 0) //Als een zwarte lijn links wordt gedetecteerd, maar niet rechts, draai links
      {
        Car_left();
      }
      else if (L_val == 0 && R_val == 1) //Als een zwarte lijn rechts wordt gedetecteerd, niet links, draai rechts
      { 
        Car_right();
      }
      else //ga vooruit
      { 
        Car_front();
      }
    }
    else //de middelste sensor detecteert geen zwarte lijnen
    { 
      if (L_val == 1 && R_val == 0) //Als een zwarte lijn links wordt gedetecteerd, maar niet rechts, draai links
      { 
        Car_left();
      }
      else if (L_val == 0 && R_val == 1) //Als een zwarte lijn rechts wordt gedetecteerd, niet links, draai rechts
      { 
        Car_right();
      }
      else //anders stoppen
      { 
        Car_Stop();
      }
    }
    if (Serial.available())
    {
      ble_val = Serial.read();
      if (ble_val == 'S') 
      {
        flag = 1;
        Car_Stop();
      }
    }
  }
}

/***************Begrenzing*****************/
void Confinement() 
{
  flag = 0;
  while (flag == 0) 
  {
    L_val = digitalRead(L_pin); //Lees de waarde van de linkersensor
    M_val = digitalRead(M_pin); //Lees de waarde van de middelste sensor
    R_val = digitalRead(R_pin); //Lees de waarde van de rechtssensor
    if ( L_val == 0 && M_val == 0 && R_val == 0 ) //Ga vooruit wanneer er geen zwarte lijnen worden gedetecteerd   
    {    
        Car_front();
    }
    else 
    { 
      Car_back();
      delay(700);
      Car_left();
      delay(800);
    }
    if (Serial.available())
    {
      ble_val = Serial.read();
      if (ble_val == 'S') 
      {
        flag = 1;
        Car_Stop();
      }
    }
  }
}


/***************puntmatrix******************/
//deze functie wordt gebruikt voor de weergave van de puntmatrix 
void matrix_display(unsigned char matrix_value[])
{
  IIC_start();  //gebruik de functie om gegevensoverdracht te starten
  IIC_send(0xc0);  //selecteer een adres
  for (int i = 0; i < 16; i++) //afbeeldingsgegevens hebben 16 tekens
  {
    IIC_send(matrix_value[i]); //gegevens om afbeeldingen te verzenden
  }
  IIC_end();   //beëindig de gegevensoverdracht van afbeeldingen
  IIC_start();
  IIC_send(0x8A);  //toon besturing en selecteer pulsbreedte 4/16
  IIC_end();
}

//de conditie waaronder gegevensoverdracht begint
void IIC_start()
{
  digitalWrite(SDA_Pin, HIGH);
  digitalWrite(SCL_Pin, HIGH);
  delayMicroseconds(3);
  digitalWrite(SDA_Pin, LOW);
  delayMicroseconds(3);
  digitalWrite(SCL_Pin, LOW);
}

//gegevens verzenden
void IIC_send(unsigned char send_data)
{
  for (byte mask = 0x01; mask != 0; mask <<= 1) //elk teken heeft 8 cijfers, die één voor één worden gedetecteerd
  {
    if (send_data & mask)  //stel hoge of lage niveaus in op basis van elk bit (0 of 1)
    {
      digitalWrite(SDA_Pin, HIGH);
    } 
    else 
    {
      digitalWrite(SDA_Pin, LOW);
    }
    delayMicroseconds(3);
    digitalWrite(SCL_Pin, HIGH); //trek de klokpin SCL_Pin omhoog om de gegevensoverdracht te beëindigen
    delayMicroseconds(3);
    digitalWrite(SCL_Pin, LOW); //trek de klokpin SCL_Pin omlaag om signalen van SDA te wijzigen 
  }
}

//het teken dat gegevensoverdracht eindigt
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);
}

/***************motor rijdt****************/
void Car_back() 
{
  digitalWrite(MR_Ctrl, LOW);
  analogWrite(MR_PWM, speeds_R);
  digitalWrite(ML_Ctrl, LOW);
  analogWrite(ML_PWM, speeds_L);
  matrix_display(back);  //toon de afbeelding van achteruitrijden
}

void Car_front() 
{
  digitalWrite(MR_Ctrl, HIGH);
  analogWrite(MR_PWM, 255 - speeds_R);
  digitalWrite(ML_Ctrl, HIGH);
  analogWrite(ML_PWM, 255 - speeds_L);
  matrix_display(front);  //toon de afbeelding van vooruitrijden
}

void Car_left() 
{
  digitalWrite(MR_Ctrl, HIGH);
  analogWrite(MR_PWM, 255 - speeds_R);
  digitalWrite(ML_Ctrl, LOW);
  analogWrite(ML_PWM, speeds_L);
  matrix_display(left);  //toon de afbeelding van links afslaan
}

void Car_right() 
{
  digitalWrite(MR_Ctrl, LOW);
  analogWrite(MR_PWM, speeds_R);
  digitalWrite(ML_Ctrl, HIGH);
  analogWrite(ML_PWM, 255 - speeds_L);
  matrix_display(right);  //toon de afbeelding van rechts afslaan
}

void Car_Stop() 
{
  digitalWrite(MR_Ctrl, LOW);
  analogWrite(MR_PWM, 0);
  digitalWrite(ML_Ctrl, LOW);
  analogWrite(ML_PWM, 0);
  matrix_display(STOP01);  //toon de stopafbeelding
}

(5)Testresultaat

Voordat de programmacode wordt geüpload, moet de Bluetooth-module worden verwijderd; anders mislukt het uploaden van de code.

Na het succesvol uploaden van de code, schakel de locatieservices in op uw apparaat en verbind vervolgens de Bluetooth-module.

Zodra de Bluetooth-module is aangesloten en ingeschakeld, en de mobiele APP succesvol verbonden is met de Bluetooth, kunnen we de mobiele APP gebruiken om de tankrobot te besturen.

U kunt de robot ook bedienen met de afstandsbediening.