Thursday, August 20, 2009

TH-F6A Radio Recorder using Mini-ITX

There's a few amateur satellites up in the sky that i'd like to listen to. The problem is that i'm usually neither awake nor home as they pass over. I could cart my radio and antenna around during the day but that's a pain and i'd get a lot of strange looks in the parking lot. I would probably also need a good excuse for being away from my desk for most of the day :-) Unfortunately, I can't be everywhere at once... But, I can surely program a machine to be there for me! Tonight, I hacked together a quick solution to the problem using the following:
  • an old mini-itx machine (EPIA1000)
  • my TH-F6A portable radio
  • the infamous arrow antenna
  • of course, the Python Programming Language
You can see the basic layout in the image below. I needed a way for getting the wav files off remotely, which is why you see the cicso NIC sticking out of the front. If you look closely, you can see a ton of scratches on the box. Believe it or not, I can't see any of these in person, the machine looks like it's been through a war in the photo!


Now, I needed a quick and effective way to record audio and store it off, pyaudio to the rescue! The code is not optimal in the sense that it waits until the end of the duration to writes the stream out to disk. I'm not very concerned about this as the LEO satellite passes are typically around 12 minutes and there's nothing else on the hard drive.

def record(filename, durationMinutes):

print 'recording for %s minutes' % (durationMinutes)
Format = pyaudio.paInt16
Chunk = 1024

Channels = 1
Rate = 44100
Seconds = 60 * durationMinutes
p = pyaudio.PyAudio()

stream = p.open(format = Format,
channels = Channels,
rate = Rate,
input = True,
frames_per_buffer = Chunk)

all = []
for i in range(0, Rate / Chunk * Seconds):
data = stream.read(Chunk)
all.append(data)

stream.close()
p.terminate()

data = ''.join(all)
wf = wave.open(filename, 'wb')
wf.setnchannels(Channels)
wf.setsampwidth(p.get_sample_size(Format))
wf.setframerate(Rate)
wf.writeframes(data)
wf.close()
I put in some smarts using datetime and threading that would kick off a recording session at a specific time. I then wrote a quick snippet to kick it off for a test. Above, you can see that my radio was tuned in to NPR (i'm not a huge fan of NPR, but the music is good now and then).

def scheduleRecording(outputFilename, datetimeStart, durationMins):

print 'scheduled recording to file: ', outputFilename
print 'at : ', str(datetimeStart)
print 'for %s minutes.' % (durationMins)

now = datetime.datetime.now()
waitSeconds = datetimeStart - now

t = threading.Timer(waitSeconds.seconds,record,kwargs={'filename':outputFilename,'durationMinutes':durationMins})
t.start()


if __name__ == '__main__':

filename = 'test.wav'
passTime = datetime.datetime(2009,8,20,22,30,0)

scheduleRecording(filename, passTime, 1)
The code is really rough but right now I just want it to work. It's Python after all, I can easily add a list of different file names, datetimes, etc... Now that this is ready, I need to find a sat pass to record. Ah, but wait! You're probably interested in seeing the final rig. Check it out below in all of its glory.


Now everything seems fine and dandy but that couldn't be further from the truth. Here's a few problems:

Problem 1- my HT is not programmable in real-time. This means that unless I manually put the radio in my hand and press buttons, I have no way of changing the frequency/tone/mode. No adjusting for doppler shift during the pass for this rig!!

Problem 2 - I do not have any sat tracking software installed, or own a rotator. As a result, my arrow will be sitting outside on an angle to catch what it can. Now, I do have a very nice camera tripod but with all the rain we've been getting lately, I have no way of protecting it.

This is a quick and dirty test bed that i'm going to be experimenting with for the next few days at least. A neat idea would be to leave it hooked up and record the LMARS net every evening and make the captures available in mp3 format! I may just do that.. . . But for now, it's off to find a satellite pass!

No comments: