Interconnecting two 56k modems back to back
We’re a couple of friends who gather every year to build a mini festival out in the woods in the southern parts of Sweden. This was just an BYOB (Bring Your Own Booze) event from the start, but as the party grew, we decided that we needed more planning ahead of the event. So Anderstorpsfestivalen was created by four people. The main idea was to start 9 months ahead of time to be able to plan and execute all tasks, everything ranging from activities, food blueprints for stuff we’d like to build before the event. We’re also executing interesting build projects like getting two modems to talk to each other, more on that later.
After the 3rd iteration we’re kinda burned out, it was a lot of work to arrange a big party with all the logistics and we underestimated tons of things, for example, money and time/planning required. As one of us lives in San Francisco in the United States, we flew over there to have a crew party in September 2018. After a couple of days and under the influence of a beer or two, we started talking, should we do this again? I don’t know if we really wanted to do this again despite all the stress, time, effort, sweat that went into this or if it was just the alcohol talking but we all agreed that we should do this again. The ideas of what we should do better this year and what really would be cool to build these months and present at the festival were just flying, idea after idea, some went into the trash straight away, others were picked up and discussed and lots of improvements added to the ground ideas straight away.
We decided to build a dashboard that you could run in a terminal only using text, graphs drawn with text, donuts drawn with text and so forth (more on that later). As the theme of the festival kinda soon became “1996” what better to have two 56k modems interconnected back to back to render the dashboard between two Raspberry PIs? If the dashboard is just plain text, a 56k modem could easily transfer the data and it would look super cool with the text slowly updating. I was in charge of getting the two modems to speak and transfer bits in between them. My first ever interconnection at home was actually a 56k modem, so I had used the technology earlier, but I was a little unsure on how many things worked.
Step 1 - Buying all the hardware needed
First off, I have thrown away all my old modems, I had to buy new ones. eBay is a great source for these items. I bought two “US Robotics Courier 56K 3453B 56 Kbps Modem” for about 30 dollars.
The reason I chose these modems are because they are extremely well designed, tolerant and have by far the best “documentation”. In order to get a “terminal equipment” connected to an old modem which only has a DB25 serial port I had to buy an adapter from DB25 to DB9. Price: ~4 dollars each.
I also needed a serial-to-USB adapter since no normal computer today has a serial port. I’m using Raspberry PI 3b+, which only has USB ports. Since I’m using Raspian, any adapter actually works. I chose the most simple one I can find, also one without a cable attached to the adapter since I’ll attach one myself later anyway. I bought an adapter called: Deltaco Seriell adapter RS-232 DB9ha. Price ~10 dollars each.
You also need a zero-modem cable in between the modem and the USB-adapter itself. Since the USB-adapter has a male connector, you need to have a female connector on one side of the zero-modem cable and the other side needs to be male connector, since the DB25-DB9 converter has a female connector on the DB9 side. Price: ~4 dollars each.
And last, but not least, you need a RJ11 telephone cable to connect the “line” between each modem, simulating a PSTN land wire. What I also found out here is that there are two types of connectors. RJ10 and RJ11 where the connectors have different widths. The wider one (RJ11) fits into the modem without glitching. If you use the smaller RJ10, it will still work, however just fiddling with the cable in between the modems can easily cause a glitch and they can lose connectivity since the RJ10 connector is a little too small so it’s moving around since it’s not entire held in place due to the smaller size.
There are fixed cables to buy up to a couple of meters, make sure they have RJ11 connectors, a lot of shops market RJ10 cables as RJ11 cables, which they are not. RJ10 is used for telephones and RJ11 for data. Since I needed at least 5 meters of cable and I own my own crimping tool I bought 5 meters of cable and some RJ11 connectors and made my own for a cost of about 5 dollars.
Step 2 - Setting up the environment
Finally, time to get ready! I installed Raspbian on two Raspberry PIs and connected everything in the following order.
Step 3 - Getting the modems to talk to each other
I can tell you straight away, this was not an easy task. First off, modems are not designed to talk to each other without a switchboard in between. Second, modems use the power on the telephone line supplied from the switchboard located at the central office. If they don’t have power, it’s counted as “NO DIAL TONE”. There are settings in the modem where you can go around this and ignore that there is no dial tone, however, the modems were still unavailable to talk to each other due to the lack of power. We then build a simple circuit adding 12V to the telephone line with a simple 12V DC adapter. We build the following circuit using 12V, no capacitor and a resistor of 480 Ohm.
I’m using minicom to get into the “console” of the modems. Simply open minicom and set the device to /dev/ttyUSB0, set the speed to 9600 for example, no stopbits and you should be good to go. If you type anything you will most likely get an error back and you won’t see what you are typing, enable local echo with the command ATE1, you just have to type it without seeing it, after that, all input is local echo.
We can then use the following commands:
Modem 1 (caller)
- ATE1 - Enables echoing on the terminal so you can see what you are typing
- ATX3 - Blind dialing, ignores dial tone
- ATD0 - Call number “0”, doesn’t matter what you type, since we don’t have a switchboard and the modems are interconnected back to back, if all works, it should ring on the other end.
Modem 2 (answerer)
- ATE1 - Enables echoing on the terminal so you can see what you are typing
- ATX3 - Blind dialing, ignores dial tone
- ATA - Answer an incoming call
I found out, if you blind dial 0 on modem1 and then answer using ATA on modem2, they can with the 12V adapter talk to each other and you can hear that they are negotiating. I found out that the sound they make is not the sound as you are used to hearing while dialing up the Internet and the modems seem to negotiate in a really really low bitrate ignoring the settings of the terminal (minicom). I got the modems to talk to each other at 300 baud, which is not a lot.
The fun part is that if you then use for example “cat” in Linux and pipe a text file over the USB port:
cat test.txt > /dev/ttyUSB0
You can clearly see the text being transmitted to other minicom window in a REALLY slow manner (300 BAUD). This felt like a true BBS. I tried forcing the modems by setting you should call and negotiate in 28800 for example, but the modems just kept on failing the negotiation or just hanging up as soon as I answered. I tried using the following AT commands:
Step 4 - Getting more speed out of the modems
After that I had to think, why don’t the modems negotiate more than 300 baud? I played around with maybe over 100 settings in the modems, I spent maybe 20 hours on this without any luck.
Google you might say! Yes, indeed, I spent hours on Google, the problem is, the majority of the information you find are outdated or broken links. Some of them use examples, scripts and stuff that doesn’t work on newer systems.
I referred back to the original documentation of the modem on the US Robotics homepage.
- Command reference guide: https://support.usr.com/support/sportster/sportster-files/techref_uk.pdf
- More AT commands: https://support.usr.com/support/756/756-ug/six.html
Didn’t really find anything. After spending a lot of time on the USR homepage I found out that you can use these modems if you are buying a leased line. What that basically means is, you buy a point-to-point telephone line from your service provider between your modems. This circuit has no power or switchboard in between since it’s connected point to point basically. Interesting, that’s exactly what I want to do. I stumbled upon some documentation for the newer model of the modem, 3553C (I have the B-model) thinking I’ll try the commands anyway.
In that documentation it says: “Set your terminal or communications software to the rate at which you want the modems to communicate.” I then set minicom on both sides to 9600 to begin with.
Then use AT command “AT&L1” to “Forces the modems off hook at power on and enables them to re-establish the connection should it be broken (for leased lines only).”
After typing AT&L1 into the modems, they actually called each other, the negotiation sound was the normal “dialing up Internet sound” you are used to hear when dialing up the Internet. The modems managed to negotiate perfectly fine at 9600 BPS. I also tried to disconnect the 12V adapter and this still works just fine. So in leased line mode, the adapter I talked about above is unnecessary and a simple RJ11 cable in between the modems work just as fine.
The guide also says:
- Set DIP switch 10 OFF. This tells the Courier 56K Business Modem to load NVRAM settings at power-on. It does not matter whether the Courier 56K Business Modem is in Dumb or Smart mode (DIP switch 8).
- Decide which modem is to be the calling modem and which the answering modem.
- Set the answering modem to Auto Answer, DIP switch 5 OFF, and the calling modem to Auto Answer suppressed, DIP switch 5 ON.
- Power off and power on the modems. This initiates the new DIP switch settings and loads the power-on defaults, including &L1. The modems go off hook and establish the connection.
The idea of this is that the modems should be assigned as 1. The calling modem and 2. The answering modem, this can be done using DIP switches. This also enables auto redial in case of any failure, it takes about 10 seconds and then the modem calls the other modem again reestablishing the connection. To get this to work you also need to save the AT&L1 variable into the modem using &W. &W means write the configuration to the NVRAM, so if the modem loses power it will still remember that configuration.
Command: AT&L1&W
Step 5 - Increasing the speed
I found out that the modems cannot in a back to back mode negotiate faster than 19200 for some reason. I cannot find out why, the only information I found was “you cannot get the modems to speak at 56k in a back to back / leased line scenario, but I cannot even get 28800 or 33600.
But for my main purpose of the modems, drawing a text terminal, 19200 is good enough, so I settled for that speed.
Note that, in order to get the modems to talk to each other without sending junk, you need to initialize both modems with minicom, at least once before sending any data over /dev/ttyUSB0, why, I don’t know yet, I’m trying to figure it out. You need to start minicom once every reboot of the RPI, if you don’t initialize the modems with minicom and try to send data via the /dev/ttyUSB0, the modem will recognize there is a terminal equipment connected and call each other and everything sounds good, but you will only receive rubbish on the other end. It’s enough to just start minicom and then instantly quit to get this to work.
Future
The next step for version 2.0 is to enable PPP between the modems and hopefully ditching minicom and only use PPP to initialize the modems, dial, negotiate and set IP-addresses.
More on this in the next post!