ESP32 Đọc Config từ Thẻ SD

Trong hướng dẫn này, chúng ta sẽ tìm hiểu sâu về việc sử dụng file config trên thẻ Micro SD Card. Hướng dẫn sẽ bao gồm các khía cạnh sau:

Hướng dẫn này giúp bạn quản lý các cài đặt cấu hình thông qua một file được lưu trữ trên thẻ Micro SD Card, mang lại tính linh hoạt cho nhiều kiểu dữ liệu khác nhau như integer, float và string.

ESP32 micro thẻ SD config file

Linh Kiện Cần Thiết

1×mô-đun phát triển ESP-WROOM-32
1×Alternatively, ESP32 Uno-form board
1×Alternatively, ESP32 S3 Uno-form board
1×Cáp USB Type-C
1×Thẻ Micro SD
1×Module Thẻ Micro SD
1×Dây Jumper
1×Đầu Đọc Thẻ SD USB 3.0
1×(Khuyến nghị) Screw Terminal Expansion Board for ESP32
1×(Khuyến nghị) Breakout Expansion Board for ESP32
1×(Khuyến nghị) Power Splitter for ESP32

Or you can buy the following kits:

1×DIYables ESP32 Starter Kit (ESP32 included)
1×DIYables Sensor Kit (30 sensors/displays)
1×DIYables Sensor Kit (18 sensors/displays)

Về Module Thẻ Micro SD

Chưa quen thuộc với Module Thẻ Micro SD, bao gồm pinout, chức năng và lập trình? Hãy tìm hiểu về chúng trong hướng dẫn ESP32 - Micro SD Card.

Cách Hoạt Động

Các cặp key-value được lưu trữ trước trên thẻ Micro SD Card theo định dạng sau:

  • Mỗi cặp key-value nằm trên một dòng. Nói cách khác, mỗi cặp key-value được ngăn cách với các cặp khác bằng ký tự xuống dòng
  • Key và value được ngăn cách bằng ký tự =

Code ESP32 sẽ tìm kiếm key và tìm giá trị tương ứng, rồi lưu giá trị đó vào một biến. Kiểu biến có thể là int, float, hoặc String

Sơ Đồ Đấu Nối

ESP32 micro thẻ SD module sơ đồ đấu dây

This image is created using Fritzing. Click to enlarge image

Nếu bạn chưa rõ cách cấp nguồn cho ESP32 và các linh kiện khác, xem: Cách Cung Cấp Nguồn Điện Cho ESP32.

※ Lưu ý:

Nếu bạn sử dụng Ethernet shield hoặc bất kỳ shield nào có khe cắm thẻ Micro SD, bạn không cần sử dụng Module Thẻ Micro SD. Bạn chỉ cần chèn thẻ Micro SD vào khe cắm trên shield.

Cách Đọc Config Vào Biến

  • Tạo file config.txt trên PC của bạn bằng Notepad hoặc Notepad++
  • Copy các cặp key-value dưới đây và paste vào file config.txt:
myString_1=Hello myString_2=newbiely.com myInt_1=2 myInt_2=-105 myFloat_1=0.74 myFloat_2=-46.08
  • Kết nối thẻ Micro SD với PC qua đầu đọc thẻ SD USB 3.0
  • Đảm bảo rằng thẻ Micro SD được định dạng FAT16 hoặc FAT32 (Google để tìm hiểu thêm)
  • Copy file config.txt vào thư mục gốc của thẻ Micro SD
  • Ngắt kết nối thẻ Micro SD khỏi PC
  • Kết nối thẻ Micro SD với ESP32 qua Module Thẻ Micro SD theo sơ đồ đấu nối ở trên
  • Copy code dưới đây và mở bằng Arduino IDE
