Gemini internet capsule launched

Exciting stuff: I’ve managed to create a public-facing Gemini capsule. I have tested it over at an account I created at So everything checks out and should be working hunky-dory. Note that, for now, the site won’t be active 24/7. I’ll turn my server off at night-time, pending a more permanent solution.

Point your favourite gemini client to:


and have it! The domain name is a bit of an oddity, admittedly, but I’m using FreeDNS, so I’m kinda going with a name I can get.

The plan for the foreseeable future is that my blog will now reside on Gemini rather than WordPress. WordPress is a nightmare. The internet in general is a nightmare. I want to try out Gemini for awhile and see how I get on.

I won’t be abandoning the Interwebs permanently. I still need that for banking and stuff. Not to mention my favourite finance site: Stockopedia.

Posted in Uncategorized | Leave a comment

Will the brain slugs take over Gemini capsules?

Gemini is a protocol that sits between gopher and http, being closer to the former than the latter. A “capsule” is just another name for “site”.

A poster argued:

Y’know, Geminispace probably won’t be free of ads forever. Assuming we don’t abolish capitalism within the next few years, eventually someone is gonna pay someone else to shill their stuff on their gemlog. It’s just gonna happen.


I am more optimistic. I don’t think we have to worry about capitalists. It hasn’t been a problem for gopher, so I doubt that it will be a problem for gemini. I imagine the first thing we’ll see is some kind of gemini equivalent of a virus, shitposting, and trolling.

Political content on gemini seems fairly contained at the moment. There is a lot of talk about the downsides of capitalism on the www. The criticisms I’ve seen are fair. Geminispace exists for those seeking a quieter, more sane, place on the internet. Not the sugar-hyped autism that passes for most web pages these days.

Spend a few hours on gopher/gemini, then go back to your web browser. You immediately notice that for the vast majority of sites, “yeah, this shit is bad.” Bear in mind that I’m using adblocking and other minor filters, too.

Talking of which: Firefox. This morning I saw a notification on Firefox saying that I needed to restart Firefox because it had been upgraded. This came as a genuine surprise to me, as I use Debian Stable. My philosophy to updates is this: I am the system admin of my computer. I set policy, and absolutely no-one else. You don’t ever download anything unless I say so.

It’s easy for sites to follow the herd. There’s one financial site I visit. I don’t want to mention their name, because I don’t want to embarrass them. I genuinely respect the site, and wish them all the best in their commercial endeavours. My only slight peeve is that they revamped the site, made it more “web 2.0”. And, sure enough, it ran slower, with some of the features that I liked removed.

So, to reiterate to the team that may have sussed out who I am talking about: I think your site is great and provides a valuable and worthwhile service. I am grateful for its existence and the team that is behind it. I just preferred the old version.

Gopher vs Gemini

The first rule of Gemini Club is that everybody talks about Gemini Club. The second rule of Gemini Club is that everybody only talks about Gemini Club.

I like Lagrange as a browser. I tried out Bombadillo, which is for terminals. Bombadillo is written in Go. Works pretty well, actually. I had tried to install a Rust client a few weeks back. It failed to compile. The more I try to use Rust, the less I like it. The whole crate thing takes ages to update, and there seem to be frequent compilation failures. This is odd, especially considering that reproducible build systems, this kind of stuff should never happen. I am becoming increasingly sceptical of programming language package managers. I don’t think they necessarily deliver the benefits they claim.

I tried out Bombadillo on a few gopher and gemini sites. I must say, old gopher was surprisingly good. I don’t know much about authoring gopherholes (i.e. sites), but it seems a bit fiddly. There seems to be a distinction between pure text files, and map files. Map files are, ultimately, text documents, but seem to require fiddly markup. So writing them is a chore.

Gemini is way easier to write. I think there can be a little bit of pros vs cons when it comes to how pages should be rendered.

Perhaps interactive terminal clients could use colour for headings. Gemini does, after all, support that concept. Maybe have a switch to turn off colouring if for some reason you don’t want it.

I think that the way Lagrange shows its links is a stylistically problematical. They render them to look like headings, rather than as references. The document’s structure is confused. Contrast this with how terminal clients render links. The display bracketed numbers down the left-hand site. This makes them look much more like references.

