Arduino Projects

GFX prototype tool

I’m starting to dust off some seasonal projects and realized I hadn’t made this simple tool public which others may find handy. With projects like the NeoPixel Tree it can be much quicker to code visual sequences locally instead of waiting for new firmware to upload to the MCU every time you want to tweak something.

The tool just wraps around the Adafruit GFX Graphics Library and instead of outputting to physical pixels it runs through SDL2. It’s somewhat similar to what I did in swift-gfx-wrapper but keeps it all in C.

GitHub repo:

Arduino Coding Fun iOS Projects

Flip Dots! The technical bits.

I first want to acknowledge that I did the thing that I try to never do: I showed off a snazzy project, left some hints here and there of how it worked, said I would follow up with full details… and never did. That’s lame.

I’ve had multiple people reach out for more info and I’m glad they did, since that’s pushed me to finally get some repos public and this belated follow-up written. Apologies!

To jump straight to it, I’ve published these two repos:


Let’s first go over the hardware involved. The most important piece, of course, is the Alfa-Zeta XY5.

In my case, the 14×28 board was made up of two 7×28 panels connected together via RJ-11.

The panels are pricey, but they can be thought of as “hardware easy-mode”. Alfa-Zeta has done the hard job building the controller that drives the hardware and all we have to do is supply power and an RS-485 signal that abides by their protocol.

If you purchase a panel from them there are two important documents to request:

  1. The main manual that describes the specs, features, and things like the DIP switch settings.
  2. The protocol for sending commands to the controllers (which is really simple).

These can easily found by searching around, but if you own a panel the company should supply them. Most of the protocol can be deduced by looking at open source code.


The 24V -> 5V converter isn’t necessary if you supply power to the MCU independently, say through a USB power adapter.

Connection overview

  • 24V DC goes to both panels
  • 24V DC goes to the step-down converter, 5V DC goes to the 5V input of the NodeMCU
  • NodeMCU is wired to the RS-485 to TTL converter
    • VCC -> 3.3v
    • Gnd -> Gnd
    • DE -> 3.3v pulled high because we're always transmitting
    • RE -> 3.3v pulled high because we're always transmitting
    • DI -> TX[x] x being 0 or higher depending on board
    • RO -> RX[x] most boards only have the main serial IO, but boards like the Mega have multiple
  • RS-485 -> Only one panel controller – not both

An Arduino Mega is driving the board in this photo.



See for the code that runs on the MCU.

At the moment there isn’t much to it – you can either compile the firmware to run in a mode that writes data from UDP packets to the board, or you can draw “locally” using Adafruit GFX methods.

See the README in the repo above for more details.

iOS / iPadOS / macOS

See for the code that runs on these devices.

Semi-interestingly I utilized Adafruit GFX again, this time via swift-gfx-wrapper to draw to the board over UDP. It’s hacky and experimental, but that’s part of the fun.

See the README in the repo above for more details.

Arduino Projects

Tree OTA updates

Something I should’ve done long ago – enabling OTA (Over The Air) firmware updates so I don’t have to disassemble the project box and move the tree every time I want to change its code.

To add a touch of UX, the pixels represent the upload progress. 😎

NeoPixel tree being updated via OTA firmware update.
Arduino Fun iOS SwiftUI

NeoPixel tree progress

This weekend the NeoPixel tree got many much-needed updates!

Though I have more ideas to implement, the basics of what I wanted to do are complete, like sending commands remotely.

What we can currently do:

  • Set the brightness
  • Change the color
  • Turn the pixels off
  • Run some built-in sequences, like a nice rainbow
  • Set repeating color patterns
  • Set individual pixels

I also threw together a really quick iOS app to set the color with SwiftUI’s built-in ColorPicker view. Thanks to the Rover project (another one that’s been neglected), I had some UDP client code I could borrow to speed up development.

Changing the color of the tree with a SwiftUI ColorPicker view.
Arduino Fun Projects Raspberry Pi

Domo Arigato

If the objective was to make the robot less creepy, I’ve failed miserably.

Arduino Fun Projects

A not-quite-Retina external screen

Arduino Troubleshooting Windows

Arduino Leonardo, VirtualBox, and Windows

I realize this post may be useful to about three other people in the world, but sharing is caring.

What I wanted to do

On my Windows 11 machine I wanted to be able to write and upload firmware to an Arduino Pro Micro (Leonardo) using PlatformIO.

The standard way to accomplish this is to install PlatformIO in VSCode for Windows and you’re done. However, I’m a bit of long time *nix user and really like my PlatformIO + Git workflow in that environment.

