highlight.js

星期五, 8月 31, 2018

Arduino 1.8.6 無法上傳程式到 Arduino Nano 控制板

同事因為用到 Arduino Nano 控制板, 卻發現 Arduino 1.8.6 版無法上傳程式, 總是會有以下的錯誤訊息:


查了官網的資料後, 發現在 Arduino Nano 的 Getting started 文章中, 有以下的補充:

NOTE: We have updated the NANO board with a fresh bootloader. Boards sold from us from January 2018 have this new bootloader, while boards manufactured before that date have the old bootloader. First, make sure you have the Arduino AVR Core 1.16.21 or later looking at the Board Manager. Then, to program the NEW Arduino NANO boards you need to chose Processor > "ATmega328P". To program old boards you need to choose Processor > "ATmega328P (Old Bootloader)". If you get an error while uploading or you are not sure which bootloader you have, try each type of processor 328P until your board gets properly programmed.

也就是說, 2018 年 1 月開始, 官方售出的 Arduino Nano 控制板上方的 bootloader 是新版的, 所以 Arduino 1.8.6 預設是配合此新版的 bootloader, 如果是之前買到的 Arduino Nano 控制板, 在上傳程式時就必須選取『工具/處理器/ATmega328P (Old Bootloader)』選項, 才能正確上傳:

星期一, 8月 06, 2018

firebase-arduino 程式庫無法更新資料

如果您有使用 firebase-arduino 程式庫由 ESP8266 控制板上傳資料到 Firebase 的資料庫, 會發現從約莫上週五開始, 就會失敗, 這是因為 Firebase 更新了他們的數位指紋 (fingerprint), 為此 firebase-arduino 也在幾天前修改了程式庫內容 (可參考這一篇文章)。您可以重新下載程式庫, 安裝到 Arduino 開發環境中就可以解決, 或者也可以直接修改 FirebaseHttpClient.h 檔, 將 kFirebaseFingerprint 字串的內容修改為 "6F D0 9A 52 C0 E9 E4 CD A0 D3 02 A4 B7 A1 92 38 2D CA 2F 26" , 再重新編譯程式執行即可。

星期三, 7月 11, 2018

MicroPyton 執行 UTF-8 with BOM 格式的檔案會出錯

在執行 MicroPython 的程式檔時,如果檔案是以 UTF-8 with BOM 的格式儲存, 例如以下的閃爍 LED 程式:


執行時就會發生錯誤:


這時只要將檔案另存新檔, 選取 UTF-8 格式即可, 以下使用 Visual Studio Code 為例:



另存後可以看到檔案格式已經變更:


重新執行就不會發生錯誤了:


星期五, 4月 27, 2018

App Inventor BLE 元件錯誤 "failed resolution Lcom/google/common/collect/List"

在測試 App Inventor 2 的 BLE 元件時, 遇到奇怪的問題, 執行到 WriteBytes 函式, 傳給 values 參數 list (清單) 資料, 就會發生以下的執行時期錯誤:
查了網路上發現這個討論串, 提出的臨時替代方案就是改用 WriteStrings, 並且直接傳送字串給 values 參數, 而不是內含個別字串的清單, App Inventor 會把這個字串轉成由個別字元組成的清單, 一一將字元傳送出去。因此, 如果你本來要送出 12,14 這 2 個位元組, 就要改成送出字串, 其中第一個字元字碼 (ASCII code) 是 12、第二個字元字碼是 14。

不過 App Inventor 並沒有指定字碼傳回對應字元的積木, 因此就有聰明的人想出對策, 由於在 Web(網路) 元件中有提供解譯 HTML entity 成對應字元的功能, 也就是把像是 "&#65" 這樣的字串轉譯為字碼 65 的字元 'A', 藉由此法, 我們就可以撰寫一個傳回指定字碼對應字元的函式:


如此就可以在 WriteStrings 中使用上述函式來組合多個位元組資料了。

星期二, 3月 13, 2018

ESP8266 MicroPython 使用 poll() 出現 Fatal exception 28(LoadProhibitedCause)

