Arduino, 用了 lcd.print 或 serial.write, 突然就出問題


很多人都有類似的經驗, 也很多人不明白原因

每個程序都是一點點構建起來的, ARDUINO 的 SKETCH 也是一樣, 當你抄寫了一個基本的 SKETCH, 然後慢慢修改, 增加需要的功能, 多加一些字串的輸出, 突然有一天, 你會發現加多一些字串後, 之前好好的程序, 突然就跑飛了.

比較細心的玩家, 會嚐試恢復沒加油添醋時的程序版本, 然後像是發現新大陸般, 慶幸還可以繼續用原來的程序工作, 但是無法添加想要的東西了, 因為一加上去就程序跑飛, 原因不明.

比較粗心的玩家, 就不知道該如何是好, 只會埋怨沒辦法, 或不知道問題出在哪, 然後放棄, 一般很多人和小朋友很類似, 既然解決不了, 放棄它找別的玩.

更多的玩家, 就聽從別人的誤傳, 再買更高級的產品, 希望 RAM 越多越好, FLASH 越大越好, 但是很快又有機會重蹈覆轍.

那到底問題出在哪裡呢? 其是, 用 ARDUINO 是不會了解真正的原因, 因為層次不同, 並沒有機會接觸到 MCU 真正的解構和理解它固有的限制.

原理就不多說, 但主要是 ARDUINO IDE 的設計, 會把字串之類的常數, 優化後, 留一並只存在 FLASH 中, 需要用的時候, 會先複製到 RAM 中再來處理, 所以, 每個和 print 有關的語句, 都要用到更多的 RAM, 累積下來, 多幾個 print 的呼叫, 突然就會使 RAM 耗盡, 但是並沒有警示或檢查, 所以玩家就會不明不白地陷入混亂.

解決的方法,


//如果原來是這句, 字串會存在 FLASH,
//用到才複製到 RAM 作進一步處理

lcd.print("hello, xiaolaba 2014-02-24");

.

//把它的字串包在 F() 當中, 字串也會存在 FLASH,
//但是需要用很多次的話, 大略也只會一次性複製到RAM,
//相對的呼叫時不需動更多的RAM

lcd.print(F("hello, xiaolaba 2014-02-24"));

比較表, F() 使用和不用 F()

string bytes
hello, xiaolaba 2014-02-24 26
4 more 104
function call sketch size
F() call 2664
standard call 2600
64 difference
standard call x 5 2646
F() call x5 2812
166 difference

.

.

網上有人寫了比較多的資料, 不再熬述

http://www.baldengineer.com/blog/2013/11/20/arduino-f-macro/

http://www.forward.com.au/pfod/ArduinoProgramming/index.html#What%20fails%20when%20you%20add%20lots%20of%20Strings%20to%20your%20Arduino%20program.|outline

廣告

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s