Beyond the Packet: Designing Reliable Serial Communication for Embedded Systems
Serial communication between microcontrollers sounds simple until the protocol quietly breaks your system. Prabo Semasinghe walks through the design steps for building a robust communication framework: packet structure, error detection, acknowledgment handling, state machine design, and the failure-mode testing that actually proves it works.
Project Log: Pixelblaze Christmas Lights
Festive fun and the hacker spirit combine in my janky attempt to adorn my house with addressable LEDs! In this post, I show you how I used a Pixelblaze and a cheap strip of WS2811 RGB LEDs (and not a little bit of hot glue and paper clips) to make a super cool set of Christmas lights.
Using a board with NuttX RTOS as an RS-485 / Modbus Slave Device
This practical walk-through shows how to turn a NuttX-equipped board into an RS-485 Modbus RTU slave using a cheap MAX485 transceiver and an STM32F4Discovery board. It explains why a simple UART plus a GPIO for DE/RE is enough, why the RP2040 needs special handling, and gives step-by-step configuration in NuttX, wiring for the transceiver, and a quick test using FreeModbus and mbpoll.
On hardware state machines: How to write a simple MAC controller using the RP2040 PIOs
Hardware state machines are nice, and the RP2040 has two blocks with up to four machines each. Their instruction set is limited, but powerful, and they can execute an instruction per cycle, pushing and popping from their FIFOs and shifting bytes in and out. The Raspberry Pi Pico does not have an Ethernet connection, but there are many PHY boards available… take a LAN8720 board and connect it to the Pico; you’re done. The firmware ? Introducing Mongoose…
How 5G impacts future IoT development
The Internet of Things (IoT) applications are ubiquitous today. IoT is used in almost every industrial, commercial, and consumer market segment, including autonomous driving, smart factories, automation and preventive maintenance, smart homes, smart cities, security, asset tracking, supply chain management, agriculture, farming, healthcare, smart medicine and remote surgery, augmented reality applications, activity monitoring, and more. The three most promising uses of IoT are smart manufacturing, autonomous driving, and healthcare, particularly remote surgery.
Picowoose: The Raspberry Pi Pico-W meets Mongoose
This example application describes the way to adapt the George Robotics CYW43 driver, present in the Pico-SDK, to work with Cesanta's Mongoose. We are then able to use Mongoose internal TCP/IP stack (with TLS 1.3), instead of lwIP (and MbedTLS).
How to use SPI devices in NuttX RTOS
You can get an SPI sensor running on NuttX in minutes by following a concrete RP2040 example. This post walks through the board glue code, Makefile and header edits, menuconfig settings, wiring, and flash steps needed to register a MAX6675 thermocouple on a Raspberry Pi Pico. Read it to learn where to add board-level code, enable drivers, and test the device from NSH.
When a Mongoose met a MicroPython, part II
In the first part of this blog, we introduced this little framework to integrate MicroPython and Cesanta's Mongoose; where Mongoose runs when called by MicroPython and is able to run Python functions as callbacks for the events you decide in your event handler. Now we add MQTT to the equation, so we can subscribe to topics and publish messages right from MicroPython.
ANCS and HID: Controlling Your iPhone From Zephyr
In this blog post, we see how certain BLE services can be used to control an iPhone from a Nordic nRF52840 using The Zephyr Project. Specifically, we see how to control certain multimedia functionality using the HID service. Finally, we learn how to use the ANCS client library provided by Nordic in The Zephyr Project to accept or decline an incoming call.
How to use I2C devices in (Apache) NuttX: Adding support for an I2C device in your board
You can add an I2C sensor to NuttX with a few file edits, menuconfig tweaks, and a standard build-and-flash cycle. This guide shows how the BMP280 barometer was integrated into the Raspberry Pi Pico bringup by copying and adapting an existing board driver, wiring the sensor to I2C0, enabling the BMP280 option in menuconfig, and compiling and flashing the resulting nuttx.uf2. It includes exact wiring and build tips.
Creating a Hardware Abstraction Layer (HAL) in C
In my last post, C to C++: Using Abstract Interfaces to Create Hardware Abstraction Layers (HAL), I discussed how vital hardware abstraction layers are and how to use a C++ abstract interface to create them. You may be thinking, that’s great for C++, but I work in C! How do I create a HAL that can easily swap in and out different drivers? In today’s post, I will walk through exactly how to do that while using the I2C bus as an example.
VHDL tutorial - A practical example - part 2 - VHDL coding
Gene Breniman walks through the VHDL coding for a CPLD-based data acquisition engine, turning the hardware spec into a working state machine and signal generators. The article explains SPI and I2S timing choices, an internal SPI peripheral latch, and counter-based timing (seqCount and CycleCnt) used to create LRCK, BCK, SPI SCK and nvSRAM write control. It’s a practical, implementation-focused guide for embedded designers.
Introduction to Microcontrollers - Beginnings
Mike Silva's beginner tutorial series walks through core microcontroller concepts and practical steps to get started, from wiring an LED blinky to understanding startup code. He compares embedded and desktop programming, explains why C and assembly matter, and introduces AVR and STM32 Cortex-M3 toolchains and hardware. Expect clear examples, no-nonsense tool advice, and the essential hardware knowledge to move from simulator to a real board.
Surprising Linux Real Time Scheduler Behavior
An embedded Linux data acquisition project ran into puzzling UART latency whenever heavy UI animations ran. Moving all app threads to SCHED_FIFO helped but did not eliminate delays. After reading about kernel worker thread interactions, Matthew moved the UI back to the normal scheduler and the jitter vanished. The post highlights an unexpected kernel level priority inversion risk and a pragmatic workaround.
Introduction to Microcontrollers - Driving WS2812 RGB LEDs
Mike Silva walks through a practical, cycle-counted AVR assembly implementation to bit-bang WS2812B RGB LEDs from an 8MHz AVR, hitting the chip's tight 1.25µs-per-bit timing. The post breaks down the WS2812B self-clocked protocol and GRB byte order, explains register and calling-convention choices, and includes a complete C example plus power-consumption warnings for driving LED strips.
Beyond the Packet: Designing Reliable Serial Communication for Embedded Systems
Serial communication between microcontrollers sounds simple until the protocol quietly breaks your system. Prabo Semasinghe walks through the design steps for building a robust communication framework: packet structure, error detection, acknowledgment handling, state machine design, and the failure-mode testing that actually proves it works.
Practical CRCs for Embedded Systems
Stephen Friederichs shows a practical way to get correct CRC code quickly by using PyCRC to generate C implementations, then verifying them on the desktop and an AVR ATMega328P. The post walks through the common generation algorithms, how to self-test with the standard "123456789" check value, and a real timing comparison that exposes the speed versus memory tradeoffs for embedded systems.
On hardware state machines: How to write a simple MAC controller using the RP2040 PIOs
Hardware state machines are nice, and the RP2040 has two blocks with up to four machines each. Their instruction set is limited, but powerful, and they can execute an instruction per cycle, pushing and popping from their FIFOs and shifting bytes in and out. The Raspberry Pi Pico does not have an Ethernet connection, but there are many PHY boards available… take a LAN8720 board and connect it to the Pico; you’re done. The firmware ? Introducing Mongoose…
Creating a GPIO HAL and Driver in C
Creating a GPIO Hardware Abstraction Layer (HAL) in C allows for flexible microcontroller interfacing, overcoming the challenge of variability across silicon vendors. This method involves reviewing datasheets, identifying features, designing interfaces, and iterative development, as detailed in the "Reusable Firmware" process. A simplified approach prioritizes essential functions like initialization and read/write operations, showcased through a minimal interface example. The post also highlights the use of AI to expedite HAL generation. A detailed GPIO HAL version is provided, featuring extended capabilities and facilitating driver connection through direct assignments or wrappers. The significance of a configuration table for adaptable peripheral setup is emphasized. Ultimately, the blog illustrates the ease and scalability of developing a GPIO HAL and driver in C, promoting hardware-independent and extensible code for various interfaces, such as SPI, I2C, PWM, and timers, underscoring the abstraction benefits.
Working with Strings in Embedded C++
This article discusses the use of strings in embedded systems. It explains how the need for and use of strings in embedded systems has changed with the advent of cheaper, full graphic displays and the growth of the ‘Internet of Things’ (IoT). The article also covers character literals, C-Strings and string literals, and the difference in memory models between them. It also highlights the safety and security issues that arise from using strings in embedded systems. Finally, it explains how C++11 introduced a Raw string literal type that is useful for storing file paths or regular expressions.
Introduction to Microcontrollers - Beginnings
Mike Silva's beginner tutorial series walks through core microcontroller concepts and practical steps to get started, from wiring an LED blinky to understanding startup code. He compares embedded and desktop programming, explains why C and assembly matter, and introduces AVR and STM32 Cortex-M3 toolchains and hardware. Expect clear examples, no-nonsense tool advice, and the essential hardware knowledge to move from simulator to a real board.
MSP430 LaunchPad Tutorial - Part 4 - UART Transmission
Want to stream sensor or debug data from an MSP430 LaunchPad to a PC or Bluetooth module? Enrico swaps in an MSP430G2553 and shows how to configure SMCLK, P1 pin multiplexing, and UCA0 baud/dividers (with modulation) to approximate 115200 baud. The post also walks through interrupt-driven RX/TX handling and a low-power wait loop that sends a "Hello World" reply on demand.
Introduction to Microcontrollers - Driving WS2812 RGB LEDs
Mike Silva walks through a practical, cycle-counted AVR assembly implementation to bit-bang WS2812B RGB LEDs from an 8MHz AVR, hitting the chip's tight 1.25µs-per-bit timing. The post breaks down the WS2812B self-clocked protocol and GRB byte order, explains register and calling-convention choices, and includes a complete C example plus power-consumption warnings for driving LED strips.
VHDL tutorial - A practical example - part 2 - VHDL coding
Gene Breniman walks through the VHDL coding for a CPLD-based data acquisition engine, turning the hardware spec into a working state machine and signal generators. The article explains SPI and I2S timing choices, an internal SPI peripheral latch, and counter-based timing (seqCount and CycleCnt) used to create LRCK, BCK, SPI SCK and nvSRAM write control. It’s a practical, implementation-focused guide for embedded designers.
Help, My Serial Data Has Been Framed: How To Handle Packets When All You Have Are Streams
Framing byte streams is easier to get wrong than you think, and a bad scheme can leave your embedded device acting on the wrong packet. Jason Sachs walks through common plaintext and binary framing approaches, explains why CRCs alone can still permit false resynchronization, and demonstrates COBS as a simple, low-overhead byte-stuffing method that prevents delimiter collisions and guarantees resynchronization.
Endianness and Serial Communication
A single wrong byte order can cost you a day of debugging, and Stephen Friederichs walks through how to avoid that when sending multi-byte data over a byte-oriented serial link. He demonstrates an ATmega328P sending 16-bit ADC readings, capturing raw bytes with RealTerm, and plotting with Octave, showing how swapped endianness can produce plausible but incorrect results. The post gives practical steps to capture, test, and verify byte order.
Creating a Hardware Abstraction Layer (HAL) in C
In my last post, C to C++: Using Abstract Interfaces to Create Hardware Abstraction Layers (HAL), I discussed how vital hardware abstraction layers are and how to use a C++ abstract interface to create them. You may be thinking, that’s great for C++, but I work in C! How do I create a HAL that can easily swap in and out different drivers? In today’s post, I will walk through exactly how to do that while using the I2C bus as an example.
Arduino robotics #4 - HC-SR04 ultrasonic sensor
Lonnie Honeycutt shows how to turn a $50 mobile platform into a simple autonomous robot by adding an HC-SR04 ultrasonic sensor to an Arduino. The post walks through wiring, a minimal test sketch and the integration code used on Clusterbot, plus practical tips on range limits, motor choices and library options to make obstacle avoidance reliable for hobby builds.
How to use I2C devices in (Apache) NuttX: Scanning for Devices
Hands-on guide to scanning I2C peripherals on NuttX using a Raspberry Pi Pico, showing how the RTOS exposes i2c master instances and the i2ctool. The article walks through where the RP2040 I2C driver lives, how to enable I2C0 in menuconfig, build and flash nuttx, and run the i2c dev command to probe the bus. Verify sensors like BMP280 or SSD1306 before registering drivers.
The CRC Wild Goose Chase: PPP Does What?!?!?!
Jason Sachs walks through a CRC rabbit hole and explains why ambiguous CRC names and incomplete specs lead to subtle protocol bugs. He demonstrates how XMODEM and KERMIT variants with a zero initial value can miss dropped leading-zero bytes, praises the X.25 standard for providing test vectors and a clear CRC16 definition, and warns that RFCs that ship only sample code are a poor substitute for a proper specification.





