WSL sounds like a great option for this case, but unfortunately from what I’ve read, serial communication doesn’t play too nicely without a bunch of hoops to jump through.

To keep things (somewhat) simple I installed a Linux VM through VirtualBox and added a USB Device Filter for the attached Arduino Leonardo so it would be forwarded and accessible by PlatformIO. Using VSCode as my editor would still be possible thanks to its awesome remote features.

Arduino Coding iOS Projects Swift SwiftUI

Flip Dots!

I saw flip dots (also called flip discs) last year for the first time and instantly knew I needed some in my life. If you’re not familiar with them, check out how they work!

The particular model I have is the ALFAZETA XY5, which may be the easiest way to get up and running, but certainly not the least expensive.

After getting the board, all you need is:

  1. 24V power supply
  2. Something that talks over RS485 (in my case I used an ESP8266 connected to a MAX3485 board)
  3. Their documentation that defines the controller data protocol

I plan to write in more detail how it all works, but for this demo the stack is:

  1. SwiftUI app that runs SwiftGFXWrapper (which is mainly Adafruit’s GFX Library under the hood)
  2. The app sends the entire pixel buffer over UDP to the ESP8266
  3. The ESP8266 sends data to the XY5 over RS485 using their controller’s protocol

Update: Here’s more info on how it all works!

Arduino Projects

nRF24L01+ and SLIP

Currently a work in progress, I’ve nerd sniped myself to get TCP/IP working over SLIP with a pair of Arduinos equipped with nRF24L01+ radios.

Arduino Gadgets iOS Projects

iPad Zoom mute button

At work we’re primarily using Zoom for meetings while we’re in remote mode. Due to the recent problems found in their desktop software, I run it only on my iPad to provide a little more security (thanks to iPadOS’ sandboxed environment), plus the front facing camera on my iPad Pro is superior to my iMac and MacBook Pro’s.

The first issue I found with this setup was that I wanted to get the iPad into a position more perpendicular like a web cam, rather than the angled up shot below my face. I don’t think anyone wants to look up my nose unless I’m on a telehealth call, so I ordered this flexible stand for about $25 from Amazon and got it mounted:

Trying to bend this thing will give you a workout.

So far so good, until my first meeting. I wanted to follow conference call etiquette by muting myself when I wasn’t speaking, but it was a pain to reach and manually tap the mute button every time. Plus, although the flexible arm is super strong, it’s still going to wobble wildly if you touch the iPad and your video is going to show that.

Was there a way I could toggle muting myself without touching the iPad? After a quick Google search, the answer was YES!

The attached keyboard (Smart Keyboard Folio, Magic Keyboard) didn’t make any sense in this case, but a Bluetooth keyboard would be perfect!

Logical answer

The logical answer is to connect up a Bluetooth keyboard and hit Command + Shift + A when you want to toggle muting your mic, and you’re done. That’s it.

I’m not totally logical

Of course, the route I chose was different. I have enough keyboards on my desk, I really just want one button to do one thing.

Recently, I rigged a button to turn pages in the Books app over Bluetooth. We should be able to do the same thing here, right?

Figuring out the codes

The objective is clear: When we press a button, we send “command+shift+a” to the iPad.

Using Adafruit’s HID codes, we find:

  • Left shift == 0x02
  • a == 0x04

But what’s the “Command” button? Is that the “meta” or “GUI” key? If so, is it a modifier or just a regular key?

Lots o’ troubleshooting

I spent a lot of time troubleshooting over and over:

Compile a new sequence of commands, upload new firmware to the microcontroller, re-pair with the iPad, open Zoom and try to mute: No go.

From what I could tell, “shift + a” were working, but “shift + command + a” wasn’t. It wasn’t until I almost gave up that I had a breakthrough:

Let’s try remapping another key to “command” and see if we can press that key. How about Caps Lock?

It worked.

In my code I wrote:

// gold
ble.println("AT+BleKeyboardCode=02-00-39-00-00-00-00"); // shift + caps lock
ble.println("AT+BleKeyboardCode=02-00-04-00-00-00-00"); // shift + a

This is as if the user pressed “shift + caps lock”, and then “shift + a” at the same time, then released. Now the Zoom app was getting the proper command from a Bluetooth “keyboard”.


This setup is virtually identical to what I have here, it’s just a different button.

The USB cable coming in is only for power, and if I had the Adafruit Feather version on hand I would’ve used that with a battery so the box would be totally wireless.

The button is no more complicated than this tutorial.



A better version of this would be:

  • A button to also toggle video
  • Using the Adafruit Feather BLE version with a battery so the box would be entirely wireless