/* * Mã ESP32 này được phát triển bởi newbiely.vn * Mã ESP32 này được cung cấp để sử dụng công khai, không có ràng buộc. * Để xem hướng dẫn chi tiết và sơ đồ kết nối, vui lòng truy cập: * https://newbiely.vn/tutorials/esp32/esp32-read-config-from-sd-card */ #include <SD.h> #define PIN_SPI_CS 5 // The ESP32 pin GPIO5 #define FILE_NAME "/config.txt" #define KEY_MAX_LENGTH 30 // change it if key is longer #define VALUE_MAX_LENGTH 30 // change it if value is longer // variables int myInt_1; int myInt_2; float myFloat_1; float myFloat_2; String myString_1; String myString_2; void setup() { Serial.begin(9600); if (!SD.begin(PIN_SPI_CS)) { while (1) { Serial.println(F("SD CARD FAILED, OR NOT PRESENT!")); delay(1000); } } Serial.println(F("SD Card initialized.")); myInt_1 = SD_findInt(F("myInt_1")); myInt_2 = SD_findInt(F("myInt_2")); myFloat_1 = SD_findFloat(F("myFloat_1")); myFloat_2 = SD_findFloat(F("myFloat_2")); myString_1 = SD_findString(F("myString_1")); myString_2 = SD_findString(F("myString_2")); Serial.print(F("myInt_1 = ")); Serial.println(myInt_1); Serial.print(F("myInt_2 = ")); Serial.println(myInt_2); Serial.print(F("myFloat_1 = ")); Serial.println(myFloat_1); Serial.print(F("myFloat_2 = ")); Serial.println(myFloat_2); Serial.print(F("myString_1 = ")); Serial.println(myString_1); Serial.print(F("myString_2 = ")); Serial.println(myString_2); } void loop() { } bool SD_available(const __FlashStringHelper * key) { char value_string[VALUE_MAX_LENGTH]; int value_length = SD_findKey(key, value_string); return value_length > 0; } int SD_findInt(const __FlashStringHelper * key) { char value_string[VALUE_MAX_LENGTH]; int value_length = SD_findKey(key, value_string); return HELPER_ascii2Int(value_string, value_length); } float SD_findFloat(const __FlashStringHelper * key) { char value_string[VALUE_MAX_LENGTH]; int value_length = SD_findKey(key, value_string); return HELPER_ascii2Float(value_string, value_length); } String SD_findString(const __FlashStringHelper * key) { char value_string[VALUE_MAX_LENGTH]; int value_length = SD_findKey(key, value_string); return HELPER_ascii2String(value_string, value_length); } int SD_findKey(const __FlashStringHelper * key, char * value) { File configFile = SD.open(FILE_NAME); if (!configFile) { Serial.print(F("SD Card: Issue encountered while attempting to open the file ")); Serial.println(FILE_NAME); return; } char key_string[KEY_MAX_LENGTH]; char SD_buffer[KEY_MAX_LENGTH + VALUE_MAX_LENGTH + 1]; // 1 is = character int key_length = 0; int value_length = 0; // Flash string to string PGM_P keyPoiter; keyPoiter = reinterpret_cast<PGM_P>(key); byte ch; do { ch = pgm_read_byte(keyPoiter++); if (ch != 0) key_string[key_length++] = ch; } while (ch != 0); // check line by line while (configFile.available()) { int buffer_length = configFile.readBytesUntil('\n', SD_buffer, 100); if (SD_buffer[buffer_length - 1] == '\r') buffer_length--; // trim the \r if (buffer_length > (key_length + 1)) { // 1 is = character if (memcmp(SD_buffer, key_string, key_length) == 0) { // equal if (SD_buffer[key_length] == '=') { value_length = buffer_length - key_length - 1; memcpy(value, SD_buffer + key_length + 1, value_length); break; } } } } configFile.close(); // close the file return value_length; } int HELPER_ascii2Int(char *ascii, int length) { int sign = 1; int number = 0; for (int i = 0; i < length; i++) { char c = *(ascii + i); if (i == 0 && c == '-') sign = -1; else { if (c >= '0' && c <= '9') number = number * 10 + (c - '0'); } } return number * sign; } float HELPER_ascii2Float(char *ascii, int length) { int sign = 1; int decimalPlace = 0; float number = 0; float decimal = 0; for (int i = 0; i < length; i++) { char c = *(ascii + i); if (i == 0 && c == '-') sign = -1; else { if (c == '.') decimalPlace = 1; else if (c >= '0' && c <= '9') { if (!decimalPlace) number = number * 10 + (c - '0'); else { decimal += ((float)(c - '0') / pow(10.0, decimalPlace)); decimalPlace++; } } } } return (number + decimal) * sign; } String HELPER_ascii2String(char *ascii, int length) { String str; str.reserve(length); str = ""; for (int i = 0; i < length; i++) { char c = *(ascii + i); str += String(c); } return str; }
  • Click nút Upload trên Arduino IDE để upload code lên ESP32
  • Xem kết quả trên Serial Monitor.
COM6
Send
SD Card initialized. myInt_1 = 2 myInt_2 = -105 myFloat_1 = 0.74 myFloat_2 = -46.08 myString_1 = Hello myString_2 = newbiely.com
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  
  • Serial Monitor hiển thị các giá trị từ biến giống hệt với các giá trị được lưu trên thẻ micro SD

Bây giờ bạn có thể chỉnh sửa code để thêm nhiều biến hơn.

※ Lưu ý:

Code trên không quan tâm đến thứ tự của các cặp key-value. Nó sẽ tìm kiếm key từ đầu đến cuối file cho đến khi key được khớp.

Video Tutorial

Việc sản xuất video tốn rất nhiều thời gian. Nếu video hướng dẫn hữu ích cho việc học của bạn, hãy đăng ký kênh YouTube để ủng hộ. Nếu nhu cầu đủ cao, chúng tôi sẽ cố gắng làm thêm nhiều video.

Bình Luận