ESP8266 WiFi Voice control Multilanguage Car
Решение требует HTTPS-соединения с веб-сервером с Google Chrome, единственным, который поддерживает Webkit!

Радиоуправляемая машина, управляемая голосом - Попробуйте онлайн ЗДЕСЬ!!!


  • В решении используется микроконтроллер ESP8266, который через регулярные промежутки времени подключается к веб-сайту HTTPS и загружает содержимое текстового файла.
  • Команды, которые ESP8266 выполняет на машине RC, записываются в текстовый файл индивидуально.
  • Команды вводятся пользователем системы, подключенным по протоколу HTTPS, через веб-интерфейс через браузер Google Chrome. Можно использовать любой мировой язык, включая языковой регион. Текущая реализация программы использует английский в регионе США.
  • Процесс преобразования голоса в текст выполняется серверами Google по запросу Xhr, который автоматически запускается пользователем.
  • Поддерживаются 4 команды прямого, обратного и бокового движения.
  • Между двумя соединениями существует пауза в 2000 миллисекунд, пока соединение не будет разорвано и текущая голосовая команда не будет выполнена.
  • Реакция системы на соединение происходит практически мгновенно в течение 30 миллисекунд.
  • ESP8266 использует HTTPS-соединение с веб-сервером посредством реализации библиотеки WifiClientSecure и сертификата веб-сервера.
  • Система подходит для школьных проектов, а также для автономных транспортных средств, управляемых из любой точки земли Проект может быть дополнен записью с камеры и различными другими датчиками.
  • Совместимость для (в Arduino Core 2.3.0):

  • ESP8266-Generic
  • NodeMCU (v1 - v3)
  • Wemos D1
  • Wemos D1 mini
  • Программа для ESP8266

    /*|-------------------------------------------------|*/
    /*| RC CAR VOICE CONTROL VIA WEB INTERFACE          |*/
    /*| Webkit (GOOGLE) technology for voice-to-text    |*/
    /*| Author: Martin Chlebovec (martinius96)          |*/
    /*| LANGUAGE English - region US --> en-US          |*/
    /*| Revison: 21. Jan. 2020                          |*/
    /*| Arduino Core 2.5.0/2.5.2 compatible             |*/
    /*|-------------------------------------------------|*/
    #include <ESP8266WiFi.h>
    #include <WiFiClientSecure.h>
    const char * ssid = "WIFI_NAME";
    const char * password = "WIFI_PASS";
    const char * host = "arduino.php5.sk"; //yourdomain
    const int httpsPort = 443; //https port
    const char fingerprint[] PROGMEM = "b0 6d 7f 8c 98 78 8e 6e 0a 57 a8 2f 7e d1 40 2a 1e 3f 48 f7";
    void setup() {
      Serial.begin(115200);
      Serial.println();
      Serial.print("Connecting to WiFi: ");
      Serial.println(ssid);
      WiFi.begin(ssid, password);
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
      Serial.println("");
      Serial.println("WiFi connected");
      Serial.println("IP address: ");
      Serial.println(WiFi.localIP());
    }
    void executed_command() {
      WiFiClientSecure client;
      Serial.printf("Using fingerprint '%s'\n", fingerprint);
      client.setFingerprint(fingerprint);
      if (client.connect(host, httpsPort)) {
        String url = "/php_car/command_executed.php";
        client.print(String("GET ") + url + " HTTP/1.0\r\n" + "Host: " + host + "\r\n" + "User-Agent: NodeMCU\r\n" + "Connection: close\r\n\r\n");
        Serial.println("Connection sucessful");
        Serial.println("Command executed to PHP service");
      } else {
        Serial.println("Error connecting to PHP service for verifying action");
      }
      client.stop();
    }
    void loop() {
      WiFiClientSecure client;
      Serial.printf("Using fingerprint '%s'\n", fingerprint);
      client.setFingerprint(fingerprint);
      if (client.connect(host, httpsPort)) {
        String url = "/php_car/translation.txt";
        client.print(String("GET ") + url + " HTTP/1.0\r\n" + "Host: " + host + "\r\n" + "User-Agent: NodeMCU\r\n" + "Connection: close\r\n\r\n");
        Serial.println("Connection sucessful");
        while (client.connected()) {
          String line = client.readStringUntil('\n');
          if (line == "\r") {
            break;
          }
        }
        String line = client.readStringUntil('\n');
        Serial.println("RC control command: ");
        Serial.println(line);
        if (line == "UP") { //if command == go UP
          Serial.println("Moving forward...");
          // PUT CODE FOR MOVE FORWARD THERE
          client.stop();
          executed_command();
        } else if (line == "DOWN") { //if command == go DOWN
          Serial.println("Moving backward...");
          // PUT CODE FOR MOVE BACKWARD THERE
          client.stop();
          executed_command();
        } else if (line == "LEFT") { //if command == TURN LEFT
          Serial.println("Turning left...");
          // PUT CODE FOR TURN LEFT THERE
          client.stop();
          executed_command();
        } else if (line == "RIGHT") { //if command == TURN RIGHT
          Serial.println("Turning right...");
          // PUT CODE FOR TURN RIGHT THERE
          client.stop();
          executed_command();
        } else if (line == "Last command executed by ESP8266. Waiting for new command.") { //if command == NO_MORE_COMMAND
          client.stop();
          Serial.println("No voice command set yet");
        } else {
          client.stop();
          Serial.println("This command is not suported");
          executed_command();
        }
      } else {
        Serial.println("Connection was not sucessful");
      }
      client.stop();
      delay(2000); // WAIT () miliseconds before next reading of variable
    }
    

    Program - ESP32

    /*|-------------------------------------------------|*/
    /*| RC CAR VOICE CONTROL VIA WEB INTERFACE          |*/
    /*| Webkit (GOOGLE) technology for voice-to-text    |*/
    /*| Author: Martin Chlebovec (martinius96)          |*/
    /*| LANGUAGE English - region US --> en-US          |*/
    /*| Revision: 22. Jan. 2020                         |*/
    /*| Arduino Core 1.0.1+                             |*/
    /*|-------------------------------------------------|*/
    #include <WiFi.h>
    #include <WiFiClientSecure.h>
    const char* ssid     =    "WIFI_NAME";
    const char* pass     =    "WIFI_PASS";
    const char* host     =    "arduino.php5.sk";
    const int httpsPort = 443; //http port
    //DIGICERT ROOT CA
    const char* test_root_ca = \
                               "-----BEGIN CERTIFICATE-----\n" \
                               "MIIEsTCCA5mgAwIBAgIQCKWiRs1LXIyD1wK0u6tTSTANBgkqhkiG9w0BAQsFADBh\n" \
                               "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" \
                               "d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD\n" \
                               "QTAeFw0xNzExMDYxMjIzMzNaFw0yNzExMDYxMjIzMzNaMF4xCzAJBgNVBAYTAlVT\n" \
                               "MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\n" \
                               "b20xHTAbBgNVBAMTFFJhcGlkU1NMIFJTQSBDQSAyMDE4MIIBIjANBgkqhkiG9w0B\n" \
                               "AQEFAAOCAQ8AMIIBCgKCAQEA5S2oihEo9nnpezoziDtx4WWLLCll/e0t1EYemE5n\n" \
                               "+MgP5viaHLy+VpHP+ndX5D18INIuuAV8wFq26KF5U0WNIZiQp6mLtIWjUeWDPA28\n" \
                               "OeyhTlj9TLk2beytbtFU6ypbpWUltmvY5V8ngspC7nFRNCjpfnDED2kRyJzO8yoK\n" \
                               "MFz4J4JE8N7NA1uJwUEFMUvHLs0scLoPZkKcewIRm1RV2AxmFQxJkdf7YN9Pckki\n" \
                               "f2Xgm3b48BZn0zf0qXsSeGu84ua9gwzjzI7tbTBjayTpT+/XpWuBVv6fvarI6bik\n" \
                               "KB859OSGQuw73XXgeuFwEPHTIRoUtkzu3/EQ+LtwznkkdQIDAQABo4IBZjCCAWIw\n" \
                               "HQYDVR0OBBYEFFPKF1n8a8ADIS8aruSqqByCVtp1MB8GA1UdIwQYMBaAFAPeUDVW\n" \
                               "0Uy7ZvCj4hsbw5eyPdFVMA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEF\n" \
                               "BQcDAQYIKwYBBQUHAwIwEgYDVR0TAQH/BAgwBgEB/wIBADA0BggrBgEFBQcBAQQo\n" \
                               "MCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBCBgNVHR8E\n" \
                               "OzA5MDegNaAzhjFodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRHbG9i\n" \
                               "YWxSb290Q0EuY3JsMGMGA1UdIARcMFowNwYJYIZIAYb9bAECMCowKAYIKwYBBQUH\n" \
                               "AgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCwYJYIZIAYb9bAEBMAgG\n" \
                               "BmeBDAECATAIBgZngQwBAgIwDQYJKoZIhvcNAQELBQADggEBAH4jx/LKNW5ZklFc\n" \
                               "YWs8Ejbm0nyzKeZC2KOVYR7P8gevKyslWm4Xo4BSzKr235FsJ4aFt6yAiv1eY0tZ\n" \
                               "/ZN18bOGSGStoEc/JE4ocIzr8P5Mg11kRYHbmgYnr1Rxeki5mSeb39DGxTpJD4kG\n" \
                               "hs5lXNoo4conUiiJwKaqH7vh2baryd8pMISag83JUqyVGc2tWPpO0329/CWq2kry\n" \
                               "qv66OSMjwulUz0dXf4OHQasR7CNfIr+4KScc6ABlQ5RDF86PGeE6kdwSQkFiB/cQ\n" \
                               "ysNyq0jEDQTkfa2pjmuWtMCNbBnhFXBYejfubIhaUbEv2FOQB3dCav+FPg5eEveX\n" \
                               "TVyMnGo=\n" \
                               "-----END CERTIFICATE-----\n";
    WiFiClientSecure client;
    void setup() {
      Serial.begin(115200);
      delay(10);
      Serial.print("Connecting to ssid: ");
      Serial.println(ssid);
      WiFi.disconnect(true);
      WiFi.mode(WIFI_STA);
      WiFi.begin(ssid, pass);
      while (WiFi.waitForConnectResult() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
      client.setCACert(test_root_ca);
      Serial.println("");
      Serial.println("WiFi uspesne pripojene");
      Serial.println("IP adresa: ");
      Serial.println(WiFi.localIP());
      Serial.println("Ready");
    }
    
    void translation() {
      if (client.connect(host, httpsPort)) {
        String url = "/php_car/translation.txt";
        client.print(String("GET ") + url + " HTTP/1.0\r\n" + "Host: " + host + "\r\n" + "User-Agent: ESP32\r\n" + "Connection: close\r\n\r\n");
        while (client.connected()) {
          String hlavicka = client.readStringUntil('\n');
          if (hlavicka == "\r") {
            break;
          }
        }
        String line = client.readStringUntil('\n');
        Serial.println(line);
        if (line == "UP") { //if command == go UP
          Serial.println("Moving forward...");
          // PUT CODE FOR MOVE FORWARD THERE
          client.stop();
          executed_command();
        } else if (line == "DOWN") { //if command == go DOWN
          Serial.println("Moving backward...");
          // PUT CODE FOR MOVE BACKWARD THERE
          client.stop();
          executed_command();
        } else if (line == "LEFT") { //if command == TURN LEFT
          Serial.println("Turning left...");
          // PUT CODE FOR TURN LEFT THERE
          client.stop();
          executed_command();
        } else if (line == "RIGHT") { //if command == TURN RIGHT
          Serial.println("Turning right...");
          client.stop();
          executed_command();
          // PUT CODE FOR TURN RIGHT THERE
        } else if (line == "Last command executed by ESP8266. Waiting for new command.") { //if command == NO_MORE_COMMAND
          Serial.println("No voice command set yet");
        }
      } else {
        Serial.println("Problem connecting to GET voice command");
      }
      client.stop();
    }
    
    void executed_command() {
      if (client.connect(host, httpsPort)) {
        Serial.println("RESET VOICE COMMAND SUCESSFUL");
        String url = "/php_car/command_executed.php";
        client.print(String("GET ") + url + " HTTP/1.0\r\n" + "Host: " + host + "\r\n" + "User-Agent: ESP32\r\n" + "Connection: close\r\n\r\n");
      } else {
        Serial.println("CONNECTION FAILED");
      }
      client.stop();
    }
    
    void loop() {
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    
      }
      translation();
      delay(2000); // WAIT () miliseconds before next reading of variable
    }
    

    Program - Arduino + Ethernet Wiznet W5100

    /*|-------------------------------------------------|*/
    /*| RC CAR VOICE CONTROL VIA WEB INTERFACE          |*/
    /*| Webkit (GOOGLE) technology for voice-to-text    |*/
    /*| Author: Martin Chlebovec (martinius96)          |*/
    /*| LANGUAGE English - region US --> en-US          |*/
    /*| Revision: 21. Jan. 2020                         |*/
    /*|-------------------------------------------------|*/
    #include <SPI.h>
    #include <Ethernet.h>
    
    byte mac[] = { 0xAA, 0xBB, 0xCC, 0x81, 0x7B, 0x4A }; //fyzicka adresa MAC
    char* serverName = "www.arduino.php5.sk"; // webserver
    
    EthernetClient client;
    void setup() {
      Serial.begin(115200);
      if (Ethernet.begin(mac) == 0) {
        Serial.println("DHCP nepridelilo adresu, skusam so statickou...");
        Ethernet.begin(mac);
      }
      Serial.print("  DHCP assigned IP ");
      Serial.println(Ethernet.localIP());
    }
    void executed_command() {
      client.stop();
      if (client.connect(serverName, 80)) {
        client.println("GET /php_car/command_executed.php HTTP/1.0");
        client.println("Host: www.arduino.php5.sk");
        client.println("Connection: close");
        client.println();
      } else {
        Serial.println("Connection failed");
      }
      client.stop();
    }
    void loop() {
      if (Ethernet.begin(mac) == 0) {
        Serial.println("DHCP nepridelilo adresu, skusam so statickou...");
        Ethernet.begin(mac);
      }
      if (client.connect(serverName, 80)) {
        client.println("GET /php_car/translation.txt HTTP/1.0");
        client.println("Host: www.arduino.php5.sk");
        client.println("Connection: close");
        client.println();
        while (client.connected()) {
          String hlavicka = client.readStringUntil('\n');
          Serial.println(hlavicka);
          if (hlavicka == "\r") {
            break;
          }
        }
        String line = client.readStringUntil('\n');
        Serial.println("Command is:");
        Serial.println(line);
        if (line == "UP") { //if command == go UP
          Serial.println("Moving forward...");
          // PUT CODE FOR MOVE FORWARD THERE
          executed_command();
        } else if (line == "DOWN") { //if command == go DOWN
          Serial.println("Moving backward...");
          // PUT CODE FOR MOVE BACKWARD THERE
          executed_command();
        } else if (line == "LEFT") { //if command == TURN LEFT
          Serial.println("Turning left...");
          // PUT CODE FOR TURN LEFT THERE
          executed_command();
        } else if (line == "RIGHT") { //if command == TURN RIGHT
          Serial.println("Turning right...");
          // PUT CODE FOR TURN RIGHT THERE
          executed_command();
        } else if (line == "Last command executed by ESP8266. Waiting for new command.") { //if command == NO_MORE_COMMAND
          Serial.println("No voice command set yet");
        } else {
    
          Serial.println("This command is not suported");
          executed_command();
        }
      }
      else {
        Serial.println("Connection failed");
        Serial.println();
      }
      client.stop();
      delay(5000);
    }