Category Archives: Amateur Radio

An Arduino powered IBM PS/2 Morse Keyboard

I’ve been trying to do a bit more Arduino programming and interfacing lately. Nothing too difficult, but just trying to expand my junkbox and my skills so that I can quickly prototype new ideas and expand the kind of projects that I can tackle in the limited time that I seem to have for playing around.

I have written programs to use an Arduino to blink or beep Morse code before, but the programs were meant to control beacons, where they might just send the same message over and over, which I just compiled into the program. Today’s experiment did two things: it reads and buffers keystrokes from an old IBM PS/2 keyboard which I rescued from exile in my garage, and it actually keys my ham radio transmitter (a Yaesu FT-817ND) using a 4N31 optoisolator.

Most keyboards that you get today are interfaced via the Universal Serial Bus (USB). That’s kind of cool, but it’s also a bit of a travesty, since they require a lot more code (and a lot more knowledge) to interface what is ultimately a pretty simple device. Back in the old IBM AT days, keyboards were equipped with a large 5 pin DIN connector, and would transmit “scan codes” represent each character along a simple serial bus. The IBM PS/2 shrunk the connector to a six pin mini-DIN connector, but retained almost all the other features.

But if you want to do a tidy job, you’ll need some extra bits and pieces to hook them to your Arduino. Luckily, Sparkfun has a couple of cheap bits that will make it easy. I ordered some 6 pin MiniDIN connectors from them, along with a tiny $0.95 breakout board which you can tack together along with some header pins to make a little breadboard friendly connector. You need four connections: 5V, ground, and a clock and data line, which I connected to pins 3 and 4 on my Arduino.

You’ll also need a library. Yes, you could roll your own, but that would have added hours to this simple project. Instead, I chose this one, more or less at random from a number of possibilities. It seemed to work fine, and compiled properly even with my Arduino 1.0 setup. The code actually comes from the guys who make the Teensy, but the code works fine on regular Arduinos.

Then, I wrote the code. I wanted the user to be able to type ahead of the sending, so I needed to implement a ring buffer to store chars (currently up to 128) which I coded up from scratch in the simplest way possible. The way I used to do Morse sending was to set the output pin to be HIGH, then delay(), then set it to LOW. But we want to process new keystrokes and add them to the buffer as soon as you can. So, I implemented my own “delay” function, which loops to find new characters and inserts them in the buffer while waiting for the timeout. This seems to work pretty well.

Without further explanation, here’s the code:

[sourcecode lang=”cpp”]
#include <PS2Keyboard.h>

// _____ _ _ _ _ __ __
// |_ _| |_ ___ /_\ _ _ __| |_ _(_)_ _ ___ | \/ |___ _ _ ___ ___
// | | | ‘ \/ -_) / _ \| ‘_/ _` | || | | ‘ \/ _ \ | |\/| / _ \ ‘_(_-</ -_)
// |_| |_||_\___| /_/ \_\_| \__,_|\_,_|_|_||_\___/ |_| |_\___/_| /__/\___|
//
// _ __
// | |/ /___ _ _ ___ _ _
// | ‘ </ -_) || / -_) ‘_|
// |_|\_\___|\_, \___|_|
// |__/
//
// Version for the PS2 Keyboard
// using the library from http://www.pjrc.com/teensy/td_libs_PS2Keyboard.html
//
// Written by Mark VandeWettering K6HX
//
// This is just a quick Morse keyer program.
//

////////////////////////////////////////////////////////////////////////
//
// Here is a queue to store the characters that I’ve typed.
// To simplify the code, it can store a maximum of QUEUESIZE-1 characters
// before it fills up. What is a byte wasted between friends?
//
////////////////////////////////////////////////////////////////////////

#define QUEUESIZE (128)
#define QUEUEMASK (QUEUESIZE-1)

int aborted = 0 ;
int qhead = 0 ;
int qtail = 0 ;
char queue[QUEUESIZE] ;

void
queueadd(char ch)
{
queue[qtail++] = ch ;
qtail &= QUEUEMASK ;
}

void
queueadd(char *s)
{
while (*s)
queueadd(*s++) ;
}

char
queuepop()
{
char ch ;
ch = queue[qhead++] ;
qhead &= QUEUEMASK ;
return ch ;
}

int
queuefull()
{
return (((qtail+1)%QUEUEMASK) == qhead) ;
}

int
queueempty()
{
return (qhead == qtail) ;
}

void
queueflush()
{
qhead = qtail ;
}

////////////////////////////////////////////////////////////////////////

int pin = 13 ; // blink the LED for now…
int tpin = 10 ; // tone pin

#define WPM (20)
int ditlen = 1200 / WPM ;

PS2Keyboard kbd ;

inline void
ps2poll()
{
char ch ;
while (kbd.available()) {
if (queuefull()) {
Serial.print("") ;
} else {
switch (ch=kbd.read()) {
case ‘\033’:
queueflush() ;
Serial.flush() ;
Serial.println("== FLUSH ==") ;
aborted = 1 ;
break ;
case ‘%’:
queueadd("CQ CQ CQ DE K6HX K6HX K6HX K\r\n") ;
break ;
default:
queueadd(ch) ;
break ;
}
}
}
}

