Redhatter (VK4MSL)

Mar 182020
 

I’ve had this stuck in my head all day…one sorta has to pronounce “Corona” as “Crona” to make this work… Apologies to John Carter and The First Class…

Do you remember back in olden day, (wo-oh-oh)
when everybody lived a care-free way (wo-oh-oh)
whatever happened to the boy next door,
now sneezing, hiding behind the bathroom wall!

Remember dancing at the high school hop
The dress I ruined with the soda pop?
Quarantine didn’t mean a thing
Hundreds of people getting in the swing!

Corona baby, Corona baby, give me your hand
let me share what I can remember
Life as before we all got caught
in the lock-down.
Corona baby, Corona baby, you can’t understand
why society was so quick to dismember.
Days in the sun, to lyin’ on our bum every day!

Mar 182020
 

So we’re all working from home at the moment with COVID-19 wreaking havoc… and of course the toilet humour has been flowing like a fountain…

Our workplace’s #random channel on Slack…

Sounds like a great start-up… of course the idea has only been around about 400 years. 🙂 Sometimes truth is stranger than fiction.

Mar 022020
 

This is just a short note… today we finally made the jump across to the NBN. We’re running hybrid-fibre coax here in The Gap, and right now the HFC NTD is running off mains power (getting that onto solar will be a future project).

I already had my OpenBSD 6.6 router running through the ADSL terminating the PPPoE link. The router itself is a PC Engines APU2, which features 3 Ethernet ports. em0 faces my DMZ and internal network. em1 is presently plugged into the ADSL modem/router, and em2 was spare.

Thus, my interface configuration looked like this:

# /etc/hostname.em0
inet 10.20.50.254 255.255.255.0
inet6 alias 2001:44b8:21ac:70f9::fe 64
# … and a stack of !route commands for the internal subnets

# /etc/hostname.em1
up

# /etc/hostname.pppoe0
# pppoedev em1: ADSL
# pppoedev vlan2: NBN
inet 0.0.0.0 255.255.255.255 NONE \
        pppoedev em1 authproto chap \
        authname user@example.com \
        authkey mypassword up

… and of course /etc/pf.conf was configured with appropriate rules for my network. For the NBN, I read up that VLAN #2 was required, so I set up the following:

# /etc/hostname.em2  
up

# /etc/hostname.vlan2                                                                                                
vnetid 2
parent em2
up 

I then changed /etc/hostname.pppoe0 to point to vlan2 instead of em1. When the NBN NTD got installed, I tried this out… no dice, there was PADI frames being sent, but nada, nothing.

Digging around, I needed to set the transmit priority, so I amended /etc/hostname.vlan2:

# /etc/hostname.vlan2                                                                                                
vnetid 2
parent em2
txprio 1    # ← ADD THIS
up 

Bingo! I was now seeing PPPoE traffic. However I wasn’t out of the woods, nothing behind the router was able to get to the Internet. Turns out pf needs to be told what transmit priority to use. I amended my /etc/pf.conf:

# Scrub incoming traffic
match in all scrub (no-df)

# Set pppoe0 priority
match out on $external set prio 1  # ← ADD THIS

# Block all traffic by default (paranoia)
block log all
#block all

That was sufficient to get traffic working. I’m now getting the following out of SpeedTest.

~25Mbps down / ~18Mbps up on Internode HFC NBN

The link is theoretically supposed to be 50Mbps… but whatever. The primary concern is that it didn’t suddenly drop to 0Mbps when the plug got pulled in September. I’ll check again when things are “quieter” (it’ll be peak periods now), but as far as I’m concerned, this is a matter of ensuring continued service.

It already outperforms the ADSL2+ link (which was about 15Mbps / 2Mbps). Next stop will be to port the old telephone number over, but that can wait another day!

Feb 272020
 

Gotta love advertisers, they don’t bother to read or do any form of minimal research, make crass assumptions, then promptly shoot themselves in the foot:

Hello

My name is XXXXXXXX,…

Really, given it’s in your From header and your email signature, I’d have never guessed!

…and I’m a content manager at XXXXXXX XXXXXX. I’m reaching out because I came across your site and as I see you take on advertisers.

