highlight.js

星期四, 11月 16, 2017

小心, ESP8266 有看門狗 (Watch Dog Timer)

ESP8266 雖然有 Arduino Core 可以直接用 Arduino IDE 寫程式, 不過 ESP8266 畢竟不是 Arduino, 有些硬體上的差異還是可能讓你的程式掛掉, 今天就遇到一個搞死我的問題。我有一個機器人的程式, 跑一些動作時 ESP2866 就會 reset, 本來以為是供電不足, 但馬達單獨供電還是會 reset, 開了 Serial 看資料才發現, reset 時有以下訊息:
Soft WDT reset


ctx: cont
....
原來 ESP8266 有看門狗計時器 (Watch Dog Timer), 程式會在 loop() 結束或是呼叫 delay() 時更新看門狗計時器, 如果很長一段時間沒有更新看門狗計時器, 就會啟動 reset 機制, 警告你程式某些地方有閒置過久的問題。舉例來說, 如果你在 ESP8266 上跑以下這個在 loop() 中閒置 10 秒的程式:
void setup() {
  Serial.begin(9600);
  Serial.println("Begin testing");
}

unsigned long prevTime;

void loop() {
  prevTime = millis();
  while(millis() - prevTime < 10000);  
}
就會在序列埠監控視窗中看到看門狗計時器 reset 的訊息:


解決的方法很簡單, 只要在閒置區域中呼叫 yield() 或是 delay(0) 就會更新看門狗計時器, 也就不會 reset 了。修改的程式如下:
void setup() {
  Serial.begin(9600);
  Serial.println("Begin testing");
}

unsigned long prevTime;

void loop() {
  prevTime = millis();
  while(millis() - prevTime < 10000) {yield();}  
}

星期六, 11月 11, 2017

中計, 同一資料型別但不同平台資料長度不同的陷阱

這幾天測試 ESP8266 的 Arduino core, 拿以前寫的 Arduino 程式來試看看相容性, 遇到一個程式怎麼跑數值都錯, 這個程式會從感測器讀取兩個位元組的資料, 再由這兩個位元組組成一個 16-bit int, 結果原來是 ESP8266 的 int 是 32-bit, 而 Arduino 的 int 是 16-bit, 因此, 原本以下正確的程式:
return int(word(high,low));
遇到負數時會出現超過 32767 的數值, 害我還回頭看感測器的規格書, 以為是自己程式寫錯了。後來才想到, 可能是資料長度的問題, 改成以下這樣就正確了:
return int16_t(word(high,low));

星期四, 11月 09, 2017

Arduino 命令行錯誤:avr-g++: error: missing argument to '-mmcu='

不知道為什麼, 突然遇到使用 Arduino 命令行編譯上傳程式到 Nano 板時, 出現以下錯誤:

avr-g++: error: missing argument to '-mmcu='

明明之前都沒問題, 不知道是動到了什麼, 經過網路查詢之後, 明確加上 CPU 型號就可以了:

--board arduino:avr:nano:cpu=atmega328

雖然可解, 但我還是不知道出了什麼事?而且同樣的指令在其他機器上是可以正常運作的。

附記:使用上述方法正常編譯後, 再把 CPU 參數去掉, 就恢復正常了, 我還是不知道出了什麼事?

星期五, 9月 29, 2017

Visual Studio Code 中文字型設定

在 Visual Studio Code 中, 若沒有特別設定, 中文字會採用預設的新細明體, 如果想要更改設定, 必須更改設定中的 editor.fontFamily 項目, 例如:



 就會設定英文使用 Consolas, 中文使用思源等寬黑體。

星期日, 9月 03, 2017

在 Windows 10 安裝 .NET Framework

