From micro:bit to Linux: Building a Tiny Sensor Data Pipeline
From micro:bit to Linux: Building a Tiny Sensor Data Pipeline
A micro:bit takes a temperature reading. A Raspberry Pi Pico W receives it, adds some context, and passes it across the network. A Linux workstation cleans the incoming data and turns it into CSV, JSON, and SQLite.
That is a surprisingly complete data pipeline built from some very inexpensive hardware.
For this project, we're going to concentrate less on wiring things together and more on something I think is more interesting: what happens to the data as it travels through the system.
Our pipeline looks like this:
micro:bit
↓
sensor measurement
↓
UART serial
↓
Pico W
↓
timestamp
↓
HTTP POST
↓
Linux workstation
↓
Python + Pandas
↓
cleaned data
├── CSV
├── JSON
└── SQLite
No MQTT broker. No cloud platform. No elaborate IoT infrastructure.
Just three small computers passing data from one stage to another.
The Hardware
The physical arrangement is straightforward.
We have a BBC micro:bit collecting sensor data. We'll use its temperature reading simply because it gives us something interesting to move through the pipeline.
The micro:bit is connected to a
Raspberry Pi Pico W
through UART serial. The micro:bit's MicroPython implementation supports UART
communication, including reading and writing bytes, and its API provides a
temperature()
function.
The Pico W, in turn, connects over Wi-Fi to a Linux workstation.
That's about as deeply as we need to get into the hardware for this article.
The interesting part is what happens next.
Follow the Data
Imagine that the micro:bit measures:
23
That's our starting point.
The micro:bit converts the measurement into a simple line of text and sends it through UART:
23\n
On the wire, though, there's no CSV file moving between the micro:bit and Pico.
UART is a serial communication system. MicroPython's UART interface reads and writes byte streams.
Conceptually, our data now looks like:
b"23\n"
The Pico receives those bytes and turns them back into useful data.
Then the Pico adds a timestamp:
2026-10-15T16:03:27,23
Now our measurement has two pieces of information:
timestamp,temperature
Before the Pico can attach a meaningful calendar timestamp, however, its clock has to know the correct time.
On bare-metal MicroPython, calendar time depends on the real-time clock (RTC). That clock can be set manually or synchronized using network time protocol (NTP). Since our Pico W is already using Wi-Fi, we can synchronize its clock when the program starts before we begin timestamping sensor measurements.
The Pico W then sends that record across the local network using an HTTP POST.
This makes the Pico W the HTTP client and the Linux workstation the HTTP server. HTTP follows that client/server model, with the client initiating a request and the server handling it.
Notice what we still don't need: we don't need the Pico continually creating physical CSV files.
We're just moving small structured records.
The Linux workstation can decide what files and databases should ultimately be created.
Code on the micro:bit
The micro:bit has a very small job:
- Read the sensor.
- Turn the reading into text.
- Send it through UART.
- Wait.
- Repeat.
The micro:bit MicroPython API provides
temperature(), while its UART API provides
uart.write().
A simplified program looks like this:
from microbit import *
uart.init(
baudrate=9600,
tx=pin0,
rx=pin1
)
while True:
temp = temperature()
uart.write(str(temp) + "\n")
sleep(5000)
Every five seconds our micro:bit produces another measurement.
Its responsibility ends there.
That separation is important. The micro:bit doesn't know anything about Pandas, HTTP, SQLite, JSON, or whatever we're eventually going to do with the data.
It simply measures something and reports it.
Code on the Pico W
The Pico has a more interesting job. It sits between the device generating the measurements and the computer that will process them.
Conceptually:
UART IN
↓
decode reading
↓
add timestamp
↓
HTTP POST
↓
Wi-Fi OUT
MicroPython's UART interface gives us methods such as
readline()
for retrieving incoming data.
Our Pico code might begin along these lines:
from machine import UART, Pin
import time
uart = UART(
0,
baudrate=9600,
rx=Pin(1),
tx=Pin(0)
)
while True:
if uart.any():
data = uart.readline()
if data:
temperature = data.decode().strip()
timestamp = time.time()
record = {
"timestamp": timestamp,
"temperature": int(temperature)
}
print(record)
We've deliberately left the Wi-Fi connection and clock synchronization details out of this example so that the important transformation remains visible.
Before entering this measurement loop, the Pico W would connect to Wi-Fi and
establish the correct time via NTP. The RP2 MicroPython port uses the POSIX
epoch for
time.time(), but meaningful current calendar time still depends on the Pico's RTC being
set correctly.
The Pico has changed this:
23
into something conceptually like:
timestamp + 23
The next step is to POST that record to an endpoint running on Linux.
A Pico W can operate as an HTTP client, sending requests to a server.
Conceptually:
response = requests.post(
SERVER_URL,
json=record
)
The exact networking code can vary with the MicroPython HTTP library being used. The architectural point is more important: the Pico pushes each completed record upstream.
The Linux Workstation
Now we reach the machine that can comfortably do the heavier work.
Let's imagine a small Python web service receives:
{
"timestamp": 1792109007,
"temperature": 23
}
Each HTTP POST gives the Linux service one new sensor record.
The service can accumulate those individual records for a short period:
POST #1 → one record
POST #2 → one record
POST #3 → one record
POST #4 → one record
↓
collection of records
↓
Pandas
Then it can periodically hand that collection to Pandas as a batch:
import pandas as pd
df = pd.DataFrame(records)
Now we have something resembling:
timestamp temperature
1792109007 23
1792109012 23
1792109017 24
1792109022 23
This is where we can validate measurements, remove incomplete records, convert timestamps, rename columns, sort the data, or perform whatever other cleanup our application requires.
The little microcontrollers didn't have to do any of that.
One Dataset, Three Destinations
Once Pandas has cleaned our data, we can distribute it in forms appropriate for different consumers.
CSV
For someone opening the measurements in Excel:
df.to_csv(
"temperature_clean.csv",
index=False
)
The resulting file might look like:
timestamp,temperature
2026-10-15T16:03:27,23
2026-10-15T16:03:32,23
2026-10-15T16:03:37,24
JSON
For developers, APIs, automation, or other applications:
df.to_json(
"temperature.json",
orient="records",
date_format="iso"
)
Pandas supports several JSON orientations, including
records, and supports ISO-formatted dates when writing JSON.
SQLite
And finally, we can put the same records into a small relational database:
import sqlite3
connection = sqlite3.connect(
"temperature.db"
)
df.to_sql(
"readings",
connection,
if_exists="append",
index=False
)
connection.close()
Pandas supports writing DataFrame records into SQL databases and accepts a
standard
sqlite3.Connection.
Now our tiny temperature sensor has produced three useful data products:
-
temperature_clean.csv -
temperature.json -
temperature.db
The Bigger Idea
The fun part of this project isn't really temperature measurement.
It's the division of labor.
micro:bit
MEASURE
↓
Pico W
TIMESTAMP + TRANSPORT
↓
Linux
PROCESS + STORE + DISTRIBUTE
Each machine performs the job appropriate to its place in the system.
- The micro:bit remains a simple field device.
- The Pico becomes the bridge between the sensor and the network.
- And Linux becomes our data-processing machine, where Python and Pandas can clean and transform incoming measurements before sending them to CSV, JSON, SQLite, or somewhere else entirely.
Look at the whole thing again:
SENSOR
│
▼
micro:bit
│
UART bytes
│
▼
Pico W
│
timestamp record
│
HTTP POST
│
▼
Linux workstation
│
Python
│
Pandas
│
cleaned dataset
┌────────┼────────┐
▼ ▼ ▼
CSV JSON SQLite
│ │ │
▼ ▼ ▼
Excel Dev Data
tools queries
That's a complete little edge-to-Linux data pipeline sitting on a desk.
And we deliberately left out one technology that often appears in telemetry systems: MQTT.
That's where we'll go in Article #2.
We'll keep the same basic pipeline, but add MQTT and see how the flow of our sensor data changes when we introduce a publish-and-subscribe messaging layer.
But first, it's worth understanding the simple system.
Once you understand the data moving from sensor → serial → HTTP → Pandas → database, MQTT doesn't have to feel like another mysterious technology piled onto an IoT project.
It is simply the next piece of the pipeline.
