ESP32 บันทึกและเรียกค่าจาก Preferences เช่น ชื่ออุปกรณ์และความชื้นเป้าหมาย ใช้ในระบบ Smart Farm

ESP32 Preferences – บันทึกค่าการตั้งค่าแบบถาวร

เก็บค่าการตั้งค่า ESP32 แบบถาวรด้วย Preferences

บทนำ:

Preferences คืออะไร?

Preferences เป็นคลาสที่อยู่ใน Arduino Core for ESP32 ใช้สำหรับ จัดเก็บข้อมูลถาวร (non-volatile storage) ลงในหน่วยความจำแฟลชของบอร์ด โดยข้อมูลจะ ไม่หายแม้ปิดไฟ เหมาะกับการเก็บค่าการตั้งค่าต่าง ๆ เช่น:

  • ค่าคอนฟิกอุปกรณ์ (เช่น ตั้งเวลาเปิด/ปิดอัตโนมัติ)

  • ค่าเซตพ้อยต์อุณหภูมิ

  • ค่ารหัส Wi-Fi

  • สถานะอุปกรณ์ล่าสุด

แล้วมันต่างจาก EEPROM ยังไง?

แม้ Preferences และ EEPROM จะใช้เก็บข้อมูลถาวรเหมือนกัน แต่มีความแตกต่างหลัก ๆ ดังนี้:

จุดเปรียบเทียบPreferencesEEPROM
รองรับหลาย key✅ ใช้ key เป็นชื่อแยกแต่ละค่า❌ ใช้เป็น byte address
ใช้งานง่ายกว่า✅ ใช้ฟังก์ชัน putString(), getInt() ฯลฯ❌ ต้องกำหนด byte address เอง
มีระบบ namespace✅ จัดกลุ่มข้อมูลได้❌ ไม่มีระบบจัดกลุ่ม
ความปลอดภัยข้อมูล✅ มีระบบ commit อัตโนมัติ❌ ต้องระวังเขียนทับ address

 

ดังนั้นหากคุณใช้ ESP32 ไม่จำเป็นต้องย้อนกลับไปใช้ EEPROM เลย เพราะ Preferences ถูกออกแบบมาให้ใช้งานได้สะดวกและปลอดภัยกว่าโดยตรง

ทำไมต้องใช้ Preferences กับ ESP32?

เหตุผลที่ควรใช้ Preferences มีหลายข้อ โดยเฉพาะในการสร้างระบบ Smart Farm หรือ IoT เช่นระบบ PoPo ที่ต้อง:

✅ จำค่าตั้งเวลาอุปกรณ์ (เช่น เปิดพัดลมเวลา 10:00 น.)

✅ จำค่า Wi-Fi ที่ผู้ใช้ป้อน (เพื่อเชื่อมต่ออัตโนมัติเมื่อรีสตาร์ท)

✅ เก็บสถานะ “เปิด/ปิดอัตโนมัติ” หรือโหมดต่าง ๆ

✅ ทำให้ระบบ รีสตาร์ทแล้วทำงานต่อได้ทันที โดยไม่ต้องตั้งค่าใหม่ทุกครั้ง


โดยรวมแล้ว Preferences คือเครื่องมือสำคัญที่ช่วยให้ ESP32 กลายเป็นอุปกรณ์อัจฉริยะที่ “จำได้” และ “ทำต่อ” ได้แม้ไฟดับหรือบอร์ดรีสตาร์ท

เริ่มต้นใช้งาน Preferences บน ESP32

หลังจากรู้แล้วว่า Preferences คืออะไรและทำไมถึงควรใช้ มาดูวิธีเริ่มต้นใช้งานกันเลยครับ ง่าย ๆ ไม่กี่บรรทัดก็ใช้ได้แล้ว

1. การ import ไลบรารี Preferences.h

ก่อนอื่นต้อง include ไลบรารีนี้เข้าไปในโค้ดของเราก่อนครับ
#include

2. การประกาศตัวแปร Preferences และเริ่มต้นใช้งาน

Preferences prefs; // ประกาศตัวแปร prefs สำหรับเรียกใช้งาน
ในการเริ่มใช้งาน ต้องเรียก prefs.begin() ก่อน โดยมีรูปแบบดังนี้:
prefs.begin("my-app", false);
พารามิเตอร์อธิบาย
"my-app"ชื่อ namespace ใช้แยกกลุ่มข้อมูล
falseถ้า false = อ่าน/เขียน, ถ้า true = อ่านอย่างเดียว

