บทความกลาง-ยาก20 นาที

ESP32-S3 TinyML: การสร้างระบบ AI บน Edge ด้วย ESP32-S3

เรียนรู้วิธีการสร้างระบบ AI บน Edge ด้วย ESP32-S3 และ TinyML รัน TensorFlow Lite Micro บนไมโครคอนโทรลเลอร์ พร้อมโค้ดตัวอย่างและการประยุกต์ใช้จริง

Cyno IoT Team
14 มีนาคม 2569
ESP32-S3 TinyML Edge AI

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 BoardESP32-S3-DevKitC-1 หรือ NodeMCU ESP32-S3~250 บาท
USB CableUSB-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)

ขั้นตอนการเก็บข้อมูล:

  1. ต่อ IMU (MPU6050) เข้ากับ ESP32-S3 (I2C)
  2. เขียนโค้ดเก็บข้อมูล accelerometer + gyroscope
  3. บันทึกข้อมูลสำหรับแต่ละ gesture (เช่น สั่น, หมุน, นิ่ง)
  4. แต่ละ gesture เก็บประมาณ 50-100 samples
  5. ใช้ 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

ขนาด model ลดจาก 1 MB → 250 KB

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 Home
📷

Image Classification

ตรวจจับวัตถุ เช่น คน, สัตว์, รถยนต์ จากกล้องที่ต่อกับ ESP32-S3 ใช้ในระบบรักษาความปลอดภัย

Security
🏭

Predictive Maintenance

ตรวจจับการสั่นของเครื่องจักรที่ผิดปกติ เพื่อทำนายการเสียหายก่อนเกิดขึ้น ลด downtime ของโรงงาน

Industrial
🌾

Smart Agriculture

ตรวจจับโรคพืชจากภาพใบไม้ หรือทำนายความต้องการน้ำจากข้อมูล sensor

Agriculture

สรุปและแหล่งเรียนรู้เพิ่มเติม

🎓 สิ่งที่คุณได้เรียนรู้

  • TinyML คืออะไรและทำไมมันสำคัญ
  • ESP32-S3 เหมาะกับ TinyML อย่างไร (Vector Instructions, SRAM, CPU power)
  • การติดตั้งและตั้งค่า TensorFlow Lite Micro บน ESP32-S3
  • โปรเจกต์จริง: Gesture Recognition, Anomaly Detection
  • เทคนิค optimization: Quantization, Pruning

📚 แหล่งเรียนรู้เพิ่มเติม

🚀 โปรเจกต์ต่อไปที่คุณควรลอง

  1. Keyword Spotting: สร้างระบบคำสั่งเสียง "เปิดไฟ", "ปิดไฟ"
  2. Face Recognition: ใช้ ESP-WHO ตรวจจับใบหน้า
  3. Wearable AI: สร้าง smartwatch ที่ตรวจจับ activity
  4. Smart Doorbell: ตรวจจับคนที่หน้าประตูและแจ้งเตือน

บทความที่เกี่ยวข้อง