A couple of months ago, I penned a column, The Worm Turns, in which I revealed that — although I’d been bravely fighting my urges — my will had crumbled and I had decided to create a display comprising a 12 x 12 = 144 array of ping pong balls, each illuminated with a tricolor WS2818 LED (a.k.a. a NeoPixel).

First, I found a pack of 144 ping pong balls on Amazon for only $11. I ordered two cartons because I knew I would need some spares. Of course, this immediately tempted me to increase the size of my array to 15 = 15 = 225 ping pong balls, but I’d already ordered 150 NeoPixels in the form of five meters of 30 pixels/meter strips from Adafruit, so I decided to stick with the original plan, which we will call “Plan A” so no one gets confused.
Thank goodness I restrained myself, because the 12 x 12 array is proving to be a lot more work than I expected — a 15 x 15 array would have brought me to my knees.
The next step was to build a 2-ball prototype because I wanted to see whether it was best to attach the NeoPixel to the outside of the ball (the fast-and-easy option) or inside the ball (the slow-and-painful alternative). Although you can’t see it from the picture or from this video, there is a slight but noticeable difference in the real-world, and one method is indeed better than the other — can you guess which one?

Have you ever tried to drill 3/8” holes into 144 ping pong balls? Me neither. Over the years, I’ve learned a thing or two, and one of the things I’ve learned is that drilling holes in ping pong balls always ends in tears. Thus, I ended up cutting these holes using a small pair of curved nail scissors (there’s one long evening I’ll never see again).
The reason for using the strips is that this is the cheapest way to purchase NeoPixels with associated capacitors in the easiest-to-use form. Unfortunately, the ball-to-ball spacing (43 mm) on the board is greater than the pixel-to-pixel spacing (33 mm) on the strip. This means chopping the strip into segments, attaching each segment to its associated ping pong ball, and then connecting adjacent segments together using three wires. So, 144 x 3 = 432 short wires to strip and solder. Do you have any idea how long this takes? I do!

Now, you may have noticed that I was driving my 2-ball prototype with an Arduino Uno, but this is too large to be used in my array. In the past, I would have been tempted to use an Arduino Nano, which is reasonably small and not-too-expensive. On the other hand, the fact that this is an 8-bit processor running at only 16 MHz with only 32 KB of flash memory and only 2 KB of SRAM would limit the effects I could achieve.
Sometimes (rarely) the fates decide to roll the dice in one’s favor. In this case, while I was pondering which processor to employ, the folks from Seeed Studio contacted me to tell me about their Seeeduino XIAO.
OMG! This little rapscallion — which is only the size of a small postage stamp and costs only $5 — is awesome! In addition to a 32-bit Arm Cortex-M0+ processor running at 48 MHz, this bodacious beauty boasts 256 KB of flash memory and 32 KB of SRAM.
As an aside, it’s important to note is that the Seeeduino XIAO’s programming connector is USB Type-C, which means you’re going to need a USB-A to USB Type-C cable.

In addition to its power and ground pins, the Seeeduino XIAO has 11 data pins, each of which can act as an analog input or a digital input/output (I/O). Furthermore, one of these pins can by driven by an internal digital-to-analog converter (DAC) and act as a true analog output, while the other pins can be used to provide I2C, SPI, and UART interfaces.
Sad to relate, there is one small fly in the soup or a large elephant in the room (I’m feeling generous today, so I’ll let you pick the metaphor you prefer). The problem is that, although it can be powered with the same 5 V supply as the NeoPixels, the Seeeduino XIAO’s I/O pins use a 3.3 V interface, but the NeoPixels require 5 V data signals, so we need some way to convert between the two.
In the past, I would probably have used a full-up bidirectional logic level converter, like the 4-channel BOB (breakout board) from SparkFun, but I only need a single unidirectional signal, so this seems a bit of overkill.
Happily, I recently ran across an awesome hack on Hackaday.com that provides a simple solution requiring only a single general-purpose IN4001 diode.

