Thursday, May 31, 2018

Generating RF with an osmo-fl2k VGA dongle

I've continued to play with the cheap ($10) USB VGA dongles which can be used as a fast digital to analog converter. Working with Ross, VK1UN, we've been climbing the learning curve of  GNURadio Companion to generate the samples we need to transmit modulated RF.

The fl2k_file command line tool needs a file with 8 bit signed samples. These are clocked out at 100M samples per second by default.

To get started I've written some pretty inefficient c to write out suitable files.

First here's a function that writes a suitable simple sine wave carrier. (I use 80 samples per cycle to get RF on 1.25MHz).

#include
#include
#include

const char *outFileName = "samples.dat";

void makeCarrier(int samplesPerCycle) {
    FILE *outfile = fopen(outFileName, "wb");
    int8_t byte;
    for(int sample = 0; sample < samplesPerCycle; sample++) {
double current_radian = M_PI * sample * 2 / samplesPerCycle;
        double carrier_sin_value = sin(current_radian);
        byte = (int8_t)(carrier_sin_value * 127.0);
        printf("%f, val = %f, byte = %d\n", current_radian, carrier_sin_value, (int)byte);
        fwrite(&byte, sizeof(byte), 1, outfile);
    }
    fclose(outfile);
}

Double sideband can be generated by simply multiplying samples of a modulating sine wave by the samples of the carrier.

// Produces an double sideband signal suitable for fl2k_file
void makeDsb(int samplesPerCycle) {
    // ratio of the carrier to the modulating sine wave
    int ratio = 3000;

    FILE *outfile = fopen(outFileName, "wb");
    // make sure we get enough samples for a full wave of the modulation
int totalSamples = samplesPerCycle * ratio;
    for(int sample = 0; sample < totalSamples; sample++) {
double carrier_radian = fmod((M_PI * sample * 2 / samplesPerCycle),(M_PI * 2));
        double mod_radian = fmod((M_PI * sample * 2 / samplesPerCycle) / ratio,(M_PI * 2));
        
//printf("%03d carrier r = %f, mod r = %f\n", sample, carrier_radian, mod_radian);

        double carrier_sin_value = sin(carrier_radian);
        double mod_sin_value = sin(mod_radian);
        
        double am_sample = carrier_sin_value * mod_sin_value;
        //printf("%f\t%f\t%f\n", carrier_sin_value, mod_sin_value, am_sample);

        int8_t byte = (int8_t)(am_sample * 127.0);
        //printf("byte = %d\n", byte);
        fwrite(&byte, sizeof(byte), 1, outfile);
    }
    fclose(outfile);
}

AM requires the modulating audio (ranging from -1 to +1) to have 1 added to it and the result divided by 2 before again multiplying by samples in the carrier sine wave.

// Produces an AM'd signal suitable for fl2k_file
void makeAm(int samplesPerCycle) {
    // ratio of the carrier to the modulating sine wave
    int ratio = 3000;

    FILE *outfile = fopen(outFileName, "wb");
    // make sure we get enough samples for a full wave of the modulation
int totalSamples = samplesPerCycle * ratio;
    for(int sample = 0; sample < totalSamples; sample++) {
double carrier_radian = fmod((M_PI * sample * 2 / samplesPerCycle),(M_PI * 2));
        double mod_radian = fmod((M_PI * sample * 2 / samplesPerCycle) / ratio,(M_PI * 2));
        
//printf("%03d carrier r = %f, mod r = %f\n", sample, carrier_radian, mod_radian);

        double carrier_sin_value = sin(carrier_radian);
        double mod_sin_value = (sin(mod_radian) + 1.0) / 2.0;
        
        double am_sample = carrier_sin_value * mod_sin_value;
        //printf("%f\t%f\t%f\n", carrier_sin_value, mod_sin_value, am_sample);

        int8_t byte = (int8_t)(am_sample * 127.0);
        //printf("byte = %d\n", byte);
        fwrite(&byte, sizeof(byte), 1, outfile);
    }
    fclose(outfile);
}

To look at the output file, to see if it's reasonable, I wrote a utility to read the bytes, spit out a text file with the numbers in it, feed that into gnuplot and look at the graph. Great but I've just had a better idea, the audio editing software Audacity can import files and setting it to signed 8 bit PCM works well and the waveform is easy to see.


Here's how AM looks:


The file is transmitted with fl2k_file simply as:

fl2k_file samples.dat

The output AM can view viewed on a CRO.


And shown on an SDR, here it is in SDR#. You can see the carrier and two nice sidebands.


On an AM radio, I hear a strong carrier with nice sounding tone.

I realise this is all very basic stuff but it's been great to learn a bit about it. The real power tool in all this is GRC (GNU Radio Companion).