Where do you see that?

So I’m interested in purchasing some space for a sponsored article on your site.

Seriously honey, if you need to ask for a price, you can’t afford it. I bill by the nanosecond of page view time for each pixel occupied by your content.

I’m always looking for high-quality sites, like yours, so I will be glad to discuss prices and guidelines with you.

Mmm, hmm, you seriously haven’t had a very close look have you?

The content we write is always unique, relevant and informative.

As unique and informative of the load-of copy-pasta deja-moo you’ve just emailed me (in duplicate I might add)?

Moreover, we want to promote article we publish on your site. We have more than 10k subs in our email newsletter and 7k on Facebook, as you can see, we can offer not just money.

Harvesting 10000 email addresses randomly off the internet does not constitute subscriptions. Buying 7000 Facebook accounts and making them “like” your page does not constitute approval.

Ohh, and you might want to have a look at this, or this, or maybe this. Life’s too short to stuff around with a glorified BBS.

Looking forward to hearing from you.

Best regards

XXXXXXXX XXXXX

Well, you won’t hear from me directly, but you may hear from Google as you violated their terms of service in sending that spam. So yeah, I guess I do take on advertisers. I take them on and take them down.

Honest advertisers have no reason to come here, because they already have a good idea of how to build up reliable clientele without breaking laws like the Spam Act 2003 or making invalid assumptions. They do their homework. You, on the other hand, dear wannabe advertiser, are the reason such laws exist!

Updated 1 March 2020:

So, having not received a direct reply… they try again:

Just making sure you receive our last email below.

On Wednesday, February 26, 2020 at 7:30 PM, XXXXXXXX XXXXX <spammer@example.com> wrote:

${quote of original email in full}

You clearly don’t read the websites of those whom you pester do you? Actually, don’t answer that, because we know that from your original email.

Feb 082020
 

So, lately I’ve been helping out with running the base at a few horse rides up at Imbil. This involves amongst other things, running three radios, a base computer, laptops, and other paraphernalia.

The whole kit needs to run off an unregulated 12V DC supply, consisting of two 105Ah AGM batteries which have solar and mains back-up. The outlet for this is a Anderson SB50 connector, fairly standard for caravans.

Catch being, this is temporary. So no permanent linkages, we need to be able to disconnect and pack everything away when not in use. One bug bear is having enough DC outlets for everything. Especially of the 30A Anderson Power Pole variety, since most of our radios use those.

The monitor for the base computer uses a cigarette lighter adapter, while the base computer itself (an Intel NUC) has a cable terminated with a 30A power pole. There’s also a WiFi router which has a micro-USB power input — thankfully the monitor’s adaptor embeds a USB power outlet, so we can run it off that.

We need two amateur radios (one for voice comms, one for packet), and a CB set for communications with the ride organisers (who are otherwise not licensed to use amateur bands). We may also see a move to commercial frequencies, so that’s potentially another radio or two.

I started thinking about ways we could make a modular power distribution system.

The thought was, if we made PDU boxes where the inlet and outlet were nice big SB50s, configured so that they would mate when the boxes were joined up, we could have a flexible PDU system where we just clip it together like Lego bricks.

This is a work in progress, but I figured I’d post what I have so far.

Power outlets on the distribution box, yet to be wired up.

I still need to do the internal wiring, but above is basically what I was thinking of. There’s room for up to 6 consumers via the 30A power pole connections along one side, each with its own 20A breaker. (The connectors are rated at 45A.)

Originally I was aiming for 6 cigarette lighter sockets, but after receiving the parts, I realised that wouldn’t fit, but two seems to work okay, and we can always make a second box and slap that on the end. Each has a 15A breaker.

Protecting the upstream power source is a 50A breaker. So total of the down-stream port + all outlets on the box itself may not exceed 50A.

The upstream and downstream ports are positioned so that boxes can just be butted up against each-other for the connectors to mate. I’ve got to fine-tune the positioning a bit, and right now the connectors are also on an angle, but this hopefully shows the concept…

