Skip to content

Connected Embedded Systems

This is the starting point for a new book on connected embedded systems: sampling and sensing, control, real-time scheduling and the networked devices that bring them together.

  • Aliasing: When Sensors Lie covers sampling, the Nyquist rule and aliasing.
  • PID Control: Teaching a Drone to Hover builds up proportional, integral and derivative control.
  • PID on a Microcontroller: From Maths to Zephyr takes the same controller onto a simulated microcontroller running Zephyr, covering loop rate, fixed-point arithmetic, resolution and threads.
  • Priority Inversion: The Mars Pathfinder Resets explores priority inversion in a preemptive real-time scheduler.
  • Sensor Fusion: Building an IMU on the GY-85 builds up the accelerometer, gyroscope and magnetometer, fuses them with a complementary filter in 3D, and generates the Zephyr code.
  • CAN Bus: From Two Wires to Zephyr covers differential signalling, bit stuffing, arbitration, error confinement and decoding a frame by eye, then a sandbox with Zephyr (MCP2515) and SocketCAN code.
  • Real-Time Clocks: Inside the DS3231 covers why an RTC is needed, the BCD time registers, control and status, alarms and the latched INT/SQW interrupt, wiring it to a GPIO and the Linux kernel driver, then a sandbox with a simulated Raspberry Pi terminal (i2c-tools) and Zephyr code for an ESP32-S3. A knowledge test goes with it.
  • MQTT: Publish, Subscribe and the Broker in the Middle follows a greenhouse of ESP32-S3 nodes through a Mosquitto broker on a Raspberry Pi: why a broker, topics and wildcards, QoS on a flaky Wi-Fi link, retained messages and persistent sessions, keep-alive and the Last Will, and the packets byte by byte, then a sandbox with mosquitto_sub, mosquitto_pub and Zephyr code.
  • CoAP: The Web, Shrunk for Sensors takes the same greenhouse to CoAP over UDP: methods and response codes, CON and NON with retransmission and deduplication, Observe, discovery with /.well-known/core and content formats (text, JSON, CBOR), the 4-byte header byte by byte, and a tab comparing MQTT and CoAP (bytes on the air, design trade-offs, five scenarios), then a sandbox with libcoap’s coap-client and Zephyr code.
  • Bluetooth Low Energy: Advertising, GATT and the Coin Cell turns greenhouse node 1 into a XIAO nRF52840 on a coin cell: advertising and discovery on a radio waterfall, the 31-byte advertising packet byte by byte, connections with channel hopping, latency and AFH, the GATT attribute table and the CCCD, throughput, battery life, and a comparison with Wi-Fi and 802.15.4, then a sandbox with bluetoothctl on a Raspberry Pi and Zephyr code.
  • Zigbee and Thread: Meshes on 802.15.4 grows the greenhouse into a 120 m glasshouse: why a mesh, self-healing routes, sleepy end devices that poll their parents, Zigbee clusters and binding (with zigbee2mqtt), Thread’s IPv6, 6LoWPAN and border router, the same reading as a Zigbee and a Thread frame byte by byte, and a comparison with Matter, then a sandbox with ot-ctl on a Raspberry Pi and a Zephyr Thread node.
  • Wires and Buses: High-Z, I2C, SPI and I3C starts with what an output pin can do (push-pull, open-drain, high impedance), then pull-ups and rise time, I2C at the wire level and what goes wrong with it (clock stretching, arbitration, a stuck bus), SPI and its four modes, and I3C, with oscilloscope traces and logic-analyser decoding, then a sandbox with i2c-tools and spidev_test on a Raspberry Pi and Zephyr code.
  • Low Power: Sleep, Wake and the Coin Cell follows a battery sensor node’s current on a log scale: duty cycle and average current, the nRF52840’s sleep states, wake sources (including the DS3231 alarm waking System OFF), the leaks that spoil a sleep current, battery internal resistance and brown-out, measuring microamps without fooling yourself, and the whole budget, then a sandbox with Zephyr System ON and System OFF code.
  • GPIO from Linux User Space: libgpiod and pigpio drives the greenhouse fan relay, button and vent servo from C on a Raspberry Pi: who owns a pin (the kernel’s GPIO character device against pigpio’s direct register access), the libgpiod v2 C API, edge events and debounce, output timing and jitter, what pigpio’s DMA timing adds, why pigpio stops at the Pi 5, and choosing a route, then a sandbox with the libgpiod tools, pigs and pinctrl.
  • Device Tree, Overlays and Kernel Drivers shows how Linux learns about hardware it cannot discover: reading a .dts, Raspberry Pi overlays in config.txt, how a compatible string binds a driver (the DS3231 RTC, gpio-leds, gpio-keys), what happens to user-space GPIO once a driver owns a pin, and a first platform driver of your own, then a sandbox for a Pi 4 or Pi 5.
  • Qt Events: One Slot, Three Sources builds a Qt 6 Widgets application on the Raspberry Pi desktop around its event loop: the files and build steps (CMake at the command line or in Qt Creator), one slot fired by a GUI button, a QTimer and a physical GPIO button through libgpiod, what blocking the loop does, worker threads and queued connections, QMqttClient signals, and plotting with QCustomPlot, as the groundwork for a GUI MQTT subscriber.
  • Interfacing to ADCs Safely: Op-amps and Front Ends protects a delicate ADC input: resolution and the reference, the op-amp as a comparator and as a voltage follower, loading the reference the wrong way and the right way, source impedance and the sample capacitor, clamps and a rail-to-rail follower for inputs out of range, gain and offset to use the full range, and a Raspberry Pi with an MCP3208 over SPI reading a non-linear IR distance sensor, then a sandbox for building a front end.