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:
Lưu file config.txt trên thẻ Micro SD Card, bao gồm các cặp key-value.
Đọc cấu hình từ thẻ Micro SD Card và lưu trữ vào biến int.
Đọc cấu hình từ thẻ Micro SD Card và lưu trữ vào biến float.
Đọc cấu hình từ thẻ Micro SD Card và lưu trữ vào biến String.
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.
| 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) | | |
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á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

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.
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
#include <SD.h>
#define PIN_SPI_CS 5
#define FILE_NAME "/config.txt"
#define KEY_MAX_LENGTH 30
#define VALUE_MAX_LENGTH 30
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];
int key_length = 0;
int value_length = 0;
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);
while (configFile.available()) {
int buffer_length = configFile.readBytesUntil('\n', SD_buffer, 100);
if (SD_buffer[buffer_length - 1] == '\r')
buffer_length--;
if (buffer_length > (key_length + 1)) {
if (memcmp(SD_buffer, key_string, key_length) == 0) {
if (SD_buffer[key_length] == '=') {
value_length = buffer_length - key_length - 1;
memcpy(value, SD_buffer + key_length + 1, value_length);
break;
}
}
}
}
configFile.close();
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;
}
SD Card initialized.
myInt_1 = 2
myInt_2 = -105
myFloat_1 = 0.74
myFloat_2 = -46.08
myString_1 = Hello
myString_2 = newbiely.com
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.
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.