Reviving 56k modems
This is probably my most weird blog post yet. I wrote earlier about the rack bar, something I briefly touched upon was the two 56k modems in the rack. To understand why we mounted two US Robotics 3453 about 2 meters from each other at a 90 degree angle in a 42U rack laying down on it’s side we have to jump back to October 2018.
Wberg and Summalajnen visited me in San Francisco and we spent 2 weeks talking about what we wanted to build for next year’s iteration of ANDERSTORPFESTIVALEN. Part of our brainstorming session ended up talking about how ridiculous it was browsing the web using a dialup connection. The slow speed, combined with the sparse amount of information presented using barebones UI, all of this in order to access the exciting world of the early internet. Fighting for your slot on the phone line with family, having the dialup modem hang up due to someone lifting the phone. All of these are problems of the past that we luckily don’t have to experience anymore using the modern Internet. What if we could recreate this experience? Not simulate, recreate. Simulation would be building a “dialup environment” but knowing it wasn’t real would make it a simple gimmick, to get the actual feeling we would have to actually make it “like it used to be.
Could we connect two modems together and build something using these? Bar dashboard? A bar menu? The exact shape was still unknown but we knew that we needed modems in order to see if this idea would even be feasible. We ordered two US Robotics 3453 modems, two relics of the past that can be found on Ebay for about $10 dollars today. The modems are built like tanks (except for the RJ11 port) so you can expect these to work as well today as they did back then. Once the delivery was in, I had a chance to meet up with wberg during an event, where we spent one night connecting these old modems together, hoping they would just call each other out of the box.
Sadly, this was not the case. Digging deeper and using the AT commands for these modems, we issued commands to have these dial up but the modems only complained about no dial tone. Could this check be disabled? The modem surely must have an on-board configuration that allows us to set the parameters of operation? Digging deeper into the S-Registers of the modem (the custom settings for this particular modem) we found some hints that the modems could do this, but nothing was documented to the point where we could understand it out of context.
If you’ve ever tried to search the internet for information about this it’s clear that most of these endeavours stopped being interesting to people once broadband became inexpensive enough to run long distances along with cheap ethernet for home connections. The majority of sites that present information are either forums linking to dead sites or ASCII graphs trying to convey information around this subject. It’s highly frustrating to see how fast information disappears from the internet, almost like tribal knowledge falling out of view. The “hard links” that people used as references are long gone and we are left deciphering clues from russian forum posts. After a while it turns out that the definite source on DIY phone circuits available today is ePanorama.net’s index of “Telephone line audio interface circuits”. I’ve taken the liberty to archive this site locally, if this site ever goes offline I pledge to host this once again in order to help people avoid the same situation that we had to endure to find information.
Back to the modems, it turns out that these modems needs a line current in order to open relays on the modem. Without the modem detecting current, the software just refuses to open the line regardless of what S-Registers we tried. This took us a long time to figure out and after hearing the internal speaker open it’s line for the 200th time without any result we almost gave up. Foxbat helped solder a small circuit to emulate line voltage and to our surprise both modems for the first time started dialing numbers! Sadly, they did not connect to each other. Getting the modems to dial was only a small part of the larger challenge, the actual problem was configuring these modems to talk to each other. Having changed every single parameter in the S-Register didn’t help either as it became very hard to know what settings were set on each modem. To remedy this, we went over every single bitmask in the S-Registers and reconfigured these to be the same at which point the modems finally opened up a connection between each other.
Once the actual modem link finally was alive, some configuration had to be done in order to make sure that the modems communicated back and forth, then figuring out how to actually pipe data over these beasts. For someone that’s born with REST and JSON, it’s almost unthinkable that you can pipe whatever data you want to a serial port without having to think about what the modems do underneath but this really is the case with modems. It’s amazing how simple this actual step was and I could see why people believed newer solutions to be complex. Once we got the hang of the underlying transfer representation, I wrote a quick mockup of how a “menu” reading our Firestore database would look using NodeJS and blessed (yes, I’m linking to neo-blessed because the original project was abandoned).
With this actually working, the question was “What do we do with this shit?”. Since the “terminal bar menu” had been an idea we’ve thrown around for Anderstorpsfestivalen quite a bit over the years it was obvious that we had to do this, but was this the only thing? The experience we tried to replicate was the modems actually being interrupted, so what if we added an actual phone you could lift to break the modems? What if this phone also had someone actually screaming at you through the receiver? All these ideas got thrown around now that we knew that the actual idea was possible.
Rendering the bar menu / dashboard itself without even using X really stroke a chord for us. By making it so simple that it can be streamed like a BBS it can convey a certain visual experience that modern rendering stacks will have a hard time to approximate. Browsers do a tremendous job at rendering fonts and graphics so stepping away from this stack gets us closer to the past. On top of this, combining old rendering technologies with modern realtime backends seemed like an extremely stupid idea which meant it had to be done.
In order to build a bar menu out of this I started to sketch out a simpler “framework” around blessed. Blessed itself has a pretty normal rendering loop but since we wanted to develop isolated “modules” that would fit on a grid, simplifying the developer experience would help iterating on the different parts. Since wberg hadn’t worked with NodeJS at all before, it would also help him if the modules had clear entry and exit points instead of being one large file. I began iterating on this framework in December 2018, rewrote the entire thing in February 2019 once I knew what the pain points were and started onboarding wberg on to writing modules for this. The structure of the framework essentially looked like this:
The framework handled all the backend services (DarkSky, Google Calendar, Firestore, Postgres and SNMP) and exposed these through nice interfaces to every single module. Since Firestore has realtime updates, the framework could help to redraw these modules on updates from Firestore to create a realtime update experience. Each module would make up one distinct “square” of a larger grid. Since there would have to be multiple pages, the system would handle the display loops for each of these modules and placing them on the correct place. The framework then multiplexed the output of these modules onto different targets, such as a telnet server and an SSH server, allowing us to stream the actual data over the modems easily. It also hosted a local rendering pipeline for developing parts. The different exposed hooks for the part is:
Load: This function is run once when the modules is first loaded which allows the module to bind data notifications, hook into firestore notifications and do the first pass of data fetching. The data services is exposed here from the framework which allows the part to store a reference to this object for future invocation.
Hook: This function should replace a “blessed-grid” object class which i implemented that has all the information the system needs to display the part, this includes borders, labels and padding for the part.
Display: Runs every time the module is displayed from being hidden, this is where the module would render the data and modify the render state that the framework holds for the part.
Update: For animations, this function is run every frame as long as the part is displayed and allows the part to modify the render buffer to create simple animations.
After a couple hours spent iterating on these parts with wberg we ended up with these pages:
Common to every “data” page was that the menu to the left always persisted with the other data changing. On this page we had a schedule that read data from Google Calendar, a weather widget I implemented that used the DarkSky API to fetch data and an image to ASCII art renderer which i beat into submission in order to scale images and render them to the different parts.
The second page holds detailed sales statistics from PSQL, showing remaining stock, how many of the different items that had been sold at any given point, top 5 sold items and some beautiful (absolutely terrible) ASCII bars that would render the top sold beers & drinks.
At page 3 we started running out of ideas so we implemented some more data queries from PSQL together with actual network data pulled over SNMP from our network layer, this allowed the people visiting to see the statistics of the festival WIFI in realtime on this dashboard. How did we envision this to look at the actual bar? Since I rendered the bar earlier to visualize the idea it was easy to throw in a screenshot into the rendering to find out.
So the last remaining issue to solve was how to build our circuit in order to get the phone to break the modems and the attached Raspberry Pi to play back a sound into the actual phone. Since the phone we had functioned like a proper telephone and allowed power to flow through the upper conductors on the phone jack (3&4) when the hook was on, using that to detect if the phone was on the hook or not became easy. The last part was figuring out how to interface audio onto an old phone, luckily the page I mentioned earlier had a pretty sketch that made this seem trivial.
Wberg drew a world class professional blueprint of how the electronics was connected when we added in the GPIO detector for the phone.
With all of the outstanding problems solved and with the help of Love Olsson (thanks again for everything Love, without your help this wouldn’t have worked out) there was just a matter of keeping polishing all the rough edges, solve bugs in the dashboard, make the modem software better for the hangup functionality and implement the Python wrapper that controls the sound playback until mid-July 2019.
Time really flies and I was suddenly in Anderstorp. It feels like I skipped almost a year but that’s the amazing part about working on longer projects like these. Since they technically never get finished, the showcase at the festival becomes the actual goalpost. It’s hard to describe the relief I felt once we setup the modems back to back and tested the dashboard onsite, seeing it work over the modems for the first time.
One problem had started to manifest itself that turned out to be harder to deal with onsite, this being the aged RJ11 connectors on the modems that had deteriorated over time. Since our current location here was in the middle of the forest in Sweden, finding new connectors to solder on wasn’t an option. After watching wberg trying to adjust the pins for an hour, decided to just hard solder a 5 meter cable between the modems which in theory would eliminate all these issues (also make the modems permanently connected).
Thankfully this solution worked. Sometimes bruteforce really is the best solution to a problem. Gujjdo worked on mounting these modems to the switches within the racks, as the alignment had to be perfect for the symmetry between both sides of the rack to work.
With all this mounted, we started up the modems and the dashboard and waited for the night to set in order to see it in action.
What about the stupid phone? Not forgotten! In fact we mounted a real telephone jack on the side of the bar for the phone to be plugged into and waited until the second day of the festival at which point we brought this phone up. One last minute addition that we built on-site was that since we already had the audio circuit built, what if we allowed the microphone from the phone to actually be piped out through the large loudspeakers? Like a really bad announcement microphone that you hear at trains, cruise boats or shopping malls where the PSTN system is also an announcement system. Soldering on some connectors to jack this into the mixer was a breeze and the phone got a fair amount of usage as an announcement microphone.
Fozzie captured an audio clip of how bad this actually sounded using a handheld dictaphone. You can really hear the profile of the electret condenser microphone just screaming cruise boat.
In general, I was really happy about how all this eventually came together. It was a long multi month team effort where everyone helped to build the complete idea. It also sort of proved my point that technology put in the right context can be art, allowing people to experience specifically crafted moments through using and observing these contraptions. Being there really conveys outdated 90s technology that had gotten a second life and many people remarked on the memories and feelings that this brought back to them. That in itself was very fulfilling, setting out to communicate a specific feeling and succeeding in using the tools to do just that.
Modems for sure are part of a lost era, representing the heydays of the Internet. Edward Snowden wrote about these days in his book “Permanent Record”.
“Before you recoil, knowing well the toxic madness that infests that hive in our time, understand that for me, when I came to know it, the Internet was a very different thing. It was a friend, and a parent. It was a community without border or limit, one voice and millions, a common frontier that had been settled but not exploited by diverse tribes living amicably enough side by side, each member of which was free to choose their own name and history and customs. Everyone wore masks, and yet this culture of anonymity-through-polyonymy produced more truth than falsehood, because it was creative and cooperative rather than commercial and competitive. Certainly, there was conflict, but it was outweighed by goodwill and good feelings—the true pioneering spirit.” 1
It’s fair to say that we didn’t completely catch the full representation of what Snowden mentions, although we provided a small glimmer of it. Hopefully our future plans for this will realize the vision further, the true pioneering spirit.
Snowden, Edward. Permanent Record (p. 4). Pan Macmillan. Kindle Edition.↩︎