Hands-on: make a new model appear in edge_ai.models()
Module 7 — Under the hood and extending the firmware · Slides: slides.md · Module overview · Course page
Fill five points in s19_extend_model.py, which spans two worlds: the top half builds a C ROW from a spec in Python, the bottom half queries the registry with count() and models() and then selects and runs our model. Then add the model to real firmware, prove it with the model count before and after, and walk a checklist before trusting the result on hardware.
Objectives
Section titled “Objectives”By the end of this lesson, you will:
- Fill the five points in practice/s19_extend_model.py until it prints a ROW with all four function names and the classes complete, and find the model’s registry index by name (on the emulator, Fall isn’t found yet, which is correct).
- Add a model to the firmware (three edits in the full source, or ai_engine_register() in the public SDK), then show edge_ai.count() before and after, the new name in models(), and a real verdict on select.
- Walk the pre-trust checklist (symbols checked with nm, the .ml_weights section, a clean build, a hard power cycle), and explain the reason for each item.
Before you start
Section titled “Before you start”You’ve been through lesson 7.3, and know the three edits, the four-function contract, and the equivalent routes in the SDK. If you’ll be doing the firmware part, install ModusToolbox and clone the public SDK, with a model already wrapped to the four-function contract.
- Hardware: a TESAIoT Dev Kit board already flashed with BENTO’s MicroPython firmware, or the BENTO Emulator inside BENTO IDE — the top half of the file (the spec and the ROW) can be practised on the emulator. Actually adding a model requires building the firmware with ModusToolbox, then flashing the board. The full source isn’t yet public, so use the public SDK with ai_engine_register() instead of editing ai_engine.c.
- Prior lesson: lesson 7.3 — Adding your own model: three edits, a four-function contract, and Vela
Concepts
Section titled “Concepts”This file crosses worlds: write a spec → print the C ROW you need to place → ask the registry whether it’s shown up → select and run it, then read the verdict. The five points to fill in are: (1) "sensor": edge_ai.SENSOR_IMU and "labels": ["normal", "fall"] in SPEC (2) deq_fn = "AIM_%s_dequeue" % prefix in make_row(), which assembles the text #if defined(EDGE_AI_MODEL_fall) / #define FALL_ROW {...} / #endif for you to copy and place — forget this point, and the ROW has .dequeue = None, which won’t compile (3) n = edge_ai.count() (4) mine = i when the name matches, finding the index by name rather than hard-coding a number, and (5) edge_ai.select(idx), followed by r = edge_ai.result(), wrapped in try/except OSError, since a new model may fail to init.
On the emulator, you can practise the top half — the registry has five models and doesn’t yet have Fall, which is correct, since the browser can’t build C. The bottom half can be tried with an existing model, such as Motion. On the board, in the full source, make the three edits, then rm -rf proj_cm55/build; make program EDGE_AI_MODEL=combo. If using the public SDK, call ai_engine_register(&desc) from your own code at boot, then build with ModusToolbox. After that, press Re-check: count() must increase (on the board, six becomes seven), the new name turns green, then Run mine — move the board until the class switches between normal and fall. Before trusting the result, walk the checklist: test the .tflite in Python before wrapping it; check with nm that symbols don’t collide; large weights sit in .ml_weights; the front end matches training; a clean build; and a hard power cycle — one change per flash.
Worked example
Section titled “Worked example”s19_extend_model_full.py supports both STYLE = "AIM" (a model from DEEPCRAFT Studio) and "IMAI" (a Ready-Model .a), checks that the four-function contract is complete, compares count() before and after, and colours the verdict by CONF_FLOOR, with latency.
| File | What this file teaches |
|---|---|
| examples/s19_extend_model_full.py | Adding your own model into Edge AI (full version) |
Practice
Section titled “Practice”The # TODO comments are at lines 44 (SPEC sensor and labels), 60 (deq_fn), 129 (count), 138 (mine = i), and 156 (select and result). If the printed ROW has a None in it, point 60 is still empty. If the model-count diff is always zero, check point 129.
| Practice file | Topic |
|---|---|
| practice/s19_extend_model.py | Adding your own model into Edge AI (the fill-in-the-code version) |
Solution
Section titled “Solution”Open the solution after trying on your own at least once, and read how to use the solutions first.
| Solution | Pairs with |
|---|---|
| solution/s19_extend_model.py | practice/s19_extend_model.py |
Check your understanding
Section titled “Check your understanding”The same questions are in quiz.yaml for automated checking.
-
The printed ROW has .dequeue = None. Which point is still empty? (single choice · objective 1)
- a) Point 1, SPEC
- b) Point 2, deq_fn in make_row()
- c) Point 3, count()
- d) Point 5, select
Solution
b — make_row assembles all four function names from the prefix. If deq_fn is still None, the ROW text won’t compile.
-
Running on the emulator, scan_registry() doesn’t find Fall Detection. What does that mean? (single choice · objective 1)
- a) The code is wrong
- b) That’s correct — the emulator has five models already compiled in, and the browser can’t build C
- c) The browser needs a refresh
- d) The name needs adding to edge_ai.py
Solution
b — adding a model requires a toolchain and flashing the board. This is exactly the boundary between firmware work and app-level work.
-
Which piece of evidence confirms a model was genuinely added successfully? (single choice · objective 2)
- a) The build passes with no errors
- b) count() has increased, the new name is in models(), and after select, the verdict genuinely switches with real motion
- c) The model file is in the right folder
- d) The ROW prints out completely
Solution
b — a passing build, or a file in the right place, doesn’t yet prove all four functions are correctly wired. You need to see both the registry and the verdict on the board.
-
Why does the checklist call for a hard power cycle before trusting the result on hardware? (single choice · objective 3)
- a) To clear files from flash
- b) After flashing, some sensors and the NPU need to be reinitialised from real power, otherwise a reading might still be stuck from before
- c) So WiFi reconnects
- d) It isn’t necessary
Solution
b — one change per flash, then a power cycle before trusting it, makes sure the result you see genuinely comes from this change.
The MVP for lessons 7.3–7.4: a newly added model raises edge_ai.count(), its name shows up in edge_ai.models(), and selecting and running it gets a real verdict on the board.
- All five points in the practice file are filled in. Run it on the emulator and check the printed ROW field by field.
- On the board, note
edge_ai.count()before adding the model. - Add the model (three edits in the full source, or
ai_engine_register()in the SDK), build it, hard power-cycle, notecount()after adding it, and the verdict when running Run mine. - Write out the checklist you actually walked in your learning log, with evidence for each item (for example,
nm’s output).
Going further
Section titled “Going further”In the next module (Capstone), we’ll combine everything from DAQ through to apps into our own Edge AI app, in a single file.
Next lesson: lesson 8.1 — Designing the capstone: Guardian’s three pillars in one file
Reflect
Section titled “Reflect”- If count() increased but the verdict never changed at all, which layer would you investigate first?
- In a real product, would you add a model at build time or load it at run time, and why?
Review questions
Answer on your own first, then open the answer.
-
The printed ROW has .dequeue = None. Which point is still empty? (Objective 1)
- จุดที่ 1 SPEC
- จุดที่ 2 deq_fn ใน make_row()
- จุดที่ 3 count()
- จุดที่ 5 select
Show answer
Answer: B. จุดที่ 2 deq_fn ใน make_row()
make_row ประกอบชื่อฟังก์ชันทั้งสี่จาก prefix ถ้า deq_fn ยังเป็น None ข้อความ ROW จะคอมไพล์ไม่ผ่าน
-
On the emulator scan_registry() does not find Fall Detection. What does that mean? (Objective 1)
- โค้ดผิด
- ถูกต้องแล้ว Emulator มีห้าโมเดลที่คอมไพล์มาแล้ว และ build C ในเบราว์เซอร์ไม่ได้
- ต้องรีเฟรชเบราว์เซอร์
- ต้องเพิ่มชื่อใน edge_ai.py
Show answer
Answer: B. ถูกต้องแล้ว Emulator มีห้าโมเดลที่คอมไพล์มาแล้ว และ build C ในเบราว์เซอร์ไม่ได้
การเพิ่มโมเดลต้องมี toolchain และ flash ลงบอร์ด นี่คือเส้นแบ่งระหว่างงานเฟิร์มแวร์กับงานระดับแอป
-
Which evidence proves the model was really added? (Objective 2)
- build ผ่านโดยไม่มี error
- count() เพิ่มขึ้น ชื่อใหม่อยู่ใน models() และ select แล้ว verdict สลับตามการขยับจริง
- ไฟล์โมเดลอยู่ในโฟลเดอร์ถูกที่
- ROW พิมพ์ออกมาครบ
Show answer
Answer: B. count() เพิ่มขึ้น ชื่อใหม่อยู่ใน models() และ select แล้ว verdict สลับตามการขยับจริง
build ผ่านหรือไฟล์อยู่ถูกที่ยังไม่ได้แปลว่าทั้งสี่ฟังก์ชันต่อสายถูก ต้องเห็นทั้งทะเบียนและ verdict บนบอร์ด
-
Why does the checklist demand a hard power cycle before trusting hardware results? (Objective 3)
- เพื่อล้างไฟล์ใน flash
- หลัง flash เซนเซอร์และ NPU บางตัวต้อง init ใหม่จากไฟจริง ไม่งั้นค่าที่อ่านอาจค้างจากรอบก่อน
- เพื่อให้ Wi-Fi ต่อใหม่
- ไม่จำเป็น
Show answer
Answer: B. หลัง flash เซนเซอร์และ NPU บางตัวต้อง init ใหม่จากไฟจริง ไม่งั้นค่าที่อ่านอาจค้างจากรอบก่อน
หนึ่งการเปลี่ยนต่อหนึ่งการ flash แล้ว power-cycle ก่อนเชื่อ ช่วยให้แน่ใจว่าผลที่เห็นมาจากการเปลี่ยนครั้งนี้จริง
Cite this lesson
If you teach from this lesson or reuse it in slides or documents, credit it with the text below. If you changed it, add (adapted) after the title.
"Hands-on: make a new model appear in edge_ai.models()" from TESA Open Knowledge by the Thai Embedded Systems Association (TESA), https://github.com/tesaiot/tesa-qualification-program, licensed under CC BY-NC 4.0
Thai attribution: "ลงมือทำ: ให้โมเดลใหม่โผล่ใน edge_ai.models()" จาก TESA Open Knowledge โดยสมาคมสมองกลฝังตัวไทย (Thai Embedded Systems Association: TESA) https://github.com/tesaiot/tesa-qualification-program สัญญาอนุญาต CC BY-NC 4.0
TESA Open Knowledge · © 2026 สมาคมสมองกลฝังตัวไทย (TESA) · CC BY-NC 4.0
Content is licensed CC BY-NC 4.0. Reuse it non-commercially and credit the Thai Embedded Systems Association (TESA) every time. · How to cite TESA