From raw numbers to physical quantities: tilt, energy, altitude and dBFS
Module 3 — Processing with maths and physics · Slides: slides.md · Module overview · Course page
Enter the Processing stage with the raw → derived → viz pattern. Turn raw numbers into four quantities people understand — tilt angle with atan2, motion energy, altitude from pressure, and sound level in dBFS — and choose the right widget for each.
Objectives
Section titled “Objectives”By the end of this lesson, you will:
- Explain the raw → derived → viz pattern, and say which quantities use a ready-made dsp function (tilt, altitude) and which need your own formula (energy, dBFS).
- Compute roll and pitch from three-axis acceleration with atan2, and explain why the accelerometer’s unit cancels out in the ratio formula.
- Compute motion energy from motion(), which is in m/s² (divide by 9.81 to get g, then subtract 1 g), and relative altitude with dsp.altitude(p, p0).
- Choose a widget (Seg7, Bar, Chart, Arc) to match each quantity, and explain why dBFS uses a log scale.
Before you start
Section titled “Before you start”You’ve been through module 2, can read raw sensor values, and remember the four-beat skeleton from lesson 1.4. Open s06_physics_viz_full.py (in lesson 3.2) and try it before taking it apart.
- Hardware: a TESAIoT Dev Kit board already flashed with BENTO’s MicroPython firmware, or the BENTO Emulator inside BENTO IDE — Tilt, Energy and Altitude work on the emulator; real sound level needs the board’s microphone.
- Prior lesson: lesson 2.4 — Hands-on: IMU and sound in one file
See it work first
Section titled “See it work first”Run s06_physics_viz_full.py first. Pick a quantity in the dropdown, then tilt, shake, or raise and lower the board — the computed number genuinely changes. This lesson’s question is: “how does a number from a sensor turn into a quantity that actually means something?”
Concepts
Section titled “Concepts”A raw number like (0.20, -6.97, 6.87, 1.1, -0.4, 0.3) from sensors.bmi270.motion() doesn’t tell a person anything yet. The Processing stage turns it into a meaningful quantity through three beats: raw → derived → viz (read raw → compute → display). This lesson’s four quantities all share the same skeleton, differing only in the formula in the middle. dsp computes on the C side, so it’s fast — two quantities have ready-made functions, and we write the formula for the other two ourselves.
Tilt angle: the accelerometer measures gravity’s vector, which always points toward the ground. When the board tilts, this force spreads across three axes, and we recover the angle with $\text{roll} = \operatorname{atan2}(a_y, a_z)$ and $\text{pitch} = \operatorname{atan2}(-a_x, \sqrt{a_y^2 + a_z^2})$ — the exact same formula dsp.tilt(ax, ay, az) uses, returning (roll, pitch) in degrees (roll first). The formula is a ratio of axes, so the unit cancels out, and atan2 knows the quadrant, giving a full-range angle with no division-by-zero problem.
Motion energy: motion() returns acceleration in m/s² (at rest ≈ 9.81). Dividing the vector’s magnitude by 9.81 gives units of g: $|a| = \sqrt{a_x^2 + a_y^2 + a_z^2} / 9.81$. At rest, this is about 1 g, so we subtract 1: energy = abs(mag - 1.0), making “still = 0”, leaving only the part caused by movement. Altitude: air pressure drops with height. dsp.altitude(p, p0) uses the barometric formula against a reference pressure p0, captured once before the loop, giving a relative altitude — raising the board 1 metre raises the value by about +1.0 (if p0 isn’t given, it’s compared against 1013.25 hPa). Sound level: $\text{rms} = \sqrt{\frac{1}{N}\sum s_i^2}$, then $\text{dBFS} = 20\log_{10}(\text{rms}/32768)$ — using 20 because RMS is an amplitude, and a log scale because human ears perceive loudness logarithmically. The decibel scale squeezes the wide range from −96 to 0 into something easy to read.
The viz step is choosing the picture that matches the data: Seg7 for a prominent number, Bar for a level against a 0..100 range, Chart for a trend over time, and Arc for an angle. Every quantity is normalized into the 0..100 range with clamp100 before feeding Bar and Chart.
Worked example
Section titled “Worked example”This lesson’s examples are physics apps using the same raw → derived → viz skeleton: 03_baro_pressure_altitude.py shows pressure with a trend graph (storing hPa × 10, since Chart accepts integers), while 09_radar_theremin.py converts a hand’s distance from the radar into a musical note with ui.tone. Try predicting before running each one: what quantity does it turn the raw value into?
| File | What this file teaches |
|---|---|
| examples/03_baro_pressure_altitude.py | DPS368: a pressure display + trend graph + high/low stats |
| examples/09_radar_theremin.py | Radar Theremin: hand distance = a musical note (J8 speaker) + a pitch gauge on screen |
This lesson’s slides also reference files in another lesson and under shared/:
- m03-processing/l02-physics-gauges-lab/examples/s06_physics_viz_full.py — Physics Lab: raw -> derived -> viz (full version)
- m03-processing/l02-physics-gauges-lab/practice/s06_physics_viz.py — Physics Lab: raw -> derived -> viz (the fill-in-the-code version)
- shared/interactive/math_lab.html
Check your understanding
Section titled “Check your understanding”The same questions are in quiz.yaml for automated checking.
-
Which quantities in this lesson have a ready-made function in dsp? (select every correct answer) (multiple choice · objective 1)
- a) Tilt angle (dsp.tilt)
- b) Altitude (dsp.altitude)
- c) Motion energy
- d) Sound level (dBFS)
Solution
a, b — tilt and altitude exist in the dsp module; energy and dBFS we write ourselves with math.sqrt and math.log10.
-
ax = 0, ay = 6.9, az = 6.9 m/s². What is roll = atan2(ay, az)? (single choice · objective 2)
- a) 0 degrees
- b) 45 degrees
- c) 90 degrees
- d) Can’t be computed without converting to g first
Solution
b — atan2(6.9, 6.9) = 45°. The formula is a ratio, so units cancel out — m/s² or g both give the same angle.
-
The board lies still, so motion() gives |a| ≈ 9.81 m/s². If you write energy = abs(mag - 1.0) without dividing by 9.81, what do you get? (single choice · objective 3)
- a) About 0, as intended
- b) About 8.8 — the bar stays full even while still
- c) About −1
- d) An error, because math.sqrt can’t accept a negative value
Solution
b — you must divide by 9.81 to get units of g first. At rest, mag ≈ 1, and subtracting 1 leaves about 0.
-
Why capture pressure p0 once before the loop, and pass it into dsp.altitude(p, p0)? (single choice · objective 3)
- a) Because dsp.altitude always needs two values
- b) To get a relative altitude against the starting point, which clearly shows the board being lifted, independent of that day’s weather
- c) To warm up the sensor
- d) To convert hPa to kPa
Solution
b — p0 is an optional argument. Without it, altitude is compared against 1013.25 hPa, giving height above sea level that depends on the weather. Supplying your own p0 puts zero at the moment the program starts.
-
Why does sound level use the dBFS (log) scale instead of the RMS value directly? (single choice · objective 4)
- a) Because log computes faster
- b) Because ears perceive loudness logarithmically, and sound’s range is very wide — log keeps quiet sounds from being squeezed unreadable
- c) Because RMS can be negative
- d) Because Bar only accepts negative values
Solution
b — the decibel scale compresses a wide range, roughly −96 to 0 dBFS, into something easy to read, the same way the Richter scale or pH does.
- Compute the roll angle of (ax, ay, az) = (0, −6.97, 6.87) m/s² by hand or with a calculator, and compare it against
dsp.tiltin the REPL. - With the board lying still, compute energy both dividing by 9.81 and without, and note in your learning log how they differ.
- If you have a board, raise and lower it by one metre and watch how much
dsp.altitude(p, p0)changes.
Going further
Section titled “Going further”In lesson 3.2, we’ll fill in four formulas in the s06_physics_viz.py file and watch all four gauges move with real motion.
Next lesson: lesson 3.2 — Hands-on: four physics gauges on screen
Reflect
Section titled “Reflect”- What devices around you convert raw numbers into quantities the same way this lesson does — a step counter, or a phone that knows which floor it’s on?
- If you had to show air pressure to an everyday person, which widget would you choose, and why?
Review questions
Answer on your own first, then open the answer.
-
Which quantities in this lesson have a ready function in dsp? (select all that apply) (Objective 1)
- มุมเอียง (dsp.tilt)
- ความสูง (dsp.altitude)
- พลังงานการเคลื่อนไหว
- ระดับเสียง dBFS
Show answer
Answer: A. มุมเอียง (dsp.tilt) · B. ความสูง (dsp.altitude)
tilt กับ altitude มีในโมดูล dsp ส่วน energy กับ dBFS เราเขียนสูตรเองด้วย math.sqrt และ math.log10
-
With ax = 0, ay = 6.9 and az = 6.9 m/s², what is roll = atan2(ay, az)? (Objective 2)
- 0 องศา
- 45 องศา
- 90 องศา
- คำนวณไม่ได้เพราะไม่ได้แปลงหน่วยเป็น g ก่อน
Show answer
Answer: B. 45 องศา
atan2(6.9, 6.9) = 45° สูตรเป็นอัตราส่วน หน่วยจึงหักล้างกัน ใช้ m/s² หรือ g ก็ได้มุมเท่ากัน
-
At rest motion() gives |a| ≈ 9.81 m/s². If you write energy = abs(mag - 1.0) without dividing by 9.81, what do you get? (Objective 3)
- ราว 0 ตามที่ต้องการ
- ราว 8.8 แถบจะเต็มตลอดแม้วางนิ่ง
- ราว −1
- error เพราะ math.sqrt รับค่าลบไม่ได้
Show answer
Answer: B. ราว 8.8 แถบจะเต็มตลอดแม้วางนิ่ง
ต้องหาร 9.81 ให้เป็นหน่วย g ก่อน ตอนนิ่ง mag ≈ 1 แล้วลบ 1 จึงเหลือราว 0
-
Why capture the pressure p0 once before the loop and pass it to dsp.altitude(p, p0)? (Objective 3)
- เพราะ dsp.altitude ต้องมีสองค่าเสมอ
- เพื่อให้ได้ความสูงสัมพัทธ์เทียบกับจุดเริ่ม ซึ่งเห็นการยกบอร์ดชัดและไม่ขึ้นกับสภาพอากาศวันนั้น
- เพื่อให้เซนเซอร์อุ่นเครื่อง
- เพื่อแปลง hPa เป็น kPa
Show answer
Answer: B. เพื่อให้ได้ความสูงสัมพัทธ์เทียบกับจุดเริ่ม ซึ่งเห็นการยกบอร์ดชัดและไม่ขึ้นกับสภาพอากาศวันนั้น
p0 เป็นอาร์กิวเมนต์ไม่บังคับ ถ้าไม่ใส่จะเทียบกับ 1013.25 hPa ได้ความสูงเหนือน้ำทะเลที่ขึ้นกับอากาศ การใส่ p0 เองทำให้จุด 0 อยู่ที่ตอนเริ่มโปรแกรม
-
Why is sound level shown in dBFS (log) rather than raw RMS? (Objective 4)
- เพราะ log คำนวณเร็วกว่า
- เพราะหูรับรู้ความดังแบบ log และช่วงของเสียงกว้างมาก log ทำให้เสียงเบาไม่เบียดกันจนอ่านไม่ออก
- เพราะ RMS ติดลบได้
- เพราะ Bar รับเฉพาะค่าติดลบ
Show answer
Answer: B. เพราะหูรับรู้ความดังแบบ log และช่วงของเสียงกว้างมาก log ทำให้เสียงเบาไม่เบียดกันจนอ่านไม่ออก
สเกล decibel บีบช่วงกว้างตั้งแต่ราว −96 ถึง 0 dBFS ให้อ่านง่าย แบบเดียวกับริกเตอร์หรือ pH
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.
"From raw numbers to physical quantities: tilt, energy, altitude and dBFS" 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: "จากตัวเลขดิบสู่ปริมาณทางฟิสิกส์: มุมเอียง พลังงาน ความสูง และ dBFS" จาก 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