2022/09/04

App Inventor #7 ESP32 語音控制-IOT 專案必備程式庫範例 (Voice Control ESP32 with IoT Essential Code Base/Voice command )

 

前言:


大家好, 歡迎收看本週的Weekend project with Stonez56。
本周要進行的是 App Inventor 第7集 -  語音控制ESP32 - IOT 專案必備程式庫範例


本週要來示範如何設計App inventor 2 語音控制 APP, 只要加上我之前介紹的IoT專用必備程式庫, (請參考下方的#27連結), 為了讓初學者更好上手, 本次採用沒有放入MQTT的程式庫, 讓範例更簡單一點. 我們先來看一下實際的操作影片. https://www.youtube.com/watch?v=senjdb-cREY&t=40s


整個範例做完,你就可以以語音來控制遠端的 ESP32 了.  本次範例, 除了可以控制ESP32上的LED開 & 關, 也可以控制伺服馬達的開 & 關, 這集也加上了多語功能的控制, 中文和英文都可以喔. 範例中也設定了法文, 西班牙文, 和日文,有興趣的朋友可以自行加上這些語言的控制程式碼. 


#27 AsyncWifimanager ElegantOTA ESP32 (WiFi 密碼管理+ WiFi 韌體更新)
https://stonez56.blogspot.com/2021/07/asyncwifimanager-elegantota-esp32-wifi.html 


請先到上方的連結, copy 所有的程式嗎, 再複製到 Arduino 編輯程式中存檔.

也要記得把  esp32_servo.h 檔案給儲存下來.

好, 那我們就開始吧今天的練習吧~





Source code:


37_vioceControl_ESP32_ECBv1.ino

#include "esp32_servo.h" //------->
#define myLED 2          //------->

#include <AsyncElegantOTA.h>
const char *FOTA_USERNAME = "un"; 
const char *FOTA_PASSWORD = "pw"; 
/****************************************************************************************************************************
  Async_AutoConnect_ESP32_minimal.ino
  For ESP8266 / ESP32 boards
  Built by Khoi Hoang https://github.com/khoih-prog/ESPAsync_WiFiManager
  Licensed under MIT license
 *****************************************************************************************************************************/
#if !(defined(ESP32))
#error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting.
#endif
#include <ESPAsync_WiFiManager.h> //https://github.com/khoih-prog/ESPAsync_WiFiManager
AsyncWebServer webServer(80);

#define DEVICE_NAME "VoiceCommandESP32"  //------->
DNSServer dnsServer;

void setup()
{
    pinMode(myLED, OUTPUT);  //------->
    servo_setup();           //------->
    // put your setup code here, to run once:
    Serial.begin(115200);
    while (!Serial)
        ;
    delay(200);
    Serial.println("\nStarting Async_AutoConnect_ESP32_minimal on " + String(ARDUINO_BOARD));
    Serial.println(ESP_ASYNC_WIFIMANAGER_VERSION);

    ESPAsync_WiFiManager ESPAsync_wifiManager(&webServer, &dnsServer, DEVICE_NAME);  //------->

    //ESPAsync_wifiManager.resetSettings();   //reset saved settings
    //ESPAsync_wifiManager.setAPStaticIPConfig(IPAddress(192, 168, 132, 1), IPAddress(192, 168, 132, 1), IPAddress(255, 255, 255, 0));
    ESPAsync_wifiManager.autoConnect();
    if (WiFi.status() == WL_CONNECTED)
    {
        Serial.print(DEVICE_NAME);  //------->
        Serial.print(F(" Connected. Local IP: "));
        Serial.println(WiFi.localIP());
    }
    else
    {
        Serial.println(ESPAsync_wifiManager.getStatus(WiFi.status()));
    }

    webServer.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
        { request->send(200, "text/plain", "Hi! I am ESP32S. access to URL /update to update firmware"); });  //------->

    webServer.onNotFound([](AsyncWebServerRequest *request)   
        { request->send(404, "text/plain", "Page not found!"); });  //------->
    
    // move the motors  //-------> NEW ADDITION Codes
    webServer.on("/go", HTTP_GET, [](AsyncWebServerRequest *request)
        {
            String motor = "";
            String rotation = "";
            // Get input value from URL/go?motor=msg1&rotation=msg2
            if(request->hasParam("motor") && request->hasParam("rotation")){
                if(request->hasParam("motor")){
                    AsyncWebParameter* p = request->getParam("motor");
                    Serial.print(p->name().c_str());
                    Serial.println(p->value().c_str());
                    motor = p->value();
                }
                if(request->hasParam("rotation")){
                    AsyncWebParameter* p = request->getParam("rotation");
                    Serial.print(p->name().c_str());
                    Serial.println(p->value().c_str());
                    rotation = p->value();
                }

                if(rotation == "0"){
                    digitalWrite(myLED, LOW);
                }else if(rotation == "1"){
                    digitalWrite(myLED, HIGH);
                }else{
                    servo_spin(rotation.toInt());
                }
                request->send(200, "text/plain", "Command executed!");
            }else{
                request->send(200, "text/plain", "Error command!");
                Serial.println("Error commands!");
            }
        });
    
    //AsyncElegantOTA.begin(&webServer); // Start ElegantOTA WITHOUT username & password
    AsyncElegantOTA.begin(&webServer, FOTA_USERNAME, FOTA_PASSWORD); // Start ElegantOTA with username & password 

    webServer.begin();
    Serial.println("HTTP server started");
}

void loop() {

}


esp32_servo.h

// ESP32Servo by John K. Bennett,autoConnectKevin Harrington Version 0.11.0
// https://github.com/jkb-git/ESP32Servo/blob/master/src/ESP32_Servo.h
#include <analogWrite.h>
#include <ESP32PWM.h>
#include <ESP32Servo.h>
#include <ESP32Tone.h>

/** Define SERVO pins **/

#define SERVO_PIN2 13   //
Servo SERVO_LR; //left right

const int MAX_ANGLE = 170; //keep servo at minimum range
const int MIN_ANGLE = 10;
int SERVO_LR_POS = 90;

void servo_setup()
{
    SERVO_LR.setPeriodHertz(50); // standard 50 hz servo
    // http://yehnan.blogspot.com/2013/09/arduinotower-pro-sg90.html
    SERVO_LR.attach(SERVO_PIN2, 500, 2400);

    //init position 90 degree for LR & UD
    SERVO_LR.write(SERVO_LR_POS);
}

void servo_spin(int angle){
    // motor protection
    if(angle > MAX_ANGLE) angle = MAX_ANGLE;
    if(angle < MIN_ANGLE) angle = MIN_ANGLE;
    
    SERVO_LR.write(angle);
}