Prototyping · Study deck

Choosing a Programming Language

A greenhouse team can explore a watering rule quickly on a laptop.

Voltage Vera is your guide for this deck.

languages
iotclass.org

After studying this chapter

Learning objectives

You will be able to:

  • Choose a prototype language from evidence needs rather than habit or tool preference.
  • Separate device firmware, gateway, application, data, and test-harness language roles.
  • Identify when target timing, memory, power, safety, or update constraints require target-specific measurement.
  • Record what a language prototype proves, what it does not prove, and what must be checked again before production.
iotclass.org

Major section

In 60 Seconds · Start With the Story

The team should choose by evidence role.

  • A greenhouse team can explore a watering rule quickly on a laptop.
  • The final control board has far less memory, wakes from sleep, reads real pins, and must recover after lost power.
  • A short laptop script may expose bad maths or confusing data.
iotclass.org

Major section

Choose Runtime by Risk · Match Language to Execution

A host Python script can prove a calibration rule quickly, but it cannot prove MCU sleep current.

  • C or C++ can expose vendor-driver and interrupt behavior, but they do not automatically produce maintainable state logic.
  • Calibration formulas can be checked with host tests and then ported to firmware.
  • In the Language choice should route each prototype question through the constraint that matters, the runtime role, the run evidence, and the handoff decision diagram, Language choice should follow the prototype risk.
  • In the Language choice should route each prototype question through the constraint that matters, the runtime role, the run evidence, and the handoff decision diagram, Most IoT prototypes use several languages at once.

Why it matters

These artifacts reduce rewrite risk because reviewers can compare behavior across runtimes instead of trusting that a manual port stayed equivalent.

Language choice should route each prototype question through the constraint that matters, the runtime role, the run evidence, and the handoff decision.
Language choice should route each prototype question through the constraint that matters, the runtime role, the run evidence, and the handoff decision.
iotclass.org

Major section

Boundaries Carry Product Risk

A language boundary is also a unit, timing, ownership, and failure boundary.

  • Bugs often appear when a host script uses floating-point units differently than firmware, a gateway changes null handling, a dashboard assumes fresh state, or a firmware port changes payload field names.
  • Numeric and timing differences are common.
  • One owner confirms target measurements after firmware changes.
iotclass.org

Major section

Boundaries Carry Product Risk (continued)

Python may use floating point comfortably while firmware moves to fixed-point integer math.

  • JavaScript may treat missing, null, and undefined values differently from a C struct decoder.
  • A Rust no-std build may avoid heap allocation while a gateway implementation uses dynamic JSON parsing.
  • Runtime costs also decide whether a language is evidence for the target.
iotclass.org

Major section

Boundaries Carry Product Risk (continued)

One owner keeps the schema and test vectors current.

  • An event loop on Node.js can hide blocking calls that would starve a microcontroller control loop.
  • The shared tests should catch unit conversion, rounding, stale-state, and missing-field behavior before those differences reach a pilot.
  • One owner records dashboard or gateway assumptions.
iotclass.org

Major section

Boundaries Carry Product Risk (continued)

Garbage collection, interpreter startup, package size, TLS library footprint, task stack, allocator policy, exception handling, debug logging, and update image size can change memory, power, and recovery behavior.

  • The language decision is strong when a reviewer can repeat the target run, host run, and shared-interface tests and see which constraints each runtime actually proved.
  • A mixed-language prototype is therefore healthy only when it has a boundary owner.
  • Without those owners, each language can be locally reasonable while the system contract drifts across payload fields, units, error states, and retry behavior.
iotclass.org

Major section

Language Choice Is Evidence Choice · Avoid Language Slogans

The development environment chapter recorded how a prototype is built, uploaded, and observed.

  • This chapter asks what language should carry each software risk.
  • The useful question is not "Which language is best?" but "Which language makes this evidence easiest to trust?".
  • "Prototype in Python, ship in C" can be useful in some projects, but it is not a rule.
A language choice must pass timing, memory, power, safety, ecosystem, workflow, and target-evidence gates.
A language choice must pass timing, memory, power, safety, ecosystem, workflow, and target-evidence gates.
iotclass.org

Major section

Language Roles in an IoT Prototype · Constraint Gates

Most IoT prototypes are mixed-language systems even when the device firmware is small.

  • A reliable review names the role each language is playing.
  • App state may share that target but has a different job.
  • A host rig can stress parsers and state machines at high speed.
  • Others require target hardware.
Languages serve different runtime and boundary roles across firmware, gateways, services, analysis, and host testing.
Languages serve different runtime and boundary roles across firmware, gateways, services, analysis, and host testing.
iotclass.org

Major section

Measure the Constraint That Decides · Common Language Families

The exact language is less important than the runtime behavior, support boundary, and review trail.

  • C and C++ firmware: Strong fit for hardware control, small runtime, vendor SDKs, interrupts, RTOS integration, and target-specific power work.
  • MicroPython or CircuitPython: Strong fit for board exploration, sensor calibration, REPL-driven debugging, and quick demos.
  • CPython on Linux devices: Strong fit for gateways, test rigs, data processing, automation, and integration scripts.

Why it matters

Rust firmware: Strong fit when compile-time safety and explicit ownership help reduce memory and concurrency risk.

iotclass.org

Major section

Prototype-to-Production Handoff

A fast language can reveal domain logic before the production runtime is ready.

  • Algorithms, payload examples, calibration notes, test vectors, and state names can be kept when they do not depend on the original language.
  • Drivers, sleep and wake code, interrupts, memory ownership, and update logic must be rebuilt for the target.
  • the Prototype-to-production language handoff diagram separates prototype logic that transfers from runtime behavior that needs target testing.
  • The handoff in the Prototype-to-production language handoff diagram sorts a fast prototype by what can survive a runtime change.
