August 14, 2021

Converting a Cisco 7609 into a beer tap

Beer Tap

Last year I thought that we had reached some sort of peak in terms of how far one can go in building useless things by converting a 42U rack into a bar. Shortly after that the people that built the bar visited San Francisco and we started thinking about what the next project could be. After a good amount of alcohol we discussed memories and I started thinking back to the Tech PoP” at DreamHack. You see, at DreamHack, the network volunteer crew used to have a couple of racks that they setup for display showcasing the routers that powered the network, a marketing ploy which was cool in 2006 when the bandwidth that DreamHack used actually mattered. Fast forward to 2015 and the network crew started filling the racks with useless hardware just to make it look cool, there was even a big NAS connected that served no purpose other than stroking the egos of the people that volunteered in the tech crew.

The problem here is not so much that they wanted to build something aesthetically nice but that they didn’t go far enough. If you’re going to have useless hardware, why not explore the concept further rather than a look but don’t touch” visual display of garbage hardware? One of us started joking about converting one of the old core routers to a beer tap and Wberg realized that he might actually be able to source one of the routers of the same model that used to sit in that PoP. Fast forward to 2020 and we start discussing the actual reality of converting a Cisco 7609 into a beer tap. Wberg works as a network architect and has had this idea for a long time, converting a router to a beer tap but it’s not like you can convert 1M EUR of hardware into a beer tap. Time did it’s thing and Wberg was able to source a used 7609 in working condition, I don’t think we ever imagined this actually happening but now Wberg posed the question I have 100 kilos of core router, what do we do with it?”

A quick primer on what the Cisco 7609 is: Cisco’s top of the line router built around the year 2000 for ISPs to serve as core router”. It’s a chassi containing 2 power supplies, fan packs and a backplane which allows you to mix & match different line cards”. The line cards are the interesting part as they provide the actual network interfacing and is the user interface” of the device. The Cisco 7609 can hold 9 line cards of different types that are mounted vertically into the chassi. The top of the device serves as cable management, allowing you to neatly organize the incoming cables into distinct channels and feed the line cards. Sort of a side note but this device actually went end of support in July 2021, over 20 years of being supported by Cisco.

7609

Plan of attack

The first was figuring out what the end result was going to be. If we wanted a beer tap then we had to modify the machine quite heavily and it was unlikely to ever work again, however, if the router wouldn’t run then it wouldn’t look as visually pleasing as a real one does. So it was either powering this beast and figuring out how to pipe in beer into a live 7609 OR re-building all the parts that provided visual indication which made it look active. The decision seems easy, why spend a huge amount of time on rebuilding a device that already works? Well, the moment you turn the router on and hear the fans it’s obvious that the only approach is to rebuild it. Behind the cable management tray there are two fan packs” which each packs 4 x 48V industrial fans. These fans are built for reliability and air throughput, not for a low noise profile. On top of this, if we were to use the existing line cards we would need to ACTUALLY feed traffic on the ports for the activity LED to look busy.

With that in mind, how do we go about rebuilding this thing? The constraints are:

  • All LEDs on the front needs to work
  • Ethernet cables needs to be connected
  • Fiber cables needs to be connected
  • Can’t sound like a jet engine
  • Preferably controllable intensity of the ports

At this point in time we still believed in the idea that we could salvage the existing LEDs and build a jig that would power them to avoid having to rebuild EVERYTHING. For that reason the approach that made most sense was to remove the unnecessary parts of the line card and keep the structure and LEDs. Since this trash was built in the early 2000s I was skeptical towards cutting these line cards but Bengan & Summa did not let themselves be persuaded by my thoughtfulness about toxic dust and cut right through all of the line cards, removing approx. 70% of them.

bengan cuttar

lcs

It should be said that since this was during 2020 I wasn’t able to travel to see the line cards in person and relied on Wberg’s analysis of the cards to help guide the project into a feasible solution. Once Wberg got back to Stockholm, he and Love (king of electronics) scheduled a quick session to examine the line cards and the outcome was sadly not that positive. Not only was almost every line card different but each LED was a green/orange one without on-board dimming meaning that we would have to build 7 different jigs with tons of standalone PWM chips and shift registers. On top of that, if we somehow blew one of these LEDs the replacement would be a pain as the baseboard was an early 8 layer board with hidden traces.