Perhaps gemini authors should adopt the convention that links are always considered references, never headings. They sure do render to look like headings, though.

Another thing that I would like to see is authors dating their pages consistently. Historical context is useful.

That’s all that comes to mind. Be seeing you.

Posted in Uncategorized | Leave a comment

The entire WWW summed up in three pictures

“For Wales? Why Richard, it profit a man nothing to give his soul for the whole world. . . but for Wales!”

― Robert Bolt, A Man for All Seasons

(Way to trashtalk an entire country, Bob. You really slipped that one under the net.)

With that quote in mind, here are the pictures I promised you …

Contestant number 1:

Validate me

Contestant number 2:

Y’all my bitches now

Contestant number 3:

I’m here to discuss the modalities

In other words: narcissists, gatekeepers, and scammers. I was going to include SJWs, but I figured they were just a sub-category of narcissists.

I was going to just show the first picture, but realised that I needed three to display the whole gamut.

So, let’s talk about the first picture, shall we? It is what prompted this post in the first place.

The lady in question is Scarlett Dixon. Doxxing people is usually considered completely uncool dude, but her name is a matter of public record already. It’s from the Twitter account scarlettlondon, which no longer seems active. Presumably the blowback she received from it ruined her credibility. The picture was posted in 2018, so I’m way late to the party.

What really grinds my gears is the sheer fakeness of it. The sheer emptiness. For Listerine White. Like, I have to plaster on this phony smile to avoid the realisation that my life amounts to absolutely nothing. Scarlett says:

The best of days start with a smile and positive thoughts. And pancakes, And strawberries. And bottomless tea.

Holy shit.

I do give you a little insight into how I start my day in a positive way.

Hold that thought. I’ll be pouring scorn on it shortly.

Adforum picks up the news:

… a plate of tortillas conspicuously disguised as pancakes sits next to her … Shortly after Dixon put the photo on Instagram, someone posted it on Twitter, pointing out that it looks nothing like “anybody’s normal morning,” and announced that “Instagram is a ridiculous lie factory made to make us all feel inadequate.”

Further down:

As Dixon notes in her statement, her posts are intended to be exaggerated: “Sometimes my photos are whimsical and OTT [over the top] and a little too pink, but I’m not presenting this as an ‘idealistic’ version of life that young girls should aspire to” (brackets added).

See, I’m not going to give her a pass on this. For starters, she said that “I do give a little insight into how I start my day.” She presents it as a truthful statement, which she then retracts. Secondly, she presents it as an aspiration for young girls. This is terrible! No wonder the youth is so messed up. They are presented with images that no well-balanced person could emulate.

Turning to the Gemini protocol …

My Gemini site (OK, “capsule”, if you insist) is coming along to my satisfaction. I intend to migrate my former website over to it. I’m in no rush, though. I might make it public at some stage. We’ll see. Gemini “capsules” (grrr) contain a lot of meta-discussion about Gemini itself. My capsule won’t be about that though. It will contain technical information that I’m accumulating. I won’t bother mirroring it over http, either. It’ll be something exclusive to Gemini. It will represent over 20 years of accumulated information that I have.

Update 1: 2022-05-21

There was more I wanted to talk about, but just could find the stuff that I found on Gemini. I actually found what I was looking for by perusing my $HOME/.config/lagrange/visited.2.txt site.

Gemini has a search engine, but alas I couldn’t find the content I knew I had seen. I’m not the first one to notice that the Gemini could use a decent search engine. And I wonder if Gemini capsules should establish a set of conventions for things like blogs. Not standards, but conventions. At first this might seem like semantic nitpicking, but allow me to explain. By “standard”, I mean “baked into the protocol”. That would be too restrictive. “Convention” is to be understood as “best practises.” Informal extensions. On practise I would like to see is that pages should be dated by their creation and update date. On one level, I am always fascinated by the history of these documents. And on another level, it gives context to the page. Information can become stale. Dating articles can be useful from that perspective.

But I have digressed too far already …

The article that I had in mind was at gemini:// The page referenced “scantily-clad women”, and at first I thought that the article must have been based on a post I made recently about Gemini and the WWW. However, that article predates my own, so I know that it was purely coincidental.

