2015/03/20

LinkIt ONE:透過MediaTek Cloud Sandbox存取LED

LinkIt ONE不僅有硬體與軟體,聯發科還提供雲端服務MediaTek Cloud Sandbox,底下簡稱MCS。

這一篇要試著練習使用,在MCS上建立一台虛擬裝置,透過網頁介面可把LED設為ON,而實體裝置(LinkIt ONE板子)讀取後便會點亮真正的LED,並且會把LED狀態上傳到MCS的虛擬裝置,從網頁介面觀看顯示LED的狀態。

主要內容與程式碼,都來自於官方文件Implementing using Linkit ONE connecting to MediaTek Cloud Sandbox,並參考分享文[LinkIt One 教學] 連接 LinkIt ONE 到 MediaTek Cloud Sandbox | CAVEDU教育團隊技術部落格;關於MCS的網站操作介面,並不會詳細介紹,還請自行參閱MCS說明文件Getting StartedKey concepts

流程如下:

1. 註冊MCS帳號,會寄一封確認郵件到你填寫的email信箱,點按其中的網址後便可啟動,然後輸入帳號密碼登入,進入MCS的Dashboard,如下圖。
2. 點按上方選單「Development」,新增Prototype。可把所謂的Prototype想像成是張藍圖,之後會以Prototype為樣板建立實際的裝置。
你可以建立多個Prototype,分別代表不同的應用,譬如收集氣溫數據、心跳讀數等等,此範例建立能存取板子內建LED的Prototype,命名為LED Commander。進入Prototype的細節頁面,上半部如下。
下半部才是重點,有Data channel,代表雲端服務與實體裝置之間想要溝通傳輸的資料;Notification可設定條件發出通知,譬如發出email,此篇不使用;User privileges設定不同使用者存取同一Prototype的權限,此篇不使用;Firmware管理韌體版本,是否進行空中更新,此篇不使用;Test device則是建立裝置,想像成存在於雲端中的虛擬裝置,與實體裝置(真正的板子)進行溝通。
3. 增加Data channel,此篇範例需要兩個,一個從實體裝置上傳LED狀態到雲端上的Test device,另一個由Test device設定LED狀態,讓實體裝置抓取並設定。目前可用的Data channel如下,其中Display是「顯示」,Controller則是「控制」,此篇分別需要一個。
建立Display的Data channel,如下,其中Data type設為On / OFF,代表LED亮滅;Data Channel Id非常重要,此範例命名為LED,之後程式碼必須使用此Id來指出想存取哪個Data channel。
再建立Controller的Data channel,如下,Data type同樣也是ON / OFF,經由網頁介面操作後,讓實體裝置抓取。Data Channel Id命名為LED_CONTROL。
Data channel建立完成後,便可看到如下的樣子。

4. 然後是建立Test device,隨便取個名字。
建立後,進入細節頁面,請記下DeviceId與DeviceKey,非常重要,代表實體裝置的身分,程式碼裡須使用,才能存取MCS雲端服務。
5. 以上便是MCS雲端介面需要做的操作動作,接下來便是程式,其中須使用程式庫HttpClient,可到此下載。底下程式碼,來自於MCS提供的範例,而我稍作修改,此處僅列出大概模樣,原始碼請到GitHub下載

共有兩支檔案,其中settings.h記錄一些設定值:

#define WIFI_AP "__SSID__" // 填入WiFi網路名稱SSID
#define WIFI_PASSWORD "__PASSWORD__" // 填入WiFi密碼
#define WIFI_AUTH LWIFI_WPA // LWIFI_OPEN, LWIFI_WPA, LWIFI_WEP

#define SITE_URL "api.mediatek.com"
#define SITE_PORT 80
#define DEVICEID "__DeviceId__" // 填入你的DeviceId
#define DEVICEKEY "__DeviceKey__" // 填入你的DeviceKey

#define LED_ID "LED" // 填入顯示LED狀態的Data channel ID
#define LED_CONTROL_ID "LED_CONTROL" // 填入控制LED的Data channel ID


另一支檔案是主程式碼,概略如下:

// 方便輸出Serial的輔助函式
void pf(const char *fmt, ...){ /* 省略 */ }

// 初始化,連接WiFi網路
void setup(){ /* 省略 */ } 