Time for PLAN B. I had worked with APA102 previously with the cube and found them easy to work with (except for electrical noise) and encouraged Wberg to buy a strip to play with to explore what could be done if we replaced each LED. Wberg was quickly able to make the strip work and became equally confident that using a separate LED strip was the way forward in this case. Wberg initially explored just attaching the LED strip straight against the profiles on the chassi but the pitch didn’t match up which meant that the LEDs were unaligned from the front profiles. We probably could have gotten away with this but it didn’t look perfect, you could tell that this was a fake and that the router wasn’t booted. If we already gone this deep, going deep enough to make it look perfect is the only option.

Finding solutions to constraints

So how does one go about making it perfect? At this point neither me or Wberg had any ideas. There were tons of constraints here, especially with the 48 port cards. The 48 port card have about 6mm of clearance underneath the baseboard with 4 mm of clearance against the outer chassi meaning that whatever solution we created it would have to be small. We started by sketching out the line card with most constraints in Fusion360 to have a shared reference of the measurements.

outlineboard

I looked around on the web for some inspiration and ended up disassembling an old computer to see how they piped light from the motherboard to the front panel. In this old computer I found a light pipe”, essentially a plastic part that relies on the fact that the LED is strong enough that refraction doesn’t matter. Think of it as a straw filled with water, if you have a strong enough LED on the other end of the straw the other side will look lit as a result. I designed an array of light pipes that I had my friend Love 3D print in order to see if it even worked, it didn’t work. The transmission in a 3D printed part is way lower than polished injection molded plastic part which sort of killed our idea. Because every part had to be different, injection molding was also off the table due to cost.

lightpipe

At this point Love asks me: Why not use optical fiber?”. I was initially dismissive of this idea, thinking of fiber as more as an expensive medium to transmit data but after thinking about i stumble on a link for a star ceiling”, essentially someone piping tons of 3mm fibers into small holes in their ceiling for a very unique light. This time the question actually hits me, why NOT use fiber? Optical fiber is BUILT for this purpose. It’s often flexible and focuses on one thing: transmitting light over distances. If we could mount a fiber cable against each individual APA102 light on the strip, could we just pipe the light to where it needed to be? I ordered a bunch of different fiber cables from AliExpress and of course the transmission was exactly what we wanted.

In hindsight I feel so dumb even writing this. This was the obvious solution, staring us in the face. We were even going to use fiber cables as part of the mock wiring” and I wasn’t able to connect the dots. I think this is a lesson in getting stuck in what the tools one has used can/cannot do. I never imagined fiber cable being used for something other than data transmission which is why I even ruled it out when asked. Growing up in the 90’s, 1 in 5 friends had these lamps with spinning fiber cores in their rooms so of course this is not a new discovery by any chance.

fiberlamp

Creating the parts

With this problem out of the way, the next problem was how are we going to mount the fiber cables against the chassi”? We need to somewhat precisely align the fiber cable which immediately had me reach against 3D printing. What if we printed a focuser” that served both as protection and alignment for the LED strip but also as a holder for the fiber and a receiver” that would be glued against where the normal LED would have been positioned. Since I didn’t have the actual line cards in San Francisco, Wberg bought a 3D printer in Sweden to allow us to iterate remotely.

Let’s start with the focuser. I toyed around with a bunch of different ideas on how to design it and settled on a cradle that would hold the strip with a plate that partly locks in place and is held with screws against the focuser. Getting here took a couple of iterations but once I explored the teeth” concept and did a test print which made it was obvious that this was the design to go for. The idea was to reduce the part count as much as possible and to be able to increase the structural integrity in order to lower the amount of stress we would put on the LED strip. One added bonus is that this could be printed with a minimal amount of supports, only requiring supports for the hex nut holders. Being able to avoid supports allowed us to spend less time on finishing the holes that would hold the fiber as the press fit would be equal across the receiver.

focuser design