Prototype-to-production language handoff
Prototype-to-production language handoff
iotclass.org

Major section

Worked Scenario: Cold-Room Monitor Logic · Mixed-Language Boundary Record

A team is prototyping a cold-room monitor.

  • The device samples temperature and door state, records excursions, and sends a compact status payload to a gateway.
  • The language decision is staged around evidence rather than around one permanent choice.
  • The target firmware and host harness both run against those examples.
Mixed-language boundary record
Mixed-language boundary record
iotclass.org

Major section

Python Foundations for Device Prototypes · Language Evidence

Python is useful in an IoT prototype when the first job is to make data and control flow visible.

  • A small program can hold numbers, strings, lists, tuples, and dictionaries; select a path with if/elif/else; repeat work with for or while; and stop or skip an iteration with break or continue.
  • The practical boundary is not syntax memorisation.
  • Its client creates the matching socket, connects to the server address, and sends data.
iotclass.org

Deck summary

Key takeaways

The team should choose by evidence role.

  • A host Python script can prove a calibration rule quickly, but it cannot prove MCU sleep current.
  • A language boundary is also a unit, timing, ownership, and failure boundary.
  • Python may use floating point comfortably while firmware moves to fixed-point integer math.
  • One owner keeps the schema and test vectors current.
iotclass.org

Retrieval practice

Recall check 1 of 4

Voltage Vera says: answer from memory, then check your reasoning.

Q1In this chapter's cold-room monitor example, a CPython/pandas script explores calibration curves from CSV exports. Per the chapter, what can that script NOT prove about the ESP32-C3 firmware?

ACalibration threshold logic that a script can explore with test vectors.
BFirmware heap, radio association, OTA slot, and wake-to-publish energy.
CGateway SQLite queue and service behavior outside ESP32 firmware.
DJSON Schema or CBOR payload definitions checked outside firmware.
Show answer

Answer: B see answers page

iotclass.org

Retrieval practice

Recall check 2 of 4

Voltage Vera says: answer from memory, then check your reasoning.

Q2Per this chapter's per-language measurement guidance, what should a Rust firmware review verify that is not listed for C/C++ firmware?

ABinary size, stack, heap, interrupts, watchdog, boot, sensor timing and OTA slot size for C/C++ firmware
BEvent loop, dependency lockfile, API contract and dashboard state for TypeScript/JavaScript
CHAL support, no-std crates, allocator and panic policy, probe-rs/defmt logging, RTIC/Embassy task behavior
DCalibration, payload shaping and gateway automation separated from MCU memory claims for Python
Show answer

Answer: C see answers page

iotclass.org

Retrieval practice

Recall check 3 of 4

Voltage Vera says: answer from memory, then check your reasoning.

Q3Per this chapter's 'Boundaries Carry Product Risk' section, why can a host script and firmware disagree even when both implement the 'same' calibration logic?

AThe faster runtime gets a newer sensor value; synchronizing clocks makes float/fixed-point rounding and absent-field decoding identical even with shared test inputs.
BRuntimes differ: Python float vs firmware fixed point and JS missing/null/undefined vs C decoding; shared tests must catch units, rounding and absent fields.
CConverting firmware output to float at the gateway recovers all lost fixed-point precision and makes missing fields match the host script.
DShared test vectors are language-specific and cannot compare units, rounding or absent fields across runtimes reliably.
Show answer

Answer: B see answers page

iotclass.org

Retrieval practice

Recall check 4 of 4

Voltage Vera says: answer from memory, then check your reasoning.

Q4A team prototypes sensor calibration in a high-level script, then wants to reuse the result in battery-powered firmware. What should they keep, and what must they check on target hardware?

AKeep the entire script unchanged, because one correct bench reading proves firmware timing and sleep behavior.
BDiscard every prototype result, because changing languages erases payload examples, state names, and calibration evidence.
CKeep calibration notes and test vectors; measure timing, memory, sleep current, watchdog, and recovery on target hardware.
DChoose the shortest source code, and skip board measurements for power, memory, watchdog, and update behavior.
Show answer

Answer: C A language prototype can produce reusable evidence, but only when the team separates language-neutral findings from target-runtime behavior that must be rebuilt and measured.

iotclass.org

Print reference

Answers 1 of 4

Answer key.

  1. B · The chapter's cold-room example splits evidence by runtime: CPython/pandas preserves calibration threshold logic and test vectors but cannot prove board-specific constraints like heap headroom, radio association time, OTA slot size, or wake-to-publish energy -- those require the C++/ESP-IDF firmware slice on the actual ESP32-C3.
iotclass.org

Print reference

Answers 2 of 4

Answer key.

  1. C · The chapter gives each language family its own measurement checklist: C/C++ firmware needs binary size, stack, heap, interrupt latency, watchdog, boot time, sensor timing, and OTA slot size; Rust firmware additionally needs HAL support, no-std crates, allocator policy, panic behavior, probe-rs/defmt logging, and RTIC/Embassy task behavior, plus team review readiness.
iotclass.org

Print reference

Answers 3 of 4

Answer key.

  1. B · The chapter names specific numeric and timing mismatches across language boundaries -- Python floating point vs firmware fixed-point integer math, JavaScript's missing/null/undefined handling vs a C struct decoder, a Rust no-std build avoiding heap allocation vs a gateway's dynamic JSON parsing -- and says shared tests should catch unit conversion, rounding, stale-state, and missing-field behavior before those differences reach a pilot.
iotclass.org

Print reference

Answers 4 of 4

Answer key.

  1. C · A language prototype can produce reusable evidence, but only when the team separates language-neutral findings from target-runtime behavior that must be rebuilt and measured.
iotclass.org