3. การเก็บค่า (put) และเรียกคืนค่า (get)

Preferences รองรับหลายประเภทข้อมูล เช่น int, float, String ตัวอย่างเช่น เราอยากเก็บค่าอุณหภูมิตั้งต้นไว้:
// บันทึกค่า
prefs.putFloat("tempSet", 25.5);

// อ่านค่า
float temp = prefs.getFloat("tempSet", 0.0); // ถ้าไม่มีค่าให้ใช้ 0.0 แทน
หรือถ้าเป็นข้อความ:
prefs.putString("wifiPass", "12345678");

String pass = prefs.getString("wifiPass", "defaultpass");
✅ Tip: อย่าลืมปิดเมื่อใช้เสร็จ เพื่อเคลียร์หน่วยความจำ
prefs.end();
 

สรุปโครงสร้างแบบสั้น ๆ

#include <Preferences.h>
Preferences prefs;

void setup() {
  Serial.begin(115200);
  prefs.begin("my-app", false);          // เริ่มใช้งาน Preferences
  prefs.putInt("count", 10);             // บันทึกค่า
  int value = prefs.getInt("count", 0);  // ดึงค่ากลับมา
  Serial.println(value);
  prefs.end();                           // ปิดการใช้งาน
}

ตัวอย่างการใช้งาน Preferences บน ESP32

การใช้ Preferences ช่วยให้บอร์ด ESP32 “จำค่าเดิมได้” แม้จะปิดไฟหรือรีเซ็ตไปแล้ว โดยเฉพาะในระบบ Smart Farm ที่ต้องเก็บค่า config ต่าง ๆ ของผู้ใช้ไว้ให้พร้อมใช้งานทุกครั้งที่เปิดเครื่อง

✅ 1. เก็บ ชื่ออุปกรณ์ ที่ผู้ใช้ตั้งเอง
#include <Preferences.h>
Preferences prefs;

void saveDeviceName(String name) {
  prefs.begin("config", false);
  prefs.putString("deviceName", name);
  prefs.end();
}

String loadDeviceName() {
  prefs.begin("config", true);
  String name = prefs.getString("deviceName", "MyESP32");
  prefs.end();
  return name;
}
 🔧 ใช้ในระบบ PoPo เพื่อแสดงชื่ออุปกรณ์ในหน้าแอป เช่น “พัดลมโรงเรือน”, “แสงสว่างโซน A”
✅ 2. เก็บค่า เซ็ตพอยต์ความชื้น (Humidity Setpoint)
void saveHumiditySetpoint(float humidity) {
  prefs.begin("config", false);
  prefs.putFloat("humSet", humidity);
  prefs.end();
}

float loadHumiditySetpoint() {
  prefs.begin("config", true);
  float humidity = prefs.getFloat("humSet", 50.0); // ค่า default = 50%
  prefs.end();
  return humidity;
}
📌 นำไปใช้เปรียบเทียบกับค่าความชื้นจริง ถ้าต่ำกว่าก็เปิดปั๊มน้ำอัตโนมัติ
✅ 3. 3. เก็บค่า WiFi SSID/Password แบบปลอดภัย
void saveWiFiConfig(String ssid, String password) {
  prefs.begin("wifi", false);
  prefs.putString("ssid", ssid);
  prefs.putString("pass", password);
  prefs.end();
}

void loadWiFiConfig(String &ssid, String &password) {
  prefs.begin("wifi", true);
  ssid = prefs.getString("ssid", "");
  password = prefs.getString("pass", "");
  prefs.end();
}
🔐 ข้อมูล SSID และรหัสผ่านจะถูกเก็บในหน่วยความจำแฟลช ไม่หลุดหายเมื่อรีสตาร์ท และไม่ต้องใส่ใหม่ทุกครั้ง
การใช้งานKeyNamespaceประเภทข้อมูล
ชื่ออุปกรณ์"deviceName""config"String
Setpoint ความชื้น"humSet""config"float
WiFi SSID/Pass"ssid", "pass""wifi"String
Preferences_esp32_becareful

ข้อควรระวังและแนวทางที่ดีเมื่อใช้ Preferences กับ ESP32