The way this works is rather clever. From the NeoPixel’s data sheet we learn that a logic 1 is considered to be 0.7 * Vcc. Since we are powering our NeoPixels with 5 V, this means a logic 1 will be 0.7 * 5 = 3.5 V, which is higher than the XIAO’s 3.3 V digital output. Bummer!
Actually, if the truth be told, there is some “wriggle room” here, and the 3.3 V signal from the XIAO might work, but are we the sort of people for whom “might” is good enough? Of course we aren’t!
The solution is to add a “sacrificial NeoPixel” at the beginning of the chain, and to power this pixel via our IN4001 diode. Since the IN4001 has a forward voltage drop of 0.7 V, the first NeoPixel will see a Vcc of 5 – 0.7 = 4.3 V. Remember that the NeoPixel considers a logic 1 to be 0.7 * Vcc, so this first NeoPixel will accept anything above 0.7 * 4.3 = 3.01 V as being a logic 1. Meanwhile, the next NeoPixel in the chain will see the 4.3 V data signal coming out of the first NeoPixel as being a valid logic 1. Pretty clever, eh?
I’m currently about half of the way through wiring everything up. I cannot wait to see my array light up for the first time. Once everything is up and running, I will return to regale you with more details. Until that frabjous day, I will delight to hear your comments, questions, and suggestions.
Max – love the Neopixel voltage converter hack. So cunning you could pin a tail on it and call it a weasel…. Can you actually use the sacrificial Neopixel as a LED (if so does it have reduced brightness?
The Seeduino looks a good bit of gear as well – especially seeing as you can use it surface mount or thru hole. Don’t like the USB-C but I guess I better get used to it…..
Remember the old saying, “eagles may soar, but weasels rarely get sucked into jet engines” LOL
Well spotted — in fact the “sacrificial NeoPixel” can indeed still be used — it will just be a bit dimmer. In some systems this wouldn’t be a problem — if it were for a low-level indicator, for example — or maybe if you knew you were going to run the other NeoPixels as 80%, so running this one at 100% would be about the same — in my case, I want all the ping pong balls to be identical, so I’m happy to simply add an extra pixel and drive it to black.
You could mount the extra pixel on the back of your array and use it for a “health indicator ” for troubleshooting or indicating which of several effects is on tap. I assume there will be buttons or some such to select the effects. so an indicator visible form the side or bottom might be useful.
It’s like you are reading my mind — I was just thinking that myself yesterday evening. In fact I think that might have been in the back of my subconscious because I hot-glued the sacrificial pixel so it was pointing up (from the back) so I could see it, even though that makes the wiring a little trickier.
I’m really impressed with the little scamp, and I haven’t even powered it up yet LOL — the USB Type-C was unexpected, but it prompted me to purchase some USB A to USB Type-C cables from Amazon, and I know they will come in useful 🙂
I always find it difficult to judge – are those holes on the Seeeduino at standard 0.1 inch spacing?
Sorry — I should have mentioned this — yes, they are 0.1″ spacing — and it comes with two rows of 7-pin headers for you to use if you want, so you could easily use this on a breadboard.
I just posted this video ( https://youtu.be/U6I9VJCxqAY ) showing me preparing the little wires.
Also difficult to judge, but the spacings on the Neopixel connections also look like 0.1 inch. Which gives me an idea. Could you solder the neopixels to veroboard (stripboard)? Then the only work would be soldering them to the veroboard – if that is possible then it would be heaps quicker than stripping all those wires – and you’d have to make 3 cuts in the strips under each neopixel – very quick and easy with the proper tool. And positioning might be a problem if they aren’t exactly lined up with the holes in the veroboard, but you could make a jig for that…. You’d also have to buy LOTS of veroboard but it’s not that pricey.
I just measured them — the spacing between the power, signal, and ground connections on the strips is indeed 0.1″ — maybe I’ll do things differently next time, but I’m committed to my current approach for this prototype 12 x 12 array — it’s Sunday morning and I’m soldering away 🙂
I must say that this XIAO board does look nice. Will have to keep it in mind for future projects. Assuming that I find any time for such…
One potential issue is there are no mounting holes so I assume you either attach it to a breadboard (which somewhat negates the size advantage or use sticky tape of some kind.
I just got a set of LoRa boards from SparkFun to play with. Hoping that I’ll find time to get them going….
The Grove Shield for seeeduinoXIAO is coming soon. You could find its updates in https://forum.seeedstudio.com/t/the-extension-board-for-seeeduino-xiao-grove-shield-for-seeeduino-xiao-just-came-out-how-do-you-like-this-screen-printing-of-the-board/251542
Oooh — now that is cool — I didn’t know you were doing that — I have a Grove Beginner Kit for Arduino sitting on my desk — so this Grove Shield for XIAO would be an easy way for me to attach the XIAO to the back of the 12 x 12 array and also to add Grove sensors.
That’s true — in the fullness of time I might just hot-glue it to the board — another approach is to hot-glue two 7×1 0.1″ sockets to the board, and then use the headers on the XIAO to plug into them — I’ll take pics when I get round to this part.
Elizabeth — see the response from Ming below — so the Grove Shield for XIAO does have mounting holes — in this case I would use hot-glue 1/4″ plastic stand-offs to the base board, then use the associated plastic nuts to attach the shield to the standoffs, then plug the XIAO into the shield. Observe that the shield has 8 Grove connectors (four of which can be snapped off if not required). Seeed Studio have a bunch of little Grove breakout boards (BOBs) with a wide variety of sensors and actuators that can be plugged into these Grove Connectors.
The XIAO makes the Grove connectors look huge.
Let’s see, Seeed has Grove BOBs while SparkFun has Qiic BOBs. SparkFun has a Qiic to Grove cable though…
Not that I have any time to mess with any of this.
This is the fun stuff — you should make time LOL
Regarding the woe filled exercise of drilling holes in ping pong balls:
Haven’t tried this, but maybe a Hole Saw https://amzn.to/3mlKIns would save you from the curved scissors?! Or if those teeth are still too gnarly to not tear the ball apart, how about this: https://amzn.to/2IR4WYt a set of Diamond Hole Saws [metric]. Or, if you fancy the English system: https://amzn.to/3mjqmLp
Just DON’T hold the ball with your fingers! Maybe, also, pad the vice teeth with something like China Packing Foam: https://amzn.to/3nnangW
Using the scissors wasn’t all that bad — but I must admit that if I was doing this again (especially for a larger array with more balls), I might be tempted to use the diamond hole saws 🙂
Can you share a link to where you got the LEDs and maybe even the code you used? I’m struggling to create a similar project
Sure — the link to the LEDs is actually in the column — the 2nd paragraph where it says “30 pixel per meter strips (https://www.adafruit.com/product/1376?length=1) — you’ll need 5 meters. With regard to the code, I’ve been posting a series of articles on LEDs in the UK’s Practical Electronics magazine (https://www.electronpublishing.com/). This particular series started in March 2020 — and we started working with the 12×12 array in July 2020 — you can access the code associated with my projects from the downloads page
(https://www.electronpublishing.com/product-category/downloads/) — you will need to set up an account, but it’s free. Also, email me at max@clivemaxfield.com and I’ll be able to help some more.