The idea for maintenance is the box will fold out. Not sure if the connection between all the outputs on the lid will be via a bus bar or using individual cables going to the tie point inside the box just yet. Those 30A outlets are just begging for a single cable to visit each bus-bar style. I also have to figure out how I’ll connect to the cigarette lighter sockets too.

Hopefully I’ll get this done before the next ride event.

Dec 222019
 

No doubt many will have heard about the “bushfire crisis” that has basically been wreaking havoc for the past month. Here in Brisbane things haven’t been too bad, but we’ve had our fair share of smoke haze and things of course are exceptionally dry.

From where I sit, this is a situation we have let ourselves get into. Some argue that this is all because of the lack of back-burning, and to a certain extent this is true.

Back-burning doesn’t make it rain however. The lack of back-burning is a casualty of a few things, partly a lack of firefighting resources, and also significantly, a hotter, dryer climate.

Climate change has been known about for a long time. When I was growing up in the early 90s, the name used was the “greenhouse effect”. The idea being that all the “greenhouse gasses” we were generating, was causing heat to be trapped in the atmosphere like a greenhouse, and thus heating up the planet.

Back then, there didn’t seem to be any urgency to combat the problem.

So, we’ve just continued the way we always have since the start of the industrial revolution. Some things have improved, for instance electric vehicles just weren’t practical then, they are slowly gaining traction.

Large-scale PV generation in the 90s would have been seen as a joke, now we have entire paddocks dedicated to such activities. Renewable power generation is big business now. Whilst it won’t displace all traditional methods, it has an important place going forward.

Yet, in spite of all this progress, we’ve still got people in government, and in big corporate organisations who cling to the “business as usual” principle.

When South Australia announced they were going to install a big battery to help back-up their power supply, the idea was poo poohed, with many saying it wouldn’t be big enough to make a difference. What it doesn’t have in running-time, it makes up for in very fast responsiveness to load changes.

A coal-fired power station operates by using thermal energy produced by burning coal, to boil water to produce steam which drives turbines that in turn, drive electric generators. A nuclear station isn’t much different — the thermal source is the only bit that changes. Geothermal is basically using a nuclear station that mother nature has provided.

The thing all these systems have in common is rotating mass. It takes significant energy to cause a step-change in rotational speed of the turbine. If the turbine is still, you’re going to have to pump a lot of energy in, somehow, to get it spinning. If it’s spinning, it’ll take a lot of energy to stop it. Consequently, they are not known for reaction times. Cold starts for these things in the realm of a day is not unknown. They also don’t take kindly to sudden changes of load. It is during these times the emissions from such generators are at their worst.

Solar is great during the day when it’s fine, but on a cloudy day like today the output is likely to be greatly diminished, and it’ll be utterly useless at night. If we had big enough battery storage, then yes, we could theoretically capture enough during the sunny days to carry us over the nights and cloudy days. That’s a big if.

So I still see the traditional methods being a necessary evil. The combination of all three options though (renewables, traditional generation and battery storage) could be a winner. Let the older stations carry the evening base-load and keep the battery topped up, ramp them down a bit when we’re getting good renewable output, use the batteries to cover the load spikes.

Nuclear could be an option, however to my mind they have two big problems:

  1. Public perception
  2. Commissioning time

Without a doubt, the modern designs for these things has greatly improved on what graced the sites of Chernobyl, Three Mile Island and Fukushima. They generate waste still, but in many cases the half-life and quantity of this waste is greatly reduced. The biggest problem though is public perception, as there are many who will not differentiate between the designs, and will immediately respond: “not in my back yard!”

Even if you could win peoples’ trust, you’ve got a second problem, getting them built and commissioned in time. If we had started in the 90s, then maybe they’d be doing useful things for us now. That boat has long set sail and is dipping over the horizon now.

Transportation is another area where we’re, as a nation, addicted to fossil fuels. It’s not hard to see why though. Go outside a major capital city, and infrastructure for a purely electric vehicle disappears.

Moreover, the manufacturers, stuck in their echo-chamber, don’t see larger electric vehicles as worth the investment.