// 取得MCS雲端服務網站的IP與連接埠
void getconnectInfo(){ /* 省略 */ }

// 建立連線,此連線負責取得控制LED的Data channel
void connectTCP(){ /* 省略 */ } 

// 上傳LED狀態
void uploadStatus(){ /* 省略 */ }

// 避免TCP斷線
void heartBeat(){ /* 省略 */ }

// 不斷上傳LED狀態,接收控制LED的資料
void loop(){ /* 省略 */ }

燒錄程式並重置開機,記得開啟序列埠監控視窗,才會開始動作;然後開啟瀏覽器進入MCS的Test device細節頁面,看到畫面如下。
點按控制頁面的LED_CONTROL,便可控制實體裝置(板子)內建的LED,其狀態會上傳到LED;可一邊觀察序列埠監控視窗的輸出訊息。

呼,完成囉。

參考資料:

26 comments:

  1. 你好,不知道你有沒有可以在Linkit One上面正常運行的DHT11 Library?

    我現在用的絕大部分Library在Linkit One上面都會出現問題,

    有的可能編譯不過,有的可能在讀資料的過程中時有時無,

    我注意到你的練習中有用到DHT11,不知道能不能教一下,

    謝謝!!

    ReplyDelete
    Replies
    1. 編譯不過,這是正常現象,因為你找到的通常是用於Arduino的程式庫,須自行修改。
      讀資料的過程中時有時無,因為Linkit One不是普通的微控制器,它有即時作業系統,會產生中斷、多個執行緒會做切換,而一般DHT11程式庫不是為此而設計的。
      我用的程式庫是http://playground.arduino.cc/Main/DHT11Lib

      Delete
    2. 謝謝你,

      不知道有沒有辦法避免掉範例中的Time Out Error?

      我不大懂他的機制是甚麼?


      另外不知道哪裡有詳細教學 MCS的部分?

      官方的教學其實蠻"簡潔的",像我這種網路白癡要上手還蠻困難的.....

      Delete
    3. 避免掉範例中的Time Out Error,大概要熟知Linkit one系統底層的人才辦得到,請到官方論壇問問。

      這篇不就是MCS的教學了?

      Delete
    4. 我其實沒有看得很懂裡面的網路名詞,

      以官方的範例來說,

      傳不同的資料(例如改傳浮點數)只要更動的地方在define的Device ID、Key和data channel ID,

      然後更動"void uploadStatus()"、和"void loop()"這兩個函式的內容?


      剩下的應該都是聯上MCS固定的函式吧?

      Delete
    5. 這篇介紹上傳、下載LED狀態,也就是0或1。
      MCS使用REST API,你送出HTTP request,它回傳HTTP response,
      其API的文件在此https://mcs.mediatek.com/resources/zh-TW/latest/api_references/。

      在request裡指名你要讀取哪個data channel,以及其他參數,然後response會是xml或json格式,你再解析,取出需要的資料。

      Delete
  2. This comment has been removed by the author.

    ReplyDelete
  3. 您好,我想請問一下
    Linkit one有辦法連接mysql嗎?
    想做自動回傳資料的資料庫,但是都找不太到相關的資料

    ReplyDelete
  4. bnn9876543218/3/16 14:17

    您好,想請教是否有成功使用LWifi的WifiWebServer範例建立Linkit One Server端的經驗呢?
    我的Serial monitor顯示Linkit One Server端的IP Address為192.168.0.131
    但是我用瀏覽器輸入http://192.168.0.131/on,得到無法顯示網頁
    使用命令提示字元也ping不到Linkit One Server端的IP
    使用的作業系統為Win7 64位元,瀏覽器測試過IE及Chrome

    ReplyDelete
    Replies
    1. > 的經驗呢?
      好像有,很久以前了。

      > 顯示Linkit One Server端的IP Address為192.168.0.131
      代表linkit one板子成功連接到你給定的Wi-Fi AP。

      > 得到無法顯示網頁
      嗯,瀏覽器的電腦也位於同一個區域網路嗎?

      > ping不到
      嗯,WifiWebServer範例並沒有實作ping的協定,所以沒有。


      Delete
    2. > http://192.168.0.131/on
      為什麼有個on?
      輸入http://192.168.0.131/試試看。

      Delete
  5. 請問從Arduino開發環境怎麼去看Linkit One的library??

    ReplyDelete
    Replies
    1. 沒辦法。
      自己去目錄裡找原始碼檔案。

      Delete
  6. Connecting to AP
    calling connection
    Content length is: 17

    54.254.183.59,443The connection info: 54.254.183.59,443
    The TCP Socket connection instructions:
    IP: 54.254.183.59
    Port: 443
    443
    Connecting to TCP
    54.254.183.59
    443
    send TCP connect
    waiting TCP response:
    send TCP heartBeat
    calling connection
    Content length is: 41

    400,None of data points uploaded success.DbHZCyTS,bXeeLzOeIQIHoC1r,0calling connection
    Content length is: 41

    400,None of data points uploaded success.calling connection
    Content length is: 41

    400,None of data points uploaded success.calling connection
    Content length is: 41

    然後最下面兩排無限一直跑,一直找不到問題出在哪裡,能幫助我給我一點提示嗎?

    ReplyDelete
    Replies
    1. 你用哪支程式?

      400是HTTP 400吧,代表bad request,代表傳出的HTTP請求是錯的,對方無法接受。

      Delete
  7. 都是照著上面的步驟做的...
    #define WIFI_AP "__SSID__" // 填入WiFi網路名稱SSID 是指WIFI的名稱對吧?

    ReplyDelete
    Replies
    1. > 照著上面的步驟
      是嗎?
      我的程式不會印出你貼上的那些訊息啊。

      Delete
  8. 我用的是你沒修改的
    想再請教一個問題
    如果
    #include
    #include
    #include
    #include
    #include
    #include
    然後Sketch>Include Library這裡面沒有 是不是要Add 上面有,可是 Include Library沒有的zip檔
    還有我必須學會搞懂這些東西,請問我可以知道您的連絡方式嗎?

    ReplyDelete
  9. 我用的是來自於MCS提供的範例,這個程式碼
    您的程式碼錯誤訊息會跑出
    Warning: platform.txt from core 'MediaTek ARM7 EJ-S (32-bits) Boards' contains deprecated recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} "{build.path}/{archive_file}" "{object_file}", automatically converted to recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} "{archive_file_path}" "{object_file}". Consider upgrading this core.
    C:\Users\alex\AppData\Local\Temp\arduino_modified_sketch_782725\SimpleHttpExample.ino:19:19: fatal error: aJSON.h: No such file or directory

    #include

    ^

    compilation terminated.

    Multiple libraries were found for "HttpClient.h"
    Used: C:\Users\alex\Documents\Arduino\libraries\HttpClient-2.2.0
    Not used: D:\Arduino\libraries\Bridge
    exit status 1
    Error compiling for board LinkIt ONE.
    能請大師幫忙找出我的問題出在哪嗎?

    ReplyDelete
  10. #include 後面是 aJSON.h

    ReplyDelete
  11. 您好,我是個初學者,您這篇文章中修改過的程式碼,除了程式庫HttpClient必須安裝外,還有其他程式庫要安裝嗎?

    ReplyDelete
  12. 關於LinkIt ONE的文章,已經是2015年的了,
    我不知道MediaTek Cloud Sandbox是不是有改什麼,
    不知道哪裡是否有什麼變化,會出現錯誤很正常。

    > 程式庫
    我這篇文章的程式碼,應該要HttpClient與aJSON。
    從原始碼的開頭處,就可以看得出來需要哪些程式庫。
    底下省略大於小於的符號:
    #include stdarg.h
    #include LWiFi.h
    #include LWiFiClient.h
    #include HttpClient.h
    #include aJSON.h
    #include LDateTime.h
    其中除了HttpClient與aJSON,都是LinkIt ONE開發環境已內建的程式庫。

    ReplyDelete
    Replies
    1. 你給的錯誤訊息
      > SimpleHttpExample.ino:19:19: fatal error: aJSON.h: No such file or directory
      已經告訴你,沒裝aJSON這套程式庫。

      Delete
  13. aJSON這套資料庫可以去哪裡找的到?

    ReplyDelete
    Replies
    1. Google。

      https://github.com/interactive-matter/aJson

      Delete