C++17’s Useful Features For Embedded Systems

Although the world of embedded software development languages seem to span somewhere between ASM and C89 all the way to MicroPython, there is a lot to be said for a happy medium between ease of development and features that makes the software more robust without adding overhead or bloat to the final firmware image.

This is where C++ has objectively many advantages over even C99, and as [Çağlayan Dökme] argues in a recent blog post C++17 adds many developer critter comforts to C++98 and the more recent C++11 C++14 standards.

First stepping back a generation (technically two, with C++20 also being a thing already), the addition of binary literals (e.g. 0b1010'1100) in C++14 and the expanded use of constexpr is addressed, with the latter foreshadowing C++17’s increased focus on compile time optimizations. A new attribute in C++17 that is part of this is [[nodiscard]], which when added before to the return type of a function or method requires the return value to be used in some manner, much like with functions in Ada (contrasted with procedures).

As [Çağlayan] notes, the biggest strength of compile-time checks is that it can save a lot of deploy-test-fix round-trips, with the total number of issues caught after deployment that could have been caught during compilation ideally being zero. Here C++17 streamlines the static_assert() mechanism and simplifies using if constexpr to instantiate code depending on compile-time conditions. Beyond compile-time optimizations there are a few other niceties, such as C++17 guaranteeing copy elision (return value optimization) when an object is returned directly, which is a welcome feature in hard real-time environments.

With today even MCUs having enough grunt to run multi-threaded applications and potentially firmware compiled from a many-thousand LoC codebase, picking a programming language that assists the developer with such an arduous task is very important, with Ada being the primary choice for high-reliability embedded platforms, but C++ along with C enjoying the most widespread (free) compiler support. Even if C++ isn’t supported on every single MCU out there (8051-based and most PIC MCUs mostly), whenever it is an option, it’s a pretty solid choice, especially with knowledge of these new language features.

Encoding NTSC With Your Hands Tied

Generally, when trying to implement some protocol, you are constrained by your hardware and time. But for someone like [EMMIR], that’s not enough. For example, NTSC-CRT is a video signal encoding/decoding simulator with no hardware acceleration, floating point math, or third-party libraries. Just basic C.

While NTSC has officially gone dark in America, people still make their own ATTiny-powered transmitters. NTSC is a bit of a strange standard and is sometimes referred to as never-twice-the-same color, but it does produce a distinct look.

That look is what [EMMIR] was going for. It encodes a message in a ppm format into NTSC and then back in ppm with some configurable noise. It can do this in real-time as an effect in [EMMIR’s] engine or on a rendered image via a CLI. It looks incredible, and there’s something very satisfying. There’s a video after the break showing off the effect. The code is pretty short and easy to read.

Continue reading “Encoding NTSC With Your Hands Tied”

Here’s A Plain C/C++ Implementation Of AI Speech Recognition, So Get Hackin’

[Georgi Gerganov] recently shared a great resource for running high-quality AI-driven speech recognition in a plain C/C++ implementation on a variety of platforms. The automatic speech recognition (ASR) model is fully implemented using only two source files and requires no dependencies. As a result, the high-quality speech recognition doesn’t involve calling remote APIs, and can run locally on different devices in a fairly straightforward manner. The image above shows it running locally on an iPhone 13, but it can do more than that.

Implementing a robust speech transcription that runs locally on a variety of devices is much easier with [Georgi]’s port of OpenAI’s Whisper.
[Georgi]’s work is a port of OpenAI’s Whisper model, a remarkably-robust piece of software that does a truly impressive job of turning human speech into text. Whisper is easy to set up and play with, but this port makes it easier to get the system working in other ways. Having such a lightweight implementation of the model means it can be more easily integrated over a variety of different platforms and projects.

The usual way that OpenAI’s Whisper works is to feed it an audio file, and it spits out a transcription. But [Georgi] shows off something else that might start giving hackers ideas: a simple real-time audio input example.

By using a tool to stream audio and feed it to the system every half-second, one can obtain pretty good (sort of) real-time results! This of course isn’t an ideal method, but the robustness and accuracy of Whisper is such that the results look pretty great nevertheless.

You can watch a quick demo of that in the video just under the page break. If it gives you some ideas, head over to the project’s GitHub repository and get hackin’!

Continue reading “Here’s A Plain C/C++ Implementation Of AI Speech Recognition, So Get Hackin’”

The demo toot screenshot, showing a text-only message sent from the ESP32 using the library.

Moved Off Twitter? Make Your ESP32 Toot

Since Twitter was officially taken over by Elon Musk a few days ago, there’s been significant staff cuts, a stream of questionable decisions, and uncertainty about the social media platform’s future. So it’s little surprise that a notable number of people, those in the tech and hacker scenes in particular, have decided to move over to (or at least bridge their accounts with) the distributed and open source Mastodon service.

Of course, the hacks would follow closely, and [Toby] shares a simple ESP32-based Mastodon client library for us to start with. Instead of “tweets”, messages on Mastodon instances are called “toots”, in line with the platform’s mammoth-like mascot. The library, called Luyba, is able to send toots and includes a demo firmware. Built using C++ and with support for Platform.IO, it should fit into quite a few projects out there, letting you easily send toots to whichever instance you find your home, as the library-aided demo toot shows.

What could you do with such a library on your MCU? Turns out, quite a few fun things – a home automation interface, a critter trap, an online BBC Basic interpreter, or, given image support, a camera that tweets whatever it’s pointed at. There’s quite a bit of fun hackers can have given a micro-blogging service API access and a bit of code that works with it. That said, for all the good that Twitter brought us over the years, there’s a lot that Mastodon can easily do better, between easily game-able “Trending” sidebar, bias found in auto-cropping algorithms and disarrayed internal security policies.

C23 Programming For Everyone

Here’s a history quiz: What architecture did the first C++ compiler target? Of course, it is a trick question. The original C++ — known then as C with classes — compiler wrote out standard C code that you then compiled for whatever your target was. This has a lot of advantages since C compilers are everywhere. Now we are seeing a similar approach to bring C23 to the world with Cake. Cake can translate C23 or other versions to C99 which you can then compile with normal compilers.

While the old C++ compiler, cfront, needed special steps to compile (since it was built using C++), you can build cake for Windows or Linux easily. However, it can also be built with emscripten and you can try it yourself in your web browser.

Continue reading “C23 Programming For Everyone”

Arduino Drum Platform Is Fast

Drums are an exciting instrument to learn to play, but often prohibitive if there are housemates or close neighbors involved. For that problem there are still electronic drums which can be played much more quietly, but then the problem becomes one of price. To solve at least part of that one, [Jeremy] turned to using an Arduino to build a drum module on his own, but he still had to solve yet a third problem: how to make the Arduino fast enough for the drums to sound natural.

Playing music in real life requires precise timing, so the choice of C++ as a language poses some problems as it’s not typically as fast as lower-level languages. It is much easier to work with though, and [Jeremy] explains this in great detail over a series of blog posts detailing his drum kit’s design. Some of the solutions to the software timing are made up for with the hardware on the specific Arduino he chose to use, including an even system, a speedy EEPROM, hardware timers, and an ADC that can sample at 150k samples per second.

With that being said, the hardware isn’t the only thing standing out on this build. [Jeremy] has released the source code on his GitHub page for those curious about the build, and is planning on releasing several more blog posts about the drum kit build in the near future as well. This isn’t the only path to electronic drums, though, as we’ve seen with this build which converts an analog drumset into a digital one.

Continue reading “Arduino Drum Platform Is Fast”

Building Faster Rsync From Scratch In Go

For a quick file transfer between two computers, SCP is a fine program to use. For more complex, large, or regular backups, however, the go-to tool is rsync. It’s faster, more efficient, and usable in a wider range of circumstances. For all its perks, [Michael Stapelberg] felt that it had one major weakness: it is a tool written in C. [Michael] is philosophically opposed to programs written in C, so he set out to implement rsync from scratch in Go instead.

[Michael]’s path to deciding to tackle this project is a complicated one. His ISP upgraded his internet connection to 25 Gbit/s recently, which means that his custom router was the bottleneck in his network. To solve that problem he migrated his router to a PC with several 25 Gbit/s network cards. To take full advantage of the speed now theoretically available, he began using a tool called gokrazy, which turns applications written in Go into their own appliance. That means that instead of installing a full Linux distribution to handle specific tasks (like a router, for example), the only thing loaded on the computer is essentially the Linux kernel, the Go compiler and libraries, and then the Go application itself.

With a new router with hardware capable of supporting these fast speeds and only running software written in Go, the last step was finally to build rsync to support his tasks on his network. This meant that rsync itself needed to be built from scratch in Go. Once [Michael] completed this final task, he found that his implementation of rsync is actually much faster than the version built in C, thanks to the modernization found in the Go language and the fact that his router isn’t running all of the cruft associated with a standard Linux distribution.

For a software project of this scope, we find [Michael]’s step-by-step process worth taking note of for any problem any of us attempt to tackle. Not only that, refactoring a foundational tool like rsync is an involved task on its own, let alone its creation simply to increase network speeds beyond what most of us would already consider blazingly fast. We’re leaving out a ton of details on this build so we definitely recommend checking out his talk in the video below.

Thanks to [sarinkhan] for the tip!

Continue reading “Building Faster Rsync From Scratch In Go”