由於 MicroPython 預設並沒有像是 ESP8266 Arduino Core 提供有 ESP8266WebServer 程式庫那樣的簡易 Web Server, 所以打算撰寫一個超級簡易版來用。在設計的過程中, 發現 socket 的 accept() 在沒有新連線的情況下並不會返回, 這樣程式流程就會被凍結在這裡無法進行其他的工作, 根據 MicroPythono 文件的說明, 建議你改用 uselect 模組的 poll 類別, 於是我大概寫了這樣的程式:
server.bind(('0.0.0.0', port))
server.listen(1)
poller.register(server, uselect.POLLIN)

where True:
  res = poller.poll(0)
  if res:
    (socket, sockaddr) = server.accept()
    handle(socket)
    ...
程式運作基本上都很好, 但是會在某個沒有規律的神奇時間出現嚴重例外而重置, 出現以下訊息:
Fatal exception 28(LoadProhibitedCause):
epc1=0x4025681d, epc2=0x00000000, epc3=0x00000000, 
excvaddr=0x00000010, depc=0x00000000

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)
...
經過反覆實驗, 發現只要叫用 poll() 時不要給 0 作為 timeout, 就可以避免了。因此最後修改的程式就把 poll(0) 改為 poll(1) 即可。

我寫好的 Web Server 可以參考這裡

星期五, 2月 09, 2018

APDS9960、APDS9930、APDS9900 傻傻分不清楚

同事買了一個號稱使用 APDS9960 感測器的模組, 這感測器可以測環境光線、接近距離、RGB 顏色、手勢, 看起來超威, 趕快找了對應的程式庫, 可是測了半天, 除了環境光線沒問題外, 其他怎麼測都不行。經過網路耙梳, 發現有一篇文章的回應中提到, 他在某處購買了好幾個也是號稱使用同一型號感測器的模組, 但其實使用的是舊款的 APDS9930 感測器, 因為根據 APDS9960 規格書上說明, APDS9960 的 device id 應該是 0xAB, 但他讀到的 device id 是 0x39, 和 APDS9930 規格書上標示的相同。經過這一提醒, 我就改用 APDS9930 的程式庫測試, 果然發現同事買的這一款模組並不是使用 APDS9960, 當 APDS9930 測試就成功了。而手勢偵測、RGB 顏色識別都是 APDS9960 才有的功能, 接近感測的資料取得方式也不一樣。

為了確認這一款模組到底是不是使用 APDS9930, 只好去讀取它的 device id, 一讀不得了, 既不是 APDS9960 的 0xAB、也不是 APDS9930 的 0x39, 而是讀到 0x29, 上網路查才真相大白, 原來這個模組使用的是型號更舊的 APDS9900, 規格書上標明的 device id 正是 0x29。這時我再回頭看原本 APDS9960 的測試程式, 發現其實程式一開始執行時就已經有訊息告訴我初始程序有地方出錯, 如果早點注意到, 我們就不會花這麼多時間找問題了。不過淘寶賣家你們也幫幫忙, 不要亂來好嗎?好啦, 我知道那是製造商的問題, 因為他們在電路板背面大剌剌的印了APDS9960 (底下是網路上賣家的照片):
註:這一篇文章有市面上幾款模組的樣子, 不仔細分辨還真不容易搞清楚。

星期五, 2月 02, 2018

D1 Mini Motor Shield I2C 通訊問題

因為開發產品的緣故, 同事購買了 D1 Mini Motor Shield 來控制直流馬達, 不過實際使用時發現奇特的現象, 閒置一會兒就無法控制馬達。經過簡單的除錯步驟, 發現如果 D1 Mini 與 Motor Shield 間一段時間 (實際測試約 10 秒) 沒有進行 I2C 通訊, Motor Shield 的 I2C 就會沒有任何反應。解決的方法就是每隔一小段時間, 例如 5 秒鐘, 就進行一次 I2C 通訊, 就可以維持 Motor Shield 的 I2C 正常運作。

網路上也有善心人士針對此問題, 撰寫了修正版本的 Motor Shield 韌體, 如果覺得上述手動修改程式定時進行 I2C 通訊的方式很麻煩, 也可以是是看燒錄修正版本的韌體。