My First Crystal Radio

As I was trying to organize things a bit in my “office”, I happened to unearth a bit of nostalgia. This is my first crystal radio.

My First Crystal Radio

My First Crystal Radio

I built this thing after reading about it in some old book. It’s probably about 25 years old. It uses a germanium diode from an old TV set I had taken apart. I’m pretty sure the terminal strips are also from the TV.  It’s hard wired to the frequency of the local AM radio station. The capacitors were probably bought from Radio Shack. Based on the frequency and capacitance values, I had calculated the proper number of turns to wind on the high tech coil form, made from a half inch wooden dowel. The coil and some of the wiring are attached to the substrate material (piece of plywood I found in the back yard) using a combination of masking tape and staples. It turns out masking tape doesn’t stick to unfinished wood well enough for this application.  The black wire connected to the antenna, which was just more wire dropped from my bedroom window. It also had an earth ground connection which was attached to the face plate screw on a handy electrical outlet. That made a huge difference as I recall.  It worked the first time too. It probably helped that there was only one radio station easily available in the area and that these units don’t have much in the way of selectivity. Overall, it was a fantastic, simple project to introduce a kid to electronics.

Posted in Electronics | 2 Comments

Retro LED Displays

I recently found some HP 5082-7433 LED bubble display modules on eBay. These are three digit, 7 segment displays with decimal points. The “bubble” is a magnifying lens molded into the epoxy package.

7 segment LED bubble display

7 segment LED bubble display

I ended up finding a datasheet (warning, pdf link), but not one that specifically covers this module. The pinout doesn’t match anything in that datasheet unfortunately, so it took a few minutes of trial and error to come up with one myself. Pin 1 (labeled cathode 1 in the diagram) is indicated by a tiny notch cut out of the pin. It’s hard to see, so fortunately the HP logo on the bottom of the module is on the same end as pin 1.

LED display pinout

The module pinout rendered via an extremely precise manual CAD method

Each digit is wired to share the segment anodes with the other digits but has a separate common cathode. This arrangement saves pins, but requires the digits to be multiplexed.

Somewhere below is an arduino sketch I put together to display a simple three digit hexadecimal counter using one module. I used one pin per segment and one for each cathode because a)  I’m fresh out of common cathode BCD to 7 segment display drivers, and b) I want a hex display. The first few hexadecimal display chips I turned up were in the $10 range. Crazy. Here’s the circuit wired up on a breadboard:

arduino with hexadecimal display

The Arduino with hexadecmal counter display

Each segment needs a separate current limiting resistor. I chose 2.2k here. This is a 5v Arduino, and the module datasheet indicates a typical forward voltage drop of 1.6v. That leaves 3.4v across the resistor resulting in about 1.5mA per segment. Now, there can be a maximum of 8 segments (including the decimal point) lit at one time, so that means a total of 12mA will be sunk by the cathode pins. The I/O pins on this Arduino can sink 40mA, so the smoke should remain inside.

Here is the sketch I came up with. This code is also available here.


// This is a test which will display a 3-digit hexadecimal counter
// on an HP 5082-7433 LED display

// define pin numbers for convenience
// annodes for seven segments plus decimal point
const int a = 13;
const int b = 12;
const int c = 11;
const int d = 10;
const int e = 9;
const int f = 8;
const int g = 7;
const int dp = 3; //decimal point

// each digit has a common cathode for its segments which must be pulled
// to ground to enable that digit
const int cathode[] = {4,5,6};

// this controls how long each digit is displayed. Adjust for flicker.
const int delaytime = 5;

// this is a table of what segments (left to right, a-g) should be lit for each digit to display
const byte matrix[] = {
B1111110,
B0110000,
B1101101,
B1111001,
B0110011,
B1011011,
B1011111,
B1110000,
B1111111,
B1111011,
B1110111,
B0011111,
B1001110,
B0111101,
B1001111,
B1000111};

unsigned long time;
unsigned int counter = 0x0;

void setup(){
// set all required pins to outputs
pinMode(a, OUTPUT);
pinMode(b, OUTPUT);
pinMode(c, OUTPUT);
pinMode(d, OUTPUT);
pinMode(e, OUTPUT);
pinMode(f, OUTPUT);
pinMode(g, OUTPUT);
pinMode(dp, OUTPUT);
pinMode(cathode[0], OUTPUT);
pinMode(cathode[1], OUTPUT);
pinMode(cathode[2], OUTPUT);

// start off with nothing displayed
digitalWrite(a, LOW);
digitalWrite(b, LOW);
digitalWrite(c, LOW);
digitalWrite(d, LOW);
digitalWrite(e, LOW);
digitalWrite(f, LOW);
digitalWrite(g, LOW);
digitalWrite(dp, LOW);
blankAllDigits();
time = millis();
}

