Tuesday, April 13, 2010

Hot wire polystyrene cutter for perfectly straight edges

I'm building the box that will contain the balloon's payload out of a polystyrene sheet. Polystyrene can be bought in construction supply stores such as Leroy Merlin in Europe, maybe Home Depot in the US. I've got a 160 x 60 cm sheet for about 2€ from Leroy Merlin (you have to go to the construction supply area, not the main shop).

You can cut polystyrene with a regular knife, but the easiest way is using a hot wire. At the right temperature, the wire melts the foam like butter, leaving the cleanest cut behind. And best of all, with no fumes!

There are some cool solutions out there based on soldering irons, these are ideal to cut small pieces of foam in shapes, but I want perfectly straight edges because I need to glue the box sides together. This is what I did:

Ingredients:

  • Nicrom wire. This is the cutting wire. Get it from a hairdryer or an electric heater. You can go to a recycling center and dig for one among the electronics garbage. That's how I've got mine, every time I go to the recycling place I bring more trash home than I drop off there :)
  • Car battery, or something capable of delivering 3-4 amps at 9-12 volts. I used my car's old battery. It won't power the starter, but it definitely melts the polystyrene.
  • A couple of battery cables with clamps.
  • 2 aluminum rods. 1 m long, 6-8 mm thick is enough. Hollow ones are cheaper, lighter and better. I've got them from a local hardware store for ~1.50€ each.
  • Small machine screws and bolts. I used 3mm across, 12mm long screws.
  • Two vises. Mine are small, the ones that will hold on to the bench with a clamp, rather than screws.
  • Drill or dremel tool. And a 3mm bit.

First, clamp the vises to the bench, one facing up and the other facing down. These will hold the rods.

Use one of the vises to clamp and flatten the tip of the rods. Just flatten the last 1-2 cm, this will make it easier to drill through it.

 

Cut the nicrom wire. The wire acts as a resistor, and the shorter you cut it, the hotter it will get. Hotter will cut the foam faster, but it does not have to be incandescent. In fact, if it's too hot, it can break. So it's better to err on the generous side, and if it doesn't get hot enough, you can cut it shorter later. I used about 50cm. My wire looked like a spring, so I decided to straighten just 15-20 cm and leave the rest coiled up.

Drill two holes with the 3mm bit on the rod's tips. Insert a screw through the hole and secure the nicrom wire to the rod with a bolt. Do it with both rods. The total length of the wire between the rods is 15-20 cm, so I have some coiled-up wire overhanging.

 

Clamp the two rods, one with each vise. Make sure the wire is tight. The aluminum rods are very flexible, so just tighten the wire until the rods bend a little. Also, make sure the wire is at a right angle with the bench. Try to straighten the wire as much as you can (at least the stretch that will cut through the polystyrene). Just press it between two fingers and slide the fingers down repeatedly.

Make sure the rods or the vises don't touch each other, or they will short the battery!

Now, hook up the cable clamps to the battery. You can try connecting the clamps directly to the rods, but the stretch of wire between them will probably be too short and the wire will get glowing hot in seconds. So I chose to hook up one clamp to a rod, then the other clamp to the overhanging wire. Just remember the closer the clamps are on the wire, the hotter it will get.

 

 

That's it... Use a plank as a guide (sort of like a T-square) if you need parallel edges. You can clamp the plank to the bench, so that you don't have to hold it and can focus on the cutting. Try not to stop as you cut, or you'll start melting a hole around the wire (check the fourth picture below, can you see the dents?). Just keep constant speed. You'll be surprised how extremely clean the cut is!

 

Saturday, April 10, 2010

Audio with an Arduino and PWM

The Arduino doesn't come with a DAC (digital-to-analog converter), so the two options to generate an analog signal are a resistor ladder (remember the Covox Speech Thing?), or PWM. Some commercial trackers, like the TinyTrack, use a 4-bit resistor ladder, but I thought it would be more fun to use PWM. It gets more complicated on the programming side but it takes less external components and only one output pin.

The Arduino has 3 timers capable of doing PWM. Some timing functions in the Arduino library (delay and millis) use Timer 0, so we don't want to disturb them. Timer 1 and 2 both have about the same capabilities, but Timer 1 can count up to 16 bits and Timer 2 only goes up to 8 bits. There is a great write-up by Michael Smith on generating PWM with Arduino and two timers. It uses Timer 1 to feed samples (at whatever the sample rate is) and Timer 2 to do the actual PWM (at the maximum rate possible, 16 MHz / 256 = 62500 Hz). But, by keeping the playback interrupt short enough, it is possible to do away with just one timer and simplify the code a bit. All it takes is telling the AVR to trigger an interrupt when the PWM timer overflows and feed samples from the interrupt service routine. The ISR will be called every 256 clock cycles, but that's long enough for a couple of table look-ups. A code excerpt:


void modem_setup()
{
// Configure pins
pinMode(SPEAKER_PIN, OUTPUT);

// Set up Timer 2 to do pulse width modulation on the speaker
// pin.

// Source timer2 from clkIO (datasheet p.164)
ASSR &= ~(_BV(EXCLK) | _BV(AS2));

// Set fast PWM mode with TOP = 0xff: WGM22:0 = 3 (p.150)
TCCR2A |= _BV(WGM21) | _BV(WGM20);
TCCR2B &= ~_BV(WGM22);

// Do non-inverting PWM on pin OC2B (arduino pin 3) (p.159).
// OC2A (arduino pin 11) stays in normal port operation:
// COM2B1=1, COM2B0=0, COM2A1=0, COM2A0=0
TCCR2A = (TCCR2A | _BV(COM2B1)) & ~(_BV(COM2B0) | _BV(COM2A1) | _BV(COM2A0));

// No prescaler (p.162)
TCCR2B = (TCCR2B & ~(_BV(CS22) | _BV(CS21))) | _BV(CS20);
}

void modem_start()
{
// Key the radio
radio.ptt_on();

// Enable interrupt when TCNT2 reaches TOP (0xFF) (p.151, 163)
TIMSK2 |= _BV(TOIE2);
}

void modem_stop()
{
// Release PTT
radio.ptt_off();

// Disable playback per-sample interrupt.
TIMSK2 &= ~_BV(TOIE2);
}

// Service routine for TIMER2's overflow interrupt.
// This is called at PLAYBACK_RATE Hz to load the next sample.
ISR(TIMER2_OVF_vect) {
// [...] load the next sample
OCR2B = next_sample;
}


And that's it. We call modem_setup() once at the beginning to set Timer 2 to the proper mode. Then we call modem_start() to transmit and modem_stop() to stop. You can see the real implementation here. These are the results:


PWM filtered/unfiltered

 


Received signal (MX146)

Received signal (HX1)


On the first image you can see the PWM output (below) and the same PWM signal filtered by an RC low-pass filter with cut-off frequency = 2800 Hz (above). Can you see the phase offset between the two signals? That's a consequence of the RC filter. There is some ripple at 62.5 KHz resulting from the PWM itself, but the transmitter and receiver's own filters took care of it as you can see in the the other two pictures. One thing I noticed is a bigger gain of the signal transmitted with the MX146 compared to that of the HX1. Perhaps I am overmodulating the MX146?

 

Testing a Radiometrix HX1 radio

I've got these 3 modules from Radiometrix. Look how nicely packed these came!

  • HX1: VHF transmitter, hard-tuned to 144.8 MHz, outputs 300mW. Consumes 120mA at full RF.
  • NRX1: VHF receiver, hard-tuned to 144.8 MHz
  • UHX1: VHF transceiver, can operate on any frequency in a 2 MHz range, outputs 500mW (adjustable).

I've tried the HX1. It outputs 200mW according to my power meter. The 100mW loss might be due to the dirty connection I made from the breadboard to the SO-239 connector, bad shielding or the meter itself but I still haven't figured it out completely.

