In the end I've built on the excellent work by DJ0ABR.
I had trouble recording the 118 seconds of audio at a sample rate of 12000 samples per second as it produced buffer overruns. Instead I've used the rec command from sox to record at the native sample rate of the USB audio dongle and then convert the file using sox.
I've pretty much used the code and scripts as supplied, with some modest improvements here and there.
Source code for the decoder is from here. This is a fork of the original code which has gone and been integrated into wsjt-x. I have forked it here and added my versions of the record and decode script and the simpler crontab. I've fixed a few things and pushed those changes to my fork of the code so I'd recommend that as a starting point.
Here's some spots on wsprnet.org reported from the raspberry pi:
Install a library you'll need, and sox which I use for recording:
sudo apt-get install libfftw3-dev sox
In the directory with the Makefile, type "make" to build the software. Also do mkdir wav.
The USB audio dongle is a low cost one called "3D Sound". I found that it picked up lots of hum until a junkbox audio transformer was wired in line.
cat /proc/asound/cards
and then create /etc/asound.conf with following:
defaults.pcm.card 1
defaults.ctl.card 1
# set audio levels
alsamixer # graphical in terminal
To allow the pi user access to the audio devices:
sudo nano /etc/group
and add the sound group to the pi user. You'll need to log out and back in for this to take effect.
To test the recording you can record while showing a level meter like this:
arecord -vv -fdat test.wav
Press Control-C to end the recording.
There are two scripts: record and decode. record is called from a cron job every two minutes to record 118 seconds of audio, convert it and kick off decode.
I installed in /home/pi/wsprcan
Here's my version of record:
#!/bin/bash
# WSPR Audio Recorder Script by DJ0ABR
# record WSPR signal at every even minute
# called by cronjob
BASEDIR=/home/pi/wsprcan
# number of files in wav folder
cd ${BASEDIR}/wav
file_num=$(ls -1 --file-type | grep -v '/$' | wc -l)
cd ..
if [ "$file_num" -le "1" ] ; then
DT=$(date -u +"%y%m%d_%H%M")
RECFILE=${BASEDIR}/wav/wspr_${DT}.wav
echo recording to ${RECFILE}
#arecord -d 114 -f S16_LE -r 12000 -t wav ${RECFILE}
rec -V1 -c 1 -t wav ${RECFILE} trim 0 118 &>/dev/null
echo "converting sample rate..."
sox ${RECFILE} -r 12000 /tmp/out.wav
echo removing ${RECFILE}
rm ${RECFILE}
echo moving /tmp/out.wav to ${RECFILE}
mv /tmp/out.wav ${RECFILE}
echo "running decode on ${RECFILE}..."
./decode ${DT} &
fi
# WSPR Audio Recorder Script by DJ0ABR
# record WSPR signal at every even minute
# called by cronjob
BASEDIR=/home/pi/wsprcan
# number of files in wav folder
cd ${BASEDIR}/wav
file_num=$(ls -1 --file-type | grep -v '/$' | wc -l)
cd ..
if [ "$file_num" -le "1" ] ; then
DT=$(date -u +"%y%m%d_%H%M")
RECFILE=${BASEDIR}/wav/wspr_${DT}.wav
echo recording to ${RECFILE}
#arecord -d 114 -f S16_LE -r 12000 -t wav ${RECFILE}
rec -V1 -c 1 -t wav ${RECFILE} trim 0 118 &>/dev/null
echo "converting sample rate..."
sox ${RECFILE} -r 12000 /tmp/out.wav
echo removing ${RECFILE}
rm ${RECFILE}
echo moving /tmp/out.wav to ${RECFILE}
mv /tmp/out.wav ${RECFILE}
echo "running decode on ${RECFILE}..."
./decode ${DT} &
fi
Here's my version of decode:
# Script for the K9AN WSPR decoder, by DJ0ABR
# ===========================================
# use the k9an decoder to get the spots out of the wav sound file
# the file 'spots' is used for storing all the spots and debug information
# the file wsprd.out contains the current spots in the format for wsprnet.org
# wsprdsum.out is used as a temporary storage if the upload fails
MYCALL=VK2TPM
MYGRID=QF56OF
BASEDIR=/home/pi/wsprcan
echo decoding >> spots
echo "decoding: /home/pi/wsprcan/wav/wspr_${1}.wav"
./k9an-wsprd -f 14.0956 /home/pi/wsprcan/wav/wspr_${1}.wav >>spots
# the wav file is processed, delete it (it should be in a ram disk folder if an SD card is used !)
rm ${BASEDIR}/wav/wspr_${1}.wav
# check if spots are available
FILESIZE=$(stat -c%s "${BASEDIR}/wspr_spots.txt")
echo data size= $FILESIZE >> spots
if [ $FILESIZE -ne 0 ] ; then
# add the spots to a temporary file used for uploading to wsprnet.org
echo add to wsprdsum.out >> spots
cat ${BASEDIR}/wspr_spots.txt >> ${BASEDIR}/wsprdsum.out
# upload the spots
echo upload by curl >> spots
# ping helps curl to contact the DNS server under various conditions, i.e. if the internet connection was lost
ping -W 2 -c 1 wsprnet.org #> /dev/null;
curl -m 8 -F allmept=@${BASEDIR}/wsprdsum.out -F call=${MYCALL} -F grid=${MYGRID} http://wsprnet.org/meptspots.php > /dev/null;
RESULT=$?
# check if curl uploaded the data successfully
# delete only if uploaded
if [ $RESULT -eq 0 ] ; then
# data uploaded, delete them
echo Upload OK, deleting >> spots
rm wsprdsum.out
fi
echo curl result: $RESULT , done. >> spots
fi
# ===========================================
# use the k9an decoder to get the spots out of the wav sound file
# the file 'spots' is used for storing all the spots and debug information
# the file wsprd.out contains the current spots in the format for wsprnet.org
# wsprdsum.out is used as a temporary storage if the upload fails
MYCALL=VK2TPM
MYGRID=QF56OF
BASEDIR=/home/pi/wsprcan
echo decoding >> spots
echo "decoding: /home/pi/wsprcan/wav/wspr_${1}.wav"
./k9an-wsprd -f 14.0956 /home/pi/wsprcan/wav/wspr_${1}.wav >>spots
# the wav file is processed, delete it (it should be in a ram disk folder if an SD card is used !)
rm ${BASEDIR}/wav/wspr_${1}.wav
# check if spots are available
FILESIZE=$(stat -c%s "${BASEDIR}/wspr_spots.txt")
echo data size= $FILESIZE >> spots
if [ $FILESIZE -ne 0 ] ; then
# add the spots to a temporary file used for uploading to wsprnet.org
echo add to wsprdsum.out >> spots
cat ${BASEDIR}/wspr_spots.txt >> ${BASEDIR}/wsprdsum.out
# upload the spots
echo upload by curl >> spots
# ping helps curl to contact the DNS server under various conditions, i.e. if the internet connection was lost
ping -W 2 -c 1 wsprnet.org #> /dev/null;
curl -m 8 -F allmept=@${BASEDIR}/wsprdsum.out -F call=${MYCALL} -F grid=${MYGRID} http://wsprnet.org/meptspots.php > /dev/null;
RESULT=$?
# check if curl uploaded the data successfully
# delete only if uploaded
if [ $RESULT -eq 0 ] ; then
# data uploaded, delete them
echo Upload OK, deleting >> spots
rm wsprdsum.out
fi
echo curl result: $RESULT , done. >> spots
fi
Please replace VK2TPM with your call and grid square.
The crontab file:
# Start WSPR Recording at every even minute
*/2 * * * * /home/pi/wsprcan/record
To see what's going on you need local email. I installed postfix and mutt for this. There's a log file called spots that shows what's going on and any decodes:
decoding
0648 -15 -2.5 14.097089 -2 K6PZB CM88 37
0648 -20 -2.9 14.097099 -2 VK8ZI PH57 23
0648 -24 -2.7 14.097116 -2 KD6RF EM22 37
data size= 222
add to wsprdsum.out
upload by curl
Upload OK, deleting
curl result: 0 , done.
decoding
0650 -23 -2.6 14.097048 -2 K5XL EM12 33
0650 -20 -2.1 14.097072 -2 AL7Q BP40 37
0650 -19 -2.7 14.097158 -2 JA5NVN PM74 33
data size= 222
add to wsprdsum.out
upload by curl
Upload OK, deleting
curl result: 0 , done.
0648 -15 -2.5 14.097089 -2 K6PZB CM88 37
0648 -20 -2.9 14.097099 -2 VK8ZI PH57 23
0648 -24 -2.7 14.097116 -2 KD6RF EM22 37
data size= 222
add to wsprdsum.out
upload by curl
Upload OK, deleting
curl result: 0 , done.
decoding
0650 -23 -2.6 14.097048 -2 K5XL EM12 33
0650 -20 -2.1 14.097072 -2 AL7Q BP40 37
0650 -19 -2.7 14.097158 -2 JA5NVN PM74 33
data size= 222
add to wsprdsum.out
upload by curl
Upload OK, deleting
curl result: 0 , done.
So far I haven't used the ram disk but that's probably a good idea in the long term.
I also tried VisualWSPR which looks hopeful but crashed on startup for me.
No comments:
Post a Comment