void loop(){
// display each digit in turn, pausing by delaytime in between

// get the digit to display
byte digit = getNybble(counter, 2);

// get the segment pattern from matrix[] accoring to the digit and display that
displayNybble(matrix[digit], 2);

// wait for it
delay(delaytime);

// then do the same for the other two digits
digit = getNybble(counter, 1);
displayNybble(matrix[digit], 1);
delay(delaytime);
digit = getNybble(counter, 0);
displayNybble(matrix[digit], 0);
delay(delaytime);

// increment the counter if it's been at least 100ms
if ((millis() - time) > 100){
counter++;
time = millis();
}
}

byte getNybble(unsigned int source, char index){
// What we're doing here is extracting the nybble (4 bits) that corresponds
// to the hex digit we want from the counter.
// First, shift the counter to the right by the appropriate number of bits
// so the bits we want are all the way to the right.
// Then, cast the 16 bit integer counter to an 8 bit byte which drops the leftmost 8 bits.
// Then do a bitwise AND operation with 00001111. This forces the leftmost 4 bits to zero,
// leaving just the nybble we are interested in.
return (byte)(counter >> (index * 4)) & B00001111;
}

void displayNybble(byte x, int pos){
// x is the bit pattern from matrix[] for the digit we want to display
// This gets the individual bits from x and sets each output pin accordingly.
blankAllDigits();
digitalWrite(a, bitRead(x,6));
digitalWrite(b, bitRead(x,5));
digitalWrite(c, bitRead(x,4));
digitalWrite(d, bitRead(x,3));
digitalWrite(e, bitRead(x,2));
digitalWrite(f, bitRead(x,1));
digitalWrite(g, bitRead(x,0));
enableDigit(pos);
}

void enableDigit(int pos){
// to enable a digit, pull its cathode down to ground
digitalWrite(cathode[pos], LOW);
}

void blankAllDigits(){
// to blank or disable a digit, pull its cathode high
digitalWrite(cathode[0], HIGH);
digitalWrite(cathode[1], HIGH);
digitalWrite(cathode[2], HIGH);
}
Posted in Arduino, Electronics | 3 Comments

Frankenstein’s Lawnmower

I have a battery powered lawnmower. It’s powered by a 17Ah 24V battery which lasted four seasons before it just wouldn’t finish the lawn. The replacement battery started giving me trouble by the end of the first season. It was barely adequate and had developed a strange quirk where it would spin the motor up slowly the first time it was powered up. The brushes seemed to have plenty of wear left, so as an experiment I tried touching the motor wire directly to the battery terminal. It spun up instantly, like it was new. This made me suspect the switch contacts, which turned out to be pretty chewed up. At this point, like any normal person would, I decided to have the machine serviced by an authorized service center. Just kidding. This mower literally consists of a motor, a switch, and a battery. I decided to replace the switch assembly with a MOSFET.

A simple lawn mower control circuit

Based on the observed battery life and the 40A circuit breaker in the original circuit, I estimated around 20A of current draw.

The IRF1405 is an N-Channel MOSFET intended for automotive applications. It runs $2.45 from Jameco in single quantity. It claims a maximum continuous current of 169A, however the fine print in the datasheet indicates that the TO-220 package limits it to 75A. I’ll be well within that limit, so no problem there. It needs 10V on the gate to turn fully on, while the max allowed is 20V. In the schematic, when the switch is on, the zener diode provides a nice consistent 12V to the gate of Q1. With the switch off, the gate is discharged through R3. I’m not too concerned about the switching speed in this application. I added a small gate resistor, R2, though it’s probably not necessary here. R4 is a 50A, 75mV current shunt that I will use in a future project to add some instrumentation. Since the motor is an inductive load, flyback diode D4 is required to protect the FET. I used two MBR745 diodes in parallel here because I wasn’t sure how to size a motor flyback diode. This turned out to be overkill.

I mounted the entire circuit to a piece of plywood, and the entire unit was temporarily mounted to the top of the battery with a piece of double sided tape:

The finished project shown charging

The board to the right of the battery is the mower’s original charger, balanced precariously and attached with tiny alligator clips. The small wire going out of the picture to the upper left goes to the on/off switch. The two flyback diodes are mounted to a heat sink (scavenged from an old video card) at the top of the main board. Below that is a terminal strip, then the MOSFET also on a heat sink. To the left of the FET is the current shunt. I’ll probably add a 40A breaker when I permanently mount the board.

Yesterday was its inaugural mow. I’m happy to report that it worked perfectly. It mowed the whole yard no problem, and neither the diodes nor the FET even got warm to the touch. The voltage drop across the shunt read 16mV on a fresh battery and no load. This works out to 24A, pretty close to what I was expecting. The longevity of this circuit remains to be seen, but so far I would call it a success. Plus, I’m the only one in the neighborhood with wires and plywood attached to his lawnmower.

Posted in Electronics | 7 Comments

Constant Current Dummy Load

This is a constant current dummy load I put together recently. It was inspired by the EEVblog version. Mine is simplified, using only one op-amp. It also requires a multimeter to monitor the current.

Schematic

Action Shot