What was frustrating was that all line cards have different LED counts (12, 5, 5, 5, 5, 50, 50) and when testing tolerances it was so hard to keep track of what value I had changed after Wberg printed the part. 3D printing can be weird with tolerances, especially with holes and PETG and prior to Wberg learning how to properly finish the parts. Eventually I realized that the count” of LEDs really didn’t matter, if I could build a part that worked for 5 we could extend that one. This led me to re-designing the part completely using parametric design. For all you people that 12 months ago had no idea what this even meant, imagine deriving all the measurements in the CAD software from variables to the point where I can type X LEDs and the sketch updates and create the amount that I want. The beauty of making this parametric is that it was much easier to iterate on what values we actually needed to get press fit”, as in the friction of the hole holding the fiber without having to glue it together. This example below is generated from the APA102 strip sketch, by extending the LED variable, the strip changes size and this model scales up to fit that strip, deriving the measurments from strip.

parametric design

The receiver parts seemed easier on paper, so easy that Wberg who’s new to 3D printing and CAD managed to make all the ones EXCEPT for the one that would sit underneath the 48 port board. The available space underneath the 48 port board was so tight (5mm) that my approach was to just build a caddy and use epoxy glue to fixate the fibers. This seemed like a really messy idea and I didn’t find a good way to make a cable that’s 4,2mm in diameter fit in a 3D printed caddy with 0,8mm to go and still provide strength. We went back and forth on this issue until one day where Wberg flipped the baseboard in the line card upside down and slotted in the ethernet ports into the chassi. Of course it actually fits because the ports are symmetrically placed. That gave us tons of extra space to work with (now closer to 7mm) and only required drilling some holes into the baseboard. After some designing we found that stripping the fibers of cladding and using only the core allowed us to use the most amount of 3D printed material, which added to the stability and press fit. The only remaining thing to do was cutting and stripping over a 100 optical fibers and mounting this thing which we saved for a meeting in Anderstorp.

Writing the software

Since we basically killed all logic in the router we had to create something that could mimic how a router would behave and do more exciting things than just that. I picked apart a lot of the code that I wrote for nocube and wrote something new that focused specifically on the router called slisko. The intent here was to have a piece of software that ran on a Raspberry Pi, used the SPI port to drive all the LEDs and serve as a web server where one could control the different behaviours of the router such as color changes and strobe.

The software is based around the idea that there exists LEDs” which are then repackaged in various slices with references in order to have multiple ways of querying the LEDs. You could for example ask for all the system LEDs that belong to a SUP720 card.

for _, port := range c.GetCardOfType("sup720") {
    port.Labeled["system"].SetClamped(0.0, 1.0, 0.0)
}

However if you wanted to query all LEDs of the entire device as a whole, ignoring the realm of line cards you could get all of them visually sequentially mapped.

for m, port := range c.LEDs {
    if m == int(l) {
        port.SetClamped(1.0, 1.0, 0.5)
    } else {
        port.SetClamped(0.0, 0.0, 0.0)
    }
}

I looked at some reference footage that Wberg shot for me of how an actual router blinks”. It’s easy to think that it just blinks randomly on port activity but there is some structure to the blinking. First of all it blinks negative, meaning that the LED is always lit and is turned off on activity. Second is that there are a few distinct speeds” of blinking rather than a curve. It looks like there are steps of 0/20/40/60/80/100 in terms of activity and the ports blinking on these intervals. Third is that there is a common clock across the ports on the same line card, meaning that I need to keep track of the blinks per line card rather than globally. I ended up creating a very simple interface in Go:

type Fake interface {
    Trig() float64
}

This allowed one to easily build constructs that can be chained, for example a random blinker that is chained into a stepped blinker interface and composed together per line card. In the end I had a bunch of different interfaces that the pattern chains together per linecard to create the illusion of proper blinking. Who knew that something simple as blinking a LED was this complex…

On top of this I ended up building a simulator” to be able to see how the patterns actually looked when developing the system. The simulator reads out the order of the line cards from the mapping and renders them based on a lookup table for the LEDs, consuming exactly the same data as the LED adapter would have done. This approach ended up being a lifesaver when mapping the software against the hardware placement due to the issues we ended up having with all the strips on-site. Being able to quickly write test patterns that query specific intentional LEDs and seeing the result saved a lot of debug time.

