Previous Posts:
tinyMonster AIO Robot (part-1)
tinyMonster AIO Robot (part-2)
In This Post I am Sharing ESP code, Adafruit-IO setup, SPIFFS files, IFTTT applet and working GUI and serial communication images.
ESP Code
/****************************************************/ #include <ESP8266WiFi.h> #include <ESPUI.h> #include <Adafruit_MQTT.h> #include <Adafruit_MQTT_Client.h> /****************************************************/ #include <Ticker.h> Ticker pingger; bool pingger_status = false; /********************************* GPIO **************************************/ const int mqtt_status = 2; //Builtin LED indicating MQTT Status /******************* WiFi Access Point + Station *****************************/ #define AP_SSID "tinyMonster" #define AP_PASS "xxxxxxxxx" #define WLAN_SSID "myWifi" #define WLAN_PASS "xxxxxxxxx" /************************* Adafruit.io Setup *********************************/ #define AIO_SERVER "io.adafruit.com" #define AIO_SERVERPORT 1883 // use 8883 for SSL #define AIO_USERNAME "myRobot" #define AIO_KEY "xxxxxxxxxxxxxxxxxxxxxxxxxxx" /********* Global State (you don't need to change this!) ***********/ WiFiClient client; // or... use WiFiFlientSecure for SSL //WiFiClientSecure client; Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY); /*************************** Feeds *********************************/ Adafruit_MQTT_Subscribe IO_data = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/robot-data"); /*********************** Robot Control *****************************/ byte robot_speed = 50; byte robot_status = 0; String robot_content = ""; void robot_control(String robot_data); void speed_control(Control sender, int type); void main_control(Control sender, int value); /************************* Sketch Code ******************************/ void MQTT_connect(); const char * wifi_status(); /************************ Enable Ping *******************************/ void enable_ping(){ pingger_status = true; } /************************* Read Serial ******************************/ void serial_read(){ if (Serial.available() > 0) { String incoming = Serial.readString(); ESPUI.print("Robot data",incoming); } } /*************************** SETUP **********************************/ void setup() { // ticker is used to ping Adafruit IO pingger.attach(200, enable_ping); /************************ GPIO START *******************************/ pinMode(mqtt_status,OUTPUT); /************************ GPIO END *********************************/ Serial.begin(115200); delay(500); // Connect to WiFi access point. WiFi.mode(WIFI_AP_STA); //set mode to WIFI_AP, WIFI_STA, WIFI_AP_STA or WIFI_OFF WiFi.hostname(AP_SSID); WiFi.softAP(AP_SSID, AP_PASS); Serial.print("IP address: "); Serial.println(WiFi.softAPIP()); delay(500); Serial.print("Connecting to "); Serial.println(WLAN_SSID); WiFi.begin(WLAN_SSID, WLAN_PASS); // Waiting to connect WiFi network if it cannot connect to provided wifi network or it is not in range it will move ahead and as soon as it will be in Range it will connect it automatically delay(500); while (WiFi.status() == WL_DISCONNECTED) { Serial.println("WL_DISCONNECTED"); delay(500); } if (WiFi.status() == WL_NO_SSID_AVAIL) { Serial.println("WL_NO_SSID_AVAIL"); delay(500); } else { if (WiFi.status() == WL_CONNECT_FAILED) { Serial.println("WL_CONNECT_FAILED"); delay(500); } else { while (WiFi.status() != WL_CONNECTED) { Serial.print("."); } Serial.println("WL_CONNECTED"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); } } // Setup MQTT subscription for robot feed. mqtt.subscribe(&IO_data); // Setup ESPUI setup for robot. ESPUI.pad("tinyMonster Control", true, &main_control, COLOR_SUNFLOWER); ESPUI.label("MQTT Status", COLOR_WETASPHALT, "-"); ESPUI.label("Wifi Status", COLOR_TURQUOISE, wifi_status()); ESPUI.label("MQTT data", COLOR_PETERRIVER, "-"); ESPUI.label("Robot data", COLOR_EMERALD, "-"); ESPUI.label("Control data", COLOR_CARROT, "-"); ESPUI.slider("Speed", &speed_control, COLOR_ALIZARIN, "50"); // ESPUI.begin("tinyMonster"); // Begin ESPUI in SPIFFS mode for robot. ESPUI.beginSPIFFS("tinyMonster"); } /*********************************************************************/ void loop() { ESPUI.print("Wifi Status",wifi_status()); serial_read(); if (WiFi.status() == WL_CONNECTED){ MQTT_connect(); Adafruit_MQTT_Subscribe *subscription; while ((subscription = mqtt.readSubscription(5000))) { if (subscription == &IO_data) { robot_content = (char *)IO_data.lastread; robot_control(robot_content); } } if (pingger_status){ pingger_status = false; ESPUI.print("MQTT Status","MQTT is pinged"); if(! mqtt.ping()) { mqtt.disconnect(); digitalWrite(mqtt_status, LOW); } } } else{ delay(10); yield(); } } /********************* Connect to MQTT Server ***********************/ void MQTT_connect() { int8_t ret; if (mqtt.connected()) { return; } ESPUI.print("MQTT Status","Connecting to MQTT... "); uint8_t retries = 3; while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected ESPUI.print("MQTT Status","Retrying MQTT connection in 5 seconds..."); mqtt.disconnect(); delay(5000); // wait 5 seconds retries--; if (retries == 0) { return; } } ESPUI.print("MQTT Status","MQTT Connected!"); digitalWrite(mqtt_status, HIGH); } /************** Robot Control Cmd from Voice/MQTT Cmd ***************/ void robot_control(String robot_data){ robot_data.toLowerCase(); if (robot_data.length()<=3 && robot_data.toInt() <= 100){ robot_speed = robot_data.toInt(); } if (robot_data.indexOf("stop") >= 0){ robot_status = 0; } else{ if (robot_data.indexOf("forward") >= 0){ robot_status = 100; } else if ((robot_data.indexOf("reverse") >= 0) || (robot_data.indexOf("backward") >= 0)){ robot_status = 200; } else; if (robot_data.indexOf("right") >= 0){ if(robot_status == 100 || robot_status == 200 || robot_status == 0){ robot_status += 11; } else if(robot_status == 122 || robot_status == 222 || robot_status == 22){ robot_status -= 11; } } else if (robot_data.indexOf("left") >= 0){ if(robot_status == 100 || robot_status == 200 || robot_status == 0){ robot_status += 22; } else if(robot_status == 111 || robot_status == 211 || robot_status == 11){ robot_status += 11; } } else; if (robot_data.indexOf("speed") >= 0){ if ((robot_data.indexOf("slow") >= 0) || (robot_data.indexOf("low") >= 0)){ robot_speed = 40; } else if ((robot_data.indexOf("medium") >= 0) || (robot_data.indexOf("normal") >= 0)){ robot_speed = 70; } else if ((robot_data.indexOf("fast") >= 0) || (robot_data.indexOf("full") >= 0)){ robot_speed = 100; } else; } else; } Serial.println("Robot Status = " + (String)robot_status + " Robot Speed = " + (String)robot_speed); ESPUI.print("MQTT data", robot_data); } /*************************** Wifi Status ****************************/ const char * wifi_status(){ switch (WiFi.status()) { case 0 : return "WL_IDLE_STATUS"; case 1 : return "WL_NO_SSID_AVAIL"; case 2 : return "WL_SCAN_COMPLETED"; case 3 : return "WL_CONNECTED"; case 4 : return "WL_CONNECT_FAILED"; case 5 : return "WL_CONNECTION_LOST"; case 6 : return "WL_DISCONNECTED"; default: return ""; } } /********************* WLAN GUI Speed Control ***********************/ void speed_control(Control sender, int type) { robot_speed = sender.value.toInt(); Serial.println("Robot Speed = " + (String)robot_speed); ESPUI.print("Control data", "Robot Speed = " + (String)robot_speed); } /***************** Robot Control Cmd From WLAN GUI ******************/ void main_control(Control sender, int value) { switch (value) { case P_LEFT_DOWN: if(robot_status == 100 || robot_status == 200 || robot_status == 0){ robot_status += 22; } else if(robot_status == 111 || robot_status == 211 || robot_status == 11){ robot_status += 11; } Serial.println("Robot Status = " + (String)robot_status); ESPUI.print("Control data", "Robot Status = " + (String)robot_status); break; case P_LEFT_UP: break; case P_RIGHT_DOWN: if(robot_status == 100 || robot_status == 200 || robot_status == 0){ robot_status += 11; } else if(robot_status == 122 || robot_status == 222 || robot_status == 22){ robot_status -= 11; } Serial.println("Robot Status = " + (String)robot_status); ESPUI.print("Control data", "Robot Status = " + (String)robot_status); break; case P_RIGHT_UP: break; case P_FOR_DOWN: robot_status = 100; Serial.println("Robot Status = " + (String)robot_status); ESPUI.print("Control data", "Robot Status = " + (String)robot_status); break; case P_FOR_UP: break; case P_BACK_DOWN: robot_status = 200; Serial.println("Robot Status = " + (String)robot_status); ESPUI.print("Control data", "Robot Status = " + (String)robot_status); break; case P_BACK_UP: break; case P_CENTER_DOWN: robot_status = 0; Serial.println("Robot Status = " + (String)robot_status); ESPUI.print("Control data", "Robot Status = " + (String)robot_status); break; case P_CENTER_UP: break; } }
Adafruit-IO
{gallery} Adafruit IO Dashboard to Control Robot |
---|
IMAGE TITLE: Create Adafruit IO feed at default Location |
IMAGE TITLE: Robot Data Feed |
IMAGE TITLE: Create Dashboard Using Momentary Button and Slider |
IMAGE TITLE: Create Dashboard Using Momentary Button and Slider |
IMAGE TITLE: Final Robot Dashboard |
IFTTT applet
{gallery} How to Create IFTTT Applet for Voice Control |
---|
IMAGE TITLE: Create IFTTT account and goto menu and select "New Applet" |
IMAGE TITLE: Select THIS |
IMAGE TITLE: Search for google assistant, select and link your google account with it if asked |
IMAGE TITLE: Select One of these mentioned trigger |
IMAGE TITLE: Fill it by entering a unique phrase to command the robot |
IMAGE TITLE: After creating trigger successfully select THAT |
IMAGE TITLE: Search and select Adafruit Action service and connect AdafruitIO account (if asked) |
IMAGE TITLE: Select send data to Adafruit |
IMAGE TITLE: Select earlier created AdafruitIO feed and also TextField for voice commands |
IMAGE TITLE: Select Finish to complete the Applet. Now repeat the process by selecting other action trigger |
IMAGE TITLE: Applet I created to control tinyMonster Robot Voice Robot control command with speed info |
IMAGE TITLE: Applet I created to Set tinyMonster Robot Speed using Numeric Voice command |
SPIFFS Data
SPIFFS Data tree:
- DATA
- css
-
- normalize.css
-
- style.css
-
- js
-
- zepto.min.js
-
- control.js
-
- slider.js
- index.html
HTML code of index.html with favicon modification. Anyone can add favicon of his own choice. Rest of these file are same as found in gui example data folder <...\Documents\Arduino\libraries\ESPUI\examples\gui\data> except control.js with little change of STOP for middle button. All the files are attach below. simply extract the zip file in Arduino robot project directory and upload using sketch data uploader.
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>tinyMonster Robot</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="shortcut icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACx0lEQVQ4jX2RX0hTYRjGn86+oi6M6KabEUkQEYNugu4SRMSTEAkJIhGDYJ4uIsra1ba7YMoWYql0ExUs1wkWaEUi2C7SOOGxkLlxvtbpzzHxIDTdxZac4OmiNaZFHzzwvnzP7+F9eYGGJ4RIhMPhpmg0ejISiZyLRCIXazoXjUZPhsPhJiFEAtuhxjoWi13KZrN6qVT65HneD8/zfpRKpU/ZbFaPxWKXtvvrRTAYPCqESBiG4fz86bFarbJSqbBSqbBardLzPBqG4TR661OoqrpXCJFwXddZWFjg+voGHecbi8XPLBY/8+vXZX7/vk7TXKDruo4QIqGq6t4tq0gpWS6XOTs7R9ddo2V95Pv3eb57l2ehUOTKisvXr2dZLpcppeQWOBAInDdN84tt2zQMg8+eTfHx40k+eJDh/fsZptOTnJh4yTdvDNq2TdM0vwQCgfP1AL/ffyWXy22apsl8vkDLkpRyqyxLMp8v0DRN5nK5Tb/ffwUA4PP5VCHEraUliwMDSe7ctfu/GhhIcmnJohDils/nU6EoSioej7NQsNl85ASbj5zggZ6rbBrM1PumwQwP9Fyt94WCzXg8TkVRUgBwAcDM4qJdOdvTz9ZOjcevjRLzZGunxtZOjZgnj18bZWunxrM9/VxctCsAZmosACCYyUzLsXtT7A0l2XLzKTFP9oaS7A0liXmy5eZT9oaSHLs3xUxmWgIINh7iWFvb6UeWXOND/S214Vc8MzrHy9EnvBx9wjOjc9SGX/Gh/paWXGNb2+lHAI41BuwA0NHerqZ1/fmKlKt0nA0uL/+W42xQylXq+ouV9nY1DaCjxmB7SACA3tfXx1AotEWaphFAuub5CwaAfQCaAdzt6uoqDg0NMZVKcXx8nCMjI+zu7v4AYAzAYQD7/xWwG8BBAKcA3FAU5Y4QIiGESCiKchvA9drfIQB7/kC/AMrWysZnCbshAAAAAElFTkSuQmCC" /> <link rel="stylesheet" href="/css/normalize.css"> <link rel="stylesheet" href="/css/style.css"> <script src="/js/zepto.min.js"></script> <script src="/js/slider.js"></script> <script src="/js/controls.js"></script> </head> <body onload="javascript:start();"> <div> <h4><div id="mainHeader">tinyMonster Robot</div> <span id="conStatus">Offline</span></h4></div> <hr /> <div> <div id="row"> </div> </div> </body> </html>
ESP Demo
ESP GUI, various conditions and serial commands sent to NUCLEO for various control commands
{gallery} ESP Robot WLAN control |
---|
IMAGE TITLE: tinyMonster GUI - WLAN connected but cant connect to Adafruit MQTT |
IMAGE TITLE: tinyMonster GUI - Obstacle Detected |
IMAGE TITLE: tinyMonster GUI - WLAN connected And also connected to Adafruit MQTT |
IMAGE TITLE: tinyMonster GUI - received voice command from Google assistant through Adafruit IO using IFTTT |
IMAGE TITLE: tinyMonster GUI - received control command from Adafruit IO Dashboard |
IMAGE TITLE: tinyMonster GUI - Control command from GUI and WLAN not in range |
{gallery} ESP - NUCLEO Serial Communications |
---|
IMAGE TITLE: ESP to NUCLEO serial Communication including voice commands with speed info - tinyMonster Robot |
IMAGE TITLE: ESP to NUCLEO serial Communication If WLAN is out of range and control through Acess Point - tinyMonster Robot |
.
.