The personal website of Scott W Harden

Display large Images with Scrollbars with Python, Tk, and PIL

__I wrote a program to display extremely large images in Python using TK. __It’s interesting how simple this program is, yet frustrating how long it took me to figure out.

This little Python program will load an image (pretty much any format) using the Python Imaging Library (PIL, which must be installed) and allows you to see it on a scrollable canvas (in two directions) with Tkinter and ImageTk. The above screenshot is of the program viewing the image below:

What is that image? I won’t get ahead of myself, but it’s about 5kHz of audio from 10.140mHz which includes a popular QRSS calling frequency. The image displays an hour of data. My ultimate goal is to have it scroll in the TK window, with slide-adjustable brightness/contrast/etc.

from Tkinter import *
import Image, ImageTk

class ScrolledCanvas(Frame):
     def __init__(self, parent=None):
          Frame.__init__(self, parent)
          self.master.title("Spectrogram Viewer")
          self.pack(expand=YES, fill=BOTH)
          canv = Canvas(self, relief=SUNKEN)
          canv.config(width=400, height=200)

          sbarV = Scrollbar(self, orient=VERTICAL)
          sbarH = Scrollbar(self, orient=HORIZONTAL)



          sbarV.pack(side=RIGHT, fill=Y)
          sbarH.pack(side=BOTTOM, fill=X)

          canv.pack(side=LEFT, expand=YES, fill=BOTH)


Simple DIY Stealth Apartment Antenna for HF

I don’t want to spend lots of money for a HF antenna, and even if I did my apartment complex wouldn’t allow it! This is my story, and while I’m no expert I hope that sharing my experience will help encourage others to try crazy things in the spirit of invention. A friend loaned me a Century 21 HF CW-only transceiver which puts out ~20W. As far as an antenna, I was limited to what I could build. I tried a bunch of different designs, including a trash-brew 40m base-loaded vertical, but it didn’t work that well. I found that a “contorted dipole” (I heard it’s officially called a zig-zag design) strung up on my ceiling works surprisingly well. I’ve only had it up a few days, but from Florida I’ve communicated with New York on 40m at 20W and Maine on 20m using 20W. Keep in mind that I’m brand new to CW, and that 90% of the conversations out there are way too fast for me to copy, so my greatest limitation is finding a CQ slow enough that I can respond to it.

The beauty of this antenna is four-fold. First, it’s cheap (a few bucks worth of parts). Second, it’s off the floor and out of the way (unlike my vertical antenna designs). Third, it doesn’t require a tuner to operate once it’s set up. Forth, it’s virtually invisible! Seriously, if you walk in my apartment you’d have no idea it’s there unless someone points it out.

So, will this fly for you? That’s between you and your XYL. Measurements are similar to regular dipoles (approx. quarter wavelength per leg), but I cut these long and used an antenna tuner to shorten them until I reached a 1:1 SWR. Once the SWR was set, I returned my borrowed antenna analyzer and the resulting antenna network seems pretty stable!

The physical assembly involved a package of ceiling-mount (screw-type) plant hooks and a couple packages of 50’ of picture hanging wire from Target (a few bucks total). The coax to the radio is pretty straightforward. Just a short patch of cable running up to the ceiling, then the shield goes one direction (to the 3 ground wires) and the center wire goes in the other direction (to the antenna elements). Both antennas are permanently soldered together, which is fine because SWR stays low and I don’t have to jumper things around when I want to change bands.

Don’t get confused by those coils! They’re not used for the antenna!!! They’re just there to help weigh down the wire to prevent it from wobbling due to the AC. Seriously, they do nothing, you don’t need them. They’re not even touching the antenna! Which reminds me, the two 20m radials were made from actual wire (because I had it lying around), so they’re coated in yellow. No biggie! No reason other than convenience that I didn’t use the picture hanging wire. Okay, that sums it up.

I hope this information helps! If you build a similar setup, let me know - I’d love to see it. If you have questions, feel free to email me. Remember, I didn’t put much math into this - I just went with approximately quarter wavelength legs and started cutting them until the SWR was down to 1:1, then I didn’t adjust it any more. It’s been several days and SWR seems stable, so no antenna analyzer is needed anymore. Good luck with your project, and with any luck I’ll work ya’ on the band. 73!

Convert Text to CW Morse Code with Linux

