Language: English · فارسی
This document explains the Deploy stage from a .tflite file to a blinking LED.
models/xxx_int8.tflite
│
▼ python/04_tflite_to_c_array.py
firmware/.../model_data.h (byte array in Flash)
│
▼ Arduino IDE / PlatformIO / ESP-IDF
Microcontroller → TFLM Interpreter → Invoke() → decision
- Arduino IDE 2.x or PlatformIO
- Suitable USB cable for the board
- Serial driver (for some CH340/CP2102 boards)
Until you have a board, complete steps 1–4 fully on the PC and keep the firmware ready.
python python\02_train_mnist_tiny_cnn.py
python python\03_quantize_to_tflite.py --model models\mnist_tiny_cnn.keraspython python\04_tflite_to_c_array.py `
--tflite models\mnist_tiny_cnn_int8.tflite `
--out firmware\hello_sine_arduino\model_data.h `
--var g_modelConceptual code (simplified):
#include "tensorflow/lite/micro/micro_interpreter.h"
#include "tensorflow/lite/micro/micro_mutable_op_resolver.h"
#include "model_data.h"
constexpr int kArenaSize = 80 * 1024;
uint8_t tensor_arena[kArenaSize];
void setup() {
const tflite::Model* model = tflite::GetModel(g_model);
static tflite::MicroMutableOpResolver<6> resolver;
// resolver.AddConv2D(); resolver.AddFullyConnected(); ...
static tflite::MicroInterpreter interpreter(
model, resolver, tensor_arena, kArenaSize);
interpreter.AllocateTensors();
}
void loop() {
// 1) sensor → buffer
// 2) same preprocessing as training
// 3) copy into interpreter.input(0)
// 4) interpreter.Invoke()
// 5) read interpreter.output(0) → LED / serial
}Ready templates: firmware/hello_sine_arduino/ and firmware/esp32_tflm_template/
- Too small → Allocate/Invoke fails
- Too large → fills all RAM
Practical method: start at 60KB, raise until stable, then trim with arena_used_bytes().
For production use MicroMutableOpResolver.
Inspect model ops with a TFLite analysis tool or Netron:
- Go to https://studio.edgeimpulse.com and create a free account
- Create project → data type (Audio / Accel / Image)
- Upload data or capture from the board with the CLI
- Impulse design: Processing block + Learning block
- Generate features → Train
- Model testing
- Deployment → Arduino library → Build
- In Arduino IDE: Sketch → Include Library → Add .ZIP Library
- Upload the library’s ready example
Official docs:
https://docs.edgeimpulse.com/hardware/deployments/run-arduino-2-0
Pros: Preprocessing + model + SDK in one package.
Cons: You see less “under the hood” — for deep learning, also walk Path 1.
- Arduino IDE → Preferences → Additional Boards URL:
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
- Boards Manager → install
esp32 - Board: ESP32S3 Dev Module (or your board model)
- If you have vision: PSRAM = Enabled
- TFLM library / official Espressif example or Edge Impulse
Production notes:
- Wi‑Fi together with heavy inference can stress RAM/CPU
- Use I2S for audio
- ESP-NN improves speed
- Onboard sensors: IMU, microphone, …
- Official Arduino TensorFlow Lite library (match version to the board)
- Edge Impulse examples for Nano are ready
- Cheap and popular
- TFLM is supported; ecosystem is a bit more hands-on than Arduino Sense
- Great for IMU and educational projects
- STM32Cube.AI for model conversion
- CMSIS-NN performs well on Cortex-M
- More industrial path
- Model is Full INT8
- Firmware input shape = training shape
- Input scale (0–1, −1–1, int8 scale) matches
- Arena is large enough
- Serial opens correctly at 115200 or 125200
- You have a golden test (a known sample that must yield class X)
Training: 96×96 image, grayscale, normalize 0..1 then quantize to int8.
On MCU:
- Capture camera frame
- Resize to 96×96
- RGB→Gray (if needed)
- Convert to int8 with the same model scale/zero_point
memcpyintoinput->data.int8Invoke()- argmax on output
If any of these differ, accuracy dies even if the model is excellent.
| Symptom | Likely cause |
|---|---|
| AllocateTensors fails | Arena too small / model too large |
| Output always one class | Bad input / wrong scale |
| Board resets | Stack overflow / RAM exhaustion |
| Good on PC, bad on board | Mismatched preprocess / sensor noise |
| TFLM compile error | Incompatible library version |
Golden tactic: first send a precomputed feature vector from the PC over serial and only Invoke on the MCU. If that works, the problem is sensor/preprocess — not the model.
- Complete the pipeline through
.tfliteandmodel_data.h - Measure inference on PC with the TFLite Interpreter
- Build a project in Edge Impulse and test in Studio
- Write firmware and comment where the sensor hooks in
When the board arrives, just plug in the cable and Upload.
Next step: 05-Roadmap-0-to-100.md