void
mydelay(unsigned long ms)
{
unsigned long t = millis() ;
while (millis()-t < ms)
ps2poll() ;
}

#define FREQ (700)

void
scale()
{
long f = 220L ;
int i ;

for (i=0; i<=12; i++) {
tone(tpin, (int)f) ;
f *= 1059L ;
f /= 1000L ;
Serial.println(f) ;
delay(300) ;
}
noTone(tpin) ;

}

void
dit()
{
digitalWrite(pin, HIGH) ;
tone(tpin, FREQ) ;
mydelay(ditlen) ;
digitalWrite(pin, LOW) ;
noTone(tpin) ;
mydelay(ditlen) ;

}

void
dah()
{
digitalWrite(pin, HIGH) ;
tone(tpin, FREQ) ;
mydelay(3*ditlen) ;
digitalWrite(pin, LOW) ;
noTone(tpin) ;
mydelay(ditlen) ;
}

void
lspace()
{
mydelay(2*ditlen) ;
}

void
space()
{
mydelay(4*ditlen) ;
}

void
setup()
{
pinMode(pin, OUTPUT) ;
pinMode(tpin, OUTPUT) ;
Serial.begin(9600) ;
kbd.begin(4, 3) ;
Serial.println("Morse Code Keyboard by K6HX") ;
}

////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////

char ltab[] = {
0b101, // A
0b11000, // B
0b11010, // C
0b1100, // D
0b10, // E
0b10010, // F
0b1110, // G
0b10000, // H
0b100, // I
0b10111, // J
0b1101, // K
0b10100, // L
0b111, // M
0b110, // N
0b1111, // O
0b10110, // P
0b11101, // Q
0b1010, // R
0b1000, // S
0b11, // T
0b1001, // U
0b10001, // V
0b1011, // W
0b11001, // X
0b11011, // Y
0b11100 // Z
} ;

char ntab[] = {
0b111111, // 0
0b101111, // 1
0b100111, // 2
0b100011, // 3
0b100001, // 4
0b100000, // 5
0b110000, // 6
0b111000, // 7
0b111100, // 8
0b111110 // 9
} ;

void
sendcode(char code)
{
int i ;

for (i=7; i>= 0; i–)
if (code & (1 << i))
break ;

for (i–; i>= 0; i–) {
if (code & (1 << i))
dah() ;
else
dit() ;
}
lspace() ;
}

void
send(char ch)
{

if (isalpha(ch)) {
if (islower(ch)) ch = toupper(ch) ;
sendcode(ltab[ch-‘A’]) ;
} else if (isdigit(ch))
sendcode(ntab[ch-‘0’]) ;
else if (ch == ‘ ‘ || ch == ‘\r’ || ch == ‘\n’)
space() ;
else if (ch == ‘.’)
sendcode(0b1010101) ;
else if (ch == ‘,’)
sendcode(0b1110011) ;
else if (ch == ‘!’)
sendcode(0b1101011) ;
else if (ch == ‘?’)
sendcode(0b1001100) ;
else if (ch == ‘/’)
sendcode(0b110010) ;
else if (ch == ‘+’)
sendcode(0b101010) ;
else if (ch == ‘-‘)
sendcode(0b1100001) ;
else if (ch == ‘=’)
sendcode(0b110001) ;
else if (ch == ‘@’) // hardly anyone knows this!
sendcode(0b1011010) ;
else
return ; // ignore anything else

if (!aborted) {
Serial.print(ch) ;
if (ch == 13) Serial.print((char) 10) ;
}
aborted = 0 ;
}

////////////////////////////////////////////////////////////////////////

void
loop()
{
ps2poll() ;

if (!queueempty())
send(queuepop()) ;
}
[/sourcecode]

To key the transmitter, I used a 4N31 optoisolator. This code uses pin 13 to key the transmitter, so I wired it to pin 1 on the optoisolator, passing through a 1K current limiting resistor, and pin 2 ground. Pins 4 and 5 are wired to the tip and shield of a 3.5mm socket, which I then connected to the FT-817 key input using a 3.5mm stereo cable I had lying around. I could have used a little NPN transistor to do the keying, but the optoisolator keeps any current from the radio from circulating in the Arduino (and vice versa) which is a nice little insurance that nothing will zap either my radio or my microcontroller.

Here’s the resulting project:



Feel free to drop me a line if you find this code to be useful. Let me know how you adapted it to do something cool in your shack or lab.

Addendum: Friends Atdiy and Whisker of the tymkrs empire made a similar project a while ago, except that they used a board based upon a Propeller board, which does a lot of what my project does as well. If you like the Propeller instead (and if you’ve been following my blog and reading about WA0UWH’s beacon, why wouldn’t you?) you might check out their video:



Hellduino: Sending Hellschreiber from an Arduino

