highlight.js

星期一, 11月 27, 2017

ESP8266 Arduino Core 中 ctype.h 內預先定義的常數

我在編譯 ESP8266 的 Arduino 程式時, 遇到一個莫名其妙的事情, 底下這行程式碼一直遇到編譯錯誤:
    double _N;        //-- Number of samples
錯誤訊息如下:
expected unqualified-id before numeric constant 
想說, 奇怪, 這裡哪來的數值常數?找了一下才發現, 原來 ESP8266 Arduino Core 中 ctype.h 定義了 _N 為 04, 如下:
#define  _U  01
#define _L  02
#define _N  04
#define _S  010
#define _P  020
#define _C  040
#define _X  0100
#define _B  0200
所以如果你的程式中使用到了 _N, 就會變前處理器取代成 04, 我的那一行程式就變成:
    double 04;        //-- Number of samples
自然無法編譯成功了。要注意的是, 除了我碰到的 _N 外, 還有許多已經被 ctype.h 事先定義的名稱, 如果你遇到的奇怪的編譯結果, 可以到原始碼找看看, 可能你也跟我一樣遇到類似的情況, 解決的方法最簡單的就是更改自己的程式變數名稱, 避免和 ESP8266 Arduino Core 中的名稱衝突。

星期五, 11月 17, 2017

ESP8266 的 EEPROM 注意事項

在 ESP8266上使用 EEPROM 要注意兩件事, 首先是必須叫用 EEPROM.begin(), 並指定要使用的 EEPROM 區域大小:
  EEPROM.begin(sizeof(int) * 4);
其次, 寫入 EEPROM 的操作必須叫用 EEPROM.commit() 才會真的儲存下來:
  EEPROM.commit();
這是和 Arduino 不同的地方。如果同一個程式希望在 Arduino 和 ESP8266 上都能編譯,可以使用 ESP8266 Arduino Core 在前處理器上定義的名稱 ESP8266 來做條件式編譯, 例如:
  #ifdef ESP8266
  EEPROM.commit();
  #endif
這樣就只會在編譯 ESP8266程式時叫用 commit(), 若式編譯 Arduino 程式時, 這一行就不會生效了。

星期四, 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 時, 執行範例如下:

等待進度完成即可。

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