USRP to MAP65

I wanted to use my USRP Software Defined Radio to monitor the whole 23cm EME band activity especially during moon bounce contests.

MAP65 expects IQ data in 96000 samples per second (sps) using  a stereo audio device as input. This input device can be a virtual audio cable  and this is what will be used below.

GNU-RADIO is used for rate conversion and streaming.

The USRP has a programmable data rate and its minimum is 250k so it cannot reach 96k without rate conversion. Conversion can be done multiplying first x 3 and then diving by 8 since 256*3/8= 96

After rate conversion there are 2 ways to send data to MAP65.

The easy way (“Solution 1”)  is to just send IQ data to a virtual audio device within GNU-RADIO. This works but sometimes there are some audio gaps and clicks

There is also another way (“Solution 2”)  One could send the IQ data over UDP datagrams. A python script outside of GNU-RADIO can take the UDP data stream and send it to the virtual audio device.  The second way resulted in clearly better audio

If you want to find out how install GNU-RADIO on Windows follow the link below.

How to install GNU-RADIO on Windows

Below both solutions will be described:

SOLUTION 1 : STREAM DIRECTLY TO THE VIRTUAL AUDIO DEVICE (EASY)

Put the following flow graph together, assign the Virtual Audio Cable to be the default sound device in Windows , leave the Device Name blank in Audio Sink  and you are done !

Note: Forgot to add a low pass filter between USRP and rational resampler. This is needed to avoid aliasing . Need to update picture below

USRP_TO_SOUNDCARD

SOLUTION 2 : STREAM OVER UDP AND USE A PYTHON SCRIPT TO SEND SAMPLES TO THE VIRTUAL AUDIO DEVICE

As in Solution 1 above, after some low -pass filtering, rate is converted to 96k. Then it is being sent over UDP.

USRP_to_UDP.grc

Some code was written (see below) in python to get the IQ data from the UDP stream and send it to a virtual audio device. MAP65 uses this virtual audio card as the input device.

As mentioned above, direct streaming to the virtual audio device within GNU-RADIO did not result in very clean audio but it was good enough for successful JT65 decodes.

On the other hand Solution 2 , resulted in clean FFT plots and there were no issues with gaps and clicks anymore.

Python script for Solution 2 can be found at the end of this page. Obviously, there must be a virtual audio cable installed for these solutions to work and referring to the code below the output_device_index should be set accordingly.

IMPORTANT : JT65 RECEPTION REQUIRES A TCXO , BUT USRP1 COMES WITH A SIMPLE DRIFTING CRYSTAL OSCILLATOR

I had to replace the 64 MHz oscillator in the USRP with a suitable 64 MHz TCXO.  Luckily I found one on ebay .

Edited by

Michael Margaras, SV1CAL

#Written by Michael Margaras-SV1CAL
#March 2014
import pyaudio
import wave
import sys
import time
import struct
from struct import *
CHUNK=32768

p = pyaudio.PyAudio()

count = p.get_device_count()
devices = []
for i in range(count):
    devices.append(p.get_device_info_by_index(i))

for i, dev in enumerate(devices):
    print “%d – %s” % (i, dev[‘name’])

FORMAT=pyaudio.paFloat32
CHANNELS=2
RATE=96000

input_device_index=0
output_device_index=5
dst = p.open(format = FORMAT,channels = CHANNELS,rate = RATE,output = True,output_device_index = output_device_index,frames_per_buffer = CHUNK)
import socket
UDP_IP = “127.0.0.1”
UDP_PORT = 50024
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
sock.bind((UDP_IP, UDP_PORT))
while True:   
    data, addr = sock.recvfrom(CHUNK)
    dst.write(data)

Leave a Reply

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

WordPress.com Logo

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

Facebook photo

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

Connecting to %s

%d bloggers like this: