2-14 / Series
2-14 № 14 · 2026

Think in Python.
Have the AI translate.

Assemble the parts, run the board, stream the readings home — the thinking stays on the Python side

Even when you are working against a board, the thinking stays on the Python side.

2-13: Make Diagrams and Documents — Mermaid, Marp, and the Other Tools took us as far as designing a sensor housing in Build123d code and 3D-printing it the same day. Inside that housing sits a board, sensors attach to the board, and the readings travel back to you over the network. This chapter builds that whole run. Buy the parts, wire them on a breadboard, verify the logic in Python on a PC, translate only what needs translating into C or Rust once it works, and stack the collected readings in your own store.

This chapter can be read as the first specification you hand to an AI. There are four things to decide — which board, which language, where the readings live, and how much you keep in your own hands. The AI knows how to write the code. What the human supplies is the answer to those four.

What is hard is that logic and hardware get mixed together

Anyone who has written embedded code knows where the time goes.

Logic errors and hardware instability get mixed together. When it stops working, you cannot separate the code from the wiring from the power supply. That is the single biggest reason embedded development has been slow.

The first thing you write is Python

On a new embedded job, the first thing you write is Python.

Read a value from a sensor, apply a filter, make a decision — write that on a PC rather than on the device. Prepare sample data as JSON, load it in Python, pass it through the filter, and print the decision.

def detect_anomaly(values):          # the decision fits in these few lines
    avg = sum(values) / len(values)
    return any(abs(v - avg) > 3 for v in values[-10:])

This code runs on a PC. It finishes in a second. You can plot it and check it with your eyes. You can swap the test data and run it again as often as you like. The rest — read the sample JSON, pass it to this function, print the result — is what the AI writes.

Whether the logic is correct can be settled apart from the hardware.

Leave the translation to the AI

Once the logic works in Python, translate it to C.

What the human decides and hands over looks roughly like this. The translated code itself comes from the AI.

Flash what comes back and run it. The logic is already settled in Python, so *if it fails on the device, the cause is on the hardware side*. Debugging gets a direction.