I wanted to reproduce some of their text because it amused me no end.

I’m first and foremost protesting the “Gemini is good because we don’t as many scantily clad Babylonian whores” misogynist rhetoric.


Instead we’re saying that visual media are being associated with women and text media are being associated with men. That’s not necessarily based in actual reality (as you correctly observe with the voracious readers in your own life) but that’s how it is being coded, which is pretty wack.

That’s a kind of odd way of stating things, in my view. Yeah, I kinda get where s/he is coming from, although you need a bit of context for it, which I might not be representing properly.

I really love the next bit, though:

Plain text is seen as sober, thoughtful, chaste, male, clay, ribcage, wands, clubs, odd, 陽, I bless Ra, the fierce sun burning bright.

The web is seen as intoxicated, impulsive, slutty, snake, apple, cups, hearts, even, 陰, I bless Isis—Luna in the night.

Plain text is seen as the honest truth.

The web is seen as Babylonian, tarted up, performed.

That’s a mythology that can get kinda pretty messed up very quickly, can create an environment where the proverbial bitches can’t hang with the proverbial streets.

Sir, you are a true wordsmith! May the light of Ra always shine upon you.

Posted in Uncategorized | Leave a comment

Gemini: a www alternative

So, do think that watching scantily-clad young ladies twerking in their bikinis on OnlyFans is a bunch of bullshit? Concerned that Google, Microsoft and Facebook are becoming the gatekeepers of the internet? Annoyed that most sites have become bloated pieces of garbage more interested in harvesting your eyeballs than in providing interesting content?

Then I have a suggestion for you: Gemini. Gemini is an internet protocol, similar to HTTP and gopher (Wikipedia). It also defines a file format, similar to HTML. Gemini derives its name from the Gemini space program, which was conducted between Mercury and Apollo. In the analogy, Mercury is the equivalent of the Gopher protocol, Apollo is the equivalent of the World Wide Web, and Gemini occupies an intermediate ground between the two.

In terms of a facetious editor analogy: Gopher is Ed, Gemini is Vim, and HTML is a 1GB Eclipse IDE download.

The Gemini markup language seems to be inspired by markdown, but with a formal specification rather than ad hoc extensions that markdown often has. Whilst HTML is basically infinitely extensible, Gemini is deliberately constrained. You can’t run riot with JavaScript and all that baloney.

This makes writing client software well within the scope of one man hacking away in his bedroom. As opposed to a browser like Firefox. A lot of the clients I’ve tried were rather flaky, or just plain failed to compile. Fortunately, someone pointed me to a nice one called Lagrange. It seems to be one recommended a lot, and is “feature-complete”. So that’d be the the one to try in the first instance. You can compile it from source, if you feel you must. Or, you can do what I did, and just download and run an AppImage. I think there is a Flatpak package too, but I can’t be doing with all that nonsense.

Lagrange has fantastic font rendering. Really gorgeous. Although maybe it’s just Helvetica (?) It has a default “dark”” theme, which you can change. One reviewer said it was depressing, but I think it is very stylish and the whole rendering is pleasantly aesthetic. A really nice touch is a sidebar in which you can display a table of contents. What an ingenious idea! Gemini docs (GMI’s) can have headings and subheadings, so it is easy for the browser to generate it. It is an interesting demonstration as to how sometimes simpler can be more powerful.

Comparing Gemini to Vim is a very apt one, I think. Although folks have developed plugins for Vim (but you can’t do that with Gemini), in a way, I think that’s the wrong way of thinking about Vim. You should do things the Vim way, bend your thinking to its way of thinking, rather than the other way around. Vim is not Emacs. It’s a different mindset.

I had tried kicking the tyres of Gemini about half a year ago, and found them to be a bit flat. With the discovery of Lagrange, I have a renewed interest. There’s a combination of factors. Github announced that it was upping its login arrangements. Google is doing something similar too. It looks like we’ll be jumping through more hoops to get Thunderbird to work. Even worse, it is my understanding that regular 2FA (2-factor authorisation) won’t work. It’s some kind of Google propitiatory bullshit.

