Semorphe

記住設定

拔掉電源,它還記得。 · ⏱ 約 25 分鐘

你會學到三件事

  1. 變數在斷電時全部消失,而 EEPROM 不會
  2. EEPROM.read / EEPROM.write 用位址存取
  3. EEPROM 有寫入次數上限,所以不能一直寫

開始之前

到目前為止,你的板子每次開機都失憶。

第 10 課的 state、第 5 課校正出來的範圍、第 11 課的 WiFi 密碼—— 拔掉電源就沒了。

這一課給它一本永遠不會被擦掉的筆記本。

🟢 先把編輯器打開,跟著下面一起做:跟著做

一、變數住在哪

斷電之後
一般變數(RAM) 消失
程式碼(Flash) 留著,而程式跑的時候改不了
EEPROM 留著,而且改得了 ← 這一課

Arduino Uno 有 1024 個位元組的 EEPROM。不多,而夠記設定。

二、用位址存取

EEPROM 是一格一格的,用編號存取:

1int n = EEPROM.read(0);      // 讀第 0 格2EEPROM.write(0, n + 1);      // 寫回第 0 格
0從內建記憶體位址讀一個位元組0變數n1+把寫進內建記憶體位址宣告int(整數)變數n=使用命名空間std引入函式庫EEPROM.h12

⚠️ 它不是變數,是一排格子,你要自己記得「第 0 格放的是什麼」。

積木盤上這兩顆寫著「從內建記憶體位址 … 讀一個位元組」 與「把 … 寫進內建記憶體位址 …」。

位址   0    1    2    3   ...  1023
內容  [ ]  [ ]  [ ]  [ ]       [ ]

⚠️ 每一格只裝得下 0~255(一個位元組)。

想存一個大一點的數字要拆成好幾格,或用 EEPROM.put() / EEPROM.get() (它們會自己處理多格)。

⚠️ 從來沒寫過的格子讀出來是 255,不是 0。 所以「第一次開機」要有辦法分辨,常見做法是在某一格放一個約定好的記號。

三、⚠️ 它會壞

EEPROM 的每一格大約可以寫 10 萬次。聽起來很多,而:

下面這個寫法不要學,它會把那一格寫爛:

🚫 這一段是反例——課文在說不要這樣寫,別照著拉。

1void loop() {2    EEPROM.write(0, n);      // 🔴 千萬不要這樣3}
0變數n把寫進內建記憶體位址定義函式 回傳型別void(無回傳)loop使用命名空間std引入函式庫EEPROM.h12

loop 一秒跑幾萬次,這樣寫的話,那一格幾秒鐘就報廢了。

EEPROM 是給「設定」用的,不是給「狀態」用的。

判準:這個值多久變一次? 一秒好幾次 → 不要寫進去。 使用者調整一次才變 → 可以。

EEPROM.update() 比 write() 好:值沒變的話它不寫。

四、開機計數器

照著打上這一段——它會記得自己開機過幾次:

1void setup() {2    Serial.begin(9600);3    int n = EEPROM.read(0);4    Serial.println(n);5    EEPROM.write(0, n + 1);6}
96000從內建記憶體位址讀一個位元組變數n0變數n1+把寫進內建記憶體位址序列埠輸出小數位數並換行宣告int(整數)變數n=開啟序列埠 傳輸速率定義函式 回傳型別void(無回傳)setup使用命名空間std引入函式庫EEPROM.h12345

每次開機印出「這是第幾次開機」,然後加一存回去。

⚠️ 到 255 之後會繞回 0,因為一格只有一個位元組。這不是錯誤,是它的容量。

完成的樣子

這一課的參考做法——程式碼每一行的號碼,就印在對應的那塊積木上。

1#include <EEPROM.h>2using namespace std;3void setup() {4    Serial.begin(9600);5    int n = EEPROM.read(0);6    Serial.println(n);7    EEPROM.write(0, n + 1);8}9 10void loop() {11}
96000從內建記憶體位址讀一個位元組變數n0變數n1+把寫進內建記憶體位址序列埠輸出小數位數並換行宣告int(整數)變數n=開啟序列埠 傳輸速率定義函式 回傳型別void(無回傳)loop定義函式 回傳型別void(無回傳)setup使用命名空間std引入函式庫EEPROM.h123410567

換你了

把第 5 課校正出來的最暗/最亮值存進 EEPROM,開機時讀回來。

⚠️ 而它們可能超過 255——想一下怎麼處理。 (提示:analogRead 最大 1023,除以 4 就塞得進一格,代價是精度。 或者用兩格。或者用 EEPROM.put()。)

到編輯器做這一題:練習:把校正值存進 EEPROM,開機讀回來

做一個

每次開機,把開機次數加一存進 EEPROM,並印出來。

🔴 第一次開機的時候,EEPROM 裡是什麼?不是 0,是上一個人留下的東西, 或者出廠的 255。你要怎麼分辨「沒存過」和「存過 255 次」? ⚠️ 這一課說 EEPROM 有寫入次數上限,每次開機寫一次會不會用完?算一下。

到編輯器做這一題:做一個:這塊板子開機過幾次

這一課你做了什麼

如果卡住了

你看到 多半是因為
第一次讀到 255 正常。從來沒寫過的格子就是 255
值到 255 就繞回 0 一格只有一個位元組。要更大就用多格或 put()
存進去的大數字讀出來不對 超過 255 被截斷了
用久了那一格壞掉 寫太頻繁了。改用 update(),而且不要放進 loop
在編輯器打開這一課 →