Here's how I generate an amplitude modulated carrier suitable for sending to the fl2k dongle. (Click to enlarge it so you can read it).


The GNU Radio flow document is here.

Note that GRC always defaults to complex and in this case we want floats. This will run indefinitely and fill up your disk so just run for a few seconds and then open the file in Audacity to have a look at the waveform.

To avoid local AM stations I've been sending it with "fl2k_file -s 80e6 am_out.dat" which puts it on about 900kHz on the broadcast band.

Here's a GRC flow graph that shows how I read a WAV file with audio (ELO don't bring me down), resample it up and produce AM'd carrier to transmit. (Again click to read it).


Here's how it sounds on an AM radio.


Anyone know how to do this but with single side band?

Update: Ross transmits decodable WSPR

Transmitting a captured audio output from WSJT-X on AM, Ross has been able to decode the transmission.


And again but with double sideband modulation:


Next challenge is single sideband modulation.

Tuesday, May 29, 2018

Sydney - Adelaide via FreeDV 700D. Better than SSB

It's 4:30pm Sydney time and I've just had a digital voice contact using David, VK5DGR's new 700D FreeDV mode. Sydney to Adelaide is about 1,100km so a good distance for 7MHz. My local noise level here is not great at about S6 and yet we were able to have a pretty good contact on 40m.


Version 1.3, which includes the new 700D mode, is available as a pre-built binary for macOS, Linux and Windows. I grabbed the latest development source and it builds according to the README on Ubuntu 18.04 just fine.

My set up is a USB headset mic and a Signalink USB radio interface. All works well although David suggests that decoded digital voice might be more readable via a speaker than via headphones.

We chatted back and forth in digital mode pretty well and then switched to SSB to compare. I was certainly putting out more power on SSB and I suspect David was too but to me the digital copy was as good as or slightly better than SSB. This is a fantastic milestone to reach!

Signal notification service

As there isn't a huge amount of FreeDV activity at the moment, there is a fantastic feature that can monitor and send an email if there is five seconds of sync. You run a python script included in the source and give it your email credentials. This script listens on UDP port 3000 and if you enable this in FreeDV's options screen it will email you when someone's on the channel. (It only sends one email a minute so you don't get swamped).

This is a great idea and should be a standard for other digital mode clients.

How I sound

We had a three way contact today on 7.177 between Peter, VK3RV in Sunbury Victoria, David, VK5DGR in Adelaide and myself, VK2TPM in Sydney. David recorded one of my transmissions and sent me the off air recording which can be decoded in the FreeDV app. We could barely hear each other in SSB. Here's how it looks and sounds:


Note that there are command line tools distributed with the FreeDV source code including freedv_tx and freedv_rx which will encode and decode all the way from voice wav through to modem audio.

Here's how you decode a captured file:

freedv_rx 700D vk2tpm.wav - | sox -t raw -r 8000 -e signed-integer -b 16 - decoded.wav

Note that the output file is a 16 bit mono file with 8kHz sample rate.

Check out the FreeDV site for much more information and give me a call on 7.177Mhz.

Tuesday, May 22, 2018

Home made ubitx box

Inspired by the excellent ubitx.net web site, I have bent a larger box so that the front panel ergonomics are improved. I added a nice tuning knob with finger depression and added a microphone pre-amp, compressor and noise gate board. The tuning knob is on its own on the right (not cramped with the volume control and mic socket) and with the new software it's a pleasure to spin up and down the dial.


I'm just using the mic amp board as it comes with a dynamic mic and levels look good but there's the option to add trimmers for both the compression and noise gate level. I have an output gain control knob in there.


My rudimentary metal work skills are slowly improving and I'm quite proud of the nibbled hole for the LCD display in this one. My nibbler has been sticking, which was frustrating, but a little WD-40 did the trick. I learned from a recent Adam Savage video that WD stands for "water displacement".

Sunday, May 06, 2018

Updated uBitx raduino software

Inspired by the latest edition of the Soldersmoke podcast, I took a look at the updated software that has been created for the embedded Arduino Nano.

My uBitx is looking much nicer since I made a new lid for it and mounted the speaker with a grill made of offcuts from the gutter guard we had installed last year.

I used the latest version of the Arduino IDE 1.8.5. Next I went to library manager and updated all updatable libraries and the same for boards. From the downloaded software from GitHub I opened the ubitx_20.ino file and did a build (the tick button). All built smoothly for me.

The Raduino board (sandwiched with the display) was removed from the uBitx, mainly because the position of my volume control blocks the mini USB port. I removed the display and plugged the board in to USB.

When I programmed it gave timeout errors saying that the board wasn't responding. I tried a different computer and different cables. Finally I tried the "old bootloader" option and all was good.