simulator

Assembling the insanity

Down in Anderstorp we started with removing as much as we could from the larger chassi. We didn’t need the backplane, so that was removed. Same with the fanpacks, also useless weight. Essentially everything we could remove that didn’t affect the structural integrity was removed to make it easier to plumb pipes of beer into it. We were going to use an external tap cooler and isolate the pipes into the router, relying on the fact that people are drinking quite heavily to keep the beer cool. We opted to keep the PSUs intact but that was mostly because they can easily be removed and provide a lot of stability, making the router bottom heavy when mounted. I can tell you that they didn’t spare any expenses on metal here, drilling holes in this chassi took our poor metal drill a long time and a lot of oil.

sit

Onto the preparation of line cards, as mentioned before we had to do the final 3D print and prepare all optical fibers + mount it all together. We started the week by printing out the parts and verifying fit, tweaking some parameters and then burning out the last pieces on the printer. From there it was just a matter of spending an afternoon.

F1

F2

F3

F4

With this out of the way we could start mounting the line cards and wiring the chassis for power. It was one of those really hot nights that I never remember used to happen in Sweden where you were unable to wear anything other than swim trunks at midnight which lends itself well to a night of cabling.

F3

F4

After a few resolderings and fixes on the LED strips (soldering 144/M APA102 was 1000% less fun than 72/M) it finally started up with all LEDs working. I started adjusting the mapping in the software but noticed a flickering noise, something I’ve sadly encountered before with the cube. The flickering was random, more pronounced on certain dimming frequencies and changed depending on how the cabling was routed which indicated electrical noise. What I didn’t account for is the increased electrical noise that the denser APA102 generates, partly because you have over a 100 sources of PWM on the same power line without any smoothing. This one took a while to figure out as we experimented with a range of different approaches to solving this issue but the solution ended up being as simple as soldering a capacitor to each power input side of the 48 port cards. After reading up more on this issue it seems like this is quite common with dense APA102 (email me if I’m wrong) and adding capacitors to the power helps keep the signal through the strip stable. If you are searching Google like I did looking for how to fix electrical noise for APA102: Add 1000uF of capacitors to each end of your strip, absolutely solves the problem.

F3

F4

Summalajnen got the honor to brush” the router, meaning aligning all cables in a visually pleasing way, sort of like brushing your own hair but in this case network cables. We wanted all ports to have a connection for it to look like the router was active and Summa spent a good amount of time cabling and stripping the cables to look perfect. We ended up mounting a small 20 LED strip on top of the

About the beer

With all of this done we had Foxbat, our resident beer brewer, step in and actually connect the beer parts of the machine. Foxbat had consulted with us prior to the festival regarding how to adapt one of his tap coolers (Lindr Kontakt 40K) into more of an intermediary fridge. The Kontakt 40 is primarily built to be served out of but Foxbat came up with the clever idea of mounting cleaning adapters” in order to fit extension tubing. A small brass connector that screws into where the tap handles on the Kontakt 40 sits, on which Foxbat then mounted an adapter that allowed connection to regular 3/8” tubing. We coated all of the extension tubing in off the shelf isolation from a hardware store to keep the beer chilled and hoped that the throughput of which we sold beer would be enough to avoid having to serve warm beer.

For the beer handles on the router, we purchased two chrome plated Lindr dispensers and drilled holes on two of the blanking plates which are used to cover empty slots in the router. Foxbat then piped the output from the Kontakt 40 through the back side of the router to the tap handles on the blanking plate. Almost a magical experience to see the first glass being poured from router after all the work we put into this and the fact that the adapter solution that Foxbat came up with actually worked.

Foxbat had brewed two beers to the festival. One lager titled Dr. Ankbat’s Dirty Deeds” in which he added too much malt which made it a stronger lager, initially I found it a bit strong but after drinking shitty canned lager for 2 weeks it served as a nice contrast with more taste. The other beer was a NEIPA (New England India Pale Ale) that we titled CHONG CHAMBER IPA after listening to Mullah Said by Muslimgauze and reading a review on RYM by SlarkSlark that described the album. Personally I really enjoyed both of them, Foxbat has brewed beer for the past two events and although he’s always vocally critical of his own work the result is better than many of the beers you can buy at bars.

