ESP32-S3 TinyML: การสร้างระบบ AI บน Edge ด้วย ESP32-S3
เรียนรู้วิธีการสร้างระบบ AI บน Edge ด้วย ESP32-S3 และ TinyML รัน TensorFlow Lite Micro บนไมโครคอนโทรลเลอร์ พร้อมโค้ดตัวอย่างและการประยุกต์ใช้จริง
📑 เนื้อหาในบทความ
TinyML คืออะไร?
TinyML เป็นเทคโนโลยีที่ enable ให้เราสามารถรัน Machine Learning models บน microcontrollers ที่มีทรัพยากรจำกัด เช่น ESP32, Arduino หรือ STM32 โดยไม่ต้องส่งข้อมูลไปประมวลผลบน Cloud
ข้อดีของ TinyML: ประหยัดพลังงาน, ลด latency, เพิ่มความเป็นส่วนตัว (privacy), ทำงานได้แม้ไม่มี internet
ข้อดีของการใช้ AI บน Edge
- Low Latency: ประมวลผลได้ทันทีโดยไม่ต้องส่งข้อมูลไป Cloud
- Privacy: ข้อมูลไม่ต้องออกจาก device
- Offline: ทำงานได้แม้ไม่มี Internet
- Low Power: ประหยัดพลังงานมากกว่าการส่งข้อมูลไป Cloud ตลอดเวลา
- Cost Effective: ลดค่าใช้จ่ายในการส่งข้อมูลและประมวลผลบน Cloud
ทำไม ESP32-S3 เหมาะกับ TinyML?
🚀 จุดเด่นของ ESP32-S3
- • Dual-core Xtensa LX7 (240 MHz)
- • 512 KB SRAM
- • Vector instructions สำหรับ AI
- • สนับสนุน TensorFlow Lite Micro
- • ราคาถูก (~200-300 บาท)
⚡ Vector Instructions
ESP32-S3 มี AI Acceleration Instructions ที่ทำให้การประมวลผล Neural Networks เร็วขึ้น 2-3 เท่า เมื่อเทียบกับ ESP32 รุ่นก่อน
- • MAC (Multiply-Accumulate) operations
- • SIMD (Single Instruction, Multiple Data)
- • รองรับ int8 quantization
💡 เกร็ดความรู้: ESP32-S3 สามารถรัน TensorFlow Lite Micro models ที่มีขนาดถึง 1-2 MB ได้อย่างลื่นไหล ซึ่งเพียงพอสำหรับ: Image classification (ตรวจจับวัตถุ), Keyword spotting (ตรวจจับเสียง), Anomaly detection (ตรวจจับความผิดปกติ)
อุปกรณ์ที่ต้องใช้
🛒 Hardware List
| อุปกรณ์ | รายละเอียด | ราคาประมาณ |
|---|---|---|
| ESP32-S3 Dev Board | ESP32-S3-DevKitC-1 หรือ NodeMCU ESP32-S3 | ~250 บาท |
| USB Cable | USB-C (สำหรับ ESP32-S3) | ~50 บาท |
| Sensors (Optional) | IMU, Microphone, Camera ขึ้นกับโปรเจกต์ | ~100-500 บาท |
| Breadboard & Jumper wires | สำหรับต่อวงจรทดลอง | ~50 บาท |
📋 Software Requirements
- Arduino IDE 2.x หรือ PlatformIO
- ESP32 Arduino Core (เวอร์ชันล่าสุด)
- TensorFlow Lite for Microcontrollers library
- EI Compute (Edge Impulse) - สำหรับ train models แบบง่าย
การติดตั้ง Environment
ขั้นตอนที่ 1: ติดตั้ง Board Package
// ใน Arduino IDE ไปที่:
// File → Preferences → Additional Boards Manager URLs
// เพิ่ม: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
// แล้วไปที่:
// Tools → Board → Boards Manager → ค้นหา "ESP32" → ติดตั้งขั้นตอนที่ 2: ติดตั้ง TensorFlow Lite Library
// ใน Arduino IDE ไปที่:
// Sketch → Include Library → Manage Libraries
// ค้นหา "TensorFlow Lite" → ติดตั้งเวอร์ชันล่าสุด
// หรือดาวน์โหลดจาก:
// https://github.com/tensorflow/tflite-micro-arduino-examples💡 Tip: ถ้าใช้ PlatformIO ให้เพิ่ม library dependencies ใน platformio.ini:
lib_deps =
tensorflow/tflite-microโปรเจกต์ที่ 1: Hello World ของ TinyML
เริ่มต้นด้วยการสร้าง Simple Model ที่ทำนายผลลัพธ์จากข้อมูล input ง่ายๆ เช่น การทำนายค่า y จาก x (Linear Regression)
โค้ดตัวอย่าง: Simple Inference
#include <TensorFlowLite.h>
#include <tensorflow/lite/micro/all_ops_resolver.h>
#include <tensorflow/lite/micro/micro_error_reporter.h>
#include <tensorflow/lite/micro/micro_interpreter.h>
#include <tensorflow/lite/schema/schema_generated.h>
#include <tensorflow/lite/version.h>
// รวม model file (generated จาก TensorFlow)
#include "model_model.h" // ไฟล์ .h ที่ถูก convert จาก .tflite
// ตั้งค่า tensors
const int kTensorArenaSize = 2000;
uint8_t tensor_arena[kTensorArenaSize];
// สร้าง objects
tflite::ErrorReporter* error_reporter = nullptr;
const tflite::Model* model = nullptr;
tflite::MicroInterpreter* interpreter = nullptr;
void setup() {
Serial.begin(115200);
// สร้าง Error Reporter
static tflite::MicroErrorReporter micro_error_reporter;
error_reporter = µ_error_reporter;
// โหลด Model
model = tflite::GetModel(g_model);
if (model->version() != TFLITE_SCHEMA_VERSION) {
error_reporter->Report("Model version mismatch!");
return;
}
// สร้าง Interpreter
static tflite::AllOpsResolver resolver;
static tflite::MicroInterpreter static_interpreter(
model, resolver, tensor_arena, kTensorArenaSize, error_reporter
);
interpreter = &static_interpreter;
// จอง memory สำหรับ tensors
TfLiteStatus allocate_status = interpreter->AllocateTensors();
if (allocate_status != kTfLiteOk) {
error_reporter->Report("AllocateTensors() failed");
return;
}
Serial.println("Model initialized successfully!");
}
void loop() {
// อ่านค่า input (จาก sensor หรือข้อมูลจำลอง)
float input_value = 5.0; // ตัวอย่าง: x = 5.0
// ใส่ค่า input เข้าไปใน input tensor
TfLiteTensor* input = interpreter->input(0);
input->data.f[0] = input_value;
// รัน inference
TfLiteStatus invoke_status = interpreter->Invoke();
if (invoke_status != kTfLiteOk) {
error_reporter->Report("Invoke failed");
return;
}
// อ่านผลลัพธ์จาก output tensor
TfLiteTensor* output = interpreter->output(0);
float predicted_value = output->data.f[0];
Serial.print("Input: ");
Serial.print(input_value);
Serial.print(" | Predicted: ");
Serial.println(predicted_value);
delay(1000);
}⚠️ หมายเหตุ: โค้ดนี้เป็นตัวอย่างพื้นฐานเท่านั้น ในการใช้งานจริง คุณต้อง:
1. Train model ด้วย TensorFlow/Python ก่อน
2. Convert เป็น .tflite format
3. Quantize เป็น int8 เพื่อลดขนาด model
4. Convert เป็�ก C array (.h file) ด้วย xxd
โปรเจกต์ที่ 2: Gesture Recognition ด้วย IMU
ใช้ IMU Sensor (MPU6050) ตรวจจับท่าทางการเคลื่อนไหว เช่น การสั่นไหว, การหมุน, การเคลื่อนไหวเฉพาะ
การเตรียมข้อมูล (Data Collection)
ขั้นตอนการเก็บข้อมูล:
- ต่อ IMU (MPU6050) เข้ากับ ESP32-S3 (I2C)
- เขียนโค้ดเก็บข้อมูล accelerometer + gyroscope
- บันทึกข้อมูลสำหรับแต่ละ gesture (เช่น สั่น, หมุน, นิ่ง)
- แต่ละ gesture เก็บประมาณ 50-100 samples
- ใช้ Edge Impulse หรือ Python สร้าง model
โค้ดตัวอย่าง: IMU Data Collection
#include <Wire.h>
#include <Adafruit_MPU6050.h>
Adafruit_MPU6050 mpu;
void setup() {
Serial.begin(115200);
Wire.begin();
if (!mpu.begin()) {
Serial.println("Failed to find MPU6050 chip");
while (1) {
delay(10);
}
}
mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
mpu.setGyroRange(MPU6050_RANGE_500_DEG);
mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
Serial.println("MPU6050 Found!");
}
void loop() {
sensors_event_t a, g, temp;
mpu.getEvent(&a, &g, &temp);
// ส่งข้อมูลเป็น CSV format
Serial.print(a.acceleration.x); Serial.print(",");
Serial.print(a.acceleration.y); Serial.print(",");
Serial.print(a.acceleration.z); Serial.print(",");
Serial.print(g.gyro.x); Serial.print(",");
Serial.print(g.gyro.y); Serial.print(",");
Serial.println(g.gyro.z);
delay(10); // 100 Hz sampling rate
}🎯 เคล็ดลับ: ใช้ Edge Impulse สร้าง model แบบง่ายๆ โดยไม่ต้องเขียนโค้ด TensorFlow เอง เพียงแค่อัปโหลดข้อมูลและกด Train!
โปรเจกต์ที่ 3: Anomaly Detection สำหรับ IoT
ตรวจจับ ความผิดปกติ ในข้อมูล sensor เช่น อุณหภูมิสูงผิดปกติ, การสั่นที่ผิดปกติ, หรือพฤติกรรมที่ไม่ธรรมดา
Use Cases
🏭 อุตสาหกรรม
- • ตรวจจับการสั่นของเครื่องจักที่ผิดปกติ
- • ทำนายการเสียหายของ motor
- • ตรวจสอบคุณภาพการผลิต
🏠 Smart Home
- • ตรวจจับก๊าซรั่วที่ผิดปกติ
- • ตรวจจับการใช้พลังงานที่ผิดปกติ
- • ตรวจจับเสียงผิดปกติ (เสียงแตก, คริก)
โค้ดตัวอย่าง: Autoencoder-based Anomaly Detection
// โครงสร้างแนวคิด (Conceptual Code)
// ในการใช้งานจริง ต้อง train Autoencoder model ก่อน
float detect_anomaly(float sensor_data[]) {
// ใส่ข้อมูลเข้า input tensor
for (int i = 0; i < INPUT_SIZE; i++) {
input->data.f[i] = sensor_data[i];
}
// รัน model
interpreter->Invoke();
// คำนวณ reconstruction error
float reconstruction_error = 0.0;
TfLiteTensor* output = interpreter->output(0);
for (int i = 0; i < INPUT_SIZE; i++) {
float error = sensor_data[i] - output->data.f[i];
reconstruction_error += error * error;
}
reconstruction_error = sqrt(reconstruction_error / INPUT_SIZE);
// ตรวจสอบว่าเป็น anomaly หรือไม่
if (reconstruction_error > ANOMALY_THRESHOLD) {
Serial.println("⚠️ ANOMALY DETECTED!");
return reconstruction_error;
}
return 0.0;
}💡 หมายเหตุ: Autoencoder คือ Neural Network ที่เรียนรู้ที่จะ "คัดลอก" ข้อมูล input ไปยัง output ถ้าข้อมูลใหม่มีความผิดปกติ reconstruction error จะสูง
การปรับปรุงประสิทธิภาพ (Optimization)
เทคนิคการทำให้ Model ขนาดเล็กลง
1️⃣ Quantization (int8)
แปลง weights จาก float32 เป็น int8 ลดขนาด model ลง 75% และเพิ่มความเร็วในการ inference
2️⃣ Pruning
ลบ weights ที่มีค่าใกล้ 0 ออก ทำให้ model เบาขึ้น
3️⃣ Knowledge Distillation
ใช้ model ใหญ่สอน model เล็ก ให้สามารถทำนายผลลัพธ์ที่ใกล้เคียงกัน
การเพิ่มประสิทธิภาพการ Inference
- ใช้ X0W (ESP32-S3-Specific): เปิดใช้งาน vector instructions ใน ESP-IDF
- Batch Processing: ประมวลผลหลาย samples พร้อมกัน (ถ้า memory พอ)
- Model Tiling: แบ่ง model ออกเป็นส่วนๆ ถ้า model ใหญ่เกินไป
- Disable WiFi/Bluetooth: ปิดฟีเจอร์ที่ไม่ใช้ขณะ inference เพื่อประหยัดพลังงาน
แอปพลิเคชันจริงที่ใช้ TinyML
Keyword Spotting
ตรวจจับคำสั่งเสียง "เปิดไฟ", "ปิดไฟ" โดยไม่ต้องส่งเสียงไป Cloud → เพิ่มความเป็นส่วนตัวและลด latency
Smart HomeImage Classification
ตรวจจับวัตถุ เช่น คน, สัตว์, รถยนต์ จากกล้องที่ต่อกับ ESP32-S3 ใช้ในระบบรักษาความปลอดภัย
SecurityPredictive Maintenance
ตรวจจับการสั่นของเครื่องจักรที่ผิดปกติ เพื่อทำนายการเสียหายก่อนเกิดขึ้น ลด downtime ของโรงงาน
IndustrialSmart Agriculture
ตรวจจับโรคพืชจากภาพใบไม้ หรือทำนายความต้องการน้ำจากข้อมูล sensor
Agricultureสรุปและแหล่งเรียนรู้เพิ่มเติม
🎓 สิ่งที่คุณได้เรียนรู้
- TinyML คืออะไรและทำไมมันสำคัญ
- ESP32-S3 เหมาะกับ TinyML อย่างไร (Vector Instructions, SRAM, CPU power)
- การติดตั้งและตั้งค่า TensorFlow Lite Micro บน ESP32-S3
- โปรเจกต์จริง: Gesture Recognition, Anomaly Detection
- เทคนิค optimization: Quantization, Pruning
📚 แหล่งเรียนรู้เพิ่มเติม
🌐 Official Resources
🚀 โปรเจกต์ต่อไปที่คุณควรลอง
- Keyword Spotting: สร้างระบบคำสั่งเสียง "เปิดไฟ", "ปิดไฟ"
- Face Recognition: ใช้ ESP-WHO ตรวจจับใบหน้า
- Wearable AI: สร้าง smartwatch ที่ตรวจจับ activity
- Smart Doorbell: ตรวจจับคนที่หน้าประตูและแจ้งเตือน