Update: Welcome Hack-a-day readers! If you are looking for the schematics for this “transmitter” (really just a simple oscillator, send some love to radio guru Steve Weber over at his website. You could really use any oscillator you like, even a canned oscillator (although the square waves would generate lots of harmonics).

Yesterday’s project coupled a simple Colpitt’s oscillator (snipped from Steve Weber, KD1JV) with an Arduino. Steve used it to send temperature telemetry in Morse code back to his shack from an outdoor thermometer. But I thought that something else could be done: sending telemetry in Hellschreiber.

Hellschreiber is an early type of facsimile teleprinter system developed in the 1920s, which has enjoyed a certain amount of popularity in the amateur radio community. It sends characters using a conventional on-off keyed transmitter, just like Morse, but instead of sending dots and dashes of different lengths, it scans characters left to right, and top to bottom, and keys the transmitter on where each letter is “on”. Thus, a Morse transmitter can be modified pretty simply to send Hellschreiber.

So I did.


Here are some details. Hellschreiber is normally defined as sending characters defined on a 7×7 matrix, at 122.5 dots (2.5 characters) per second. But the actual font is actually defined on a 7×14 matrix. To keep the bandwidth of the signal down, the font doesn’t ever define a character that requires turning single dots on or off: the minimum signal changes are two dots long. These “half dots” are sent at 245 baud, or about 4.08ms per dot. Because I needed to account for the time spent looking up the character, I tuned that down to about 4.045ms. I was concerned that because I was keying the oscillator on and off, the startup time (which I estimated at about 2ms) could be a problem, but I suspect the shutdown time is about 2ms as well, so the overall system works better than you might imagine. The startup and shutdown keying waveforms are a bit erratic though, and the bandwidth of the signal is probably too wide. I think a better way to do this would be to build an oscillator that runs continuously, and then key a buffer amp with a filtered pulse to keep the bandwidth low. But for a 500 microwatt transmitter (estimated, and represents power going into the antenna, not radiated) it probably works just fine.

Here’s the source code:

[sourcecode lang=”cpp”]

int radioPin = 13 ;

typedef struct glyph {
char ch ;
word col[7] ;
} Glyph ;

Glyph glyphtab[] PROGMEM = {
{‘ ‘, {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}},
{‘A’, {0x07fc, 0x0e60, 0x0c60, 0x0e60, 0x07fc, 0x0000, 0x0000}},
{‘B’, {0x0c0c, 0x0ffc, 0x0ccc, 0x0ccc, 0x0738, 0x0000, 0x0000}},
{‘C’, {0x0ffc, 0x0c0c, 0x0c0c, 0x0c0c, 0x0c0c, 0x0000, 0x0000}},
{‘D’, {0x0c0c, 0x0ffc, 0x0c0c, 0x0c0c, 0x07f8, 0x0000, 0x0000}},
{‘E’, {0x0ffc, 0x0ccc, 0x0ccc, 0x0c0c, 0x0c0c, 0x0000, 0x0000}},
{‘F’, {0x0ffc, 0x0cc0, 0x0cc0, 0x0c00, 0x0c00, 0x0000, 0x0000}},
{‘G’, {0x0ffc, 0x0c0c, 0x0c0c, 0x0ccc, 0x0cfc, 0x0000, 0x0000}},
{‘H’, {0x0ffc, 0x00c0, 0x00c0, 0x00c0, 0x0ffc, 0x0000, 0x0000}},
{‘I’, {0x0ffc, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}},
{‘J’, {0x003c, 0x000c, 0x000c, 0x000c, 0x0ffc, 0x0000, 0x0000}},
{‘K’, {0x0ffc, 0x00c0, 0x00e0, 0x0330, 0x0e1c, 0x0000, 0x0000}},
{‘L’, {0x0ffc, 0x000c, 0x000c, 0x000c, 0x000c, 0x0000, 0x0000}},
{‘M’, {0x0ffc, 0x0600, 0x0300, 0x0600, 0x0ffc, 0x0000, 0x0000}},
{‘N’, {0x0ffc, 0x0700, 0x01c0, 0x0070, 0x0ffc, 0x0000, 0x0000}},
{‘O’, {0x0ffc, 0x0c0c, 0x0c0c, 0x0c0c, 0x0ffc, 0x0000, 0x0000}},
{‘P’, {0x0c0c, 0x0ffc, 0x0ccc, 0x0cc0, 0x0780, 0x0000, 0x0000}},
{‘Q’, {0x0ffc, 0x0c0c, 0x0c3c, 0x0ffc, 0x000f, 0x0000, 0x0000}},
{‘R’, {0x0ffc, 0x0cc0, 0x0cc0, 0x0cf0, 0x079c, 0x0000, 0x0000}},
{‘S’, {0x078c, 0x0ccc, 0x0ccc, 0x0ccc, 0x0c78, 0x0000, 0x0000}},
{‘T’, {0x0c00, 0x0c00, 0x0ffc, 0x0c00, 0x0c00, 0x0000, 0x0000}},
{‘U’, {0x0ff8, 0x000c, 0x000c, 0x000c, 0x0ff8, 0x0000, 0x0000}},
{‘V’, {0x0ffc, 0x0038, 0x00e0, 0x0380, 0x0e00, 0x0000, 0x0000}},
{‘W’, {0x0ff8, 0x000c, 0x00f8, 0x000c, 0x0ff8, 0x0000, 0x0000}},
{‘X’, {0x0e1c, 0x0330, 0x01e0, 0x0330, 0x0e1c, 0x0000, 0x0000}},
{‘Y’, {0x0e00, 0x0380, 0x00fc, 0x0380, 0x0e00, 0x0000, 0x0000}},
{‘Z’, {0x0c1c, 0x0c7c, 0x0ccc, 0x0f8c, 0x0e0c, 0x0000, 0x0000}},
{‘0’, {0x07f8, 0x0c0c, 0x0c0c, 0x0c0c, 0x07f8, 0x0000, 0x0000}},
{‘1’, {0x0300, 0x0600, 0x0ffc, 0x0000, 0x0000, 0x0000, 0x0000}},
{‘2’, {0x061c, 0x0c3c, 0x0ccc, 0x078c, 0x000c, 0x0000, 0x0000}},
{‘3’, {0x0006, 0x1806, 0x198c, 0x1f98, 0x00f0, 0x0000, 0x0000}},
{‘4’, {0x1fe0, 0x0060, 0x0060, 0x0ffc, 0x0060, 0x0000, 0x0000}},
{‘5’, {0x000c, 0x000c, 0x1f8c, 0x1998, 0x18f0, 0x0000, 0x0000}},
{‘6’, {0x07fc, 0x0c66, 0x18c6, 0x00c6, 0x007c, 0x0000, 0x0000}},
{‘7’, {0x181c, 0x1870, 0x19c0, 0x1f00, 0x1c00, 0x0000, 0x0000}},
{‘8’, {0x0f3c, 0x19e6, 0x18c6, 0x19e6, 0x0f3c, 0x0000, 0x0000}},
{‘9’, {0x0f80, 0x18c6, 0x18cc, 0x1818, 0x0ff0, 0x0000, 0x0000}},
{‘*’, {0x018c, 0x0198, 0x0ff0, 0x0198, 0x018c, 0x0000, 0x0000}},
{‘.’, {0x001c, 0x001c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}},
{‘?’, {0x1800, 0x1800, 0x19ce, 0x1f00, 0x0000, 0x0000, 0x0000}},
{‘!’, {0x1f9c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}},
{‘(‘, {0x01e0, 0x0738, 0x1c0e, 0x0000, 0x0000, 0x0000, 0x0000}},
{‘)’, {0x1c0e, 0x0738, 0x01e0, 0x0000, 0x0000, 0x0000, 0x0000}},
{‘#’, {0x0330, 0x0ffc, 0x0330, 0x0ffc, 0x0330, 0x0000, 0x0000}},
{‘$’, {0x078c, 0x0ccc, 0x1ffe, 0x0ccc, 0x0c78, 0x0000, 0x0000}},
{‘/’, {0x001c, 0x0070, 0x01c0, 0x0700, 0x1c00, 0x0000, 0x0000}},
} ;

#define NGLYPHS (sizeof(glyphtab)/sizeof(glyphtab[0]))

void
encodechar(int ch)
{
int i, x, y, fch ;
word fbits ;

/* It looks sloppy to continue searching even after you’ve
* found the letter you are looking for, but it makes the
* timing more deterministic, which will make tuning the
* exact timing a bit simpler.
*/
for (i=0; i<NGLYPHS; i++) {
fch = pgm_read_byte(&glyphtab[i].ch) ;
if (fch == ch) {
for (x=0; x<7; x++) {
fbits = pgm_read_word(&(glyphtab[i].col[x])) ;
for (y=0; y<14; y++) {
if (fbits & (1<<y))
digitalWrite(radioPin, HIGH) ;
else
digitalWrite(radioPin, LOW) ;

delayMicroseconds(4045L) ;
}
}
}
}
}

void
encode(char *ch)
{
while (*ch != ‘\0’)
encodechar(*ch++) ;
}

void
setup()
{
Serial.begin(9600) ;
pinMode(radioPin, OUTPUT) ;
}

void
loop()
{
encode("K6HX QTH CM87UX TMP 72F PWR 500 MICROWATTS ") ;
}
[/sourcecode]

Let me know if you use this project for anything!

Late night pondering about the micro-power Morse beacon…

Before toddling off to bed last night, I did a bit more tinkering, and a bit of thinking, and then a bit of research.

The YouTube video I made showed that the spurious radiation from just attaching a clip lead from the oscillator to my oscilloscope gave enough signal to inject itself into my RFSpace SDRIQ software defined radio, even without any antenna attached. I hypothesized the signal should be stronger with my regular 40M dipole antenna, so I tested that, and sure enough, my FT-817 attached to the 40m dipole easily is S7, even without doing any antenna tuning. This suggests that for any application on my small property, I could reduce the power significantly (and use little/no antenna) and still have very legible signals.

I used a 3.68Mhz crystal because I have something like 200 of them (I bought them for something like $3 for a big bag) but that’s kind of a ham unfriendly frequency. While it’s not very likely for such a weak signal to propagate significantly at the power levels we are talking about, but it’s perhaps possible that someone within a radius of a mile or so might be able to hear it, and be annoyed. Steve Weber used 4Mhz crystals, which are at the edge of the 80m band, and probably less well trafficked. A good, friendly idea.

Last, I was trying to understand what the regulations actually say about legal Part 15 operation. The regulations allow for experimenters to build five transmitters of this type for experimentation. On the 80m, you are suppose to keep the average field strength at just 15 microvolts per meter at a distance of 30m. Working through the approximations presented in Understanding the FCC Regulations for Low-Power, Non-Licensed Transmitters, this suggests that the product of power and antenna gain should be less than 6.6E-8 or so. While I know the input power, I don’t know how to measure (or estimate) either the output power or the antenna gain. Can anyone point me at a reference which shows how I might calculate the properties of a small 6″ long stub antenna at 4Mhz or so? I know it’s mostly an academic exercise, but it’d be nice to know the rough limits are, and the FCC regulations for Part 15 do say that we are supposed to “employ good engineering practices in order to ensure compliance with Part 15 standards”.

One final thing: as you can see from the oscilloscope, the output is far from a clean sine wave. It’s not horrible, but I was able to detect it at 2x and 3x the carrier frequency. The obvious thing would be to design a filter to clean it up, but most filter designs assume a 50 ohm (or thereabouts) output load, which this clearly doesn’t have. Is that a problem?

A micro-power Arduino Morse radio beacon

My G0UPL QRSS beacon is working pretty well, but is only putting out about 40mw of power, when it probably should be putting out 100mw. I was pondering oscillators in general, and (as I do often) surf for information and inspiration. I found both on Steve “Melt Solder” Weber’s website, in the form of a ATtiny based Wireless Morse thermometer. It was just a cool little circuit, so I tossed it together on a corner of my breadboard.

Works pretty well! I simulated the circuit using LTSpice before I built it, and found that it takes about 2ms for the oscillator to stabilize after powering down. At 12 wpm, each dit lasts 100ms, so it’s pretty clear that you can do a reasonable job of sending morse at pretty much any speed that most humans can use. To test the oscillator, I hooked up a pair of new D cells which were measured at 3.42 volts, and the current draw was a miserly 0.461 milliamperes for a maximum input power of around 1.5mw. The Arduino can supply 20ma, so it’s pretty obvious that you can drive this oscillator directly from an output pin. So, I used the Morse code sketch that I wrote a couple of years ago and voila! Instant beacon.

Regarding the legality, without any antenna, the effective radiated power of this antenna is incredibly low. I haven’t done any analysis of the circuit to state categorically that it falls inside the restrictions of Part 15 wireless devices, but I’d be shocked if it didn’t.

Oscillator with super low supply voltage

I’m beginning to correct some of my misunderstandings re: JFETs and for some reason, oscillators are beginning to become something that I think of as interesting, particularly at very low voltages. Without comment, and for future perusal, I just present this cool link, which shows oscillators which can run on very low voltages (just a few millivolts):

Oscillator with super low supply voltage

Seeing double on QRSS grabber…

Here is a snapshot from my QRSS grabber earlier today. You might want to click it to see it full size:

I’m curious: what phenomenon is causing the strong line doubling of the signals near the bottom? Note: not all the signals demonstrate this phenomenon, and it’s relatively rare, and commonly just fades away. Also note that the signal at the top does not show this line doubling. I suspect all the signals which are line doubled are in New Mexico.

Bonus question: I keep seeing a small wiggle like the one around 10.139975 or so, starting on 10 minute boundaries and lasting for about one minute. Anybody have any idea who that is?

On junkboxes…

I’ve recently begun to try to systematically (if somewhat erratically) equip my home office (it aspires to be a lab) with the necessary parts and tools that I need to assemble projects which interest me. The reason for this is simple: if you have the tools, material and space to do a project, you will much more likely do it than if you have to acquire all three specifically. If, for instance, you want to experiment with RF oscillators or amplifiers, if you have toroids, transistors, crystals, caps and resistors floating around, you can tack one together in just a few minutes. If you toss in some diodes, you can make some mixers. Maybe you want to have some ICs around, such as the LM386s. Toss in some speakers, jacks and the like, and voila: you are building radios.

When you are just starting, each additional part or tool that you “need” but don’t have is stumbling block: it halts your progress, and keeps you from the projects that you truly want to do. So, how do you get from where you are (presumably with nothing) and get to the point where you can build things than interest you?

Here are some simple, and somewhat obvious guidelines.

  • Take a long view. You might know someone who’s garage is stuffed full of cool stuff, and what you envision as highly complex and detailed projects just seem to flow effortlessly off his desk. As far as I know, nobody starts with such collections as they emerge from the womb, so at some point, they were where you are today. Don’t suffer any angst over your relative lack of equipment and expertise. Peter Norvig has an excellent essay on learning to program. People have the expectation (fueled by books with titles like Learn to Program in 21 Days) that programming is easy, and they should be able to become experts quickly. But research shows that it takes years to develop expertise. This is good: it means you can invest modestly in acquiring the tools and materials you need, gathering both simultaneously over time.
  • Invest in tools first, consumables second. Since we are taking a long view, it makes sense to invest in tools. After all, if it takes you ten years to acquire skills, chances are you are going to use those tools quite a bit. On the other hand, components and consumables will probably get used up in projects. Acquire them lazily, as you need them, or as you find them.
  • Consider economies of scale. Often ordering a dozen of a particular part is the same cost as just ordering two or three. As an extreme example: consider the lowly 2N3904 NPN transistor. If you buy these one at a time at Radio Shack, you’ll pay about $1.19 for one. Digikey will sell them for something like $.43 in quantity one, but are down to $.12 if you buy one hundred of them. If you go to companies like Tayda Electronics you can get them for just $0.01 a piece. Consider adding fairly bulk quantities of common components to stock your junk box.
  • Substitute for hard to find components. Most of the rehashed circuits that the ham radio magazines continue to republish seem to need air spaced variable capacitors, which are frankly getting harder and harder to get, and more expensive when you can. Keep an eye out for those components, but also consider making substitutions. Hans Summers made me aware of using LEDs and other diodes as varactors. Varactors are reasonably difficult to find, but LEDs are everywhere. If you dig around, you can find articles like this excellent one on how to design circuits around this idea.
  • Spend time researching and asking questions. It’s easy to spend money, it’s hard to save money. But if you spend some time doing research, you can often learn a lot, and therefore save a lot. DIg around. See what others have done. View everything through the lens of what skills and equipment you’d need to reproduce the same kind of projects that you see.

That’s the general background: in the next few days I’ll try to do a post of what items are making it into my junkbox. Stay tuned.

WA0UWH’s Propeller Beacon received at K6HX…

I could of days ago, I blogged about WA0UWH’s Propeller Beacon. Over the last couple of days, I worked on fixing a few small issues with my old beacon code, and have an experimental QRSS grabber up and running on qrss.info. And, what’s totally cool is that I’m hearing Eldon’s QRSS beacon, just over 700 miles away. Check the screen grab:

Eldon’s signal is the slant-Morse signal just about 1/3 of the way down (right around 10.140050). His signal starts with a propeller, and then has a series of slanted lines. Forward slashes are read as dots, and backward slashes as dashes. You can work out WA0UWH (easier on the signal near the right edge), followed by the letters WA. Pretty neat!

Other callsigns are AE5XI, NM7J, KD5SSJ, KC5EVR (I think) and WV5N, read from top to bottom. Early in the morning (around 4:00AM my time) I also received W0TJ and the flying W of Bruce, W1BW, but as yet I haven’t heard anything from our VK or ZL brethren down under. I’ll keep the grabber up for the rest of the week, perhaps down only intermittently to tweak the software, and then I’ll shift to transmit over the weekend with my G0UPL beacon.

Building a distributed satellite ground station network (or not…)

My twitter intro says that I am an “enthusiast for enthusiasm”. When I wrote that, it was simply because there are some questions that I really think aren’t helpful at all. Questions like:

  • Why didn’t you just buy X instead of building your own?
  • Didn’t somebody do that years ago? Why are you playing with that old technology?
  • Why are you writing a program to do that, when you could just use Y, some program/framework/application that I use.

I hate questions like this because they aren’t really questions at all: they are simply trying to tell you that what you are doing is stupid or pointless. Here’s the thing: I mostly understand why I do the projects that I do, and I’m perfectly okay with you not understanding my rationale, or agreeing with it even if you do understand. The proper answer is “why climb a mountain?” isn’t “because it was there”. It’s not even “because no one has before”. The proper answer is “because I’ve not done it, and I enjoy mountain climbing.” Interestingly, most people won’t try to convince you that you shouldn’t like mountain climbing, but all sorts of people will try to tell you that your technical projects are a waste of time. This kind of conversation actually irritates me.

And with all this introduction, I’m going to now criticize a project, which is going to seem a bit hypocritical. Hang with me to the end, and I’ll try to resolve the apparent hypocrisy, at least partially.

The topic is the plethora of news stories about a talk given at the Chaos Communication Congress (28c3) recently held in Berlin. Some links to news stories:

Hackers aim to launch Internet satellite network, moon mission
Hacker satellite grid to counter Internet censorship??
Hackers Plan Satellite Network to Fight Internet Censorship

So, what’s my beef? After all, any reader to this blog knows that I’m interested in amateur satellite and communications, surely this is right up my alley?

And indeed it is. But the motivation is just… well… it’s stupid. Not stupid because fighting censorship is a bad idea: it’s a very, very good idea. Even essential. But the idea that satellites constructed by amateurs can play any role (much less any significant role) in fighting censorship is fantasy.

First of all, launching satellites is expensive. Really expensive. While the hardware of cubesats can be constructed quite economically, launches have costs which are multiples of ten thousand dollars, for masses which are less than 1kg launched into low earth orbit. Currently AMSAT has a project called FOX to develop a communication satellite that fits the cubesat form factor, but it’s capacity and power are very limited, mostly by the physical size and weight limitations imposed by available launch opportunities. To launch a satellite into MEO or HEO would require costs measured in the millions of dollars.

Secondly, you can’t get spectrum to operate a satellite network like they imagine. Amateur radio frequencies are subject to regulation and treaties just like any other spectrum, and the uses of such frequency are dictated by regulation and treaty. The governing international body is the IARU (the International Amateur Radio Union) and member nations enact local regulations to enforce treaty restrictions to comply with the regulations of the IARU. The purpose of amateur radio satellites must be to “(1) provide communication for the general amateur radio community and/or (2) self training and technical investigations relating to radio technique”. While these topics are fairly broad, they are not broad enough to provide a general replacement for the Internet. In fact, in the U.S. amateur radio is specifically prohibited from carrying “communications, on a regular basis, which could reasonably be furnished alternatively through other radio services.” You can’t get the frequency allocations. Nobody will launch a satellite without frequency coordination.

Third, if your concern is to bypass the censorship of governments, it seems odd to do it by launching a satellite, because governments tend to have very strict and tight controls over satellites and satellite technology. For instance, in the U.S. ITAR regulations essential prohibit the transfer of dual use technologies to other countries, even to our allies. This isn’t just a theoretical concern: American participation in the amateur satellite projects of other countries have been significantly stifled But even more basic than these issues are the fact that access to space is currently under the control of the very governments we are concerned about. While increasing commercialization is eroding that to a certain degree, we cannot rely on commercial entities to operate in defiance of the governments of the countries in which they operate. There is some possibility that an organization such as Copenhagen Suborbitals might be able provide launches, but these operations must operate within the regulations of the countries from which they operate as well, so I think the idea of access to space independent of governmental interference is a fantasy.

Here’s the bottom line though: if your goal is to prevent government censorship, every dollar that you spend could do orders of magnitude more benefit using more conventional earth-bound technology. Funding projects like the FreedomBox Foundation, HTTPS Anywhere or The Tor Project, or working to generate a mesh based Wifi capability in your area are much, much stronger ways to work to combat Internet censorship.

If you want to build satellites, it’s a perfectly reasonable thing to do. But to try to sell the idea by saying that it provides a way to combat Internet censorship? That’s misleading at best.

Addendum: Here’s the actual talk at the Chaos Communication Conference. It’s actually got some cute stuff in it, mostly because it leaves behind the fantasy that a satellite communication network will provide a hedge against censorship in the first five minutes.

WA0UWH experiments with the Propeller/QRSS.

This link will make my various Propeller loving readers happy: Eldon, WA0UWH received a Propeller microcontroller board for Christmas, and decided to try to use it to create a QRSS beacon. With other microcontrollers you generally just program it to generate a keying signal that passes into a FSK input on some other transmitter/oscillator. But Eldon used a unique feature of the Propeller: it can directly synthesize frequencies using an on chip 80Mhz oscillator and a PLL. In theory all you really need to make a QRSS beacon is a low pass filter (which Eldon also created). There are some potential problems (phase noise, temperature stability) but the idea is very cool. Check it out!

The blog of Eldon, WA0UWH: check out his recent posts on QRSS/Propeller

K6HX QRSS Beacon ON AIR…

Well, this morning I did a bit more work on my G0UPL beacon kit. As I mentioned yesterday, I got was having difficulty with the frequency swing: despite a very tightly wound gimmick, I was getting just a little over 1Hz or frequency shift. Late last night I decided to just try a new one: there obviously had to be a fault there. Sure enough, I wound a new one, installed it, and was suddenly getting 30Hz of frequency shift! Feast or famine, isn’t that the way of it? I trimmed it down, and unwound it a bit, and now am getting a nice, reasonable 4Hz or so swing, which is clearly visible in Argo, but also narrow enough to be tidy.

I had also noticed during testing that the QRSS beacon controller was powering up in 15s/dit mode, which is a tad too slow even for the patient. I then decided to take notice of the “Important Notice” on Hans’ documentation, and grounded pins five and six with a small jumper on the bottom of the board. It now powers up reliably in six second per dit mode.

I then decided to try to measure the output power. And… on the antenna terminals, I was measuring, well, nothing! That’s not good. I then backtracked to the 2N7000 FET, and found that there was indeed a signal on the Gate, and it was modulating (although the waveform looked pretty wonky). Probing various places along the filter chain quickly discovered the bad solder joint, and I had power.

I then tried to do some adjustment of the output power. I wired up a 2W 47 ohm resistor as a dummy load, and hooked up my scope. I found that if I peaked the output power with just under six volts peak-to-peak (a little less than 100mw) the 2N7000 got fairly toasty hot. I backed off the power to just 4 volts peak to peak (around 40mw) and the transistor seems fairly calm. I thought I should be able to do a bit better, but 40mw isn’t all that bad, so… I decided to get it on the air.

And here it is, appearing on KK7CC’s grabber (click to get it live), right around 10.140040 Mhz:

It works! KK7CC is in Las Vegas, which is around 560 miles from my location. Not bad for 40mw output power.

I’ll leave this up for a while, I’m interested in getting reception reports and screen grabs at my ARRL mailbox. I will eventually take it down, get it mounted inside a nice little Altoids box, and perhaps figure out why the output power is well short of the 100mw that I should be able to pull out of it.

In the mean time, I hope everyone has a safe and happy New Year’s Eve!

QRSS Beacon assembled, but not quite right…

I ordered myself one of Hans Summers’ QRSS beacon kits before Christmas, and it arrived a few days ago. Yesterday, I started tinkering it together, and today got it hooked up and began testing.

First, the good news:

  1. The oscillator is running.
  2. I was able to adjust it with the trimmer to get it into the MEPT portion of the 30m band.
  3. The AVR is alive and running.
  4. Tone output works, and it is detecting the 6s per dit QRSS mode properly.

But… all is not well. Here’s an example output recorded with Argo on my FT-817 placed adjacent, without any antenna at all. The QRSS beacon is transmitting into a 1W 47 ohm resistor that serves as a dummy load.

As you can see, the output is a bit wavy, and looks a bit unclean as well, with lots of spurs. But the primary thing is the deviation is only about 1.5 Hz (I recorded this in 10 second dit mode on Argo). I tried adding some additional twists to the gimmick cap, but that didn’t seem to help much.

I suspect the general poor quality of the output may be because I’m using a 5v power supply of unknown quality (perhaps some additional filter caps across the power leads may be helpful?). I’ll probably try to make a longer gimmick tomorrow. I also am going to get it hooked up to the scope to adjust the power properly as well. It’s also not in a box yet, and my dining room table is a bit drafty, so thermal drift is a distinct possibility.

Anyone else have any ideas on how to tame the ragged castle walls?

Addendum: I couldn’t let it sit: it’s one o’clock in the morning and I decided to make a new gimmick and try it out. And, of course, it worked a lot better, giving about 30Hz of swing! Ouch. I trimmed the length down, and unwound it a bit more, and now it’s down to a more respectable 8 or 9 Hz. I’ll probably unwind it a bit more when I get it in the case and setup for final operation.

But here’s an odd thing: I jumpered it for 6 second dits by jumpering the 2-5 connection at the top of the AVR, but it’s acting as if is set to 15s dits. Do I need to ground pins 5 and 6 as well? Perhaps they are floating?

Addendum2: I suppose I should have read the Important note on this page.

Extending Tiny BASIC on the Arduino

I was intrigued by @monsonite’s challenge to extend Tiny BASIC for the Nanode. I don’t have a Nanode, but I do have some Arduinos, and extending Mike Field’s Tiny BASIC port to include some additional Arduino functionality seemed pretty straightforward. An hour or so staring at the code told me pretty much all I need to do, so I went ahead and added a DELAY statement to duplicate the Arduino delay() call, a MODE keyword (duplicating pinMode()) and WR (duplicating digitalWrite()).

If you put all these together, you can write simple LED blinking programs entirely in BASIC. Check it out:

I might see how far I can take this idea during my vacation.

Addendum: Why does YouTube always choose a frame where my eyes are closed as the default marquee image?

Nice article on making an Arduino DDS…

My experiments with generating RTTY signals yesterday made me begin to think about generating RTTY signals with an Atmel/Arduino setup. The obvious way is to use PWM and a low pass filter to approximate a sine wave. While doing a bit of research, I found the following link which seemed to be nearly ideal: it even included an amateur radio application that uses an Arduino to generate the tones necessary to transmit WSPR. It also has a very nice lowpass filter design that can be pressed into service to smooth the PWM output. Stashed for future reference:

Arduino DDS, with WSPR applications

More on the crazy ITA2 encoding…

So, this morning, I was trying to test my understanding of the ITA2 code used in amateur radio teletype communications. I wrote up an encoder, generated some test audio files, and tried decoding them with fldigi. It mostly worked, but I had some difficulty with certain punctuation marks. I was curious what the problem should be, so I dug into the code in fldigi that does this stuff. I found this interesting chunk of code:

[sourcecode lang=”cpp”]

#if 0
/*
* ITA-2 version of the figures case.
*/
static unsigned char figures[32] = {
‘\0’, ‘3’, ‘\n’, ‘-‘, ‘ ‘, ‘\”, ‘8’, ‘7’,
‘\r’, ‘\xb7’, ‘4’, ‘\a’, ‘,’, ‘\xb7’, ‘:’, ‘(‘,
‘5’, ‘+’, ‘)’, ‘2’, ‘\xb7’, ‘6’, ‘0’, ‘1’,
‘9’, ‘?’, ‘\xb7’, ‘\xb7’, ‘.’, ‘/’, ‘=’, ‘\xb7’
};
#endif
#if 1
/*
* U.S. version of the figures case.
*/
static unsigned char figures[32] = {
‘\0’, ‘3’, ‘\n’, ‘-‘, ‘ ‘, ‘\a’, ‘8’, ‘7’,
‘\r’, ‘$’, ‘4’, ‘\”, ‘,’, ‘!’, ‘:’, ‘(‘,
‘5’, ‘"’, ‘)’, ‘2’, ‘#’, ‘6’, ‘0’, ‘1’,
‘9’, ‘?’, ‘&’, ‘\xb7’, ‘.’, ‘/’, ‘;’, ‘\xb7’
};
#endif
#if 0
/*
* A mix of the two. This is what seems to be what people actually use.
*/
static unsigned char figures[32] = {
‘\0’, ‘3’, ‘\n’, ‘-‘, ‘ ‘, ‘\”, ‘8’, ‘7’,
‘\r’, ‘$’, ‘4’, ‘\a’, ‘,’, ‘!’, ‘:’, ‘(‘,
‘5’, ‘+’, ‘)’, ‘2’, ‘#’, ‘6’, ‘0’, ‘1’,
‘9’, ‘?’, ‘&’, ‘\xb7’, ‘.’, ‘/’, ‘=’, ‘\xb7’
};
#endif
[/sourcecode]

Odd. It seems to differ significantly from the “official” ITA2 code. So, I modified my RTTY encoder to use the same encoding. I also discovered that fldigi implements “unshift-on-space”, regardless of what mode you are in, sending a space drops you back into the letter mode. This caused some things to decode improperly until I fixed it.

Now, it seems to work. If you are bored, you could download this overly long and verbose RTTY message (note, you may have to reverse mark and space frequencies, I’m not sure I got that right yet).

An RTTY message, encoded by my RTTY encoder (2.2M WAV file)