Back in 2007, my father was lucky enough to win the Multicap Art Union, and so replaced the Subaru stationwagon he’s owned since 1982 with a Holden Rodeo ute (we had the choice between that or Toyota).

This vehicle was chosen with the intent of towing a caravan with it — something he later purchased. The caravan weighs about two tonnes. Yes, an electric vehicle could theoretically tow it, and could even do a better job, but at the time, no such vehicle was available from any of the available suppliers.

To my knowledge, this is still the case. Few, if any of the electric vehicles on the market here in Australia, have the necessary facilities to tow a caravan even if the motor is capable of it.

Then there’s infrastructure to consider. A pure electric vehicle would probably be impractical outside of major regional centres and capital cities. Once you got away from the network of high-power chargers, you better plan for staying a few days in each town where you charge, because it will take that long to charge that battery from a 240V 10A socket!

Diesel-electric though, could be a winner since diesel engines similarly operate most efficiently at constant speed and could drive a generator to charge battery storage.

A return of the gas turbine engine could also be a good option. This was tried before, but suffered from the typical characteristic of turbines, they don’t like changing speed quickly. Poor throttle response is a deal-breaker when the engine is providing the traction, but it is a non-issue in a generator. They run on a wide variety of fuel types, including petroleum and diesel, so could utilise existing infrastructure, and the engines are generally simpler designs.

Is there research going into this? Not from what I’ve seen. Instead, they trot out the same old style vehicles. Many people buy them because that’s all that’s on offer that fulfils their requirements. Consequently this inflates the apparent desire for these vehicles, so the vehicle makers carry on as usual.

The lack of cycle infrastructure also pushes people into vehicles. When I do ride to work (which I’ve been trying to do more of), I find myself getting up early and getting on the road before 4:30AM to avoid being a nuisance to other road users.

In particular road users who believe: “I paid vehicle registration, therefore this road is MINE!” I needn’t waste space on that assertion, the Queensland government raised about $557M in revenue (page 14) from vehicle registration in 2018-19, whilst the DTMR’s expenditure at that time was over $6bn (page 15).

The simple truth is that a lot of these initiatives are seen as nothing but a “cost”. Some simple-minded people even say that the very concept of climate change is invented simply to slug the developed world. We need to get past this mentality.

The thing is, business as usual is costing us more. We’re paying for it big time with the impact on the climate that these emissions are having. Yes, climate does go in cycles, but what we’re experiencing now is not a cycle.

I can remember winters that got down to the low signal digits here in Brisbane. I have not experienced those sorts of conditions here for a good 15 years now. Yes, this is a land of drought and flooding rain, however, we seem to be breaking climate records that have stood longer than any of us have been alive by big margins.

The “fire season”, which is used to determine when back-burning should take place has also been lengthening. It will get to a point where there just isn’t a safe time to conduct back-burning as theoretically every day of the year will be “fire season” conditions.

This is costing us.

  • It will cost us with property being destroyed.
  • It will cost us with work being disrupted.
  • It will cost us with food production being threatened.
  • It will cost us with health issues due to increasing ambient temperatures and air pollution issues.

Lately I’ve been suffering as a result of the smoke haze that has been blowing through the Brisbane area. I recognise that it is nowhere near as bad as what Sydney has to put up with. Whilst not severely asthmatic, I have had episodes in the past and can be susceptible to bronchitis.

On one occasion, this did lead to a case of pneumonia.

About a fortnight ago I started to go down with a bout of bronchitis. I’ve had two visits to the doctor already, prescribed antibiotics and a puffer, normally by now my symptoms would be subsiding by now. This time around, that has not been the case. Whilst the previous bouts have been stress-related, I think this time it is smoke-induced.

I think once the smoke clears, I’ll recover. I am not used to this level of air pollution however, and I think if it becomes the new “normal”, it will eventually kill me. If I lived in Sydney, no question, that level probably would kill me.

This is a wake-up call. Whilst I don’t plan to join the Extinction Rebellion — as I don’t think blocking up traffic is doing anyone any favours, I do think we need to change direction on our emissions. If we carry on the way we are now, things are only going to get worse.

Nov 282019
 

