2019/01/12

Voice control with Google home and Arduino (3/3)

Continue from Part 2

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:

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.


// 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!");
}

The end.

2019/01/06

Voice control with Google home and Arduino (2/3)

Continue from Part 1

This is the part 2 of the "Voice control with Arduino and Google Home Mini" tutorial. This section primarily explain how to setup the Adafruit MQTT and IFTTT related services.

This is the demo of this tutorial:


Step 1: Adafruit IO setup 

Watch this video to see how I setup the Adafruit IO MQTT for this tutorial. This video has English Closed Captions, if you needed it.






  • If you would like learn more about MQTT, please visit Adafruit website to see it's great tutorials. Highly recommended for anyone not familiar with this technology to read. 

AIO Key

  • AIO Key is your personal key that allows your Arduino ESP8226 to talk to Adafruit IO MQTT server. Keep it safe and not to share with others. 
  • Log in to your account and Click "AIO Key" on the left menu.
  • Write down the AIO Key (You will need this in Arduino to connect to Adafruit) See below:
  • Click on the "View AIO Key" button to see your AIO Key (shown below)








Write down the AIO Key for Arduino ESP2886 coding use later. 

Step 2: Setup IFTTT Applet

  • IFTTT is stands of "If This Than That". If you were not familiar with IFTTT, you could checkout more information from these resources:
    1. What's IFTTT?
    2. How to setup IFTTT?
  • Here is how I setup my IFTTT Applet for this tutorial. This video has English Closed Captions, if you needed it.

Step 3: Check Adafruit and IFTTT setup

  • Turn on Google Home Mini and say "Turn on light one".
  • Install IFTTT App on your smartphone, if you used a smartphone rather than a Google Home.
  • Google assistant should reply "Sure, light one on".
  • From the Adafruit feeds page, you should see the data showing up there immediately reflecting the message you sent; in red square below.
  • Then, your setup is successful!

The 2nd part is completed. In the next section, I will show you all the physical setup and the Arduino codes to make this project work.


Troubleshooting:


Until then, see you next time!

Continue to read: Part 3 Arduino 程式解說 (coming soon)


2019/01/01

Voice control with Google Home and Arduino (1/3)

Preface

After received my Google Home Mini from Walmart, my family and I are really enjoyed and satisfied with the voice features and sound quality. Voice control lighting is always on my Arduino DIY list. After I received all the components, I went ahead and made this project during my X'mas holiday. The Google Home Mini I bought came with a Chromecast in a Smart TV kit package at price of USD$45 during holiday sales. What a bargain! 

* Photo from Walmart

Here are the URL links about this tutorial, totaling 3 sections:


Goal

Simply say "Ok Google, turn Light One On or Off" to Google Home Mini and it does the job!  I intended to add "One" there, so I might have the 2nd or 3rd lights that I could control in...hope not in the distant future. :)

See the demo below:


How does it work?

Programming Steps to show you the working flow

  1. Your voice command send to IFTTT through Google Home Mini 
  2. IFTTT Applets engage Google assistance service and inteprete the voice command into text and send to Adfruit.IO MQTT service
  3. MQTT service received the message(from Google home to IFTTT) and based on the Adafruit "Feeds" setting to store the received message on the MQTT server.
  4. Adruino ESP8266 at home was programmed to subscribe new message from Adafruit. As soon as the Adafruit MQTT server has updated message, Adafruit server push the message back to Arduino ESP8226.
  5. ESP8226 recevie the message and act accordingly to either trigger the relay module.
  6. If the messae is "ON" then, ESP8226 turn on light by swith relay module on. Otherwise, the message is "OFF", then trun off light by swith relay module off.

!!EXTRA CAUTION!!

SAFETY is first priority! This project involves 110V AC which it is quite dangerous if not handled carefully! Please turn the main power source off before all the AC related connections. Double and triple check for short and correct connections before turn back on AC! I'm just to show you how I made this project and not responsible for anything happened to you or your family and properties in case if there is an accident. 

