Available for pre-order
View Purchasing OptionsTL;DR: The first batch of Jumperless V5s will be shipping to me this week and will be on their way to you shortly thereafter.
But there’s a lot of other cool stuff I’ve been working on while I wait for these to be assembled. So buckle up, this is gonna be a long, action-packed tour through the Jumperverse.
First, here’s a fun little side quest, Joom.
I couldn’t really think of a good way to fit it all into the firmware so you could run it from the regular menus, so it’s just a .uf2 file that will overwrite the stock firmware. When you’re over it, you can just load the real firmware again.
Tip
A quick refresher on loading firmware on an RP2xxx:
Hold down the boot button on the back side of the USB port while plugging it in and drop these .uf2 files onto the drive that pops up.
When you have the regular firmware loaded, the Jumperless App will check for updates at startup and keep you up-to-date, but Joom doesn’t initialize USB so you need to do it this way.
As I’ve probably mentioned before, Jumperless V5 probably isn’t going to replace your TV anytime soon. Because the LEDs are mounted on the PCB and shine through a small hole ~1/2 inch above them, the viewing angle is terrible. For wires and components it’s totally fine, the light bounces around and lights up the whole row so you can see it from any angle but, to read text and navigate menus, it needs to be pointing right at your eyeballs. So, having a stand propping it up at 45° is super handy.
My friend at Alpenglow Industries is an absolute wizard with laser-cut acrylic (as well as electronics and yarn stuff), so when she floated the idea of making a laser cut acrylic stand for the Jumperless in a frankly absurd number of color options, I got to work designing it.
Turns out designing acrylic stuff that a human can assemble and stays together is hard and also I suck at it. This will fit together, but the order of operations is super weird and it probably needs to have some hot glue shoved into all the slotted parts to feel solid. But, if you have a laser and want to try it, the files are on Github.
Eventually Carrie may save me from my hubris and design a better acrylic stand than this, and offer them pre-cut in a bunch of different mix and match colors.
Originally, I was using this nice 3D-printable stand designed by someone in the community. It works great but, after designing the acrylic stand, I felt the 3D-printed version needed some pizzazz to match the overall vibe.
As soon as I showed that to people, they brought up something that seems stupidly obvious in retrospect: why didn’t I add a slot to hold the probe? So I did.
You can get both versions to print yourself on Printables (these will work for the OG Jumperless too, I added a notch to accommodate the slightly wider OG probe).
You can also put some of these self adhesive 8 x 2.5 mm rubber feet on the bottom, they’re the exact same ones on the Jumperless itself so you can have extras around if you feel like doing any soldering on your Jumperless V5 and want to take them off.
I’ve had these SBCSMDOLED adapter boards sitting around for a while, but it hadn’t crossed my mind to actually test them with a Raspberry Pi. And yep, it works.
I hooked the Jumperless’s internal UART up to the Tx Rx pins on the Pi, so what you’re seeing here is me sending typos through the second serial port that pops up when you plug in a Jumperless and which are being received on the Raspberry Pi. You can also do this in the other direction and have the Pi send commands to make connections or whatever.
What’s cool is there’s a little solder jumper on these adapters that you can bridge to connect the 5 V busses together and power your Jumperless from the Raspberry Pi. This is kinda why I didn’t want to mess with USB-C Power Delivery or anything, it’s cool to just be able to shove in 5 V from wherever, as long as it can provide 500-1000 mA.
If you want to take a swing at designing your own stand or something, here are Jumperless V5’s dimensions (in mm):
Plus a bonus exploded view:
Or, let your computer handle the measuring and just use the 3D model.
For the first 100 or so boxes of the very first run of the OG Jumperless, I went through a US-based website that didn’t offer custom sizes, took six weeks, printed in low resolution on the jankiest cardboard imaginable, didn’t crease them enough so I had to fold them with a ruler, and all for the low, low price of $7.50 per box! To get them to my standard of presentable, I ended up cutting a stencil and painting over the pink parts with glitter, much to the chagrin of some customers who don’t love glitter as much as I do (genuinely sorry about the hot chocolate!)
So then I decided to have Zhibang Packaging make the boxes for the OG Jumperless, and they were amazing, custom sized, lush cardboard, pink foil printing (instead of glitter), microscopically high resolution, at arund 1/5th the price. So much that I got the sense that I was asking too little of them. So, of course, now that I know what they were capable of the last time around, I have to push it further and make a cooler box. So, inspired by the Solder Ninja’s excellent packaging, I had them make a magnetically clasped gift box with an EVA foam insert.
Fun fact: the OG Jumperless, white cable, and probe PCB you see in that bottom left photo, I didn’t arrange that. A really cool benefit to having solid relationships with your suppliers is stuff like that. They went out of their way to coordinate with Elecrow and picked up samples from them to check the fit on the foam insert I sent them (okay, their factories are about three blocks away from each other but still, that was super nice of them.)
(Put your sound on to hear what it sounds like inside a box factory.)
What I suspect is happening here is that the US customer-facing websites are effectively drop shipping. Using basically the same factories in China but telling them to use the absolute cheapest options so they can pay them $0.50 per box and keep ~$7 per box for themselves to run a janky-ass website and be on the first page of Google search results.
There you go, that’s as close as I’m going to get to mentioning anything remotely related to tariffs in this update.
One thing they don’t tell you about having any sort of merch is that you end up only wearing shirts with our own logo on them. It started to feel weird to be wearing the same shirt every day for a year and a half, so I decided to bump that up to wearing the same three shirts for the foreseeable future.
The crop tops and 3/4 sleeve shirts were a special request and I only had a few made. But I did make a ton in men’s V-neck, men’s crew-neck, women’s V-neck, and some running shorts.
In the bottom right: my mom’s a painter and needed to do a random panel for something and asked me what she should paint, so I jokingly said she should do my logo. Now I have this awesome glittery painting of People’s Park Complex on my wall
Electronics pro tip: have a friend from high school open a printing business who will close their shop for two days while you hang out and watch them make your stuff.
We also did some R&D and figured out you can mix red, green, and blue glow in the dark pigment to get a white glow, mix it into clear Plastisol ink, and then do a top layer with that. So yeah, these also glow in roughly full color.
I’ve always thought it was lame to sell stuff that’s also an ad, so these shirts are free. How you get one is by going to Teardown 2025 where I will be handing them out. So, if you didn’t have enough reasons to go already, maybe a shirt (or running shorts) will change your mind.
The low profile, right angle, TRRS cables you see in all these photos have the ends hand painted and dipped in glitter. The prospect of doing that a thousand times wasn’t completely out of the question, but I knew after the first 100 or so I’d be questioning my life choices. So I put out an RFQ on Alibaba to have them made by someone with better equipment than cans of spray paint and The Glitter Pile
Turns out the company I was buying the cables from to paint responded, and they told me the molds they used to make these are "used up", but they’d be happy to make a new injection mold and do them in pink plastic for me.
Here’s the hand mixed, pink plastic swatch they sent:
Hell yeah.
If they’re making a custom injection mold for this, it turns out I can make these any shape I want. So I fired up Fusion 360 and made these:
I switched back to TRRS because the third ring wasn’t strictly necessary and the back end of the plug is a bit too long to make these as low profile as I would like. This is what they should look like in vivo:
The lead times are a bit long (6-8 weeks and this was about five weeks ago), and I wasn’t about to hold up shipping on account of the cables, so I had them send me their existing inventory of 100 black ones to hand paint myself. So, the first 100 or so units will probably ship with the glitter, and then they’ll start coming with these pink plastic ones when they’re ready.
To save myself from having to write every function anyone would ever want by myself, Jumperless V5 allows you to write your own apps. So I wrote you all a commented example app that should give you a sense of how to use all the functions you’ll likely need to do anything. There’s also a setup guide in the repo to show you how to add the app to the library so you can run it from the menus.
void customApp(void) {
//!add some bridges to the net file
addBridgeToNodeFile(12, 25, netSlot, 0, 0); //netSlot is the current slot
addBridgeToNodeFile(TOP_RAIL, 52, netSlot, 0, 0);
refreshConnections(-1, 1); //you need to refresh connections to make the changes take effect
//!change the top rail voltage
setTopRail((float)3.3); //this will set the top rail to 3.3V
//!GPIO
addBridgeToNodeFile(RP_GPIO_1, 42, netSlot, 0, 0);
addBridgeToNodeFile(RP_GPIO_2, 42, netSlot, 0, 0);
refreshConnections(-1, 0); //you need to refresh connections to make the changes take effect
pinMode(GPIO_1_PIN, OUTPUT); //I need to change this to GPIO 0 (so GPIO 0 = pin 20, 1 = 21, etc.), but for now they start at 1
pinMode(GPIO_2_PIN, INPUT);
//set GPIO 1 high and read it with GPIO 2
digitalWrite(GPIO_1_PIN, HIGH);
int reading = digitalRead(GPIO_2_PIN);
Serial.print("GPIO 2 Reading: ");
Serial.println(reading);
delay(10);
//set GPIO 1 low and read it with GPIO 2
digitalWrite(GPIO_1_PIN, LOW);
reading = digitalRead(GPIO_2_PIN);
Serial.print("GPIO_2_PIN: ");
Serial.println(reading);
removeBridgeFromNodeFile(RP_GPIO_1, 42, netSlot, 0);
removeBridgeFromNodeFile(RP_GPIO_2, 42, netSlot, 0);
refreshConnections(-1, 0);
//!DAC
//connect the DAC to row 20 and set it to 5.35V
setDacByNumber(1, 5.35);
addBridgeToNodeFile(DAC1, 20, netSlot, 0, 0); //connect it
refreshConnections(-1, 0);
delay(10);
//!ADC
//connect the ADC to the same row as the DAC and read the voltage
addBridgeToNodeFile(ADC0, 20, netSlot, 0, 0);//note that this is the same row as the DAC
refreshConnections(-1, 0);
//delay(100); //give it a sec (refreshConnections() is async on core 2, so it might not be done yet)
waitCore2(); //or you could also use this to wait for the core 2 to finish
float voltage = readAdcVoltage(0, 8); //readADC() will return the 0-4096
Serial.print("\n\rADC0: ");
Serial.println(voltage);
As you can see, this isn’t really an "app", it’s just a function in Apps.cpp. I did it this way so you can use literally any function in the Jumperless V5’s firmware, the ones shown are mostly the helper functions I’ve written to make my life easier. There’s no guard rails here, you have complete control of the hardware.
It’s all written in Earle Philhower’s arduino-pico, so if you’ve written code for any Arduino-like thing, the syntax should be familiar.
If you don’t feel like looking at the code on Github, I’ll go through a few snippets from the example app here to maybe give you some ideas for things you’d like to do.
//!measure current
addBridgeToNodeFile(ISENSE_PLUS, 9, netSlot, 0, 0);
addBridgeToNodeFile(ISENSE_MINUS, 28, netSlot, 0, 0);
refreshConnections();
float current_ma = INA0.getCurrent_mA();
Serial.print("current between row 9 and 28: ");
Serial.print(current_ma);
Serial.println(" mA\n\r");
//!printing stuff on the breadboard
showLEDsCore2 = -3; //this tells the second core to write to the LEDs (negative numbers clear first, check loop1() in main.cpp to see what it's doing)
//3 or -3 will "hold" control of the LEDs (so animations and other stuff aren't drawn)
b.clear(); //clear the screen
clearLEDsExceptRails(); //these are fairly similar, but this is more direct
//draw with raw rows
b.printRawRow(0b00001, 55, 0x170010, 0xffffff);
b.printRawRow(0b00011, 56, 0x150012, 0xffffff);
b.printRawRow(0b00111, 57, 0x130013, 0xffffff);
b.printRawRow(0b01111, 58, 0x100015, 0xffffff);
b.printRawRow(0b11111, 59, 0x080018, 0xffffff);
//text (also shows the insane way I deal with colors)
for (uint8_t i = 0; i < 254; i++) {
hsvColor hsvTextColor = { i, 255, 30 };
rgbColor rgbTextColor = HsvToRgb(hsvTextColor);
uint32_t textColor = (uint32_t)rgbTextColor.r << 16 | (uint32_t)rgbTextColor.g << 8 | (uint32_t)rgbTextColor.b;
b.print("Fuck you!", (uint32_t)textColor);
showLEDsCore2 = -3;
delayMicroseconds(200);
}
You can also feed it arbitrary images (after running them through image2cpp) and it will work as a 14x30 display.
//!get row input from the probe
b.clear();
b.print(" Tap Rows!", (uint32_t)0x00140a);
showLEDsCore2 = -3;
delay(100);
showLEDsCore2 = -1; //-1 will clear and then draw the wires as they are in the node file (without any extra stuff we drew)
//check for tapped rows until the probe button is pressed
int probeRow = -1;
int lastProbedRow = 0; //store this so we can clear it
Serial.println("Click the probe button to exit\n\n\n\r");
while (checkProbeButton() == 0) {
probeRow = justReadProbe(); //justReadProbe() returns the row number of the probe, or -1 if it is not touching anything
if (probeRow != -1) {
Serial.print("\r \rProbed row: ");
printNodeOrName(probeRow); //this will print names for the rows
b.printRawRow(0b11111, lastProbedRow - 1, 0x000000, 0xffffff); //clear the last probed row
b.printRawRow(0b11111, probeRow - 1, 0x172000, 0xffffff); //ugh these are off by 1 (because the first row is 0)
b.print(probeRow, (uint32_t)0x002008); //this will print the row number on the breadboard
//showLEDsCore2 = -2;
lastProbedRow = probeRow;
delayMicroseconds(100);
}
}
I might make this whole bit into its own function so you can tell it to wait until you tap a row with a single line.
//!probe tip (in measure mode)
//get the voltage on the probe tip
float probeVoltage = readAdcVoltage(7, 8); //ADC 7 is hardwired to the probe tip (in measure mode), so it's this easy
Serial.print("Probe voltage: ");
Serial.print(probeVoltage, 4);
Serial.println(" V\n\r");
//get the current on the probe tip
//the probe tip is hardwired to ROUTABLE_BUFFER_IN, so it connects that to DAC 1, sets the DAC 1 to 3.33V (which it does by default right now so you can use the probe to tap rows in measure mode), and then measures the current
//the reason this exists is to tell the position of the switch (measure or select) by sensing whether DAC 1 is powering the probe LEDs
float probeCurrent = checkProbeCurrent();
Serial.print("Probe current: ");
Serial.print(probeCurrent, 2);
Serial.println(" mA\n\r");
//this will be something around ~1-3mA if it's in select mode (because it's whatever the probe LEDs are drawing)
Make sure you set the switch on the probe to the measure
position.
//!raw CH446Q connections
//you could even do this ~10,000 faster by sending raw X and Y connections directly to the CH446Qs
//you'll need to be staring at the schematic it use this, but for doing stuff like "fake GPIO" by connecting a row to GND and a rail really fast or something, this might be useful
sendXYraw(CHIP_K, 4, 0, 1); //TOP_RAIL to AK
sendXYraw(CHIP_A, 9, 1, 1); //AK to row 1
//let's see how fast of a PWM we can get on pin 1
//we can leave AK to row 1 connected and just toggle between TOP_RAIL to AK and GND to AK
//!fake GPIO
unsigned long startTime = millis();
unsigned long timeout = 10000; //10 seconds
while (millis() - startTime < timeout) {
sendXYraw(CHIP_K, 4, 0, 1); //connect TOP_RAIL to AK
delayMicroseconds(100);
sendXYraw(CHIP_K, 4, 0, 0); //disconnect TOP_RAIL from AK
sendXYraw(CHIP_K, 15, 0, 1); //connect GND to AK
delayMicroseconds(100);
sendXYraw(CHIP_K, 15, 0, 0); //disconnect GND from AK
}
If you want to bypass all of the routing stuff entirely, you can also just send XY connections to the crossbar switches directly.
There’s more stuff I didn’t include here. If you write an app you’re happy with, submit a pull request and I’ll add it to the default app library so everyone can use it.
This scans through each row connecting them to an ADC, if it measures ~0 V, it’ll connect a GPIO to that row and wiggle the pullup resistors so it can tell the difference between a row that isn’t connected to anything and a row tied to GND.
By itself, this isn’t particularly useful, it’s more of a template app so you can give it some conditions and have it do something when they’re found.
This is the absolute slowest way to do it by writing to the filesystem every time, but it’s meant to be an example showing how to make connections "properly". If you hard-code the routing, it can scan the whole board ~300 times per second (that’s how the probe was sensed on the OG Jumperless.)
Because the DACs and ADCs are scaled to +-8 V with op amps, the precision of the feedback resistors somewhat determines how well the readings match the real voltage on those. But, as it turns out, the INA219 current/power monitors have a pretty good internal voltage reference. So this app sets a bunch of voltages and calibrates the scaling against those. It saves everything to EEPROM so you should only have to run this once.
This is more of a core function that’s been around forever, but I have a nice video of it so I’m showing it here. This also works with the DACs and any of the ten routable GPIO, and it doesn’t matter whether they’re set as inputs or outputs.
This one is awesome. It’s a new setting on Jumperless V5 that automatically fills all unused paths with redundant copies of existing paths to get a lower connection resistance. If you want more control over which paths want low resistance, you can turn it off and just make the same connection multiple times (which does the same thing but makes sure there are more free paths available for the ones you care about.)
Remember in the previous update where the PCB fab Elecrow was using had to scrap the first sample run of five and remake them? Well, after my project manager, Chris, and I talked it over, we decided to believe them when they insisted they could make the boards. The next five samples came out great, but apparently they couldn’t pull it off at scale and had to throw away the entire run of 800 PCBs, brutal. At least they told us about it pretty early this time so it didn’t push back the schedule too much.
A fun bonus from all that is I got them to send me a few of the bad boards so I could do this:
So, we went to the other fab that Elecrow uses for their high-spec PCBs and asked them to hurry. And they did an excellent job:
As of the time I’m writing this (April 21st), I am happy to report that they have 150 boards fully assembled, flashed, and first-pass tested, as well as another 150 boards with the just SMD stuff populated.
Below is the quick testing procedure I’m having them run. I’ve found that if the click wheel and power supply works on these, 99.9% of the time, everything else will work too (I’ll do the rest of the testing myself, this is just to check for major issues in production).
They should be shipping the first batch out to me this week. When they arrive at my house, I will glue on the click wheel caps, put them through some more thorough tests, polish any rough edges, give them their glittery probe cables, read them a bedtime story, then put them all in a box to ship to Mouser’s distribution center to be shipped to you.
There’s no way to know for certain how long it will take to move through Mouser’s systems and get to your doorstep, but it won’t be long now.
If you have any questions about anything or just want to get a more real-time stream of updates about how everything’s coming along, come chat with me and the community on the Jumperless Discord, Forums, GitHub, Twitter/X, Bluesky, or Mastodon.
Love,
Kevin