Windows 10 不允許直接執行離線版本的 .NET Framework 安裝程式, 如果要安裝 .NET Framework, 只能透過 Windows Update 或是使用部署映像服務與管理工具, 前者就是到『Windows 功能』(可從『控制台/應用程式與功能/程式與功能/開啟或關閉 Windows 功能』或直接搜尋『Windows 功能』) 中啟用 .NET Framework:
不過這種方式我常遇到會因為未知原因安裝失敗, 所以只好採取第二種方式。利用部署映象服務與管理工具安裝 .NET Framework 需要 Windows 10 原始光碟, 不過其實它真正需要的是光碟上 \sources\sxs 資料夾下的 microsoft-windows-netfx3-ondemand-package.cab 檔案, 如果你要安裝的機器沒有光碟機, 也可以將這個檔案複製到隨身碟, 即可依照相同的步驟安裝。

安裝的方式需要以管理員身份開啟命令提示字元, 下達 "dism /online /enable-feature /featurename:netfx3 /All /LimitAccess /Source:檔案路徑" 指令, 這裡的檔案路徑指的就是 microsoft-windows-netfx3-ondemand-package.cab 檔案的所在位置, 例如我將檔案複製到隨身碟的根資料夾下, 而隨身碟的磁碟代號為 d 時, 執行範例如下:

等待進度完成即可。

或者可以參考台南市大橋國小王聖閔老師製作的文章, 相關檔案也都有提供下載。

星期四, 8月 10, 2017

使用 Arduino 程式庫讀取新版 DHT11 溫濕度模組出錯的原因

DHT11 是許多人都用過的溫濕度模組, 不過在 2017 年 3 月時 DHT11 開始供給新版本的模組, 舊版模組就停產了。新版模組可說是功能加強版, 可偵測的範圍變大, 而且溫度也可以提供到小數 1 位。不過就是因為這小數 1 位, 如果您是使用 Arduino Playground 的程式庫讀取溫濕度, 遇到新版的 DHT11 模組就會發生校驗不正確, 幾乎無法讀取溫濕度的情況。

會出現這樣的問題, 主要是因為從 DHT11 讀取到的資料共 5 個位元組, 依序是相對濕度的整數部分、小數部分, 攝氏溫度的整數部分、小數部分, 以及由前面這 4 個位元組相加所得到的校驗值, 在程式庫中就是 bits[0]~bits[4]。不過由於舊版 DHT11 的濕度與溫度精確度都只到整數, 不會有小數, 也就是 bit[1] 和 bit[3] 永遠為 0, 所以程式庫中計算校驗值時就偷懶的只把 bit[0] 和 bit[2] 相加, 如以下所示:


當遇到溫度有小數部分時, 上列程式最後一行的校驗值檢查就一定不相等, 所以就無法正確讀取溫濕度了。要解決這個問題很簡單, 只要在計算校驗值時乖乖的把 4 個位元組相加就可以了:


雖然市面上可能還有為數不少的舊版模組, 不過我自己最近買到的就是新版的模組, 還差點因為這個問題以為買到了瑕疵品。大家可以先修改程式庫, 這樣不論新舊版模組都不會有問題。

星期六, 7月 08, 2017

製作給 Arduino PCM 程式庫使用的聲音資料

使用 Arduino PCM 程式庫需要一個儲存聲音數位化後的資料陣列, 這個陣列的內容就是以 8KHz 頻率取樣的樣本, 為了讓你自己的聲音檔可以轉換成此陣列格式, 可以合用兩個工具:AudacityEncodeAudio (這個網頁有 Mac OS 和 Linux 版), Audacity 可以把音樂檔轉成 8KHz 單聲道, 而 EncodeAudio 可以把轉好的聲音檔案轉成所需的資料陣列。

首先使用 Audacity 匯入原始的聲音檔, 然後改成單聲道:
再從左下角將取樣頻率改為 8000, 也就是 8KHz:
之後就可以匯出聲音檔案:
儲存時存檔類型請選『WAV 16-bit PCM』
接著請執行 EncodeAudio, 指定要使用的聲音檔案:
轉換完成它會把資料複製到剪貼簿中:
接著用編輯器開啟使用 PCM 程式庫的檔案, 把其中的聲音資料陣列內容換掉就可以了: