*** adafruit.io parameter changed! Please change in the code accordingly or the code below will not work! 2019/07/07 ***
- In the fingerprint setting, find this line and update the string as below:
const char* fingerprint = "77 00 54 2D DA E7 D8 03 27 31 23 99 EB 27 DB CB A5 4C 57 18";
- In the verifyFingerprint(), add two lines before !client.connect(host, AIO_SERVERPORT))
Serial.printf("Using fingerprint '%s'\n", fingerprint);client.setFingerprint(fingerprint);
Continue from Part 2
const char* fingerprint = "77 00 54 2D DA E7 D8 03 27 31 23 99 EB 27 DB CB A5 4C 57 18";
Serial.printf("Using fingerprint '%s'\n", fingerprint);client.setFingerprint(fingerprint);
This is the part 3 of the "Voice control with Arduino and Google Home Mini" tutorial. This section primarily explain how the program on ESP8226 worked.
See the demo below:
Here are the URL links about this tutorial, totaling 3 sections:
- Purpose of this tutorial / schematic / How does it work - Part 1
- IFTTT and Adafruit software setup - Part 2
- Arduino firmware - Part 3
Source code
Please accquire source code from Github:
https://github.com/stonez56/GoogleMini_NodeMCU_IFTTT_Adafruit
Section 1
This section of code is basically define relay pin numbers and status variables. See the comment in code that pin 13 is actually NodeMCU pin D7. You may see the NodeMCU ping mapping from this article.
- Purpose of this tutorial / schematic / How does it work - Part 1
- IFTTT and Adafruit software setup - Part 2
- Arduino firmware - Part 3
Source code
Please accquire source code from Github:
https://github.com/stonez56/GoogleMini_NodeMCU_IFTTT_Adafruit
https://github.com/stonez56/GoogleMini_NodeMCU_IFTTT_Adafruit
Section 1
This section of code is basically define relay pin numbers and status variables. See the comment in code that pin 13 is actually NodeMCU pin D7. You may see the NodeMCU ping mapping from this article.
// Relay settings #define relay2Pin 13 //NodeMCU pin D7 #define relay1Pin 15 //NodeMCU pin D8 int relay1Status = 0; //switch of the relay; either 0=off or 1=on int relay2Status = 0; //switch of the relay; either 0=off or 1=on
Section 2
This section is the basic settings, from Wi-Fi SSID and password to your Adafruit.IO user names and AIO_KEY that I reminded you to make copy is needed here. Exchange all the information below with your own for this program to work.There are 4 items needs to be changed with your data:
- WLAN_SSID
- WLAN_PASS
- AIO_USERNAME
- AIO_KEY
/*************************************************** Adafruit MQTT Library ESP8266 Adafruit IO SSL/TLS example Must use the latest version of ESP8266 Arduino from: https://github.com/esp8266/Arduino Works great with Adafruit's Huzzah ESP board & Feather ----> https://www.adafruit.com/product/2471 ----> https://www.adafruit.com/products/2821 Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! Written by Tony DiCola for Adafruit Industries. SSL/TLS additions by Todd Treece for Adafruit Industries. MIT license, all text above must be included in any redistribution *****************************************/ #include#include "Adafruit_MQTT.h" #include "Adafruit_MQTT_Client.h" /************* WiFi Access Point *****************/ #define WLAN_SSID "Your_HOME_SSID" #define WLAN_PASS "Your_HOME_SSID_PASSWORD" /************* Adafruit.io Setup *****************/ #define AIO_SERVER "io.adafruit.com" #define AIO_SERVERPORT 8883 // 8883 for MQTTS sercure, 1883 for non-Secure #define AIO_USERNAME "stonez56" #define AIO_KEY "4nnxxnnxxnnxxn88223"
Section 3
In Line 62, the code set up a subscription at Adafruit MQTT service Light 1 to get real time updated value. "/feeds/light-1" is the subscription name and it must be the same with the one you defined at Adafruit "Feeds".
In Line 63, it's reserved for future program extension to control RGB color light.
In Line 51, it's a MQTT publish feature that allows you to upload message from ESP8226 to Adafruit.IO MQTT server. You might need it for other projects.
/************ Global State (you don't need to change this!) ******************/ // WiFiFlientSecure for SSL/TLS support WiFiClientSecure client; //WiFiClient for non-secure //WiFiClient client; // Setup the MQTT client class by passing in the WiFi client and MQTT server and login details. Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY); // io.adafruit.com SHA1 fingerprint const char* fingerprint = "AD 4B 64 B3 67 40 B5 FC 0E 51 9B BD 25 E9 7F 88 B6 2A A3 5B"; /****************************** Feeds ***************************************/ // Setup a feed called 'test' for publishing. // Notice MQTT paths for AIO follow the form:/feeds/ //Adafruit_MQTT_Publish light_color = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/light-color"); //Adafruit_MQTT_Publish light_1 = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/light-1"); /*************************** Sketch Code ************************************/ // Bug workaround for Arduino 1.6.6, it seems to need a function declaration // for some reason (only affects ESP8266, likely an arduino-builder bug). void MQTT_connect(); void verifyFingerprint(); //set up a feed called 'light_1' / 'light_color' for subscribing to changes Adafruit_MQTT_Subscribe light_1 = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/light-1"); Adafruit_MQTT_Subscribe light_color = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/light-color");
Section 4
This part is Arduino setup function. Basically, this setup Arduino serial monitor output and connect ESP8226 to your Wi-Fi network, as well as subscribe to MQTT services.
void setup() { Serial.begin(115200); delay(10); pinMode(relay1Pin, OUTPUT); pinMode(relay2Pin, OUTPUT); Serial.println(F("Home MQTT Light Control System")); // Connect to WiFi access point. Serial.println(); Serial.println(); Serial.print("Connecting to "); Serial.println(WLAN_SSID); delay(1000); WiFi.begin(WLAN_SSID, WLAN_PASS); delay(2000); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(); Serial.println("WiFi connected"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); // check the fingerprint of io.adafruit.com's SSL cert verifyFingerprint(); //Subscribe to Adafruit Feed! mqtt.subscribe(&light_1); mqtt.subscribe(&light_color); }
Section 5
The Arduino loop keeps checking with Adafruit server to see if there were new messages. If there were new messages, then further check the subscription name. If the subscription name is equal to light-1, then check the light-1 feed_lastread content. If feed_lastread is ON or OFF then, the program call switchRelay function to either turn on light or turn off light.
This part also check the further project extension for color-light status.
uint32_t x = 0; void loop() { String feed_lastread; // Ensure the connection to the MQTT server is alive (this will make the first // connection and automatically reconnect when disconnected). See the MQTT_connect // function definition further below. MQTT_connect(); Adafruit_MQTT_Subscribe *subscription; while ((subscription = mqtt.readSubscription(5000))) { if (subscription == &light_1) { Serial.print(F("Light-1:")); Serial.println((char *)light_1.lastread); feed_lastread = (char *)light_1.lastread; feed_lastread.trim(); // // Serial.println("Light 1:" + feed_lastread); //for verifying the varialble // *** NOTICE: adafruit.io publishes the data as strings, not numbers!!! if (feed_lastread == "ON") { switchRelay(2, 1); } if (feed_lastread == "OFF") { switchRelay(2, 0); } } if (subscription == &light_color) { Serial.print(F("Color-Light:")); Serial.println((char *)light_color.lastread); feed_lastread = (char *)light_color.lastread; feed_lastread.trim(); // // Serial.println("Color Light:" + feed_lastread); //for verifying the variable // *** NOTICE: adafruit.io publishes the data as strings, not numbers!!! if (feed_lastread == "ON") { switchRelay(1, 1); } else if (feed_lastread == "OFF") { switchRelay(1, 0); } else { colorLightFunction(feed_lastread.toInt()); } } }
Section 5
This is the SwitchRealy function, it either turn off or turn on the relay module and print out the current status on Arduino serial monitor.
/* This turn on/off relay switch */ void switchRelay(int relay, int stat) { if (relay == 2) { //this is light-1; if (stat == 0) { digitalWrite(relay2Pin, LOW); Serial.println(F("Relay off")); } if (stat == 1) { digitalWrite(relay2Pin, HIGH); Serial.println(F("Relay on")); } } if (relay == 1) { //this is color-light; if (stat == 0) { digitalWrite(relay1Pin, LOW); Serial.println(F("Relay off")); } if (stat == 1) { digitalWrite(relay1Pin, HIGH); Serial.println(F("Relay on")); } } }
Section 6
This part is all directly from Adafruit sample code. Just keep them here.
void verifyFingerprint() { const char* host = AIO_SERVER; Serial.print("Connecting to "); Serial.println(host); if (! client.connect(host, AIO_SERVERPORT)) { Serial.println("Connection failed. Halting execution."); while (1); } // if (client.verify(fingerprint, host)) { // Serial.println("Connection secure."); // } else { // Serial.println("Connection insecure! Halting execution."); // while(1); // } } // Function to connect and reconnect as necessary to the MQTT server. // Should be called in the loop function and it will take care if connecting. void MQTT_connect() { int8_t ret; // Stop if already connected. if (mqtt.connected()) { return; } Serial.print("Connecting to MQTT... "); uint8_t retries = 30; while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected Serial.println(mqtt.connectErrorString(ret)); Serial.println("Retrying MQTT connection in 5 seconds..."); mqtt.disconnect(); delay(5000); // wait 5 seconds retries--; if (retries == 0) { // basically die and wait for WDT to reset me while (1); } } Serial.println("MQTT Connected!"); }