flowchart LR Idea(["the control you want
(sensor, decision)"]) Py["write it in Python
(run it on a PC)"] Data["verify with
sample JSON"] OK{"is the logic
correct?"} Trans["ask the AI to translate
to C / Rust"] HW["flash the device"] Bug{"does it run?"} HWFix["look at the hardware
(wiring, power, timing)"] Done(["done"]) Idea --> Py --> Data --> OK OK -->|fix| Py OK -->|correct| Trans --> HW --> Bug Bug -->|runs| Done Bug -->|stops| HWFix classDef good fill:#e8f5e9,stroke:#7a9a6d,color:#3a4d34 classDef bad fill:#fef3e7,stroke:#c89559,color:#5a3f1a class Py,Data,Trans good class HW,HWFix bad

Pick the language by development phase, not by hardware

Do not pick the embedded language per piece of hardware. Pick it by development phase and use case. Python first, Rust when performance demands it, C and C++ when handling what already exists — that is the AI-native embedded practice.

Development phase Language Environment Use case
Design and prototype Python (CPython) On a PC, Raspberry Pi Algorithm validation, data-collection experiments, AI model tests
Production (performance suffices) MicroPython ESP32, RP2040 Sensor control, IoT communication, light processing
Production (realtime performance needed) Rust STM32, RP2040, ESP32 High-speed control, realtime processing, memory-constrained operation
Production (edge AI, image processing) Python + C/Rust extensions Raspberry Pi, Jetson Inference, image processing, Linux deployment
Maintaining existing assets C, C++ Various microcontrollers Maintaining existing code, certified code

The first choice, where the hardware allows, is MicroPython or Python. When performance or capacity puts Python out of reach, pick Rust — its type and ownership checks run at compile time, so a mistake in AI-written code stops at the compiler. C and C++ are for maintaining existing assets and certified code. The room for choosing C or C++ on new work has narrowed to that.

At the Raspberry Pi class, the final form is often Python as well. If you can ship Python, no translation is needed. Only the parts of edge AI or image processing that need the speed become C / Rust extension modules (pybind11, PyO3) — the AI writes those too.

Move through five stages

The table above is the static menu; actual development moves through it in stages.

  1. Design and prototype — Work with the AI and confirm behavior in Python on a PC. Validate data collection, the algorithm, and AI model behavior there.
  2. Port to the microcontroller — Ask for a MicroPython translation. Run it on an ESP32 or RP2040. Many IoT and sensor use cases finish here.
  3. Identify performance bottlenecks — Run it and measure. Find where realtime performance is short and where memory is tight.
  4. Rewrite hotspots in Rust — Ask for Rust on the bottlenecks only. Decide whether to combine MicroPython and Rust, or rewrite the whole thing in Rust with embassy / RTIC.
  5. When edge AI is needed — Run on a Raspberry Pi (Linux) with Python + C/Rust extensions. Use hardware one step above a microcontroller.
flowchart TB S1["1. design and prototype
Python on a PC + AI"] S2["2. port to the MCU
MicroPython"] Q1{"performance and
memory enough?"} Done1(["done
(most IoT
stops here)"]) S3["3. find bottlenecks
run and measure"] S4["4. Rust the hotspots
(the AI translates)"] S5["5. to Raspberry Pi
Python + C/Rust ext"] Done2(["done
(realtime)"]) Done3(["done
(edge AI)"]) S1 --> S2 --> Q1 Q1 -->|enough| Done1 Q1 -->|short| S3 --> S4 --> Done2 Q1 -->|edge AI| S5 --> Done3 classDef good fill:#e8f5e9,stroke:#7a9a6d,color:#3a4d34 classDef bad fill:#fef3e7,stroke:#c89559,color:#5a3f1a class S1,S2,Done1 good class S3,S4,S5 bad

The point is not to start writing in Rust or C. Settle the logic in Python, then translate only the parts that need it. It is the same move as 2-04: Write the Logic — Own Your Tools with Python and Flet, where the logic inside Excel went out into Python, applied here to hardware. The AI carries the translation, so the human is not left moving back and forth between languages.

Think in Python. Only the final form changes language.

With MicroPython, the edit cycle is short

Small microcontrollers such as the ESP32 and RP2040 run MicroPython, a subset of Python.

Python written on a PC transfers to the microcontroller almost unchanged. There is no compile step, and the transfer takes seconds. Debugging feels the same as on a PC.

When you hit MicroPython's limits — memory, speed, available libraries — translate just that part to C. There is no need to translate all of it. Whatever can stay in Python stays.

What you build is a combination of off-the-shelf boards and modules

Seen from the electronics side, almost everything you build today is a combination.

Rather than designing a circuit, the work is deciding which module goes on which pin. Resistor calculations and level shifting still come up, and that is where you have the AI read the schematic and the datasheet — the next section.

Try it on a breadboard, then move it to a board

Start on a breadboard. Parts push in and pull out, so you can change the wiring as often as you need. Get as far as seeing the sensor value here.

Once the wiring is settled, move it to a permanent form: solder onto perfboard, or draw the board design and send it out for manufacture. A breadboard works, but wires come loose and contacts get unreliable. Anything that goes into a field or a factory, anything left powered and unattended, is easier later if you take it as far as soldering.

Where soldering is needed, and where it is not

The range that needs no soldering iron is wider than people expect.

At the prototype stage, soldering can wait. Fix things in place once you know they work.

The housing continues from the previous chapter's CAD

Once the board runs, it needs something to live in. In 2-13's Build123d or OpenSCAD, write the board dimensions, the mounting screw holes, the cable pass-through, and the cooling slots, and print it. If the dimensions are off, change the numbers and print again. The sensor housing comes back into your own hands here.

Where waterproofing or dust protection matters, buying a sealed enclosure and drilling it is sometimes faster. Anything outdoors, anything exposed to water, and anything handling high voltage carries a risk of electric shock and fire. Work on the mains side requires a licence. Start on the low-voltage DC side — what runs on batteries or USB power — and leave the AC side to someone licensed.

Parts and tools arrive by mail order

Parts come from electronic-component distributors and from the shops that carry the boards. Development boards, sensor modules, breadboards, jumper wires, USB cables — these are kept in stock and arrive in a few days. A soldering iron and a multimeter are one-time purchases that last for years.

The shape of the cost shows up in the farmer example later. A commercial IoT unit is bought at a per-unit price; an ESP32 plus sensors you assemble yourself costs only the parts. The more places you install, the more that gap matters.

Before buying, have the AI check the part numbers. "Does this sensor run at 3.3V?" "Will this plug straight into that board?" "List the parts I need." It cuts down on discovering a missing piece after the box arrives.

Have the AI read schematics and datasheets too

Schematics, wiring, datasheets — reading these can also go to the AI.

"I want to connect this OLED display module to an ESP32. Tell me the wiring and the code." Pin assignments, the library, the init code, and the display code come back.

If the datasheet is a PDF, extract the text and hand it over — "what does register 0x21 of this sensor do?" — and it answers. The AI holds hardware knowledge as well.

There are points to watch on the side that drives real hardware. If power drops while firmware is being written, recovering the board takes work. Some bootloader and fuse settings cannot be changed back. Code that drives a relay, a valve, or a motor gets read by a person before power goes on, with someone present. These are collected under "What the human holds" below.

Where the readings go

Once the board can measure, decide where the readings go. This is the IoT side.

First, choose how it connects.

Connection Suits Character
Wi-Fi Indoors, where power is available Rides the wireless LAN you already have. Easy to work with, draws more power
BLE Talking to a nearby machine or phone Runs long on batteries. Reaches about as far as a room
LoRa Fields, hills, spots spread outdoors Reaches far and runs long on batteries. Carries little data per message
Wired (Ethernet, serial) Factory lines, fixed installations Stable. Takes the work of running cable
Cellular Places with neither power nor LAN nearby Sends from anywhere. Requires a line contract

For a field or a shed with neither power nor LAN, the combination is LoRa out to the farmhouse and Wi-Fi or wire from there on. The sending interval is decided here too — record every minute, send every ten minutes together, and the batteries last.

Then decide what happens at the far end. From here on, the tools this series already stood up carry the work.

  1. The board sends JSON — record to the SD card every minute, send every ten minutes together
  2. FastAPI receives it — stand up one endpoint for readings, check the shape of the arriving JSON, then let it through (2-12)
  3. 2-03's store keeps it — into SQLite or PostgreSQL, with accumulated data dropped to Parquet
  4. The same FastAPI serves it back — add an endpoint beside it that takes a period and a location
  5. 2-04's Flet puts it on a screen — a tablet in the field, a browser in the office. For daily charts alone, Altair's HTML is enough

Instead of sending to a vendor's cloud, send to your own machine. With both the intake and the readout on FastAPI, adding a board or adding a screen means adding one endpoint. The readings stay with you, and there is no monthly contract.

One point to watch. When a board sits somewhere reachable from outside, do not leave the door open. Keep the direction one-way — board to your machine — and close any port that lets the board be called from outside. A default password, or an admin screen that opens without authentication, is an entry point. How to stand up authentication is in 2-05: Stand Up the Gate — One Login with PocketBase.

Analyzing the collected data continues in Python

Once readings accumulate in your hands, the analysis is Python as well.

Read from the store in 2-03: Lay the Foundation — SQLite, PostgreSQL, pgvector, DuckDB, Polars, aggregate with polars, chart with matplotlib / altair, do numerics with numpy. The JSON written on the board side and the Polars read on the PC side meet at the same column names.

"The sensor records temperature every minute. From this JSON, find the time of day when the temperature rose sharply, and chart it." The code comes back.

Even when the embedded body runs in C, everything around it — verification, analysis, visualization — runs in Python and AI. That is the new shape of embedded development.

Example: a room-temperature monitor stands up in three stages

One concrete example. An ESP32 measures room temperature and notifies when it goes above 30 °C.

Stage 1 (Python on a PC). Write the logic in Python. Prepare sample temperature data (JSON) and write the decision. Tuning the threshold, removing noise, setting the notification condition — experiment with all of it on the PC. What the human decides here is the decision itself: "notify when the average of the last five minutes goes above 30." Once that one line is settled, the AI writes the Python.

Stage 2 (MicroPython on the device). Transfer the Python logic to MicroPython. MicroPython is a subset of Python, so it runs almost as is. Attach a temperature sensor (a DHT22, for instance) and run it on real data.

Stage 3 (translate to C if needed). You want it to run long on batteries, or memory is tight — that is when you translate to C. Ask the AI and the translation comes out.

In many cases it ends at stage 2. MicroPython is enough.

Example: a farmer's field-sensor network

A second example. Farmer B wants soil-moisture, temperature, and solar-irradiance sensors at several spots in the field. Commercial units are priced per unit, and the data pools in the vendor's cloud.

Stage 1 (Python on a PC). Write the irrigation decision against historical weather data: "recommend irrigation if irradiance ≥ X Wh/m² and soil moisture < Y % hold for three consecutive hours." Apply it to the historical data with Polars and tune the thresholds. The AI writes the first version.

Stage 2 (MicroPython on the device). Port that logic to an ESP32 plus sensors. Because it is MicroPython, the PC code runs almost as is. Record JSON to an SD card every minute.

Stage 3 (aggregate on the farmhouse machine). Put one machine in the farmhouse — the machine from 2-02: Give the AI a PC of Its Own — The Machine the Independence Part Runs On will do. The ESP32s send JSON every ten minutes, FastAPI on that machine receives it, SQLite holds it, and accumulated data drops to Parquet. Daily charts in Altair, anomaly history in SQLite.

Stage 4 (design the irrigation actuator). Design the housing for the solenoid valve in 2-13's Build123d and print it. An ESP32 relay output opens and closes the valve, and the Python control code goes to the AI for a C translation only when MicroPython's memory falls short.

The result: only the parts cost per spot, across as many spots as you like; the data is yours; and there is no monthly vendor cloud fee. The decision logic reads as Markdown, and when something breaks you print a fresh part and repair it yourself.

The toolkit of the chapters so far converges into one project — 2-04's Python and Flet, 2-13's CAD, 2-03's Parquet, and FastAPI from 2-12: Build an API — Expose Core Logic with FastAPI carrying both the intake and the readout.

A twenty-year-old ladder becomes Python

C has run since the 1970s and Python since the 1990s, and both will keep running.

Embedded knowledge that has been held inside industry-specific languages — old PLC ladder logic, automotive special standards — moves out to the side of Python, C, and Markdown. It is the work of moving from a vendor's format to formats that cross time. It is a long job, but it advances a little every day.

The difference is the length of one round trip. Start in C++ and every fix means compiling and re-flashing the device — a round trip measured in minutes. With MicroPython the transfer takes seconds, and with Python on the PC the simulation is instant. The shorter the round trip, the more tries you get, and the sooner the decision logic settles.

And the largest example in this chapter. Twenty-year-old control logic written in industrial PLC ladder, where the engineer who wrote it has retired and no one in the company can read it now. Have the AI read the ladder, translate it to Python, and write the meaning out in Markdown. A job with no end in sight when read by hand comes back in a form that can be read.

Visualizing sensor data takes the same shape. Instead of building a web dashboard from scratch, one plot() line in matplotlib plus "turn this into an HTML report" gets to practical quality.

People who like making things move to the software side

This chapter carries a second meaning.

3-06: Companies Hire Builders argues that the supply of builders is not limited to former coders. Engineers in factories and small machine shops, people who have done electronics as a hobby, people who have shown at Maker Faire — those with experience making physical things move onto the software side.

The technical grounding for that claim is this chapter. Raspberry Pi and ESP32, MicroPython, and AI generation of circuit and control code. With those three in place, the learning cost at the entrance came down. Experience deciding what to build, experience isolating a fault when something stops, experience combining parts and separating structure — people who have been making things already hold what a builder needs. What was missing was only the hand that writes the code. The AI lends that hand.

For people who have been making things, software became one more hand rather than a new field to learn.

How to check you are done

This chapter is done when these six things hold.

  1. Python on the PC reads the sample JSON and returns one decision
  2. Flashing a MicroPython program to the board wired on the breadboard lights the LED, or prints a value to the REPL
  3. The board with a sensor attached records real readings every minute, and Python on the PC can read that record
  4. The readings travel over the network to your own machine, land in 2-03's store, and can be read back for a given period
  5. The board flashed with the translated C or Rust returns the same decision as Python
  6. With the board inside the 3D-printed housing, the same values come back after a power cycle
# send a local file to the MicroPython on the board and run it (mpremote installs with uv tool install)
mpremote connect auto fs cp main.py :main.py
mpremote connect auto run main.py

What the human holds

Values the human supplies

Actions the AI states before performing

Versions checked, and when

In summary

Even when you are working against a board, think in Python.

The tools are in place now: the foundation, the gate, documents, code, mail, meetings, the web, the API, diagrams — and the board, with the readings flowing from it. The next chapter prepares the information that flows over all of it. Files at the bottom of a shared folder, paper and scanned PDFs, and knowledge that lives only in someone's head — moved into written form.


Related articles