For most people, a software defined radio is a device. An RTL-SDR dongle perhaps, or the HackRF that a popular multi-tool for working in the radio frequency realm. But as they explain, the SDR hardware can be considered merely as the analogue front end, being just the minimal analogue circuitry coupled with a digitiser. The real software-defined part comes — as you might expect — in the software
Kate and Mike introduce GNU Radio Companion — the graphical UI for GNU Radio — as their tool of choice and praise it’s use as a general purpose digital signal processing system whether or not that includes radio. Taking their own Great Scott Gadgets GreatFET One USB hackers toolkit peripheral as an input device they demonstrate this by analysing the output from a light sensor. Instantly they can analyse the mains frequency in a frequency-domain plot, and the pulse frequency of the LEDs. But their bag of tricks goes much deeper, exploring multiple “atypical use cases” that unlock a whole new world through creative digital signal processing (DSP).
Inspired by the over-the-top stage lighting and pyrotechnics used during e-sport events, [Hans Peter] set out to develop a scaled-down version (minus the flames) for his personal Counter-Strike: Global Offensive sessions. It might seem like pulling something like this off would involve hacking the game engine, but as it turns out, Valve was kind enough to implement a game state API that made it relatively easy.
According to the documentation, the CS:GO client can be configured to send out state information to a HTTP server at regular intervals. It even provided example code for implementing a simple state server in Node.js, which [Hans] adapted for this project by adding some conditional statements that analyze the status of the current game.
These functions fire off serial commands to the attached Arduino, which in turn controls the WS2812B LEDs. The Arduino code takes the information provided by the HTTP server and breaks that down into various lighting routines for different conditions such as wins and losses. But things really kick into gear when a bomb is active.
[Hans] wanted to synchronize the flashing LEDs with the beeping sound the bomb makes in the game, but the API doesn’t provide granular enough data. So he recorded the audio of the bomb arming sequence, used Audacity to precisely time the beeps, and implemented the sequence in his Arduino code. In the video after the break you can see that the synchronization isn’t perfect, but it’s certainly close enough to get the point across in the heat of battle.
The Microsoft .NET framework has been with us in one form or another since the millennium, and though it has remained largely the preserve of the Microsoft universe, it has found its way since then through a variety of implementations to other platforms including MacOS and GNU/Linux. In Microsoft terms though its history goes back only as far as Windows 98, earlier MS operating systems remain off-limits.
Just a glimmer of .NET in DOS and Windows 3.11 comes courtesy of [Michal Strehovský], who has successfully compiled .net C# code for both Windows 3.11 and DOS. An in-depth explanation comes courtesy of [Scott Hanselman], and it involves some tricks spanning the decades since the early 1990s. The .NET Core compiler’s object files can be fed into the linker that shipped with an ancient version of Microsoft’s C++ compiler, which when used with Microsoft’s Win32s compatibility layer that brought some of Windos NT’s APIs to the 16-bit OS, allows C# from 2020 to run as though it were 1992 again. Meanwhile the DOS version uses .NET Core’s ability to produce self-contained executables along with some very significant tricks to pare down the size of the finished program from many megabytes to an eventual DOS-suitable 27k. Remember the apocryphal Bill Gates quote, that “640k should be enough for anyone“, that refers to the maximum memory available to DOS without extra memory-extending tricks.
Neither piece of software is especially useful, and we can’t see a rush of C# coders to these new platforms. But we applaud him for his ingenuity, and getting old hardware to do new tricks is right up our alley. It’s certainly dredged up a few memories from back in the day for us. Meanwhile we’ve featured .NET in a few projects over the years, most recently on an FPGA.
Since most people are carrying a camera-equipped computer in their pockets these days, QR codes can be a great way to easily share short snippets of information. You can put one on your business card so people can quickly access your contact information, or on your living room wall with your network’s SSID and encryption key. The design of QR codes also make them well suited to 3D printing, and thanks to a new web-based tool, you can generate your own custom STL in seconds.
Created by [Felix Stein], the website provides an easy to use interface for the many options possible with QR codes. Obviously you have full control over the actual content of the code, be it a simple URL or a something more specific like a pre-formatted SMS message. But you can also tweak physical parameters like size and thickness.
Once you’re happy with the 3D preview, you can have the website generate an STL for either single or multi-extrusion printers. For those of us who are puttering along with single extruder machines, you’ll need to swap the filament color at the appropriate layer manually. With so many variables involved, you’ll also need figure out which layer the swap should happen on your own.
Incidentally, this is an excellent example of where STL leaves something to be desired. When using a format like 3MF, color and material information could be baked right into the model. Once opened in a sufficiently modern slicer, all the tricky bits would automatically sorted out. Or at least, that’s what Prusa Research is hoping for.
When it comes to peer-to-peer file sharing protocols, BitTorrent is probably one of the best known. It requires a client implementing the program and a tracker to list files available to transfer and to find peer users to transfer those files. Developed in 2001, BitTorrent has since acquired more than a quarter billion users according to some estimates.
While most users choose to use existing clients, [Jesse Li] wanted to build one from scratch in Go, a programming language commonly used for its built-in concurrency features and simplicity compared to C.
The first step for a client is finding peers to download files from. Trackers, web servers running over HTTP, serve as centralized locations for introducing peers to one another. Due to the centralization, the servers are at risk of being discovered and shut down if they facilitate illegal content exchange. Thus, making peer discovery a distributed process is a necessity for preventing trackers from following in the footsteps of the now-defunct TorrentSpy, Popcorn Time, and KickassTorrents.
The client starts off by reading a .torrent file, which describes the contents of the desired file and how to connect to a tracker. The information in the file includes the URL of the tracker, the creation time, and SHA-1 hashes of each piece, or a chunk of the file. One file can be made up of thousands of pieces – the client will need to download the pieces from peers, check the hashes against the torrent file, and finally assemble the pieces together to finally retrieve the file. For the implementation, [Jesse] chose to keep the structures in the Go program reasonably flat, separating application structs from serialization structs. Pieces are also separated into slices of hashes to more easily access individual hashes.
Next, a GET request to an `announce` URL in the torrent file announces the presence of the client to peers and retrieves a response from the tracker with the list of peers. To start downloading pieces, the client starts a TCP connection with a peer, completes a two-way BitTorrent handshake, and exchanges messages to download pieces.
One interesting data structure exchanged in the messages is a bitfield, which acts as a byte array that checks which pieces a peer has. Bits are flipped when their respective piece’s status changes, acting somewhat like a loyalty card with stamps.
While talking to one peer may be straightforward, managing the concurrency of talking to multiple peers at once requires solving a classically Hard problem. [Jesse] implements this in Go by using channels as thread-safe queues, setting up two channels to assign work and collect downloaded pieces. Requests are later pipelined to increase throughput since network round-trips are expensive and sending blocks individually inefficient.
The full implementation is available on GitHub, and is easy enough to use as an alternative client or as a walkthrough if you’d prefer to build your own.
In the embedded world, twiddling a few bits is expected behavior. Firmware is far enough down the stack that the author may care about the number of bits and bytes used, or needs to work with registers directly to make the machine dance. Usually these operations are confined to the typical shifting and masking but sometimes a problem calls for more exotic solutions. If you need to descend down these dark depths you invariably come across the classic Bit Twiddling Hacks collected by [Sean Eron Anderson]. Here be dragons.
Bit Twiddling Hacks is exactly as described; a page full of snippets and suggestions for how to perform all manner of bit math in convenient or efficient ways. To our surprise upon reading the disclaimer at the top of the page, [Sean] observes that so many people have used the contents of the page that it’s effectively all been thoroughly tested. Considering how esoteric some of the snippets are we’d love to know how the darkest corners found use.
In the modern world, we take certain tools for granted. High-level programming languages such as C or Python haven’t been around that long in the grand scheme of things, and Java has only existed since the ’90s. Getting these tools working on machines that predate them is more of a challenge than anything, and [Michael Kohn] was more than willing to tackle this one. He recently got Java running on a Commodore Amiga.
The Amgia predates Java itself by almost a decade, so this process wasn’t exactly straightforward. The platform has a number of coprocessors that were novel for their time but aren’t as commonplace now, taking care of such tasks such as graphics, sound, and memory handling. Any psoftware running on the Amiga needs to be in a specially formatted program as well, so that needed to be taken care of, even loading Java on the computer in the first place took some special work using a null modem cable rather than the floppy disk an Amiga would have used back in the day.