Then there’s WordPress. It’s pretty bloated, and often a fiddle to use. I write a lot of technical content. Writing preformatted code in WordPress can be a bit of a wrestling match. When I first used WordPress, the process was somewhat tiresome. Then there was a phase where it actually did the right thing. Now it seems back to crap again.

I had investigated a bunch of blogging platforms that had been recommended. I was disappointed. Most of them seemed overfussy, and I was dubious that they would be an improvement over WordPress. I had heard that Tumblr was making a comeback. I checked out the site, but figured that it wasn’t suitable for the kind of content I was interesting in posting. I have said this before, and I’ll say it again: I’m seeing a lot of sites which have what I call the “Generation Z aesthetic” (I’m defining Gen Z as people born in the late 90’s to 2010’s). Or you could call it “Plastic Pop”. Something about them says “influencer”, you know? “This is me being the best version of myself”, and all that stuff.

I decided that probably the best way forward would be to cobble something together with Jekyll. I have never used Jekyll before. A quick try proved that it was simple enough. I could make something clean and simple, without gimmickry.

I had also discovered a small server written in golang called markdir. It served markdown pages rather than HTML.

So there was bunch of ideas floating around in my head. I was trying to form a cohesive idea out of them. The pieces looked that they may come together in the form of Gemini. I could create pages in a simple markup language. What’s more, I didn’t need any server software if I just wanted to use something internally. The browser could pull up links as required. So at least at first glance I had some kind of solution that I was looking for.

Interestingly, I have read articles suggesting that gopher is making a bit of a comeback. According to an article in 2018:

… one of the gopher sites where I post shows new members weekly: 2% growth per week. … Gopher represents the ability to bring an interconnected browsing experience to low-computing-power environments.

That’s a good point, actually. In fact, I see at least two benefits of simple protocols like gopher and Gemini:

  • bandwidth requirements are really low, so they can be used in rural areas or developing countries where internet connection is poor and slow
  • being mostly plain text, they are very accessible to visually impaired viewers
  • being simple, client software is easy to write for obscure Operating Systems like Aros (a free AmigaOS clone)
  • resource usage is light. They should run on even the lowest-specced machine. Hell, you could probably write a gopher client for an ESP32 microcontroller.

I had a quick play with gopher yesterday. It was quite interesting. I noted that it was surprisingly useable. I think I’ll stick to Gemini just now, though.

I’ve explored Gemini sites just a little bit. There’s quite a sub-cultural and retro feel to it. I mean that in a good way. Even reading some of their blogs (I think they call them phlogs) is quite interesting. Smallish snippets of ideas.

There’s a feeling that Gemini, like Gopher, is stepping back to the internet of 1991 (in a good way!). There’s something mysterious and fresh about it, with unexpected discoveries around the corner.

It’s worth mentioning that Gemini is not intended to be a replacement for the WWW. That ship has long sailed. Nor Gopher, for that matter, Rather, it is an adjunct of the two.

Anyway, I reckon I’ve said enough about all this. Go check it out if it seems interesting to you.


Posted in Uncategorized | Leave a comment

Microcontroller API design: separate out concerns

My tip: try to separate out device-specific code from SDK-specific code.

By “device”, I mean any physical piece of hardware like a DS3231 real-time clock, or an SSD1306 OLED display. Something that you attach to your mcu (microcontroller).

By “SDK” I mean whatever API may be used to implement a protocol such as I2C, SPI, etc.. Every mcu likely has a selection of APIs to choose from: Arduino, mbed, CMSIS, ST HAL, libopencm3, etc..

Ideally, keep these two sides separate. Otherwise, you will have a difficult time porting code between different mcus.

I’m not here to pour scorn on Arduino code, but you will see that, time and time again, libraries to control devices are intertwined with protocol code. This makes things hard to port.

The protocol code written for the Arduino generally does a good job, but it is not always consistent. You need to use the TinyWire library for an ATtiny85, whereas for an Uno a hardware library is used.

So ideally, to program a device you would be to write a library that initialised variables, returned initialisation code, and ways to interact with the specific device. It shouldn’t know how I2C works, for example, although it will need to be designed to be easy to use with I2C. Then, as a separate piece of code, write adapters for calling I2C.

I searched for “poor microcontroller api design”. The second match was “7 Tips for Developing Great APIs”. I won’t link to the website because I don’t want to publicise such shoddy writing.