แม้ว่า Preferences จะใช้ง่ายและสะดวกมาก แต่ก็มีข้อควรระวังที่สำคัญ และแนวทางดี ๆ ที่ช่วยให้ระบบของคุณทำงานได้ยาวนานและมีระเบียบมากขึ้น

⚠️ 1. อย่าเขียนข้อมูลถี่เกินไป (Flash Wear)

หน่วยความจำ Flash ของ ESP32 มี อายุจำกัด ประมาณ 10,000 – 100,000 ครั้งในการเขียนต่อ 1 บล็อก

🔥 ถ้าคุณ prefs.putXXX() บ่อย ๆ เช่น ทุกวินาที หรือทุกครั้งที่มีเซนเซอร์เปลี่ยนค่า = Flash เสื่อมไวแน่นอน

แนวทางที่ดี:

  • เขียนเมื่อจำเป็น เช่น เมื่อผู้ใช้กด “บันทึก” ในแอป

  • หลีกเลี่ยงเขียนใน loop()

  • ตั้ง flag ว่า “ข้อมูลเปลี่ยนแล้ว” ค่อยเขียน

bool needToSave = false;
if (humiditySetpointChanged) {
  needToSave = true;
}

if (needToSave) {
  prefs.begin("config", false);
  prefs.putFloat("humSet", newHumidity);
  prefs.end();
  needToSave = false;
}

📁 2. แยก namespace ตามหมวดหมู่ (เพื่อความเป็นระเบียบ)

Preferences รองรับ namespace ให้คุณจัดกลุ่มข้อมูลได้ เช่น:
prefs.begin("config", false); // สำหรับค่าเซ็ตพอยต์
prefs.begin("wifi", false); // สำหรับ WiFi SSID/Password
prefs.begin("user", false); // สำหรับชื่ออุปกรณ์
✅ ทำให้โค้ดอ่านง่าย แก้ไขง่าย และไม่ชนกันเวลาโปรเจกต์ใหญ่ขึ้น

🧠 3. เคล็ดลับการ Debug ค่าที่เก็บไว้

วิธีดูค่าทั้งหมดที่เก็บไว้ใน namespace:
Preferences prefs;
prefs.begin("config", true);

Serial.println(prefs.getFloat("humSet", 0));
Serial.println(prefs.getInt("timerHour", 0));
Serial.println(prefs.getBool("autoMode", false));

prefs.end();
🔎 อย่าลืมใส่ค่า default เผื่อในกรณีที่ยังไม่เคยบันทึกค่าลบค่าที่เคยเก็บไว้ (สำหรับ reset หรือ debug):
prefs.begin("config", false);
prefs.clear(); // ลบทุก key ใน namespace นี้
prefs.end();

🎯 สรุปแนวทางที่ดี:

แนวทางอธิบาย
เขียนข้อมูลเฉพาะเมื่อจำเป็นลดการสึกหรอของ Flash
แยก namespace ชัดเจนทำให้โค้ดดูแลง่าย
ใส่ default value เสมอกันโค้ดพังเมื่อยังไม่มีข้อมูล
ใช้ clear() สำหรับ debugล้างค่าเพื่อลองใหม่ได้เร็ว

“หากยังไม่รู้จัก ESPAsyncWebServer มาก่อน แนะนำให้อ่านคู่มือฉบับเต็มก่อนใช้งานจริง”
🔗 ESPAsyncWebServer Guide

ตัวอย่างโค้ดเต็ม: การใช้งาน Preferences เก็บค่าและเรียกคืนค่า

 

🎯 เป้าหมายของโค้ด

  • บันทึกชื่ออุปกรณ์

  • บันทึกค่า Setpoint ความชื้น

  • โหลดค่าทั้งสองจาก Flash เมื่อบอร์ดเปิดใหม่

#include <Preferences.h> //  โหลดไลบรารี Preferences
Preferences prefs; //  สร้างตัวแปร prefs เพื่อใช้งาน

String deviceName; //  ตัวแปรเก็บชื่ออุปกรณ์
float humiditySetpoint; //  ตัวแปรเก็บค่าเซ็ตพอยต์ความชื้น

