Six models and the edge_ai API: an app focused on one model
Module 6 — Edge AI apps · Slides: slides.md · Module overview · Course page
Open the apps module. Go from a menu offering every model to an app focused on one. Target a model with find_model() instead of an index, learn to read every class’s score and latency_ms, and wire a verdict to a first action — counting when the target class reaches CONF_FLOOR, on the rising edge only.
Objectives
Section titled “Objectives”By the end of this lesson, you will:
- Compare a menu app with a single-model focused app, and say which kind of job suits each.
- Explain find_model() and its three fallbacks (name → sensor → first), and why a model’s index should never be hard-coded.
- Fully read an edge_ai.result() dict — top from argmax, conf as the highest score, every class’s score, latency_ms, and seq, used to redraw only on a new result.
- Write the counting condition label == TARGET_CLASS and conf ≥ CONF_FLOOR (0.50), counting on the rising edge only, and explain the limits of the evaluation Ready Models.
Before you start
Section titled “Before you start”You’ve been through module 1, already used edge_ai.models(), select(), result() and stop(), and remember the verdict-to-action skeleton from lesson 1.6. Open the 16_edge_ai_sound_events.py example in BENTO IDE.
- Hardware: a TESAIoT Dev Kit board already flashed with BENTO’s MicroPython firmware, or the BENTO Emulator inside BENTO IDE — on the emulator, model scores are simulated: the audio models move with the POTEN knob, but the event class never wins over unlabelled, and there’s no Push model. Real sound and radar need the board.
- Prior lesson: lesson 5.9 — Hands-on: comparing three targets, MCU, web and PC
See it work first
Section titled “See it work first”Run 16_edge_ai_sound_events.py on the board, and switch between Cough, Alarm and Siren in one single dropdown. Watch the two-class bars move when there’s sound. Ask yourself: if this device had to count coughs in a patient’s room all night long, should the user have to pick the model themselves?
Concepts
Section titled “Concepts”A model-selection menu suits exploration and demos, but nearly every real product is a focused app: target a single model when the app opens, design a UI for exactly that job, and wire the verdict to an action. Examples 13 through 16 share the same shape: find_model() → select() → a result() loop → drawing the verdict and its bars → finally: stop(). The board has six models (Motion, Baby Cry, Push, Cough, Alarm, Siren), while the emulator has five, so the order differs. find_model() first searches by keyword in the name; failing that, it uses the first model matching a sensor (such as edge_ai.SENSOR_MIC = 2); and finally falls back to the first model, to keep the app from crashing. A fixed select(3) breaks the instant the registry changes.
The result() dict gives more than just the winning class: top is $\hat{y} = \arg\max_i s_i$, conf is $s_{\hat{y}}$, scores draws a bar for every class, showing whether the model is unsure or confident, latency_ms reports the NPU’s inference time, which differs by model, and seq is used to redraw only when there’s a new result. argmax always picks a winner, even at 0.51 versus 0.49, so we set a gate on the action: count when r['label'] == TARGET_CLASS and r['conf'] >= edge_ai.CONF_FLOOR (0.50), and count only on the rising edge (is_target and not was_target), because a single cough spans several inference results. Setting the threshold high gives certainty but misses quiet sounds; setting it low catches quickly but produces many false positives.
Cough, Alarm and Siren are DEEPCRAFT Ready Models from Imagimob AB (an Infineon group company), evaluation versions meant for experimentation only, with a limited number of inferences. If a result stays frozen and seq never moves, that’s the model hitting its ceiling, not broken code — the author recommends rebooting the board. Once you can train your own model, as in module 5, this limitation disappears.
Worked example
Section titled “Worked example”14_edge_ai_babycry.py: a result card with a confidence bar for the mic model. 15_edge_ai_radar_push.py: the Push radar model (stand about 60 cm away; needs a board with radar). 16_edge_ai_sound_events.py: a sub-menu of three audio models. 17_latency_min_max_avg.py: collects latency over 20 rounds and reports the minimum, maximum, and average. And 18_switch_cost.py: times how long switching models with select() takes, showing that switching frequently has a cost (the last two files were carried over from the author’s AIoT course).
| File | What this file teaches |
|---|---|
| examples/14_edge_ai_babycry.py | Edge AI: Baby Cry (microphone) — detecting a crying baby on the board (no network needed) |
| examples/15_edge_ai_radar_push.py | Edge AI: Radar Push (60 GHz radar) — classifying hand gestures with radar on the board |
| examples/16_edge_ai_sound_events.py | Edge AI: Sound Events (Cough / Alarm / Siren) — 3 mic models in one dropdown |
| examples/17_latency_min_max_avg.py | Measuring how long a model takes to think |
| examples/18_switch_cost.py | Switching models while the program is running |
This lesson’s slides also reference files in another lesson:
- m01-onboarding/l06-edge-ai-app-anatomy/examples/13_edge_ai_motion.py — Edge AI: Motion (IMU) with the new edge_ai API — seeing every class’s score plus latency
- m06-apps/l02-focused-app-lab/practice/s15_apps.py — an edge AI app that’s “focused on one model” (the fill-in-the-code version)
Check your understanding
Section titled “Check your understanding”The same questions are in quiz.yaml for automated checking.
-
A device counting coughs at a patient’s bedside should be what kind of app? (single choice · objective 1)
- a) A menu letting the user choose a model every time
- b) A focused app that targets the Cough model from the start, wiring the verdict to a counter
- c) An app that switches every model every second
- d) No app needed — just use the REPL
Solution
b — an end user shouldn’t need to know what models exist. Menus suit exploration and demos; focused apps suit real work.
-
Why is find_model((“cough”,), edge_ai.SENSOR_MIC) better than edge_ai.select(3)? (single choice · objective 2)
- a) It’s faster
- b) It finds the model by name, so it’s still correct even if the registry order changes, such as on the emulator, where the lack of Push puts Cough at index 2
- c) It uses less memory
- d) select(3) doesn’t work on the board
Solution
b — on the board, Cough is at index 3, but on the emulator, it’s at index 2. Querying the registry by name lets one set of code work in both places.
-
r[‘scores’] = [0.12, 0.88] for a model with [‘unlabelled’, ‘cough’]. What are r[‘top’] and r[‘conf’]? (single choice · objective 3)
- a) top = 0, conf = 0.12
- b) top = 1, conf = 0.88
- c) top = 0.88, conf = 1
- d) top = 1, conf = 0.12
Solution
b — top is the index of the highest score (argmax), and conf is that score’s value. The winning class is therefore cough, with 0.88 confidence.
-
One cough spans three inference results, giving cough’s conf as 0.8, 0.9, 0.85, then dropping. How many times does a rising-edge counter increase? (single choice · objective 4)
- a) 0
- b) 1
- c) 3
- d) 2
Solution
b — it counts only the moment it changes from not-target to target. As long as it stays above the threshold, it isn’t counted again, so one cough gives 1.
-
The Cough app has been working well for a while, then the result freezes and seq stops moving. What’s the most likely cause? (single choice · objective 4)
- a) A memory leak in the code
- b) The evaluation Ready Model hit its inference count ceiling
- c) CONF_FLOOR is set wrong
- d) The microphone is broken
Solution
b — an evaluation model limits the number of inferences. This is a property of the license, not a bug in the code. A model you trained yourself has no such limit.
- Run
17_latency_min_max_avg.pywithTARGET = "motion", then change it to"cough". Note the minimum, maximum, and average for both in your learning log. - Write out
find_model()by hand in your learning log, and explain why, on the emulator with no Push,select(3)gets a different model than on the board. - Sketch a rough graph of cough’s conf over time, and mark the points that should count under the rising-edge rule.
Going further
Section titled “Going further”In lesson 6.2, we’ll fill in s15_apps.py to make a cough-counting app, then retarget it to Alarm or Siren by changing just two lines at the top of the file.
Next lesson: lesson 6.2 — Hands-on: our own focused app
Reflect
Section titled “Reflect”- Which device around you is a single-model focused app, and what action does it take on a verdict?
- If you had to choose CONF_FLOOR for a car’s siren-detection alert, would you set it high or low, and why?
Review questions
Answer on your own first, then open the answer.
-
What kind of app should a bedside cough counter be? (Objective 1)
- เมนูที่ให้ผู้ใช้เลือกโมเดลเองทุกครั้ง
- แอปโฟกัสที่เล็งโมเดล Cough ตั้งแต่เปิด และต่อ verdict กับการนับ
- แอปที่สลับทุกโมเดลทุกวินาที
- ไม่ต้องมีแอป ใช้ REPL
Show answer
Answer: B. แอปโฟกัสที่เล็งโมเดล Cough ตั้งแต่เปิด และต่อ verdict กับการนับ
ผู้ใช้ปลายทางไม่ควรต้องรู้ว่ามีโมเดลอะไร เมนูเหมาะกับการสำรวจและเดโม แอปโฟกัสเหมาะกับงานจริง
-
Why is find_model(("cough",), edge_ai.SENSOR_MIC) better than edge_ai.select(3)? (Objective 2)
- เร็วกว่า
- หาโมเดลจากชื่อ จึงยังถูกตัวแม้ลำดับทะเบียนเปลี่ยน เช่น Emulator ที่ไม่มี Push ทำให้ Cough อยู่ index 2
- ใช้หน่วยความจำน้อยกว่า
- select(3) ใช้ไม่ได้บนบอร์ด
Show answer
Answer: B. หาโมเดลจากชื่อ จึงยังถูกตัวแม้ลำดับทะเบียนเปลี่ยน เช่น Emulator ที่ไม่มี Push ทำให้ Cough อยู่ index 2
บนบอร์ด Cough อยู่ index 3 แต่บน Emulator อยู่ index 2 การถามทะเบียนด้วยชื่อทำให้โค้ดชุดเดียวใช้ได้ทั้งสองที่
-
r['scores'] = [0.12, 0.88] for the labels ['unlabelled', 'cough']. What are r['top'] and r['conf']? (Objective 3)
- top = 0, conf = 0.12
- top = 1, conf = 0.88
- top = 0.88, conf = 1
- top = 1, conf = 0.12
Show answer
Answer: B. top = 1, conf = 0.88
top คือ index ของคะแนนสูงสุด (argmax) conf คือค่าคะแนนนั้นเอง คลาสที่ชนะจึงเป็น cough ด้วยความมั่นใจ 0.88
-
One cough spans three inferences with cough conf 0.8, 0.9, 0.85, then drops. How much does a rising-edge counter add? (Objective 4)
- 0
- 1
- 3
- 2
Show answer
Answer: B. 1
นับเฉพาะตอนเปลี่ยนจากไม่เข้าเป้าเป็นเข้าเป้า ตราบใดที่ยังค้างเหนือเกณฑ์จะไม่นับซ้ำ ไอหนึ่งครั้งจึงได้ 1
-
The cough app worked for a while, then the result freezes and seq stops moving. What is the most likely cause? (Objective 4)
- โค้ดมี memory leak
- โมเดล Ready-Model แบบประเมินผลถึงเพดานจำนวนครั้งอนุมาน
- CONF_FLOOR ตั้งผิด
- ไมค์เสีย
Show answer
Answer: B. โมเดล Ready-Model แบบประเมินผลถึงเพดานจำนวนครั้งอนุมาน
โมเดลประเมินผลจำกัดจำนวนครั้งอนุมาน นี่คือลักษณะของใบอนุญาต ไม่ใช่บั๊กในโค้ด โมเดลที่ฝึกเองไม่มีข้อจำกัดนี้
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.
"Six models and the edge_ai API: an app focused on one model" 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 API: แอปที่โฟกัสโมเดลเดียว" จาก TESA Open Knowledge โดยสมาคมสมองกลฝังตัวไทย (Thai Embedded Systems Association: TESA) https://github.com/tesaiot/tesa-qualification-program สัญญาอนุญาต CC BY-NC 4.0
Lesson link: https://tesaiot.github.io/tesa-qualification-program/en/courses/edge-ai-developer/m06-apps/l01-focused-apps/
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