This is more of a brain dump for yours truly, since as a day job, I’m dealing with OpenThread a lot, and so there’s lots of little tricks out there for building it on various platforms and configurations. The following is not so much a how-to guide, but a quick brain dump of different things I’ve learned over the past year or so of messing with OpenThread.

Verbose builds

To get a print out of every invocation of the toolchain with all flags, specify V=1 on the call to make:

$ make -f examples/Makefile-${PLATFORM} …${ARGS}… V=1

Running one step at a time

To disable the parallel builds when debugging the build system, append BuildJobs=1 to your make call:

$ make -f examples/Makefile-${PLATFORM} …${ARGS}… BuildJobs=1

Building a border router NCP image

General case

$ make -f examples/Makefile-${PLATFORM} …${ARGS}… BORDER_AGENT=1 BORDER_ROUTER=1 COMMISSIONER=1 UDP_FORWARD=1

For TI CC2538

# Normal CC2538 (e.g. Zolertia Firefly)
$ make -f examples/Makefile-cc2538 BORDER_AGENT=1 BORDER_ROUTER=1 COMMISSIONER=1 UDP_FORWARD=1

# CC2538 + CC2592
$ make -f examples/Makefile-cc2538 BORDER_AGENT=1 BORDER_ROUTER=1 COMMISSIONER=1 UDP_FORWARD=1 CC2592=1

If you want to run the latter image on a WideSky Hub, you’ll need to edit examples/platform/cc2538/uart.c and comment out line 117 before compiling as it uses a simple diode for 5V to 3.3V level shifting, and this requires the internal pull-up to be enabled:

115     // rx pin
116     HWREG(IOC_UARTRXD_UART0) = IOC_PAD_IN_SEL_PA0;
117     HWREG(IOC_PA0_OVER)      = IOC_OVERRIDE_DIS; // ← comment out this to allow UART RX to work
118     HWREG(GPIO_A_BASE + GPIO_O_AFSEL) |= GPIO_PIN_0;

For Nordic nRF52840

# Nordic development board (PCA10056) via J2 (near battery)
$ make -f examples/Makefile-nrf52840 BORDER_AGENT=1 BORDER_ROUTER=1 COMMISSIONER=1 UDP_FORWARD=1

# Ditto, but instead using J3 (near middle of bottom edge)
$ make -f examples/Makefile-nrf52840 BORDER_AGENT=1 BORDER_ROUTER=1 COMMISSIONER=1 UDP_FORWARD=1 USB=1

# Nordic dongle (PCA10059)
$ make -f examples/Makefile-nrf52840 BORDER_AGENT=1 BORDER_ROUTER=1 COMMISSIONER=1 UDP_FORWARD=1 USB=1 BOOTLOADER=USB

I’m working on what needs to be done for the Fanstel BT840X… watch this space.

Building certification test images

For CC2538

$ make -f examples/Makefile-cc2538 BORDER_ROUTER=1 COMMISSIONER=1 DHCP6_CLIENT=1 JOINER=1

Running CI tests outside of Travis CI

