We drive long distances in remote places. Sometimes we want people to be able to check-in on us while we are out and about. While cell coverage is getting better we still often find ourselves in places with no coverage.
Often we leave our HF radio tuned to a known frequency (usually 7045 kHz LSB) while we are driving and have VSC or power level squelch enabled. However this has false triggers. When driving through towns there is usually a lot of RF noise and even when we aren’t there’s noise from our car, other HF radios, or even just ionsondes or CW operators.
Random noises while driving are very frustrating. In the commercial space radios are fitted with selective calling (Selcall) functionality. This allows one radio to call another radio provided you know the ID number of the other radio.
The great thing about standards is that there are so many to chose from - Selcall being no exception. While there are many different Selcall variations today we are going to talk about the Codan specific Selcall - specifically the not the CCIR / UN / WA2 / RDD / Customs variants. Nor aircraft SelCal. The proprietary Codan “standard” is what we want to look at. The reason behind this is that there are numerous Selcall users on 7045kHz already using Codan Selcall and while it’s proprietary we can still interoperate with those users.
Modulating
The actual Codan Selcall process is actually pretty well documented with VK5QI already creating an open modulator including some of the less documented features such as channel test modes.
I decided to use freedvtnc2 as a skeleton project as it already has an FSK modem (Codec2), audio and rigctl components. From there I implemented the Selcall protocol while testing and researching some of the extra modes from our Codan 9323. Modulating a Selcall signal was now trivial - but we already knew and had that. What we really wanted was an opensource decoder. Something that could detect Selcalls.
Demodulating
Demodulating is a little bit harder, but given that we know what the signal looks like and Codec2 provides a good FSK demodulator it was not outside my skill level.
Codan Selcalls start with a preamble, usually quite long to allow radios scanning channels enough time to detect the signal. To an extent we can ignore the preamble as the Codec2 modem will handle locking onto the signal for us.
After the preamble there is a phasing pattern. This is a header that is at the start of every Codan Selcall. It’s nearly as simple as looking for this pattern to determine when a Selcall has started. But you don’t want to do an exact match as in HF radio its likely that noise has caused some bits to flip. I settled for a 85% threshold, however I think it could be even lower in practice.
Once the phasing pattern is found it’s matter of decoding the bits as they come in. There’s a few fun things in here. Codan uses a 7 bit word and 3 bits of parity, so you have to handle the incoming data as a series of bits rather than your typical bytes. Parity is only at the word level. There is no checksum on the entire message. The data is effectively sent twice (offset) so if parity fails on one word you might be able to recover it from the other.
The parity is a count of the number of 0’s in the word.
For my demodulator it works like this:
Store a rolling buffer long enough to fit a Selcall
Look for phasing pattern
If a phasing pattern is found try to decode each field - check parity - use the redundant field if required and available
Fun fact - if you are really unlucky both copies of a field could return a successful parity check but have different data - as there is no overall checksum for the message you won’t know which one is correct. When receiving a Selcall we just check if either field is our Selcall ID.
So you decoded a Selcall - what now?
Decoding the Selcall is only part of the process. We need a way of alerting the user that there’s a call for them. It would be really really really nice if ICOM allowed user defined messages (more on this later) and activating a beeper - but in the meantime lets aim for something simple. Rigctl.
When we send a Selcall we actually need to control the rig - turn the radio to data mode, trigger ptt, return the radio to voice mode. Since we already have rigctl for that, how about we use it for alerting the use as well.
The simplest solution I thought of is using the squelch adjust. On our rig you can configure the USB audio output to remain active even when the radio is squelched on the head unit. So the flow looks like this now.
Squelch the radio to a fairly high level - unlikely to get false triggers
Software listens for the Selcall
When it receives a Selcall for our configured ID number use rigctl to unsquelch the radio
(additionally) if the Selcall requested the channel test mode and the option is enabled send back a test signal
Freeselcall
I built all of this over a couple of days and have called it freeselcall. It’s had some over the air tests - but I wouldn’t say it’s battle hardened.
I realised that most people, myself included, wouldn’t want to use a terminal to perform selcalls so I’ve also added a web interface. It uses websockets so it should be easy to integrate with other systems as well.
(It even has browser notifications for those so inclined)
More than just Selcall
Freeselcall allows for sending and receiving Selcalls with various priority types along with the option for channel tests. However Codan radios can do more. They can do paging (short messages).
Today freeselcall can receive pages. It also has code to send pages however Codan decided to add some security words to process. As it stands a Codan radio will not receive the page messages from freeselcall.
I’ve spent a lot of time in Ghidra along with building a Codan 9323 emulator (it can display the LCD boot up message!) to help reverse engineer how these security bytes work. Hopefully in part 2 I can share how the paging messages work. Emulating a unique flavour of 8051 along with the hardware it connects to has been fun.
The future (and a terrible idea)
As I alluded to earlier - being able to display a message on our ICOM 7100 would be ideal. However there’s no rigctl or CI-V way of displaying a message on the 7100. Or so I thought. It was only when I was dialing in a repeater on the 7100 that I came across an idea that might work. I haven’t tested this, but here’s the plan.
Dedicate a memory channel for freeselcall.
When a call comes, if the radio is in memory mode, store what memory the radio is in.
Use CI-V command to save the current radio state as a memory in the predefined freeselcall memory channel overwriting any existing configuration in that slot.
Update the channel name with the message / selcall id / ect….
Tell the radio to load that memory
After some time has passed and the radio hasn’t PTT’d in awhile, either restore the radio to the memory it was set to or turn off memory mode
I think this will work? But I have no idea until I try
The other addition I want to add is either implementing more sensible Selcall protocols or building a more modern robust one. This can run in parallel for backwards compatibility.
I haven’t even looked into 6 digit pagecall. I haven’t seen it used on amateur bands so I’m not overly interested.
A final note….
Part 2 won’t be coming out until I’ve either been able to emulate the Codan firmware (just because thats cool in its own right) or I’ve been able to figure out the magic for the secret words. The emulator is at the point where I need to have the base and the head unit emulated at the same time and talk via the I2C bus. This shouldn’t be hard, however it’s also not something that is trivial.
Please do not send me yet another a copy of the Codan CCIR 493-4 PDF. This afaik doesn’t contain any information on the secret words and I have enough copies of it from people being helpful.
JSON’s had a tough life. Before I was all that attached with the bike I didn’t exactly treat it with same the respect I do today. It was just a cheap bike to get me from point A to point B. The more I rode it the more I fell in love with it. Combined with damage from the previous owner and other general wear and tear the frame was starting to show some signs of rusting.
The plan was to strip the bike of paint, then respray it. This wasn’t going to happen in our apartment, however an excuse to visit Mark in Adelaide presented itself. I took the bike across the border and over the period of several weeks redid the paint work.
Prep
At this point I’d become pretty familiar with the process of removing every type of bike part on my bike. Within a few hours I had removed everything which left only the frame. If you are planning on embarking on this adventure and you are unfamiliar with removal of all your parts, get some help or do some research. Some parts can be fragile, some have reverse threads and some can be damaged if force is applied in the wrong spots. There’s also a bunch of tricks to learn for when things don’t go to plan.
An example is the quill stem - often on these bikes they become stuck. If you try to strike the stem directly you’ll likely either damage it or get it more stuck. While it doesn’t always work a good starting place is to leave the stem bolt in, but proud, then strike the bolt with a hammer - this will dislodge the wedge and hopefully allow removal of the stem.
After removing all the parts from the bike frame I decided to strip most of the paint off the bike. Now stripping the paint entirely off isn’t necessary. You only need to strip the paint back far enough for the new paint to stick, along with getting the surface finish to the quality you want it. I went for stripping it back entirely (there were a few bits I couldn’t easily get to so I just roughed these up as best I could). The reasoning for stripping back entirely was to ensure there was no hidden rust - along with removing a nasty paint run was present on the bike already.
I’m really glad I did strip it all the way back during sanding I noticed some weird pattens forming, slowed down an used a higher grit sand paper. To my surprise the red and white paint scheme wasn’t original. I had suspected this given the paint run, however I could never confirm this. I never knew the make or model of the bike and by carefully sanding back the top layer it revealed a uv damaged outline of the original branding. An Apollo Eclipse. This would have been the pink and white model. For me the bike has always been red and white, that’s now part of its history. So while I could return it to original colours, they wouldn’t be original to me.
For the majority of stripping I used low grit sand paper however for the fiddly bits I restorted to wire wheel brushes on a cordless drill. Removing the paint is probably the hardest part, once its removed moving up in grit to make a smooth finish happens fairly easily. I went with the sanding approach because sand blasting seemed too expensive for this project and sanding didn’t seem like too much effort (it was a lot of work, don’t get me wrong, but it didn’t really take that long). I looked into chemical processes however youtube tutorials and reviews gave me the impression that it seemed more annoying than just sanding. Everyone has different advice on the process however I settled for about about 400 grit for the final sand working off the theory that while spray paint is thin, it still needs some roughness to the surface to stick well. I used higher grit sandpaper to touch up some parts during painting. If you want to take away anything from this blog post though, think PPE. Not just when spraying paint but when sanding. I generated so much dust when sanding back the frame.
Painting Rust
The next day with all the rust and paint sanded back I went to paint. I thought I’d be able to get away with a day of stripped bike frame in less than 20% humidity but flash rust struck. It wasn’t a big deal however, I was able to sand back the frame with high grit sandpaper again just prior to painting. I gave the frame a wipe down with some acetone to remove debris and now we were ready to paint.
Painting
I went with Rust-oleum 2X Primer and Custom Spray 5-in-1 for the paint. This was mostly because I’m familiar with how they spray and work. They probably aren’t the best choice for bike paint, however rattle cans in general aren’t good - this is because the layer of paint is so thin compared to other methods. Regardless it’s something that fit the budget, and that I could easily do.
I actually reached out to Rust-oleum to confirm my planned process prior to painting and they were able to provide a bunch of nice details and provide confidence. First up was priming. The Rust-oleum paints allow re-coat anytime within 1 hour and they recommend coats 15 minutes apart. I setup the forks and main frame near each other so I could do them at the same time. This allowed me to switch between each while waiting. I was able to get 4 coats onto each within the window. The usual rattle can advice applies - thin coats. Sicne the frame is so large I applied thin coats and moved around the frame, usually doing 3 coverages every time I did a coat. Priming was probably the hardest part not to get runs on I got a slight run during this and sanded it back prior to the top coats.
Since the bike was lacking any sort of branding, I wanted to give it some. I had a original plan for that - Crossy JSON - however since I now knew the make, model and what the original decals looked like I incorporated some of the design into my plans. There was the option of simply making some decals and slapping it onto the bike afterwards, but I really wanted to try using the decals as mask. I cut out some new decals for a mask and applied them careful. This meant that prior to the decals being applied I had to do some extra top coats in the masked off colour.
Some red coats went on. The Custom 5-in-1 cans low output mode really helped prevent any runs. I got a slight run where the rear brake sits but it was easily fixed up. The tricky part however was replicating the “original” white gradient on the dropouts. I did a few practice sprays for this to get an idea of what I was doing along with masking off everything that wouldn’t be part of the gradient and in the end it turned out great - I feel like its better than the previous gradient.
The masked off sections were removed prior to the clear coat. This is where I learnt that my masking approach was probably wrong. A negative mask would have been easier to remove (I created a bunch of damage to the paint getting each piece off) and would have made the painting process easier. Regardless I’m happy with the results given it was my first time doing this sort of thing.
I was originally concerned about runs on the clear coat - because that could have caused disaster, however even on high output mode I couldn’t have made a run if I wanted to. I’m sure the temperature helped but I feel like the chemical composition just makes it really hard to run with that paint. One approach for painting bikes it to actually not worry about clear coats, just make the top coat as thick as possible. I however wanted the finish that the clear coat provided.
Post
Prior to reassembling the bike I decided to give its internals a blast of cavity wax. This is intended to prevent rust from the inside. An idea I picked up from Croker vs ROVER. Most of the internals have drainage holes that the applicator can be fed through.
Pre-sequel
During painting I throughly washed all the parts, rebuilt bearings and placed everything in Evaporust. The Evaporust worked a treat, however flash rust struck again leaving me to have to repeat the process for many parts. The problem is that with the rust removed, washing with water just creates the perfect surface for more rust. I think the solution to this varies per part, varying from an aciditic bath, zinc plating and painting. However for the time being I went with a light coating of WD-40 (which is apparently the original purpose of WD-40). I think if I do this again I’ll have a think about how I deal with this.
I also found that many parts on my bike were broken. I ordered a replacement seat as the plastic holding it together had cracked. A spoke was broken on one of the wheels. The new spokes that I ordered were too long (they must of been the perfect size before, as the new ones were less than 2mm longer than the old) so I’ve reconfigured the wheel for a 4 cross spoke pattern.
The chain, bell, and cabling were all replaced. Along with the handlebar tape.
Finally
While the bike is mostly done now I still need to true the wheels a little better, along with draw up some of the spoke tension. I’m pretty happy with the results. There’s some bits that I messed up or could do better but for my first attempt I think I did well. It’s certainly better than when I started which is the key thing.
It feels like starting blog posts with “so I crashed my bike” is going to be a thing. So anyway, I crashed my new bike. Down a cliff, in the bush.
I think this means it has enough wear and tear on it for a review, but lets starts with why.
There’s several reasons:
Alex has a cool bike
I want to be able to carry more shopping home easier
I’d like to visit further away cafes without having to carry my backpack
Bike camping? Bike camping
I’ve been riding a lot more and can justify the investment
So JSON is great and all. I’m still going to do the rebuild and respray. However JSON can be quite limiting. With no panniers I have to wear a backpack if I need to transport anything. The geometry isn’t well suited for my bad back. I want to ride places that wouldn’t be suitable for JSON.
Alex last year found a great deal. The Cannondale Quick 1. A flat bar bike, nice geometry and Shimano 105 group set for $1,600. My initial thought was “I’ll just copy her”, however it seems that the Quick 1 was sold out in most places.
I went exploring other options. Things that were appealing to me were:
Group sets that weren’t low end (Shimano makes this so so very complex)
Brifters / dropbars
Mounting points for panniers
XL frame size
Hydraulic disc brakes
No suspension
Aluminium frame
Sub $2,000 AUD
This combination was surprisingly hard to find. The two bikes I did find were the REID Granite 4.0 and the Polygon PATH X5. The Granite 4.0 was out of stock in XL and I could only find the PATH X5 online through bikesonline.
I was extremely nervous about buying a bike without giving it a test ride before however good reviews and a promise that it could be returned in 30 days if it didn’t fit it seemed like something worth trying.
I am incredibly happy I did because this bike feels so good to ride. The geometry fits me really well, and it has a Shimano 105 group set, drop bars and hydraulic disc brakes. Assembly was a breeze. Somehow this thing has even survived me riding it off a cliff. Total shipped was $1,834.
The first thing I did was load up the bike with accessories. I’ve splurged a lot here because I want this bike to work for me. I’ve gone with the Topeak MTX pannier rack - allowing for the trunk bag to quickly be put on and removed. However I’ve actually been using Tourbon clip on backpacks. This allows me to stash my laptop and work equipment quickly on the bike and have a decent bag to carry it around the city.
For visibility I’ve fitted Garmin UT800 front light and Gardia R300L rear light. I picked these purely because I wanted to play with ANT+ lights. I really don’t recommend anyone spending this sort of money on lights. At least for me the ANT+ integration is a bit clunky and it does feel very much like a gimmick more than a feature. However what does stand out is the Gardia R300L radar. I didn’t realise how much I’d love the radar functionality. It is able to detect approaching vehicles from fairly far away and in a noisy city environment this is super handy when you don’t notice a car sneaking up on you.
Now the bike isn’t flawless, but it’s pretty damn close. The first is mudguards. For some reason the mounting hole you usually find where rim brakes are is 90 degrees from where I expected. This results is mudguard selection being very limited as a lot of mudguards will want to mount here. The other issue is the rims are entirely nameless. I assume that they aren’t tubeless ready as if they were they likely would be advertising it, so if I do go down that route I’ll probably have to rebuild the wheels.
I mentioned bike camping. This is one of the reasons I wanted to get a gravel or hybrid bike. While we have the LandCruiser to explore far away places, I wanted to test the idea of staying at places a little bit closer to home. With VLines fares capped at $9.20 the concept of taking my bike on the train, riding to camp site, and exploring the area without the need of a car seems super compellingly. I’m a bit away starting one of these journeys but I’m getting close, so stay tuned for that.