brewing

F3

F4

F3

F4

Takeaways

I’m personally extremely happy about how this project turned out. It required me to pull out so many different parts of my mental toolbox and ended up challenging both me and Wberg in various ways. One specific thing I’ve come to realize is how hard it is to describe technical concepts over text. Sure, I can see a picture of a piece but actually holding the piece in my hands allows me to grasp the problem in a much more effective way than asking questions. I wish we had some sort of haptic collaborative VR setup here to iterate on these things when split across time zones but that’s for the future to give us.

I wish that we had to spend less time debugging the electrical noise. This is one of those that I should have explored in San Francisco rather than tackled at location especially since I’ve run into this issue many times in the past. It sounds so simple to solve but when trying a variety of solutions it’s easy to confuse what solution worked which extended the timeline it took to finish the router. On top of that we were a bit too aggressive with how close we put the LED strip towards the top so the soldering ended up letting go while testing different approaches. This meant that I had to resolder these strips I don’t know how many times so if I end up working with 144/M density strips again I will design some sort of connector protection in the print.

The beer tap in itself worked perfectly throughout the event, we sold through all beer that Foxbat had brewed and I think that’s partly due to how striking the piece is in reality. It’s this huge router which isn’t supposed to sit in a bar, looking like it’s powered up with two beer handles attached to it.

Result

F4

foxbat pouring

You might have one more question: What happened to the backplane? Turned out that the backplane was an excellent gift to hand out to the person that consumed most beer that was considered bad” using our grading system.

F4

June 26, 2021

PLANET’S MAD

BAAUER. Yes, this is the person that made Harlem Shake” back in 2012 and seeing BAAUER released a new album I was skeptical. It took a while but towards the end of 2020 someone pointed me towards the movie” that was authored as part of the album. What movie? Yes, BAAUER commissioned a 40 minute video that consists purely of rendered footage synchronized to the music. The effort here is immense, I’ve speculated personally about how they made it and I assume that they extracted MIDI from the tracks and imported as events as animating this by hand seems like a lot of effort.

What’s really cool about it is that the video is like a throwback to MOSQUITO which was aired on Swedish national television between 1998-2003, although with less PHONG shading and more path tracing. Back in the late 90’s, creating weird visuals with aliens was all the jam and seeing the style re-imagined with modern technologies makes me smile. Some of the visuals are definitely rougher, especially during REACHUPDONTSTOP but synchronization makes up for the style.

There’s really not that much more to say other than enjoy these 40 minutes of JUNGLE TERROR

June 1, 2021

Struggles with Limescan

In 2018 I built a small BLE (Bluetooth Low Energy) RFID reader to enable our small iPad PoS app that I called Limetree. It’s been about 3 years since I created this and looking back I’ve come far from this very simple design. This was my first 3D printed project and at the time I was still designing the parts in SketchUp. For an unrelated reason I needed the NRF52832 feather in this device for another project so I pulled it out somewhere in mid-2020 as I had no need for the scanner during COVID. As there is a high chance I get to travel to Sweden again this year (fully vaccinated now!!!), it was time to reassemble the scanner!

Well, it didn’t work out as planned. For some reason the exact same wiring and code just refused to work and in frustration I soldered and desoldered until I damaged the Feather, which lead to the NRF52 chip refusing to boot. Oh well, guess it was time to upgrade to the NRF52840 anyway. Quick primer on the differences between these two feathers is that the latter of the two (hereafter referred to 840) has a native USB stack, which means the main chip handles the USB interface against the host computer. On the 832, there is a separate microcontroller handling USB and bootstrapping the device which prohibits you from having fancy functions such as U2F. This sounded great to me, usually microcontrollers are the less components, the better” and I decided to buy the 840 instad of the 832 as a replacement.

