Setting up an amateur Ionogram Monitoring station


This new project is added to Sidmonitor site ,  with Claudio Re and others  friends , we  have developed in last few years. Having Ionograms updated from Cyprus  gives a good point of view   on   current state, the conformation and deformation of the ionosphere caused by natural phenomena such as solar active regions and bursts,  created by the sun. Thanks to  CSP and Roberto Borri   for giving us the USRP2  , as well as Juha Vierinen for updating his software GNU Chirp Sounder  in single receiver mode.


The main project page it is here


Edward Appleton discovered the electrical characterization of ionospheric propagation subsequent to transmission experiments over the Atlantic Ocean made by  Guglielmo Marconi from England to Canada, Appleton was able to show that the ionosphere was not formed by only one conducting layer, but several distinct ones. By comparing the relative delays of ground waves and the sky wave reflected in the ionosphere, an estimation of the layers altitude could be calculated.

The Ionosphere

The ionosphere extends from about 50km altitude to about 600km where it merges with near Earth space environment. The ionosphere is created by radiation, both electromagnetic and particles coming from the sun which ionise the Earth’s upper atmosphere into free electrons and ions. The reason the free electrons persist in the ionosphere is that at these altitudes the density of the Earth’s neutral atmosphere is sufficiently thin that collisions between particles happen far less frequently than in the lower atmosphere.

The degree of ionization in the atmosphere varies with altitude in a non-uniform way. In the lower part of the Earth’s atmosphere, the troposphere extends from the surface to about 12 km. Above 12 km is the stratosphere followed by the mesosphere. At these altitudes there are plenty of molecules available, but most of the energy has already been absorbed by the time the ionizing radiation from the sun reaches these altitudes.

The ionosphere is composed of three main parts, named : the D, E, and F regions. The electron density is highest in the upper, or F region. The F region exists during both daytime and nighttime. During the day it is ionized by solar radiation, during the night by cosmic rays. The D region disappears during the night compared to the daytime, and the E region becomes weakened


The density of the electrons varies with altitude in counter balance between varying wavelengths or energies from electromagnetic and particle radiation originating from the Sun and its activities . In addition, there are also diurnal and seasonal effects. The activity of the sun is associated with the sunspot cycle, where more active sunspots usually indicate higher radiation density. There are also mechanisms such as solar flares that disrupt and decrease the ionization. Solar flares are associated with release of charged particles into the solar wind that reaches the Earth and interacts with the geomagnetic field. Other factors that complicate the environment are the motion of the neutral atmosphere, but also the magnetic and electric currents interacting with the ionized particles.


The ionosphere plays an important role in HF radio wave propagation. The different ionization layers or regions  influence radio waves propagation depending on elctron density of free electrons. Two types of ionosonde exist, Vertical and Oblique. Both vertical and oblique sounding work on the same basic principles and the main difference between these two techniques is the location of the transmitter with respect to the receiver, in this case we are using an Oblique ionogram.Obliquely propagating waves are gradually refracted as they travel trough an ionospheric layer with increasing electron density, making them more receptive for variations in the ionosphere.


With this technique it is possible to monitor large and  inaccessible areas, such as those covered by the seas or oceans. Through the study of the ionosphere and its real-time characterization, in conjunction with a worldwide network of research institutions, it was possible to re-create a detailed map of the current state ionospheric using ionograms :
The effect of propagation paths that involved multiple reflections from the ionosphere is
shown  by the separate curves.

We can see that the sounder it is divided in “hops”. From the spectrogram it’s possible to identify five separate “hops” between the frequencies 7-20 MHz in which probably all result from reflections with the Ionospheric  F-layer.

By looking at the frequency axis an operator can determine the available comminations bands and the wich one will be subject to  interference. In this spectrogram as an example, the  frequencies between 19-24MHz using a single reflection from the ionosphere would be available to a HF radio user to establish communications between Svalbard and Chilton. Between 13 to 15MHz would also available utilising a propagation route that involves two reflections from the ionosphere and one reflection from the ground. In principle between 7-11MHz would also be available using either two, three and four ionospheric reflection propagation. However because of the multiple routes available  the signals would suffer distortion from multipath interference and fading. (for more,  see Dr. Ruth Bamford Radio Communication Research Unit, Rutherford Appleton Laboratory – THE OBLIQUE IONOSPHERIC SOUNDER)

  In reality the ionosphere changes on a time scale that can be less than one minute. For our latitude (nort-west of Italy) we have decided to use Cyprus 2 wich has an intervall time of 300″ and a offset time of 240″. You will need to calculate the great circle distance between your location and cyprus (or any other ionosonde). Use this tool to do it .

Setting up Hardware 

For this project we have used three main piece of hardware :

  • A mini-pc with a Intel Core i3 CPU and 2 GB of RAM 64 bit
  • A USRP2 Unit using UHD 003.007.001 SD image
  • A Trimble GPS OCXO ( tested here )


The units are connected in this way  : The GPS unit output (10MHz and 1PPS are connected to the USRP2 ext clock input Ref. 10 MHz and 1PPS in) Then a straight ethernet cable was used to connect both the PC and the USRP2 using their 1Gb Ethernet ports.An outside  HF boradband antenna was added to the RX line of the USRP2.



I’ve used Ubuntu 13.10 but I presume you can use the latest version oh UHD,GNU Radio and Ubuntu to to the same work with Juha’s GNU Chirp version 1.24.

Installing dependences

If you will have to update sources site do :

#sudo sed -i -re 's/([a-z]{2}\.)?|' /etc/apt/sources.list
#sudo apt-get update