I used parts I had on hand, except the sense resistors which I had to order. The IRF520 is not a logic level MOSFET. It’s barely starting to turn on at a gate voltage of 5v, so I had to use a 12v power supply. Otherwise, it’s very straightforward. The op-amp will try to maintain its + and – inputs at the same voltage by adjusting the output and therefore the load on the power supply under test.  I used ten 10Ω 1% resistors in parallel for the current sense resistor, making the math easy. 1 amp = 1 volt across 1Ω.

I tested it out using the same 12v power supply. (12.6v to be specific) Drawing 500mA results in a power dissipation of about 6W in the MOSFET. With the heatsink in the action shot, it stabilized at about 150F, or 80F above ambient. The sense resistors only showed a few degrees of heating. The circuit seems to be very stable in spite of the breadboard and all of those ridiculously long wires. Apparently, this particular op-amp is very forgiving.

In the future, I’ll add on to this project with an lcd readout and microcontroller. At least, a fine adjustment would be nice. As it is, it’s difficult to control the current setting with a single potentiometer across the full 12v supply. Once it is set, however, it is nice and stable.

Posted in Electronics | Leave a comment

Resurrecting an Apple Disk II

I had an Apple IIc growing up. I still have it, along with a big stack of floppy disks. It still works, even after enough years that you kids need to get off my lawn. I decided I wanted something a bit more hackable, so I got a IIe from Ebay along with two 5.25″ floppy drives and a Super Serial card. So, I powered it all up and tested it out and… one nonfunctional drive. Not too bad considering the drive is over 30 years old. (did I mention my lawn?)

Inside the Disk II

The symptom: On power up, the drive head hits the back stop making that characteristic floppy drive noise but refuses to seek the first track. The access light stays on, and the main motor spins the disk. It just sits there like that without moving the head again. According to the Disk ][ Technical Procedures (found here), the first thing to look for is burned components. Opening things up, we see this:

Ouch!

Looks like capacitor C4 is toast. According to the docs, this means the 74LS125 is also likely dead. Those are both easy fixes, but… no such luck. The symptoms remain. I have a working drive, so I tried swapping the good board to the bad drive. That worked. Since nothing else looked damaged, I tried swapping the rest of the chips one by one into the damaged board. It turns out the MC3470, the floppy disk read amplifier, was the culprit. That’s the farthest chip to the right in the picture. This chip is a little harder to source than the other two. I ended up getting a couple from Newark, though it turns out I should have checked Ebay first. In any case, I now have two working floppy drives. Now the question is, what to do with them…

Posted in Apple II | 1 Comment

Interfacing the PS/2 Keyboard

As an exercise, and to help me learn about the protocol, I’ve set up my trusty Arduino to read scancodes from a PS/2 keyboard. The protocol is fairly simple. The keyboard uses four pins in the connector whether it is the 5 pin AT style or the 6 pin PS/2 style. These are CLK, DAT, GND, and VCC. When a key is pressed, the keyboard begins generating a clock signal on the CLK pin. At each falling edge of this clock signal, a new data bit is presented on the DAT pin. This lends itself well to an interrupt driven approach. The Arduino supports an external interrupt (interrupt 0) on digital pin 2, so that’s where I connected the clock line. The DAT line was connected to digital pin 3. Pin 2 is then configured to fire an interrupt on the falling edge of the signal, and an interrupt service routine (ISR) is attached to that interrupt so that the Arduino will read the next incoming bit from pin 3, keeping track of where we are in the data sequence so it can store the complete scancode once all of the bits have been read.

PS/2 Pin Connections

Connecting the Keyboard

To start listening for the interrupt, we need to put the following line in the setup() routine:

attachInterrupt(0, kbdint, FALLING);

In this case, kbdint is the name of the ISR which will be doing the work. It will be executed once each time the clock signal on pin 2 is pulled to ground by the keyboard, each time capturing one bit of incoming data.

void kbdint()
{
pin3 = digitalRead(3);
if(pos == 0)//start bit
{
pos++;
datavalid = 0;
scancode = 0;
return;
}
if(pos < 9)
{
if(pin3 == HIGH)
{
scancode |= (1<<(pos-1));
}
pos++;
return;
}
if(pos < 10){pos++; return;}//parity bit
pos = 0;
datavalid = 1;
return;
}

The variables used in the ISR are defined as volatile:

volatile char pos = 0;
volatile char scancode = 0;
volatile char datavalid = 0;
volatile int pin3 = 0;

The keyboard will send data in 11 bit frames consisting of a start bit, eight data bits, a parity bit, and a stop bit. A more complete analysis is found here, among other places. This code keeps track of what bit was just received by incrementing pos. It ignores the start bit, inserts each of the next 8 (data) bits into the scancode variable, and ignores the parity and stop bits. The datavalid flag could be used to indicate to some other part of the program that a complete scancode has been captured.

This is pretty basic, naive code, but I think it proves the concept sufficiently. The protocol also allows for sending data to the keyboard in order to change settings and control the various LED’s. Perhaps that will be fodder for a future post.

Posted in Arduino | 2 Comments

Hello world!

This is the obligatory “Hello World!” post. Imagine a random microcontroller on a breadboard. One LED flashes slowly. That’s what this is.

Posted in Uncategorized | Leave a comment