My first problem is with the headline itself. It uses the word “Great”. The use of superlatives and hyperbole is a red flag that the article is mostly going to be fluff. This has no place in technical writing. Save that garbage for buzzfeed articles.

Anyway, I’m off for a walk. My apologies for any broken formatting. WordPress is turning into an unfixable dumpster fire.

Posted in Uncategorized | Leave a comment

Is it my imagination, or is the #rp2040 more reliable than the #stm32?

Maybe I’m doing things wrong, but I wonder if people have found the RP2040 to work better than STM32’s? Just some of the peculiarities I’ve noticed:

  • I couldn’t quite get an oled display working with an STM32L432KC, and resorted to bit-banging
  • although the L432 has NSSP for SPI, the STM32F411 does not. The NSSP setting enables the clock pin to high between each byte/word of transmission. Some devices require this. So you may not be able to use SPI DMA (depending on device). The RP2040 just works.
  • I could get my oled to work on the STM32 using libopencm3. It works OK until I enable systick. I did some LED flashing using systick, and the mcu used to freeze, or something, after about 20 minutes. I’m not sure about the precise nature of the problem. I don’t think there’s any data races introduced, so that couldn’t be the cause of the problem. I tried using a timer instead, with similar results. I then simplified the systick/timer to only increment a tick count. The MCU then froze after approx 2h30m. Bizarre. The same project on my RP2040 is still going, even after 3h30m. A lot of the code is shared.

I must presume that I’ve been doing something wrong somewhere. I mean, the chips can’t be as unreliable as I’m making out, right?

Update 2022-05-11: I rewrote my oled/ds3231 code using the stm32 hal. My libraries remained the same, I just used the HAL to initialise the I2C and wrote a simple 2-line replacement for libopencm3’s i2c_transfer7() function. The MCU is still working after 2h54m. Hmm, I wonder what’s going on here. A bug in my code, perhaps, but basically nothing changed in it. Perhaps a bug in the way libopencm3 calls the standard library? Some subtle software or hardware bug in libopencm3 itself? It’s difficult to know what to say about that.

Posted in Uncategorized | Leave a comment

Time to break out the tinfoil and make myself a hat

So, Google Mail is going to switch to 2FA (two-factor authentication). It seems that somewhere along the chain a phone number is required. I am not happy.

Microsoft’s Github is going to switch on 2FA before the end of 2023. Although I haven’t figured out all the details, it looks like I can authenticate with command-line tools on Linux.

I am running out of a lot of trust with Google. They are too aggressive at trying to get my phone number. I am thinking seriously about hosting my own email. Fortunately, my ISP provides me with a sub-domain that I can use. I may just switch to some other free email provider, like AOL.

I’m also transitioning my Github stuff over to Gitlab. I might try their 2FA to see if I can get it working with my system after I have fully transitioned to Gitlab.

My other concern is with taxes. I have an app that generates one-time passwords on my Nexus, running Android. I use the official HMRC app. What’s annoying is that they keep wanting me to upgrade the app. It’s a 10M download. I think it just uses TOTP (Time-based One Time Password). It’s a massive download for what is actually a simple tool. It doesn’t reveal the secret key, though, so I don’t know how I’m going to transition away from the Nexus.

The Nexus is from 2012, it’s not a smartphone, so I am a bit worried about how long Android will support it. HMRC allows you to change how you log in to do your taxes, but the process seems impossible. Like, they require a valid passport. Mind has expired. Or I could submit a Northern Ireland driving license. Northern Island? I’ve never been to Northern Island. What the hell?

They do have an API for me to look at. I’m not sure I want to go down that particular rabbit-hole. Like I say, I suspect authentication is pretty straight-forward and standard if I could just get hold of the secret key.

I might try to install Android on VirtualBox for my PC, or for my Raspberry Pi. I had tried Android on my Pi a few years ago, IIRC, and walked away with the conclusion “needed some work.”

I’m not ultra-convinced that TOTP is such a great idea. We already have public-key encryption for things like ssh. And we have things like login passwords where the password is irrecoverable. If you do the TOTP stuff, then both the server and the client must store the actual key. If there’s a compromise, then the whole mechanism is useless. And sites seem to get compromised all the time.