The NRF52840 arrived and I started the work on updating the code to make it run on the NRF52840. The device has a new RGB LED which I of course wanted to take advantage of. Once I felt reasonably certain that the code matched the differences I soldered on the wires to the PN532 breakout that I had from the earlier version and booted it up. It didn’t work. After tinkering back and forth with the code I got really frustrated because it seemed to work SOMETIMES. I would change something, burn the firmware for it to work for a few minutes and then restart it and it wouldn’t work again. If you’ve ever done programming, the worst problems to debug are the ones that are not predictable because there is usually very little indication what’s going wrong.

I don’t own a SWD debugger so most of my debugging here is print statements and blind debugging using the oscilloscope. However the problem I seemed to be having here happened before the serial line initialized properly, meaning that whatever output I wrote to the computer from the microcontroller was lost into the void. I quickly realized that I could use the on-board status LED to just show different colors upon reaching certain parts of the code and wrote a quick status” function which incremented colors every time it was called, allowing me to see where it stopped. In theory, this should yield me the same color every time I started the chip which would allow me to see where it got stuck on boot. Of course, that didn’t work out either. It stopped at random points during the bringup of the chip. Almost out of ideas I started doing really harsh clean turkey” debugging, starting with all code commented out and bringing piece after piece into the library.

Eventually it cleared, the Adafruit Neopixel library I was using for easy control of the LEDs was somehow interfering with the BLE shim that Adafruit provided which sits on top of Nordic Semiconductors BLE stack. To understand this it’s important to know that while all these microcontrollers can execute code within the Arduino Framework” (which I wrote my shit in because I couldn’t be bothered in 2018), the framework” is implemented differently depending on which microcontroller you’re using. Coming from using x86 processors for the past 25 years this is a bit hard to wrap my head around but the Arduino environment” is more like libc, a set of common functions you can compile against which has stuff like ports, GPIO and hardware functions mapped for you. It also provides a setup() function which is called once and loop() function which is called in a loop as long as the device is powered.

On an old AVR Arduino from which the framework stems from, you essentially controlled the entire CPU. Your code ran in a loop and the loop was bootstrapped by the framework. This means that once the processor enters loop(), you are in control of the execution of the entire processor. There is no operating system or multitasking going on which allows you to do a lot of nifty tricks with the hardware. something that other libraries often used.

//This code is really from the Arduino AVR core
//https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/main.cpp
int main(void)
{
    init();
    
    setup();
    
    for (;;) {
        loop();
        if (serialEventRun) serialEventRun();
    }
        
    return 0;
}

On a microcontroller like NRF52840 or another popular chip like Espressif’s ESP32 this is no longer true. These devices need to keep a BLE radio or WiFi radio active and these radios are way too complex to be controlled by the user and managing the timing requirements of these stacks. For that reason these devices often run on an RTOS (real-time operating system), the NRF52840 on Zephyr RTOS and ESP32 on FreeRTOS. What this means in reality is that your loop() function is scheduled onto the OS with the lowest priority, allowing the core to deal with other more important tasks for the radio to operate in between the calls to your function. As these cores often run at significantly higher speeds (64 MHz/240MHz vs 16Mhz for the AVR) there is enough headroom to run normal Arduino code and schedule the radio without impacting the Arduino libraries. The delay() function that on AVR halted the execution insteads just yields back to the scheduler with a request to be woken up after X milliseconds.

Why does all this matter? I wanted to re-use the code for this project even though I prefer the ESP32 (the ESP32 having dual cores, making it easier to schedule tasks) but ince the NRF52840 already ran a RTOS I figured that I could just schedule tasks exactly like the rest of the libraries and yield() in the Arduino bootstrapped loop. However every time I tried to create one additional task with the Neopixel and the BLE stack, the microprocessor froze. After a lot of searching I stumbled onto a lead on the Adafruit Forums where one person seems to acknowledge that combining the Neopixel library with the BLE stack seems to cause a conflict which leads to the crash. After digging even deeper it seems that the Adafruit Neopixel library is one of those libraries that try to make the most out of the AVR core. Specifically the task that it gets scheduled on runs for a long time which is fine” when you only have one task to defer to but as soon as you start introducing multiple tasks, the BLE stack gets starved” and crashes the execution as it fails to maintain realtime. After having said FML a couple of times while realizing this I quickly switched out the Neopixel library to another library I use on the ESP32 named FastLED and this worked without a problem.