I've got the HX1 partly inspired by VE6SBS Barry's page. He successfully tracked a balloon using an HX1 radio from 600 km away. Not bad for 300 mw! I have been able to reach digipeaters in the ~35 Km range with ~50% success rate using the HX1 and a DIY 6 elements yagi antenna. With my trash-dug omni antenna, though, the success rate goes down to ~0.01% (success rate with the SRB MX146 @500mW and the omni was ~4%) , even though I have direct line of sight with the remote digipeater. I fear losing the ballon after it goes a few kilometers high, but apparently altitude has a huge impact in VHF propagation, and Barry's experience is a good proof of it.

The other issue Barry was worried about is the high frequency drift this device experiences with temperature. I think there is little to do here except taking care of good thermal insulation. I'm actually thinking of using the HX1 as a heat sink for the voltage regulator...

 

Monday, April 5, 2010

Source code is up!

You can find the source code of the APRS tracker here: http://code.google.com/p/trackuino/downloads/list

Current functionalty:
  • Reads GPS NMEA messages from Arduino pins 0 and 1 (serial RX/TX)
  • Outputs APRS position messages including latitude, longitude, altitude, course, speed and GPS time
  • Can connect to an SRB MX146 via pins 3/4 using I2C and interface with its controller to change frequency or read the temperature sensor.
  • Generates an AX.25 standard AFSK 1200 baud signal. The Arduino doesn't include a DAC, so analog signals must be generated by either using a resistor ladder or PWM. I chose the latter, since it involves less additional electronics.

Testing the SRB MX146

I just got an SRB MX146 module! It puts out 0.5 watts and operates on any frequency from 144 to 148 MHz. The frequency can be chosen from among a set of pre-programmed memories, or interfacing directly with the controller using I2C. Changing frequencies on-flight would allow transmitting position messages on the APRS frequency, then switch to a different frequency and send non-APRS data (real-time photos, for example).

This is my current set-up:


The rig

MX146 outputting 1/2W

LDO regulators


On the first picture:

  • An Arduino, the "brain" of the system. I use the internal UART to interface with the GPS and four pins for the radio, one carries an AFSK 1200 baud signal modulated with PWM, another controls the PTT, and two more for I2C.
  • The GPS (the little red board) is a Venus 634FLPx I got from here. It is supposed to work above 18 Km according to their datasheet. Plus, they have a very responsive tech support (I actually confirmed the CoCom limits with them). It fixes the position 5-30 seconds after a cold start, but you can feed it the ephemerides of the next 7 days and it will then fix in less than 5 secs. This is a 3.3 volts device, so it needs some kind of voltage conversion. The easiest and safest way to convert 5v to 3.3v is by using a diode as explained in this nice tutorial. The 3.3 volts don't need conversion back up to 5, since 3.3 volts is enough for the AVR chip to consider it a logical high.
  • On the breadboard, there is also a low-pass filter to get rid of the PWM high-pitch frequencies. PWM is done at the maximum rate allowed by the AVR's timer 2, ie. 62.5 KHz (16 MHz / 256), so this is probably not needed anyway.
  • The MX146 module is connected to the output of the LPF via a coupling capacitor and a voltage divider to bring the 5 volts off of the Arduino down to the 500mV peak-to-peak required by this device. The PTT is internally pulled-up to 3.3v by the MX146, so an open-collector transistor justs shorts it to ground on transmission.
  • Finally, I had to use three different regulators, since all 3 devices take different input voltages. In order to save some power, I used LDO regulators rather than the classic 78xx family. The LDOs usually require around 1-1.5 volts less than the matching 78xx, which means one less battery cell to lift!

 

Trash-digging at its finest: A 1:1.1 SWR VHF antenna for 2€

I followed these WA7YFF's instructions to build this fantastic 2m antenna using just a SO-239 panel-mount connector and 5 wire hangers I found in the trash around the neighborhood. I straightened the hangers with a vise, cut them for 144.8 MHz and mounted the radials overlapping with one another as suggested. I attached the radials to the connector with M3 screws and soldered the radiator to the center pin. The antenna looks very sturdy, and it's very easy to match the impedance of the transmitter by just bending the radials somewhere between 30-40 degrees. Click to zoom:


The end result is a great antenna with a 1:1.1 SWR at 5W. I have managed to reach a digipeater that is 36 Km away with my tracker and a SRB MX146 module that produces just 0.5 watts. I am at sea level, so it's not bad at all!