There are always weak links in these schemes. Devices might break, be unavailable, be non-upgradeable, lost, and all manner of things. Then you risk being permanently locked-out.

There are apps out there that can help you. But one must be extra cagey about these things. How do you know you can trust them? How do you know how long they will be around? Some guy was talking about an app for Android. He said he moved off of it, because if his Android was stolen, and it wasn’t properly secured, then the whole 2FA thing is compromised anyway. As the saying goes, a chain is only as strong as the weakest link.

Vendor-lockin. This is a big issue. Companies just love to lock you in. Look at “Do no evil” Google. The temptation is just too strong. Vendors just love setting policy, too. “It’s either our way, or the highway.” I choose “highway.” Time and time again we see that vendors just can’t be trusted. We need to stop with the attitude of “It’ll be alright on the night.”

Lambs to the slaughter.

Posted in Uncategorized | Leave a comment

A quine in the Daft programming language

“Will Hare replace C? Or Rust? Or Zig? Or anything else?” (link)

Zig, Nim, Rust, Odin, and occasionally D, as languages that appear on Hacker News.

It inspired me to start mucking around with a silly exercise. It is based on a soup of ideas: bootstrapping C implementations, quines (self-replicating code), Forth, and Val Schorre’s paper on Meta II (link)

So I came up with Daft, a minimalist language that can produce a quine of itself. Here is a quine in Daft:


What the hell, and what’s the point?

Meta II is a “meta-circular compiler”, which means that it can compile itself. The problem is that it needs it’s own assembly instructions to do it. You have to write that assembler. So we have the classical chicken-and-egg problem.

My idea is to dispense with writing that assembler, and instead writing a different assembler, an assembler that is much easier to implement.

Forth seems an interesting idea, but can we make it even simpler? Yes, we can. We use ASCII characters as opcodes. This is what the above “program” uses. Specifically:

S - push the current heap pointer onto a stack, read a string from stdin until the newline, putting the read string on the heap
2 - duplicate the top item on the stack
> - read the next char from stdin, and echo it to stdout
T - type the zero-terminated string pointed to by the top of the stack to stdout, then a newline, and pop the top of the stack

With just 4 instructions, we are able to produce a quine.

Now, admittedly, this isn’t enough in itself to make a general-purpose compiler. It’s just a thought experiment. There are no test conditions or jump instructions, for example, that would be needed to create a compiler.

Here is the implementation of the interpreter:

#include <stdio.h>

int stack[100];
int sidx = 0;

char heap[1000];
int hidx = 0;

int pop(void) { return stack[--sidx]; }
void push(int val) { stack[sidx++] = val; }
void dup(void) { stack[sidx++] = stack[sidx-1]; }