You will need:

  • Python 3.5 or later. 3.6 recommended.
  • pycryptodome (not pycrypto: if you get an AttributeError referencing AES.MODE_CCM, that’s why!
  • enum34 (for now… I suspect this will disappear once the Python 2.7 requirement is dropped for Android tools)
  • ipaddress
  • pexpect

The test suites work by running the POSIX ot-cli-${TYPE} (where ${TYPE} is ftd or mtd).

Running tests

From the root of the OpenThread tree:

$ make -f examples/Makefile-posix check

Making tests

The majority of the tests lurk under tests/scripts/thread-cert. Don’t be fooled by the name, lots of non-Thread tests live there.

The file node.py wraps pexpect up in an object with methods for calling the various CLI commands or waiting for things to be printed to the console.

The tests themselves are written using using the standard Python unittest framework, with setUp creating a few Node objects (node.py) and tearDown cleaning them up. The network is simulated.

The test files must be executable, and call unittest.main() after checking if the script is called directly.

Logs during the test runs

During the tests, the logs are stashed in build/${CHOST}/tests/scripts/thread-cert and will be named ${SCRIPTNAME}.log. (e.g test_coap_observe.py.log). Also present is the .pcap file (Packet dump).

Logs after the tests

The test suite will report the logs are at tests/scripts/thread-cert/test-suite.log. This is relative to the build directory… so look in build/${CHOST}/tests/scripts/thread-cert/test-suite.log.

make pretty with clang 8.0

Officially this isn’t supported, but you can “fool” OpenThread’s build system into using clang 8.0 anyway:

$ cat ~/bin/clang-format-6.0 
#!/bin/bash

if [ "$1" == "--version" ]; then
        echo "clang-format version 6.0"
else
        clang-format "$@"
fi

Put that file in your ${PATH}, make it executable, then OpenThread will think you’ve got clang-format version 6 installed. This appears to work without ill effect, so maybe a future release of OpenThread will support it.

Nov 242019
 

The past few months have been quiet for this project, largely because Brisbane WICEN has had my spare time soaked up with an RFID system they are developing for tracking horse rides through the Imbil State Forest for the Stirling’s Crossing Endurance Club.

Ultimately, when we have some decent successes, I’ll probably be reporting more on this on WICEN’s website. Suffice to say, it’s very much a work-in-progress, but it has proved a valuable testing ground for aioax25. The messaging system being used is basically just plain APRS messaging, with digipeating thrown in as well.

Since I’ve had a moment to breathe, I’ve started filling out the features in aioax25, starting with connected-mode operation. The thinking is this might be useful for sending larger payloads. APRS messages are limited to a 63 character message size with only a subset of ASCII being permitted.

Thankfully that subset includes all of the Base64 character set, so I’m able to do things like tunnel NTP packets and CBOR blobs through it, so that stations out in the field can pull down configuration settings and the current time.

As for the RFID EPCs, we’re sending those in the canonical hexadecimal format, which works, but the EPC occupies most of the payload size. At 1200 bits per second, this does slow things down quite a bit. We get a slight improvement if we encode the EPCs as Base64. We’d get a 200% efficiency increase if we could send it as binary bytes instead. Sending a CBOR blob that way would be very efficient.

The thinking is that the nodes find each-other via APRS, then once they’ve discovered a path, they can switch to connected mode to send bulk transfers back to base.

Thus, I’ve been digging into connected mode operation. AX.25 2.2 is not the most well-written spec I’ve read. In fact, it is down-right confusing in places. It mixes up little-endian and big-endian fields, certain bits have different meanings in different contexts, and it uses concepts which are “foreign” to someone like myself who’s used to TCP/IP.

Right now I’m making progress, there’s an untested implementation in the connected-mode branch. I’m writing unit test cases based on what I understand the behaviour to be, but somehow I think this is going to need trials with some actual AX.25 implementations such as Direwolf, the Linux kernel stack, G8BPQ stack and the implementation on my Kantronics KPC3 and my Kenwood TH-D72A.

Some things I’m trying to get an answer to:

  • In the address fields at the start of a frame, you have what I’ve been calling the ch bit.
    On digipeater addresses, it’s called H and it is used to indicate that a frame has been digipeated by that digipeater.
    When seen in the source or destination addresses, it is called C, and it describes whether the frame is a “command” frame, or a “response” frame.

    An AX.25 2.x “command” frame sets the destination address’s C bit to 1, and the source address’s C bit to 0, whilst a “response” frame in AX.25 does the opposite (destination C is 0, source C is 1).

    In prior AX.25 versions, they were set identically. Question is, which is which? Is a frame a “command” when both bits are set to 1s and a “response” if both C bits are 0s? (Thankfully, I think my chances of meeting an AX.25 1.x station are very small!)
  • In the Control field, there’s a bit marked P/F (for Poll/Final), and I’ve called it pf in my code. Sometimes this field gets called “Poll”, sometimes it gets called “Final”. It’s not clear on what occasions it gets called “Poll” and when it is called “Final”. It isn’t as simple as assuming that pf=1 means poll and pf=0 means final. Which is which? Who knows?
  • AX.25 2.0 allowed up to 8 digipeaters, but AX.25 2.2 limits it to 2. AX.25 2.2 is supposed to be backward compatible, so what happens when it receives a frame from a digipeater that is more than 2 digipeater hops away? (I’m basically pretending the limitation doesn’t exist right now, so aioax25 will handle 8 digipeaters in AX.25 2.2 mode)
  • The table of PID values (figure 3.2 in the AX.25 2.2 spec) mentions several protocols, including “Link Quality Protocol”. What is that, and where is the spec for it?
  • Is there an “experimental” PID that can be used that says “this is a L3 protocol that is a work in progress” so I don’t blow up someone’s station with traffic they can’t understand? The spec says contact the ARRL, which I have done, we’ll see where that gets me.
  • What do APRS stations do with a PID they don’t recognise? (Hopefully ignore it!)

Right at this point, the Direwolf sources have proven quite handy. Already I am now aware of a potential gotcha with the AX.25 2.0 implementation on the Kantronics KPC3+ and the Kenwood TM-D710.

I suspect my hand-held (Kenwood TH-D72A) might do the same thing as the TM-D710, but given JVC-Kenwood have pulled out of the Australian market, I’m more like to just say F### you Kenwood and ignore the problem since these can do KISS mode, bypassing the buggy AX.25 implementation on a potentially resource-constrained device.

NET/ROM is going to be a whole different ball-game, and yes, that’s on the road map. Long-term, I’d like 6LoWHAM stations to be able to co-exist peacefully with other stations. Much like you can connect to a NET/ROM node using traditional AX.25, then issue connect commands to jump from there to any AX.25 or NET/ROM station; I intend to offer the same “feature” on a 6LoWHAM station — you’ll be able to spin up a service that accepts AX.25 and NET/ROM connections, and allows you to hit any AX.25, NET/ROM or 6LoWHAM station.

I might park the project for a bit, and get back onto the WICEN stuff, as what we have in aioax25 is doing okay, and there’s lots of work to be done on the base software that’ll keep me busy right up to when the horse rides re-start in 2020.

Oct 252019
 

In my last post, I mentioned that I was playing around with SDR a bit more, having bought a couple. Now, my experiments to date were low-hanging fruit: use some off-the-shelf software to receive an existing signal.

One of those off-the-shelf packages was CubicSDR, which gives me AM/FM/SSB/WFM reception, the other is qt-dab which receives DAB+. The long-term goal though is to be able to use GNURadio to make my own tools. Notably, I’d like to set up a Raspberry Pi 3 with a DRAWS board and a RTL-SDR, to control the FT-857D and implement dual-watch for emergency comms exercises, or use the RTL-SDR for DAB+ reception.

In the latter case, while I could use qt-dab, it’ll be rather cumbersome in that use case. So I’ll probably implement my own tool atop GNURadio that can talk to a small microcontroller to drive a keypad and display. As a first step, I thought I’d try a DIY FM stereo receiver. This is a mildly complex receiver that builds on what I learned at university many moons ago.

FM Stereo is actually surprisingly complex. Not DAB+ levels of complex, but still complex. The system is designed to be backward-compatible with mono FM sets. FM itself actually does not provide stereo on its own — a stereo FM station operates by multiplexing a “mono” signal, a “differential” signal, and a pilot signal. The pilot is just a plain 19kHz carrier. Both left and right channels are low-pass filtered to a band-width of 15kHz. The mono signal is generated from the summation of the left and right channels, whilst the differential is produced from the subtraction of the right from the left channel.

The pilot signal is then doubled and used as the carrier for a double-sideband suppressed carrier signal which is modulated by the differential signal. This is summed with the pilot and mono signal, and that is then frequency-modulated.

For reception, older mono sets just low-pass the raw FM discriminator output (or rely on the fact that most speakers won’t reproduce >18kHz well), whilst a stereo set performs the necessary signal processing to extract the left and right channels.

Below, is a flow-graph in GNURadio companion that shows this:

Flow graph for FM stereo reception

The signal comes in at the top-left via a RTL-SDR. We first low-pass filter it to receive just the station we want (in this case I’m receiving Triple M Brisbane at 104.5MHz). We then pass it through the WBFM de-modulator. At this point I pass a copy of this signal to a waterfall plot. A second copy gets low-passed at 15kHz and down-sampled to a 32kHz sample rate (my sound card doesn’t do 500kHz sample rates!).

A third copy is passed through a band-pass filter to isolate the differential signal, and a fourth, is filtered to isolate the pilot at 19kHz.

The pilot in a real receiver would ordinarily be full-wave-bridge-rectified, or passed through a PLL frequency synthesizer to generate a 38kHz carrier. Here, I used the abs math function, then band-passed it again to get a nice clean 38kHz carrier. This is then mixed with the differential signal I isolated before, then the result low-pass filtered to shift that differential signal to base band.

I now have the necessary signals to construct the two channels: M + D gives us (L+R) + (L-R) = 2L, and M – D = (L+R) – (L – R) = 2R. We have our stereo channels.

Below are the three waterfall diagrams showing (from top to bottom) the de-modulated differential signal, the 38kHz carrier for the differential signal and the raw output from the WBFM discriminator.

The constituent components of a FM stereo radio station.

Not decoded here is the RDS carrier which can be seen just above the differential signal in the third waterfall diagram.

Oct 122019
 

Recently, I’ve been doing a lot of work with 6LoWPAN on the 2.4GHz band. I didn’t have anything that would receive arbitrary signals on this frequency, so I decided to splurge. I got myself my first bit of tax-deductible amateur radio equipment: a HackRF One.

It’s been handy, fire up CubicSDR, and immediately you get a picture of what’s happening on the frequency. In the future I hope to get the WIME framework working so I can decode the 802.15.4 frames and pipe them to Wireshark, but so far, this has been handy.

Since I’m not using it every day, I also put it to a second use, DAB+ reception. I used to listen to various stations a lot, and whilst FM stereo is built into my phone, I’ve got nothing that will do medium-wave AM. The HackRF stops short at 1MHz (officially 10MHz), and needs a suitable antenna to do so. However, it occurred to me that it was more than capable of doing DAB+, so after some experimentation, I managed to get qt-dab working.

Since getting that working, I bought a second SDR, a RTL-SDR v3. The idea is I’d be setting this up on the bicycle with a Raspberry Pi 3 which also has a DRAWS board fitted (the successor to the UDRC). I figured I could use this as a second receiver for amateur radio stuff, or use it for FM stereo/DAB+, maybe short wave.

So today, I was testing this: using the RTL-SDR with a Pi 3, seeing whether it would perform acceptably for that task. Interestingly, CubicSDR will de-modulate FM stereo quite happily when you’re running it via a X11 session forwarded over SSH, but it stutters its way though if you try to run it natively. I think the waterfall displays are too much for the machine to cope with: it can render them, but painting them on the screen causes too much CPU load.

qt-dab however works quite well. It occupies about 60% CPU, which means you don’t want to be doing much else. Whether I can do AX.25 packet simultaneously as planned or not is a valid question. Audio quality through the PWM output on the Pi3 is good too — I did try this with an original Pi and got an aural assault courtesy of the noisy 3.3V power rail, but it seems this problem is largely fixed on the Pi3.

In truth, I’ll probably be using the GNURadio framework directly when I get to implementing this on the bicycle. That makes a custom tailored UI a little easier to implement.

The WTF moment though was whilst putting this rig through its paces… I noticed a new station:

ELF Radio, a station dedicated to Christmas Carols

A new station, “ELF Radio” had appeared in multiplex 9A (202.928MHz)… this is exactly what it sounds like, a station dedicated to Christmas carols. We’re not even half-way though October, and they’re already out to flog the genre to death.

Now, Christmas rage was not a thing when I was younger, it seems the marketing world is intent on ruining this tradition by making excuses for starting the sales earlier and earlier… and it seems the “ambience” is part of the package deal that they insist must start long before that Celtic tradition, Halloween! As a result, most of us are thoroughly fed up by the time December rolls around.

Here’s a hint advertisers: playing this crap so soon in the year will not result in higher sales. It’s a sales repellent!