I wanted a way to have a bunch of Morse code mp3s on my mp3 player (with a WPM/speed that I decide and I found an easy way to do it with Linux. Rather than downloading existing mp3s of boring text, I wanted to be able to turn ANY text into Morse code, so I could copy something interesting (perhaps the news? hackaday? bash.org?). It’s a little devious, but my plan is to practice copying Morse code during class when lectures become monotonous. [The guy who teaches about infectious diseases is the most boring person I ever met, I learn nothing from class, and on top of that he doesn’t allow laptops to be out!] So, here’s what I did in case it helps anyone else out there…

Step 1: Get the Required Programs

Make sure you have installed Python, cwtext, and lame. Now you’re ready to roll!

Step 2: Prepare the Text to Encode

I went to Wikipedia and copy/pasted an ENTIRE article into a text file called in.txt. Don’t worry about special characters (such as " and * and #), we’ll fix them with the following python script.

import os
import time
f = open("out.txt")
raw = f.read()

cmd = """echo "TEST" | cwpcm -w 7 | """
cmd += """lame -r -m m -b 8 --resample 8 -q9 - - > text.mp3"""

i = 0
for chunk in raw.split("n")[5:]:
    if chunk.count(" ") > 50:
        i += 1
        print "nnfile", i, chunk.count(" "), "wordsn"
        do = cmd.replace("TEST", chunk).replace("text", "%02d" % i)
        print "running:", do,
        print "nnSTART ...",
        print "DONE"

Step 3: Generate Morse Code Audio

There should be a new file, out.txt, which is cleaned-up nicely. Run the following script to turn every paragraph of text with more than 50 words into an mp3 file…

import os
f = open("out.txt")
raw = f.read()
cmd = """echo "TEST" | cwpcm -w 13 | sox -r 44k -u -b 8 -t raw - text.wav"""
cmd += """; lame --preset phone text.wav text.mp3; rm text.wav"""
i = 0
for chunk in raw.split("n")[5:]:
    if chunk.count(" ") > 50:
        i += 1
        print i, chunk.count(" "), "words"
        os.system(cmd.replace("TEST", chunk).replace("text", "%02d" % i))

Now you should have a directory filled with mp3 files which you can skip through (or shuffle!) using your handy dandy mp3 player. Note that “-w 13” means 13 WPM (words per minute). Simply change that number to change the speed.

Good luck with your CW practice!

More Antenna Tinkering

Dental school is taking a lot of time away from me. I try my best to compartmentalize dental school into a chunk of my schedule (a massive chunk), trying to use the rest of the time to spend with my family (wife) and when she’s at work work on electronics (which seems to be radio these days). A few weeks ago I took the final amateur radio license exam and received my Amateur Extra license. It’s a bunch of technical questions about radio circuitry, antenna theory, and other random stuff. You can see what I mean by taking an online practice test! I applied for a new call sign (extra class operators can get shorter call signs). It seems the FCC gave me a VD. AJ4VD that is! Yes, my old call sign KJ4LDF has gone out the window as I am now AJ4VD! In Morse code, that’s .- .--- ....- ...- -..

I made my first Morse code contact from my apartment! This is the radio I’m using. It’s a Ten-Tec Century 21 HF CW transceiver which puts out ~30W. I’m using a super-cheap but surprisingly functional homebrew base-loaded vertical antenna. The main vertical element is quarter-inch copper pipe from Home Depot (a couple bucks) cut with 1’’ to spare from my 10ft ceiling. Therefore, it’s a less-than quarter-wave vertical element, requiring a tuning coil (variable inductor at the base)…

Here you can start to see the tuning coils. Briefly, I scraped a deep gash in the copper pipe such that a big glob of solder would adhere to it, and stuck a wire (yellow, coated) into that solder so it’s a good connection to the pipe. I then started wrapping the wire around a few toilet paper rolls [it’s all I could find at the time!] adding tap points (regions of exposed wire) every other turn. This functioned somewhat, but didn’t allow for fine-tuning (pun intended). I therefore scrapped the bottom half of the cardboard cylinder/coil and constructed a slightly more elegant solution…

That’s an Olvaltine container. Yeah, I know, “More chocolaty Olvaltine please!” I used a rotary tool to scrape some measured/templated gashes on each side to give the wire (picture frame hanging wire from Target, 50’ for $1.99) something to rest in. It turned out not to be enough, so I hot-glued the wire into the holes. This gives me a lot of exposed wire space to allow me to “tap” the coil wherever I want. By modifying where I clip onto the coil, I modify the length of wire in the coil that’s used, therefore modifying the inductance of the coil, allowing for some tuning capabilities. Although it has a narrow tuning range, using the current setup I’m able to get my SWR down to 1:1 on 40m (nice!).

I made a couple of contacts since I got the rig last night. First was K4KOR in central TN, who was calling CQ. I replied (slowly), and he came back to me (blazing fast Morse code). I was unable to copy ANYTHING he said (I’m not that good of an auditory decoder yet!) I’m sure he’s incredibly nice and it wasn’t intentional, but I had to give up the QSO. I know he copied my call, and I copied his, but I didn’t copy ANYTHING else he said. Does that count as my first contact? This morning I fired up the rig at 9:15 and heard W4HAY calling CQ from Northeast TN. I replied, stating that I’m new to CW so go slowly, and he was AMAZINGLY nice at sending me code at a snails pace. I was able to copy 90% of what he said, and will consider him my first solid contact!

QRSS and Life in Dental School

QRSS uses extremely simple radio transmitters at extremely low power to send an extremely slow Morse code message over an extremely large distance to extremely sensitive receivers which are extremely dependent on computers to decode. While you might be able to send a voice message across the ocean with ~100 watts of power, there are people sending messages with milliwatts! The main idea is that if you send the signals slow enough, and average the audio data (fast Fourier transformation) over a long enough time, weak signals below the noise threshold will stand out enough to be copied visually.

Without going into more detail than that, this is the kind of stuff I’ve been copying the last couple days. The image is a slow time-averaged waterfall-type FFT display of 10.140 MHz copied from a Mosley-pro 67 yagi mounted ~180 ft in the air connected to a Kenwood TS-940S transceiver. Red ticks represent 10 seconds. Therefore the frame above is ~10 minutes of audio. The trace on the image is from two different transmitters. The upper trace is from VA3STL’s QRSS quarter-watt transmitter from Canada described here and pictured below. The lower trace is from WA5DJJ’s QRSS quarter-watt transmitter in New Hampshire, described and pictured here.

I don’t know why I’m drawn to QRSS so much. Perhaps it’s the fact that it’s a hobby which only a handful of people have ever participated in. It uses computers and software, but unlike software-defined radio they don’t require complicated equipment, and a QRSS transmitter or receiver can be built from simple and cheap components.

__Argo: __There’s a popular QRSS “grabber” software for Windows called Argo. It dumps out screenshots of itself every few minutes which is nice, but it doesn’t assemble them together (which is annoying). I wrote a script to assemble Argo screen captures together as a single image. It’s a script for ImageJ.

makeRectangle(13, 94, 560, 320);
frames = nSlices();
newImage("long", "RGB White", (frames - 1) * 560, 320, 1);
for (i = 0; i < frames; i++)
    setSlice(i + 1);
    run("Select All");
    makeRectangle(i * 560, 0, 560, 320);

As far as life goes, I’m discovering that it’s not the attainment of a goal that gives me pleasure; it’s the pursuit of the goal. Perhaps that’s why I peruse hobbies which are difficult, and further challenge myself by doing things in weird, quirky ways. I’d love to experiment more with radio, but I don’t have much money to spend. Yeah, an all-band 100-watt HF/VHF/UHF rig would be nice, but I don’t want to spend hundreds of dollars on that kind of equipment… Maybe when I have a “real” job and stop being a student I’ll be in a better place to buy stuff like that. I built a cheap but surprisingly functional base-loaded vertical HF antenna for my apartment balcony (don’t worry neighbors, it’s taken inside after every use). It’s mainly for receive, but I don’t see any reason why it couldn’t be used for QRP transmitting.

__Yes, that’s an antenna made from copper pipe, wire, and toilet paper rolls. __I wound the wire around the base and created various tap points so it serves as a variable inductor depending on where I gator-clip the radio. Not pictured are 33’ radials running inside my apartment serving as grounding. The antenna feeds into a Pixie II direct conversion receiver / QRP transmitter which dumps its output to a laptop computer. I copied some PSK-31 transmissions from Canada with this setup. It works way better than a long / random wire antenna because it dramatically boosts signal-to-noise when tuned to the proper frequency.

UPDATE: VA3STL mentioned me on his site