OK WE DONE HERE NOW! RIGHT? RIGHT???? right… ?

I connect it all back up together to start testing against the iPad and see that the status LED still doesn’t fully go to green (the color I selected for success). The device fails to connect to the PN532 (RFID reader)??? Down the rabbit hole again it seems. However this is yet again one of those sometimes” issues where every reboot seems like a gamble if it will come up. I connect the feather and breakout to the oscilloscope and start trying to identify what’s going on.

Clear

Full

There is a clock signal and there is a data signal going in both directions so it’s clear that the chip is at least speaking SPI. I switch back and forth between the computer and the chip to try to figure out what’s going on. Eventually I see that the signal only bangs out sometimes”. Thinking back to what we had before, the PN532 is wired over SPI and I have a suspicion that the earlier problem is related. But why did this work so well with the NRF52832? After searching for a long time I think that I eventually found the issue in the unlikely place of the CircuitPython implementation for Adafruit, as the developers of that runtime also dealt with this. You see that the NRF52832 had an errata” (faulty hardware implementation) for the SPI which lead the developers at Adafruit to use a software SPI implementation for the older chip, documented here. So essentially what I’m discovering here is the hardware SPI on the NRF52840 is weird and fails to sync with the PN532 for some unknown reason. I’m guessing it’s some sort of assumption in the Adafruit library for the breakout, as many people have complained about similar problems with the ESP32 in the GitHub repo.

At this point I couldn’t be bothered to go deeper and decided to switch the hardware protocol to use I2C instead. The benefits of I2C vs SPI can be debated but for my use case these are interchangeable apart from having to solder the additional pullup resistors. I soldered this together and configured the code to use I2C and it worked on the first try. Board comes up with BLE and the device now works exactly as the NRF52832 did. At this point I’ve massacred the code a fair bit and it was never in good shape to begin with. One should always leave code in better shape than one found it so I end up spending some time on cleaning up the codebase and utilizing the ZephyrRTOS task scheduling instead for the loop based programming model I did earlier.

Because I had spent so much time digging into the code I also finally learned how BLE works”. My previous mental model about BLE is that it’s a wireless serial port” which is very far from the truth. A much better way to think about BLE is that you can write values into the void and tag them as representing specific characteristics, anyone that happens to listen to those messages can easily decode those. With that knowledge I could rewrite a lot of the earlier code I had to work around BLUART and just make my own characteristic. Code is of course on Github.

LETS REASSEMBLE IT

With my luck throughout this simple switch”, of course the first thing that happens when I reassemble it into the old 3D printed case is that I crack the pins in the case. This design was my first and in hindsight it’s so badly designed that I’m almost ashamed of it. Sure, everyone begins somewhere but this case was too dumb of a design to be SLA printed. Only one thing to do, open up Fusion and design a new one. I re-used the formfactor from the previous design as I couldn’t be bothered to buy a new piece of frosted plexiglass.

Clear

Full

This was also an opportunity to fix up the cabling from the earlier version. The earlier version relied on adhesive tape to fixate the Feather to the center of the board for the 4x8 LED array. This time I 3D printed a separate module that would hold the LED featherwing. Mounted this together using some screws and it’s night and day in fit compared to the older version. I do not want to re-experience the pain of debugging this microcontroller but improving physical designs is really fun.

Mounted

Working

Closing words for this one is that it’s easy to assume that other people have figured your specific use case out before and designed for it. This might be true in the world of X86 where there’s millions of users but for smaller microcontrollers, the likelihood of someone solving one problem the way you do is very low. I’ve also realized why most developers end up transitioning out from using the Arduino framework, while it’s a great way to bootstrap learnings it just makes too many assumptions about logic flow on more modern processors. I hate to blame the hardware” and I should probably just bite the bullet and buy an SWT debugger at some point. My digital caliper also broke when designing the case so I got a new one, icing on the cake to this I guess.

May 25, 2021

Biking in the Bay Area

Before moving to San Francisco I heard a lot about many different parts of the Bay Area. Tech culture, bars, commute, cost of living, hiking, sierras etc but none mentioned the insane biking that the surrounding areas gives you. There is absolute golden roads to bike less than 10 kilometers from San Francisco. For anyone who lives in SF and regulary uses Strava, these images are almost a meme at this point. It’s obligatory for any cyclist to tag their Strava uploads with these images over and over but I realized that not everyone lives in SF and uses Strava. These document my three favorite routes: Paradise Loop (90 KM), Reyes Loop (132 KM) and the Mt. Tam climb through Fairfax (105 KM).

Paradise loop

Reyes Loop

Reyes Loop

Climbing up to Hawk Hill Climbing up to Hawk Hill

Climbing up to Hawk Hill Descending Hawk Hill

Heading out with Nikola Heading out with Nikola

Climbing up to Mt. Tam Climbing up to Mt. Tam through the Lagunitas watershed.

On the ridge Up on the ridge.

Stopping for water

Stopping for water

Descending Tam Looking out from the rigde.

March 8, 2021

3D PRINTED FOOT PEDAL

Working remotely is draining in many ways but endless video conferencing is probably what one will miss the least about this entire experience. I’ve also learned that very few people seem to have grown up with long form voice conferencing and is as a result absolutely terrible at muting when not speaking. I’ve sat through so many meetings where people fail at muting and has microphones that sounds like they are screaming while skydiving next to a helicopter.

My theory around this is that personal video conferencing quality is tied to ones organizational level. In general: The higher up you are in the company organizational structure you are, the shittier your AV setup is. (Coral’s law for short).

hub

Growing up with Ventrilo -> Teamspeak -> Discord has teached one the importance of using PTT (Push To Talk). It might sound annoying to have to hold a button every time you want to speak but after a short time it becomes second nature, even to the point where I will press this button even though the application I’m using at the moment doesn’t support PTT.

Using PTT can be annoying at times. When trying to type at the same time as talking or not having your hands close to the PTT button is frustrating. A friend gave me the advice to try using a foot pedal, however I couldn’t find one that fit my requirements. I wanted one that could map to any obscure button without using active software to trigger the button. The ones that did were too expensive, which leaves me with only one option: building one myself.

I’m using what I had on the shelf for this one, meaning:

I designed a very simple enclosure that printed in two parts, one serving as both the base plate and the enclosure for the electronics and the second as the hood. I took the inspiration from pedals commonly seen for sewing machines and expression control for synthesizers.

Full

Clear

Full

Clear

Wiring it up was easy (essentially one pushbutton) and I’m using NicoHood’s HID library which made the code short. I’ve uploaded the project on my github along with the STL files if you want to build one yourself.

March 6, 2021

BÄSKA DROPPAR

Sweden has this absolutely terrific yet horrifying and awful liquor named Bäska Droppar” which I make a point of introducing to as many people as possible. On top of being almost undrinkable there is a Swedish studentesque tradition of drinking this in weird ways at weird times. The bottle doesn’t beat around the bush and proudly shows:

Noone is indifferent to the characteristic taste of Bäska Droppar which has made it a classic.”

- The tagline on the back of the bottle. Really.



bottle

There are three major milestones to keep in mind when consuming this trash liquor:

23 Besken

This is a true Swedish classic. When turning 23, one is supposed to drink 23 cl of what used to be article number 23 in Systembolaget (The Swedish liquor monopoly). 23 cl is just above a half marathon (21.0975 cl) which leads us to the next milestone.

The Marathon

If 23 cl wasn’t enough for you, you can always go the full marathon. This means drinking exactly 42.194988 cl of this experience. I do promise that after having consumed this volume of Bäsk, you’re going to wish that you didn’t.

The Victory Lap

After consuming 42.194988 cl you might experience a rush of adrenaline from having cleared this much of the horrible taste. If you still feel in good shape you should go for the victory lap, meaning clearing the remaining 7.805012 cl still left in the bottle

If you get the chance to consume this bottle of pure horror, do take the opportunity. It’s after all a Swedish classic.

March 1, 2021

1

2

3

4