Components Needed

  • NODEMCU ESP8226 * 1
  • 10A 110v/250v AC Relay * 1
  • Wall plug outlet * 1
  • Wires for Arduino connection * 4 or 5
  • Wires for Wall plug connection * 3

Schematic 

I drew this illustration below to show you how did I connected all components together.



Connections:

  • ESP8226 D7 to Relay IN
  • ESP8226 GDN to Relay GDN
  • ESP8226 3.3V to Relay VCC
  • Relay NC(Normally Open) to AC Plug outlet top end (refer to above illustration)
  • Relay C(Common) to AC 110V 
  • AC Plug outlet bottom end to AC 110V GND
  • AC Plug ground (not used in this project, my old house does not have this)
That's all for this section. Next time, I will show you how to setup Adafruit and IFTTT. They are the most important parts of this project. Until next time, see you!

Please Continue to read: Setting software - Part 2 of this tutorial

2018/12/02

Scratch Programming for Tello

Just bought a Tello Drone from an online shop during Black Friday Sales in Taiwan. I was luck to get the Tello Boost Combo with 3 battery and a 3-in-1 charging hub for USD$110.2
「Tello 3-in-1 charging hub」的圖片搜尋結果
The photo above was from DJI website.

!!! Caution !!!

  • If this is your first try to program Tello with Scratch, please do this in door first!
  • There were few times where I placed wrong blocks and Tello just kept went up and stayed close to celling and I was unable to control it at all. This was caused by wrong command blocks I used. If I was outdoor that time, I didn't know where Tello would fly to.

Download & Install 

  1. Install Scratch 2.0 Offline Editor on your Mac or PC. Download it from here: https://scratch.mit.edu/download This is the Scratch program editor. You will write your code in this editor to control Tello. If you don't know how to use Scratch, here is a good place to learn: https://scratch.mit.edu/projects/editor/?tip_bar=getStarted
  2. Install Node.js from here: https://nodejs.org/en/ This program is simulate the Tello smartphone App that it allows you to communicate your PC/Mac to Tello. You do not need to know how Node.js works. Just run the Tello.js script and Tello will be controlled by Scratch.
    • Remember where Node.js is installed
    • $> Node.js v10.14.0 to /usr/local/bin/node
    • $> npm v6.4.1 to /usr/local/bin/npm
  3. Download Tello.js and Tello.s2e from https://dl-cdn.ryzerobotics.com/downloads/tello/20180910/scratch0907.7z
    • The scratch0907.7z requires 7zip to unzip it
    • Remember where Node.js is un-zipped
    • Tello.js is used by Node.js to communicate with Tello
    • Tello.s2e is Scratch extension block code that generate specific Tello Blocks
  4. A better version of Tello.s2e has been created by Yiupa. Down it from Git-Hub. https://github.com/yiupa/tello-scratch-extension/tree/English-version Download from Git-hub to replace Tello.s2e with the new Scratch Extension TelloKanji.s2e