Along the way I first tried under Linux and then on macOS. The serial driver I needed was found via Bjorn's Techblog.

Now the uBitx is much nicer to tune and there are lots of interesting menu items to explore.

Some of the features are:
  • CAT control
  • S-Meter
  • Software defined radio output
  • Improved receive performance
  • IF Calibration
  • WSPR beacon
  • Bug fixes including CW key debouncing
Great work by KD8CEC and others on all this and of course credit to Ashar Farhan for creating the uBitx and making it all available for hacking.

Update: uBitx to uBitx contact with VK2BLQ

Encouraged by the improved tuning action, Stephen and I had our regular 20m sked with uBitx rigs on both ends. Stephen could hear me over the local noise and I could hear him pretty well when he "talked it up". Both of us have been reading the ubitx site and have independently ordered a low cost mic amplifier/compressor board.

I'm now keen to re-box my uBitx to give more room for the tuning knob. I'm looking for a knob with a finger indent that will screw on to a 6mm shaft. They are about but seem very expensive generally as an after market add on for a commercial rig.

We're also interested in digital modes on the uBitx and of course the best way to do this would be to build in a USB audio interface with VOX. Not sure that I'll go that far but worth thinking about.

Tuesday, May 01, 2018

First play with OSMO-FL2K compatible VGA dongle

Everyone knows about the popularisation of software defined radio that came about via the wonderful discovery that low cost USB TV dongles with realtech chipsets could be used. Now it looks like we have the same sort of thing but for transmitting.

Some low cost USB VGA adapters are so cheap that they are simply fast digital to analog converters. Steve M from Osmocom has figured out how to turn them into a simple output device suitable for transmitting. Mine came from Aliexpress but others are on eBay locally.

Here I tried a device and used the demo program to transmit an audio file (saved as WAV) over wide band FM to a nearby radio.


I'm on Ubuntu linux so there were some very small deviations from the instructions about USB memory buffer, I had to do this:

sudo sh -c 'echo 1000 > /sys/module/usbcore/parameters/usbfs_memory_mb'

To get some audio to transmit, I opened a 44100 rate mp3 in Audacity and saved it as WAV signed 16-bit PCM file.

The command line to transmit is:

fl2k_fm -s 130e6 -c 35e6 -i 44100 Electric\ Light\ Orchestra\ -\ Telephone\ Line.wav

So far other examples, and there are some amazing ones, require GNU Radio, but hopefully we'll get some more accessible ways to do interesting things like transmit WSPR in the near future.

This is a wonderful example of where the cheaper product is actually more useful than the more expensive versions.

There is a pretty good explanation of how this works in an earlier project VGASIG.

Here's how it looks on an SDR receiver. A little off frequency but looks reasonable to me.


And here's how the 35MHz waveform looks on a CRO:


So when working it's a decent 0.5V peak to peak waveform, DC offset. And a good signal on an FM radio at 95Mhz

I have noticed that this software/hardware works on some Linux machines and not others. It works fine on an Ubuntu 18.04 desktop but not on Fedora machines. When running on some machines it fails silently in that all appears to be running but there's no RF output.

Using the fl2k_file utility I output a sine wave. I can see the sine wave in the dongle output but there is lots of nasty spikes too. I guess a low pass filter could clean this up but it's not a good look.


Please let me know if you've got a better result than I have.

Update: Now getting a better waveform.

I've done some hacking on the FM code, basically stripping it right back and focusing on generating the cleanest wave I can on 40m.


This is running at a sample rate of 150Mega samples per second and a carrier of 7.159MHz. Not great but might be eventually useful (with some filtering) for something like WSPR transmit.

My stripped back version of the source now builds stand alone (no library) and simply generates a sine wave carrier. The source is available here.

Made a small project box

I'm not very good at this and figuring out how much extra to allow for the bend in aluminium continues to elude me but gradually I'm getting there.

The box shown here is still pretty rough but it's good enough for my little projects. Being able to make them at home means I can adjust the size to suit the project.

This morning I looked up Aluminium in Google maps and lucked upon Aluminium Engineering near by in Brookvale. What a wonderful establishment. I purchased a sheet of 0.9mm aluminium and loaded it in to the van.

The shop front is a work of art and should be classified as a heritage building to be preserved for ever.


Inside they're well stocked and the two chaps in there are friendly and informative. The warned me not to try welding 0.9mm which is fine.


Here's the shiny new hand shear which is making all of this cutting pretty easy. A cat is shown for scale.


Here is the current iteration of my box plan.


The measurements in the lid on the right are based on 0.9mm thickness and my dodgy bending. As you can see this makes a 100mm x 100mm x 40mm box. I'm using self tapping screws on the sides and it needs rubber feet to avoid scratching tables.