Dependencies required to install :

sudo apt-get -y install git-core autoconf automake libtool g++ python-dev swig \
 pkg-config libboost-all-dev libfftw3-dev libcppunit-dev libgsl0-dev \
 libusb-dev sdcc libsdl1.2-dev python-wxgtk2.8 python-numpy \
 python-cheetah python-lxml doxygen python-qt4 python-qwt5-qt4 libxi-dev \
libqt4-opengl-dev libqwt5-qt4-dev libfontconfig1-dev libxrender-dev 

Install UHD and the USRP2

Then you will need to install UHD drivers and images. I’ve used UHD 003.007.001

Install it with dpkg

$sudo dpkg -i UHD3.7.1.deb

For using it, you will need to find the same uhd-images to upload inside the USRP2 SD card. To do that you can do in two different way:

cd <install-path>/lib/uhd/utils
sudo ./ --dev=/dev/sd<XXX> --fpga=<path_to_fpga_image>
sudo ./ --dev=/dev/sd<XXX> --fw=<path_to_firmware_image>

Beware to burn it inside the SD , look at the  right device mounted  with:


For installation/informations about installing USRP2 please read the wiki on Ettus

* A Possible Ethernet  Problem on the USRP2

The UHD version 003.007.001 (and images) was  working fine with default ip address (, normally you should assign to the interface (eth0) a static IP address , for example and try to ping it.  The first time i’ve tried with an old veriosion of the UHD image (don’t remember wich one) i burnt it  inside the SD, but  had some problems  to find the device (with the command uhd_find_devices ) and even with sending a simple ICMP packet . I did not received any packet , so i decided to capture a session using Wireshark :


It was just sending out boradcast ARP request, and even with #arp -na command i wa unable to see the NIC MAC of the USRP2 Ethernet adapter or any layer 2 address. .Maybe that version of the USRP2 was old and using a RAW ethernet packet instead of the normal UDP header , wich you can see here in a normal full duplex communication : (the default IP was changed)


Unfortunately i did not have a MIMO cable with me to monitor the serial output, if you have any idea why  did not worked  and how to solve this problem with old firmware version please send me an email or contact me by wordpress form.

Install GNURadio

As i wrote before, i’ve used , with Ubuntu 13.10 GNURadio version 3.7.1 wich you can download here

Install GNURadio with :

$sudo apt-get install cmake (required)
$tar -zxvf gnuradio-3.7.1.tar.gz
$cd gnuradio
$mkdir build
$sudo cmake ../
$make test
$sudo make install clean
$sudo ldconfig

Install Anaconda Python

Anaconda Python it is a great tool ! Anaconda indeed includes over 100 of the most popular Python, R and Scala packages for data science. Download it from here and install with :


Install GCS

This will install all matplot lib and scipy needed for a lot of applications other than just GNU Chirp. Now, install GNUChirp , download it from here

And install it with :

$cd (source)
$make install

The software it is divided in two parts. All the scripts in python are in the ~/gr-juha/apps/chirpsounder$ directory . it is the recording scripts. It will need admin privilages to start and it will create the data directory in /data1/ch0/  writing new dirs each day with *.out file captured from the device. it is the configuration file. Here you can modify it to edit some important parameters such as chirp time, chirp interval time , sample rate etc and minimum/maximum distance from the target . For Cyprus2 chirp, the interval time it is of 300″ while the chirp offset is 240 sec (to be precise 239,912517) . You can use this configuration :

sounders = [[{'rep':300,'chirpt':240,'name':'cyprus','rate':0.1e6,'dur':250, 'cf':15e6,'rmin':2000,'rmax':7000.0,'fmin':4.0,'fmax':25.0}]]

You will need now two important things . 1) Resize the packet size limit with sysctl and 2) shutting down the ntp daemon to provide script access  to ntpdate command to it just type :

$sudo sysctl -w net.core.rmem_max=1000000000

$sudo sysctl -w net.core.wmem_max=1048576

$sudo service ntp stop

Another important file it is wich it is the program that will transform the *.out raw file in a PNG file plotting the resultant inside the same directory. fFor convenience, Juha wrote it so the program will  plot the output using second-last file inside the output directory. This it is good in case you want to automate the process, so it will always read a complete recording and not an on-going one. Instead, if you need a fast correlation you can modify slightly the code so it will force to read thevery last one. Edit and change those parameters from :

if len(cf)>1:
 for f in cf[0:(len(cf)-1)]:


if len(cf)>0:
 for f in cf[0:(len(cf)-0)]:

This script will calculate and   plot the PNG files using the standard directory inside it wich you can find at the bottom part of the code :

parser.add_option("-d", "--dirname",dest="dirname", action="store", type="string",
 help="Data directory (Default /ch0/chirp/2016.05.12).")

if you want to use it in a automated process you will need to modify the date dir that it is creating. You can do two things here : you can edit to point inside a single directory or, as i’ve done here , you can easly let it read just the last directory used by script. To do it, i   modified  the code  adding this variables to script

directory = ('/data1/ch0/')
workdir = max(glob.glob(os.path.join(directory, '*/')), key=os.path.getmtime)


parser.add_option("-d", "--dirname",dest="dirname", action="store", type="string",
 help="Data directory (Default workdir")

another useful  tip, since the software it using Unix Time, it is to have plotted normal time in human like format. To do it , always on script add the datetime library with

import datetime

Then add this variable  and modify plt.title(f) with the other string

now =


This is the final result :


If you have problems with “D” packets overflow  you can try this solution i’ve proposed .


2 thoughts on “Setting up an amateur Ionogram Monitoring station

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s