Step by Step

  • Start Scratch 2.0. Hold "Shift" key and click "File" menu, then click "Import Experimental HTTP Extension" and select "Tello.s2e" file where you just downloaded. 

  • The Tello interface will be shown in Scratch under "More Blocks". All the Tello command blocks are placed below.

  • First, click "Events" and drag "When green flag clicked" block to the scripting area.

  • Then click "More Blocks" and drag all the blocks to scripting area according the graphic shown below. First, "Takeoff", then "fly up 50cm", "fly forward 50cm", "fly backward 50cm", "flip f", and last "land".  
  • These commands are quite self explanatory. You may change the numbers in the white oval area to change the fly distance.
  • The "flip f" block is tell Tello to perform a flip operation. "f" means forward and you can change to "b" for backward, "l" for left flip, and "r" for right flip.
  • Click "File"->"Save" this script for future use.

  • Next, connect your PC/Mac Wi-Fi to Tello. Usually, the Wi-Fi SSID is "Tello-XXXXXX"
  • Next start Node.js 
    • For PC, open windows command line window and execute node.js (Sorry, I didn't try this on PC)
    • For Mac, open a terminal and go to the directory where you unzipped Tello.js
    • $>cd 
    • $>cd ~/Download/scratch
    • $>~/Download/scratch$ node Tello.js
    • If you see "Data received from server: ok. Received 2 bytes from 192.168.10.1:8889" Means the connection is ok!
  • Click the green flag and your Tello should be able to fly according to the command blocks you placed in the scripting area. Here I try to let Tello to fly in a square and then land.

  • From the terminal, you can see what actions have been performed and Tello responded with "OK". It means the communication is good!

  • You may also show Tello current status in the Scratch stage by click the option box in "More Blocks". See the screenshot below, such as showing height, battery %, and speed...etc.



  • Here is video of Tello followed commands from Scratch to share with you.


    That's it. I hope you enjoyed this tutorial and have a safe flight. 

    END.

====== 中 文 版 (Chinese Version)=========


最近在台灣黑色星期五銷售期間,從網上商店買了一台Tello 無人機! 我很幸運能夠買到 Tello 暢飛套組,包括了 3 個電池和3合1充電器,售價 NT$3400 元! 很超值!
「Tello 3-in-1 charging hub」的圖片搜尋結果
上面的照片來自DJI網站

!!! 請 注 意 !!!

  • 如果這是您第一次嘗試使用Scratch 來控制 Tello,請先在室內中測試程式!
  • 有好幾次,我放置了錯誤的積木指令,Tello 繼續上升並且靠近天花板,我根本無法控制它。 這是由我使用的錯誤指令區塊造成的。 如果那時我在室外,我根本不知道 Tello 會飛往哪裡。

下載必要程式及安裝 

  1. 在Mac或PC上安裝Scratch 2.0 Offline Editor。 從這裡下載:https://scratch.mit.edu/download 這是Scratch程式編輯器。 您將在此編輯器中寫程式來控制Tello。 如果你沒有使用過 Scratch,可以先到這裡熟悉一下 Scratch: https://scratch.mit.edu/projects/editor/?tip_bar=getStarted
  2. 接著從這裡安裝 Node.js: https://nodejs.org/en/
    這是用來模擬 Tello 手機 APP,它可以您將您的PC / Mac與 Tello 連線。 您不需要知道 Node.js 的工作原理,只需運行 Tello.js 程式,Scratch 就可以控制 Tello。
    • 記下  Node.js 安裝的目錄
    • Node.js v10.14.0 安裝在  /usr/local/bin/node
    • npm v6.4.1 to 安裝在 /usr/local/bin/npm
  3. 從下列網址下載 Tello.js 以及 Tello.s2e https://dl-cdn.ryzerobotics.com/downloads/tello/20180910/scratch0907.7z
    • scratch0907.7z 這個檔案需要 7zip 才能解壓縮
    • 請記下 Node.js 及 Tello.js 解壓縮後的檔案位置
    • Node.js 使用 Tello.js 與 Tello 進行連線
    • Tello.s2e 是Scratch 擴展代碼,用來產生特定 Tello 程式區塊
  4. Yiupa 修正了一個更好的 Tello.s2e 版本,你可以從 Git-Hub下載。 https://github.com/yiupa/tello-scratch-extension/tree/English-version

如何使用

  • 啟動 Scratch 2.0程式後,按住 “Shift” 鍵並點選 “File”,然後點 “Import experimental HTTP extension” 接著選擇剛剛下載的 “Tello.s2e”,即可以載入。

  • Scratch 界面將在"More Blocks"下,你可以看到所有的 Tello 命令區塊都放在下面。

  • 首先,點選 "Events" 並將 "When green flag clicked" 塊拖到右方的程式區域。

  • 然後點說"More Blocks"並如下圖所示,將所有你要使用的程式區塊拖動到右方程式區域。這裡我做的範例: 首先,“take off 起飛”,然後“fly up 50 cm”,“fly forward 50cm”,“fly backward 50cm”,“flip f”,最後“land 降落”。 
  • 這些命令非常的簡單易懂,而且您可以更改白色橢圓區域中的數字以變更飛行距離。
  • “Flip f”塊告訴 Tello 執行翻轉。 “f”表示向前,你可以改為“b”表示向後,“l”表示左翻,“r”表示右翻。
  • 最後別忘了點 “File” “Save”將此檔案保存。

  • 接下來,將您的PC / Mac Wi-Fi 連接到 Tello。通常,Tello Wi-Fi SSID 是 “Tello-XXXXXX”
  • 再來是執行 Node.js 
    • 使用PC的朋友,請打開 Command 視窗並執行node.js(對不起,我還沒試過PC,請你試試看)
    • 對於使用 Mac 朋友,請打開終端機並先到你到解壓縮Tello.js的目錄下
    • cd 
    • cd ~/Download/scratch
    • ~/Download/scratch$node Tello.js (執行 紅色指令)
    • 看到 Data received from server: Ok
      Received 2 bytes from 192.168.10:8889 表示連線已完成。
  • 接著,點下綠色𣄃誌,Tello 就應該能夠根據您放在程式區域中的指令區塊進行飛行。 在這裡,我試著讓特洛繞飛一個長方形的路徑,然後降落。

  • 從 Mac 終端機中,您可以看到被執行的區塊指令,Tello 回覆 “OK”。 表示連線沒有問題,指令收到!

  • 如果你點下 "More Blocks" 裡面有很多 Tello 的資訊可以顯示在 Scratch 的畫面裡(Scratch 左側有一雙猫的畫面) 請參閱下面截圖,例如顯示高度,電池百分比和速度等。
    這是我錄下 Tello 依照Scratch的指令飛行的影片,供您參考。

    希望你喜歡這個教學並小心飛行。

2018/11/28

筆記 - 岳母香魯豬腳


香魯豬腳岳母的拿手菜!每次回高雄阿蓮,岳母常常做這道料理。




最近剛好是自己的生日,再過一週就是太太的生日,所以我也來試做看看。
雖然已經做過兩三次,但有時煮起來很成功顏色好看豬腳Q又好吃,有時很好吃,但是顏色又沒那麼好看。所以這次把它紀錄下來,下次參考!

打電話給岳母,她只告訴我,"很簡單,按下面步驟去做就好了"...心情好像不大好...原來她要選的市長這次落選了...

口述做法:
1. 炒二片薑,十來個蒜頭不切,不壓扁下去爆香
2. 炒鍋下醬油,水、冰糖大支䓤段、辣椒
3. 魯約 50分鐘很Q嫩很好吃,或魯到到個人喜好的軟嫩度即可起鍋。

材料:
  • 豬腳一支約2斤半重 (我是傳統市場買,請商家都已去毛用熱水湯過)
  • 薑少許切片
  • 大支䓤段數支
  • 蒜頭十來個
  • 辣椒一個(看喜好程度自行調整)
  • 醬油半碗、水兩碗~三碗
  • 沙拉油少許
  • 黑胡椒少許
  • 冰糖 (必備,顏色好看的重要材料)
詳細做法:
  • 豬腳用熱水川燙再起鍋備用
  • 炒鍋下點沙拉油、二三片薑、十來個蒜頭不切,不壓扁下去爆香
  • 豬腳入炒鍋下去炒,到每面有點焦黄色
  • 下醬油,水、冰糖大支䓤段、辣椒、黑胡椒到鍋內
  • 把豬腳及醬料充份拌勻再蓋上鍋蓋,用小火慢魯..
  • 魯約 50分鐘很Q嫩很好吃,或魯到到個人喜好的軟嫩度即可起鍋。