int main()
        int c;
        while((c = getchar()) >=0) {
                switch(c) {
                        case 'S':
                                while((c = getchar()) != '\n') {
                                        heap[hidx++] = c;
                                heap[hidx++] = 0;
                        case '2':
                        case 'T':
                                puts(heap + pop());
                        case '>':


        return 0;

40 lines of code. That’s all. The question is: what would we need to add to have the same power as Meta-II?

And what will this buy us? Well, we could create a grammar for some language that we were interest in writing. Maybe it’s not a computer language, maybe it’s a string for something like RTTTL, which is a ringtone description language. I did one of those in C using lex and yacc.

Meta II and lex and yacc require separate compilation phases. My system could potentially embed an interpreter inside the runtime itself, like Forth, but geared more towards generalised language. The whole thing is so small that you could use it in a microcontroller.

To get in and out of the interpreter, maybe you could use a symbol like “¬”. code blocks could be implemented between “[” “]” pairs, with escape sequences for strings. Bracketed pairs would be inefficient, but then it would mean that you don’t have to implement backtracking of addresses, and all that.

Anyway, just some ideas. I might see if I can develop it further.

Hey, WordPress seems to be getting worse by the month.

Link to github code.

Posted in Uncategorized | Leave a comment

Square-wave and boolean-modulated output using sampling


Tones of a specified frequency can easily be produced on nearly all mcus (microcontrollers) using pwm (pulse-width modulation). The output is a square wave. This post explores the use of sampling to produce frequency waves. Although this is more processor-intensive method, it does allow for greater control of the output wave. This post introduces the concept of “boolean-modulation”, where the on-off states of an input square-wave signal is processed by boolean logic. It demonstrates how to produce an effect that is similar to a binaural beat. Additional harmonics are introduced into the output, giving them a “funkier” effect.

Algorithm for producing sampled square waves

Suppose the following:

  • fs is the desired sampling frequency of the wave. fs = 44100 (Hz) is a typical sample rate for many audio files
  • fw_t is the frequency of the square wave to output. fw_t = 440 (Hz) is the frequency of the note “A”. More specifically, it is usually referred to “A4”.

The following algorithm, written in D, determines whether the output should be 0 or 1:

import std.math;
import std.stdio;

const float fw = 440; // frequency of wave
const float fs = 44100; // sample frequency
const int nsamples = 60 * cast(int)fs; // reserve space for 60 secs of tone

void main()
        float[] samples = new float[nsamples]; // the output
        float dt = 1 / fs; // time increment is inverse of sampling freq
        float t = 0; // time
        const float fw_t = 1.0/fw; // period of output wave
        for(int i=0; i< nsamples; i++) {
                t = fmod(t, fw_t); // limit time to one wave period
                samples[i] = 0;
                if(t>=0.5*fw_t) samples[i] = 1.0; // in second-half of wave
                t += dt; // increment time

        ... any extra processing, e.g. writing to file

It is an algorithm that can be translated easily to a microcontroller with a timer. The output is a 50% duty cycle. It can be changed easily.

Boolean modulation

Binaural beats are generated when two sine waves of similar, but non-identical, sine waves are added together. This method is not especially suited to microcontrollers because the output is of variable amplitude rather than a simple on/off of a GPIO pin.

However, all is not lost. The inspiration behind binaural beats can be modified to use simple boolean logic. The strategy is to generate two square waves of slightly different frequency. Their on/off states are OR’d together to produce the output state.

Here is example code:

import waved;
import std.math;
import std.stdio;

const float fw = 500; // frequency of wave
const float fs = 44100; // sample frequence
const int nsamples = 60 * cast(int)fs; // 60s
void main()
        float[] samples = new float[nsamples];
        float dt = 1 / fs;
        float t0 = 0, t1 = 0; // time of each of the two waves
        const float fw_t0 = 1.0/fw;
        const float fw_t1 = 1.0/(fw + 1.0); // add a little binaural
        for(int i=0; i< nsamples; i++) {
                samples[i] = 0;

                bool hi0= false;
                t0 = fmod(t0, fw_t0);
                if(t0>=0.5*fw_t0) hi0 = true;
                t0 += dt;

                bool hi1 = false;
                t1 = fmod(t1, fw_t1);
                if(t1>=0.5*fw_t1) hi1 = true;
                t1 += dt;
                if(hi0 || hi1) samples[i] = 0.1;
        writeln("sample array filled");
        Sound snd= Sound(cast(int)fs, 1, samples);
        encodeWAV(snd, "out.wav");

The frequency in this case is 500Hz. There is a small offset frequency – 1 Hz works well – that modifies the on/off state.

A 60 sec sample output is available here (470k size).

The source code is available here.

Parting remarks

This is an efficient way of generating waves with interesting tonal qualities for use in note production.

Ref: db7.102

Posted in Uncategorized | Leave a comment

#libopencm3 examples for stm32f411

The examples may work on other STM32 microcontrollers, with modification.

Such examples include: a basic blink sketch, timers, exti, newlib integration with uart, spi, dma, i2c, pwm, systick, ssd1306, ds3231. So, quite a wealth of things to choose from. Check out my repo here.

Additionally, I’m creating a bunch of device drivers that I call “pot“. So far, I have drivers for the ds3231 real-time clock, the Adafruit 8×8 matrix based on the MAX7219, and the ever-useful SSD1306.

These drivers are based on the libopencm3 API. I’m creating an adapter layer for the Raspberry Pi Pico #RP2040, so you should find that all the afore-mentioned devices work with the Pico.

Have fun.

Posted in Uncategorized | Leave a comment