void setup() {
Serial.begin(115200); //  เปิด Serial Monitor สำหรับดูผล

//  เริ่มต้นใช้งาน Preferences ใน namespace "config"
prefs.begin("config", false); // false = อนุญาตให้อ่าน/เขียน

//  ดึงค่าจาก Flash หากเคยบันทึกไว้, ถ้าไม่เคย จะใช้ค่าตั้งต้น
deviceName = prefs.getString("devName", "MyDevice"); // default: MyDevice
humiditySetpoint = prefs.getFloat("humSet", 50.0); // default: 50%

//  แสดงค่าที่โหลดมา
Serial.println("ชื่ออุปกรณ์: " + deviceName);
Serial.print("เซ็ตพอยต์ความชื้น: ");
Serial.println(humiditySetpoint);

prefs.end(); //  ปิด Preferences เมื่อใช้งานเสร็จ
}

void loop() {
// ตัวอย่าง: ถ้าผู้ใช้ส่งค่ามา (เช่นจาก Serial หรือแอป)
// เราจะจำลองการบันทึกค่าใหม่
delay(10000); // รอ 10 วินาที (จำลองว่าเกิด event)

//  บันทึกค่าชื่อใหม่และค่าเซ็ตพอยต์ใหม่
deviceName = "FAN_ZONE_A";
humiditySetpoint = 60.5;

prefs.begin("config", false);
prefs.putString("devName", deviceName);
prefs.putFloat("humSet", humiditySetpoint);
prefs.end();

Serial.println("บันทึกค่าลง Flash แล้ว");
Serial.println("ชื่ออุปกรณ์ใหม่: " + deviceName);
Serial.print("เซ็ตพอยต์ใหม่: ");
Serial.println(humiditySetpoint);

while (true); // จบ loop เพื่อไม่ให้เขียนซ้ำอีก
}

🔍 คำอธิบายสั้น ๆ:

คำสั่งความหมาย
prefs.begin("config", false);เริ่มใช้งาน namespace ชื่อ “config” (false = เขียนได้)
prefs.getString("devName", "MyDevice")ดึงค่าชื่ออุปกรณ์ ถ้าไม่มีใช้ "MyDevice"
prefs.putFloat("humSet", humiditySetpoint)บันทึกค่า setpoint แบบ float ลง Flash
prefs.end();ปิดการใช้งาน Preferences เพื่อคืนหน่วยความจำ
ESP32 บันทึกและเรียกค่าจาก Preferences เช่น ชื่ออุปกรณ์และความชื้นเป้าหมาย ใช้ในระบบ Smart Farm

✅ สรุป:

  • ใช้งานง่ายมาก แค่ 3 ขั้นตอน: begin → put/get → end

  • ใช้กับทุกโปรเจกต์ที่ต้อง “จำค่า” ได้เลย

  • ปลอดภัยกว่า EEPROM และอ่านง่ายกว่ามาก

หากคุณต้องการสร้างระบบเชื่อมต่อ WiFi แบบไม่ต้องแก้โค้ดทุกครั้ง พร้อมกับบันทึก SSID และรหัสผ่านแบบถาวรด้วย `Preferences` ✅ แนะนำเรียนรู้จากคอร์สเต็ม: 🔗 WiFiManager กับ ESP32 พร้อมใช้ Preferences

✅ FAQ (คำถามที่พบบ่อย)

Q: Preferences ต่างจาก EEPROM ยังไง?
A: Preferences ใช้ NVS (Non-volatile storage) ซึ่งปลอดภัยกว่า จัดการข้อมูลเป็น key-value ใช้ง่ายกว่า EEPROM

Q: เขียนข้อมูลบ่อย ๆ จะทำให้ flash เสื่อมหรือเปล่า?
A: ใช่ครับ แนะนำให้เขียนเฉพาะตอนที่มีการเปลี่ยนค่า ไม่ควรเขียนใน loop บ่อย ๆ

Q: เก็บ password WiFi ด้วย Preferences ปลอดภัยไหม?
A: ปลอดภัยระดับหนึ่งสำหรับงานทั่วไป แต่ไม่ควรใช้กับงานที่ต้องการความปลอดภัยสูงแบบ IoT Cloud

Q: จะลบค่าใน Preferences ต้องทำยังไง?
A: ใช้ preferences.remove("key_name") หรือลบทั้งหมดด้วย preferences.clear()

Shopping Cart
Scroll to Top