Wednesday, June 9, 2010


This is my first attempt at designing the tracker board. It basically consists of a barebones Atmega328P, a GPS, a radio, temperature sensors and a cut-down (aka the "suicide") mechanism. Click to enlarge:

Also check out this pin mapping reference between the Arduino and the Atmega328P.

I wanted the option to use both the Radiometrix HX1 and SRB MX146 radios, so I wired them both, but only one can be really used at a time.

As you can see, the connection from the AVR chip to the HX1 is straight-forward, just wires and no additional components.

The MX146, however, requires a couple of BS170 mosfets to translate I2C's TTL 3.3 <-> 5v levels, a transistor to drive the PTT and a voltage divider to convert the audio input down to 500 mV peak-to-peak. The MX146 also has its own 8V regulator, since I've got the 8V version. You can absolutely leave these components out if you're only going to use the HX1.

The GPS is a Venus 634FLPx. I bought it from Sparkfun. Since this is a 3.3V device, it needs some level conversion (via the diode method described here) and its own 3.3V regulator.

I also added a couple of LM60 sensors, since I want to measure both on-board and external temperatures. The external sensor can be connected via a terminal block (X2). I also planned for a capacitive humidity sensor (X3), but I don't think I'll use it on my first flight.

A MOSFET 22nf031 controls the "suicide" mechanism that cuts the rope if the balloon somehow refuses to burst. It has its own power source (X5) to avoid draining the main Vcc, and the nicrom wire goes to yet another terminal block (X6).

Lastly, X7 is the main Vcc source, coming from a pack of lithium AA batteries.

I have the Eagle .sch file and libraries for the MX146, the Venus GPS and the HX1 if anyone is interested.

Next step: create the .brd file for a PCB house. I'm really struggling with this, since it must match the PCB house specs (I'm thinking Olimex).


  1. Hello Javi,

    I would like to have your Eagle .sch file.
    I want to simplify it a bit:
    1. I want to completely remove the MX146 module
    2. Change the Venus GPS to the EM-406A SiRF III
    This GPS runs at 5V so it does not need any level conversion thus less components and wires.

    What are the possible ways of sending me the file?


  2. Of course if you can do this on your own I will appreciate it cause I don't know how to manipulate Eagle files.

  3. Kostas, I have uploaded the eagle schematics to my google code repository.

    If you have the time, I suggest watching this eagle tutorial. I used it to learn the basics. It's a series of 11 short videos.

    I also followed this instructable to create my library with custom parts.

    It takes some time to get up to speed with Eagle, but it's not too difficult.

  4. By the way, are you planning on using that GPS on a balloon? I believe the SiRF III chip stops reporting above 18 Km due to a bad implementation of the CoCom limits (check the comments at the sparkfun page).

  5. Javi, thanks for the links.
    I think I'll spend this week learning Eagle :)

    I know the 18Km issue. It's the same for your GPS

    First, I will test it for <15km.

    Also, I will add a GSM module as a backup to the GPS in case it fails. GSM is not supported on big heights because the cells are built for ground to ground ranges. But you can make the GSM module report you the cell is currently connected. Knowing the cell you can get an average position of where to look.

  6. There are actually two limits: altitude < 18 Km and speed < 500 m/s. GPS devices should stop reporting when BOTH are exceeded. That's how the Venus chip works, or so they say in their datasheet. I also confirmed it with their tech support.

    The problem with the SiRF III chip is that, according to a few reviews I read, it stops reporting when EITHER limit is exceeded.

    I like the GSM idea, but... do you have a map of the cell positions for your country? Where did you get it?

  7. Hmm..

    That's interesting. I really didn't know that. I already have ordered the EM-406A SiRF III. But it's ok. For my first tests I just need a GPS to make a start. My first step is 10Km. I'll be satisfied if everything works up to this height. Until then I don't mind this GPS detail. But anyway thanks for the info.

    About the GSM.
    One option is the Opencellid project. From their site: This project is an open source project, aiming to create a complete database of CellID worlwide, with their locations They provide an API where you send some GSM cell data and returns you a GPS position in XML. Note that the cell data can be retrieved from the GSM module with AT commands. It's very simple.

    Second option is Google :)
    Google recently announced the Network Location Provider Protocol. You send an HTTP POST request with the cellid data and returns you a response with the position. (Request and response are in JSON format).
    Probably google hosts a huge database containing the cellids all over the world.

    I have already bought Cellular Shield with SM5100B from sparkfun. Check it out.

    About the eagle files, I'm not able to open them with Eagle 5.9 .

  8. Hi Javi,

    today I was looking at the code.
    Seems that it consists of the following sequence:
    GPS -> ARPS -> AX.25 -> Modem -> Radio.
    Lucky you are that the GPS & Modem coding was already done in other projects. Especially the modem stuff seems a bit complicated.

    Your AX25 framing implementation seems good enough.
    But I am not sure about something. Do you implement the bit stuffing? If yes, this is done in ax25_send_byte() ?

    Also, looking at the APRS code can you show me how exactly you format the data?
    The comments field how long can it be?
    Between time and latitude shouldn't exist a separator?

    Those are my first questions :)

  9. Yeah, I had to give credit to a lot of people...

    The AX25 module does the bit stuffing in ax25_send_byte and everything should be compatible with standard AX25 (start/stop flags, NRZ encoding, etc.). The proof is that I can decode the output from the arduino with AGWPE.

    Check out the APRS protocol reference. I'm not sure how long can the comment be. I believe the only limitation of APRS is the one AX.25 imposes itself (ie, a packet can't be > 256 bytes).

  10. Javi-

    I have to ask why you are not using the ATmega @ 3.3V. Is it because you need to run it with a 16MHz crystal for the code to be timed properly? If not, then you could clock it at 8MHz and run it at 3.3V, eliminating a bunch of shifter circuitry for the MX146 and GPS. Any thoughts about approaching it that way?

  11. Paul:

    I decided on the 5V design because most likely I'll be using the HX1 radio which is also 5V. I still have to interface the Venus GPS which is 3.3V. Timing-wise I'm not sure the 8 MHz will make a big difference. The modem routines take into account the F_CPU value and scale down accordingly, ie. the PWM noise frequency would become 62,5 /2 = 31,25 KHz which is still far away from the audible spectrum.

    On the other hand, if you use the MX146 module, everything becomes 3.3V and all the translation problems go away...

    Overall, I would say the answer is fear of the unknown :)

  12. Hello Javi,

    reading the ax25.h i see the following:
    struct s_address
    char callsign[7];
    unsigned char ssid;

    As far as I know a callsign is max 6 chars.
    And the ax25 address is 7 chars (callsign + SSID).
    Why do you want 7 chars for the callsign?

  13. The 7th char is C's string terminator (\0). I could treat callsigns strictly as 6-char arrays, ie:

    char *c = {'E', 'A', '5', 'H', 'A', 'V'}

    but I think it's more readable to treat them as strings at the expense of the 3 or 4 extra bytes.

  14. Oh, damn! I shouldn't have ask such a thing!
    Maybe I need a coffee break :)

    Something else.
    Can you send to your GPS module special NMEA crafted commands in order to shut down various things?

    With my GPS I can disable all kinds of things.
    That's might cause some power saving and less parsing. I have only enabled the GGA and RMC messages making the GPS UART to output less.

    Those are the commands I successfully use:

    #define RMC_ON "$PSRF103,4,0,1,1*21"
    #define RMC_OFF "$PSRF103,4,0,0,1*20"
    #define GGA_ON "$PSRF103,0,0,1,1*25"
    #define GGA_OFF "$PSRF103,0,0,0,1*24"
    #define GSA_ON "$PSRF103,2,0,1,1*27"
    #define GSA_OFF "$PSRF103,2,0,0,1*26"
    #define GSV_ON "$PSRF103,3,0,1,1*26"
    #define GSV_OFF "$PSRF103,3,0,0,1*27"
    #define WAAS_ON "$PSRF151,1*3F"
    #define WAAS_OFF "$PSRF151,0*3E"
    #define DEBUG_ON "$PSRF105,1*3E"
    #define DEBUG_OFF "$PSRF105,0*3F"

    Hope it helps.

  15. Surely you can:


    Check out the Serial lib docs but that should do it.

  16. Javi, I know and use that stuff. I just passed them to you in case you didn't know them. :)

  17. Ah, thank you. I thought it was a question :)

    I'll probably do that. Here's another suggestion for you: The Venus GPS has a "power save" mode and it supposedly re-acquires the fix quickly after resuming. Maybe the SiRF chip can do it, too? That should save lots of power.

  18. Hmm..

    How is it possible to send it to sleep? I don't know if that is possible with SiRF.

    Also, at your code. In modem.cpp you write: "int SPEAKER_PIN = 3" . What speaker is this and why on pin 3 when pin 3 is already reserved by PWM_PIN in config.h ? Do I need a speaker ?

  19. Hmm... The SPEAKER_PIN and PWM_PIN are the same thing. I believe that's fixed in the latest code snapshot. It should really read "int SPEAKER_PIN = PWM_PIN"

  20. Ok solved. But again why do you declare such a constant?
    Why don't you use straight the PWM_PIN?

    Eg. pinMode(PWM_PIN, OUTPUT);
    Instead of pinMode(SPEAKER_PIN, OUTPUT);

    What's the purpose of naming it "SPEAKER" ?

  21. hehe, ok.

    I went to an RF shop about two hours ago and there were some HAM people I know. I told them about the project and they're willing to help me.

    I bought a 19cm VHF omni antenna. They told me that with that antenna and HX1's 300mW I will not get too far. Even with a good beam antenna from the ground I will hardly get a signal from the balloon if it is on a height of >10km.

    What type of antenna are you planning to use for the aprs of the balloon?

  22. I just learned that the AGWPE software from belongs to a HAM mate from my city !!!

    I'm from Thessaloniki, Greece and my callsign is SW2HYX.

  23. On the balloon, I'm planning on using this antenna I built from coat hangers I dug out from the trash. On the base station I will use a yagi antenna I also built with a few rods from Leroy Merlin.

    I'm also worried about the antenna range, but check out this guy's page. He reached 600 km with the HX1. Apparently propagation gets much better with altitude.

  24. Oh man your antenna is big. How much .cm is it really?
    Maybe I go and change the antenna with something bigger.

    Yes, I have seen this page before. I hope he is telling the truth :)
    In his site I found another aprs that has an amplifier and outputs 10W !!!

  25. The omni is ~50 cm long (it's a 1/4 wave ground plane antenna cut for 144,8 MHz). The 5-elements yagi is much bigger, around 2m long :)

    I seriously considered using the 70cm band, which would result in a MUCH smaller antennas, but all my equipment is 2m already. Plus, the standard APRS frequency is 144,8 MHz and I'd really like to be igated by local digipeaters to maximize the chances of recovery.

  26. This comment has been removed by the author.

  27. Hey Javi,

    I went to a local RF shop and changed the small rubber omni with a 50cm telescopic :)

    Now I have finished with the ARPS system and I think I'm transmitting but I must find a person with a receiver to verify that :):)

    In your code I see this: "unsigned short int crc"
    Is there an explanation for the "short int" or just again a messy code situation ?!?!

  28. Javi !!!

    It works !!!

    I get iGated !!!


    Man thanks a lot. Your work is great.

  29. Great! You seem to be reaching out ~70 km away. How much power are you transmitting with? Do you have a picture of your antenna or any reference I can check on-line?

    As for the "unsigned short int"... To be honest, I really stole the crc calculation somewhere else but I do agree with it. If that code ever gets ported to a 32-bit platform, "int" would become 32 bits whereas "short" stays 16 bit long (most of the times).

  30. ...and the antenna is at home behind walls...Think the difference when it will be on open air.. Really, where did you see the 70km? Can you show me?

    I'm transmitting with HX1's 300mW. Nothing more. (Should we add an amplifier to the project ?!?!)

    My antenna is called "DIAMOND RH789" and I found you a link:

    This is a photo of my work:

    I'm asking you those program-related questions because I see that from the 2KB of RAM on the ATmega328 after a transmission only ~200 byte are left free. So I try to reduce some memory allocated space. I wrote my own nano-GPS class for exclusive use from this project.

  31. Javi, I am interested in discussing your project via email. I am working on something very similar (Same end product goals) but may have a slightly different approach that may eliminate headaches down the road. I'd email you, but I can't seem to find it on your site. Can you reach me at

  32. zeckalpha, why don't you share your ideas with us? That's the purpose of the blog.

  33. I was able to get my custom Arduino board up and running with the Trackuino firmware @ 3.3V/8MHz thanks to Javi's help. Details are on my website at As I do more development/experimenting, I'll make sure to keep that site updated to share my progress with the community.

  34. Kon: go to SW2HYX-5. Under "stations who heard you directly" you can see SZ7SER in Serres, which is 70.0 km from you.

    Your other callsign (-11) seems to have a distorted distance value (>8000 Km), I have no idea why.

    Also, the "qAR" in the path indicates that SZ7SER heard you directly on RF

    It's really unbelievable that you're getting that far with 0,3W and indoors!

  35. Javi, where does SW2HYX-5 come from?
    My source callsign ssid is: 11.
    How Am I the 5?

    I'm also talking with some guys on IRC who have done many flights and they told me that with a radiometrix 10mW module at 433MHz they heard it from 550Km away.....

    Also they informed me that a GPS called ublox can reach 50km altitude.

  36. I just sent a 433 MHz module over 1200 km...

    That wasn't doing GPS though.

  37. Hello Javi,

    I now plan to build my receiver. Using Radiometrix NRX1 144.8 receiver with an arduino. From that, I can have serial output to a computer. Then build some graphical pc software which reads those values from serial port.

    But I need the code for demodulation of the FSK signal and the code for the decoding of AX25 frame.

    Do u happen to have any experience on this?


    KI4MCW seems to be making progress in that direction. I'm working on a project which is a combination of that and this... But the emphasis will be on the tracking.

  39. Demodulating FSK is much more complex than modulating it, since you need to sample the analog signal and discriminate the mark/space by detecting the frequency of the signal. There are two ways (at least):

    1. Zero-crossing: check how many times the signal crosses 0 volts and that gives an approximate idea of the frequency. This is simple, but vulnerable to noise. The WhereAVR project does it this way.

    2. Autocorrelation method: this is the optimum way. You can rebuild the original train of 1s and 0s by multiplying the FSK signal by a delayed copy of itself and low-pass filtering the result. There is a nice explanation of the process here. And an implementation here.

    I don't know how KI4MCW is doing it, but the project looks interesting.

  40. Do you plan to include a demodulation part with NRX1 in trackduino ?

  41. Is it possible to use RadioShield
    with NRX1 ?

  42. Kon: I might add AX.25 decoding in the future, but not immediately.

    I don't know about the radio shield, but it has a dedicated MCU for packet encoding/decoding, so I'm sure it will work. I wouldn't use it personally because I want to keep power usage as low as possible and 2 MCUs are overkill, but if you try it, I want to hear how it does.

  43. I am developing a version of the Trackuino firmware which should add support for the RadioShield, and for the Adafruit Data Logger, as well as to modularize the Ax.25 code and the GPS code so more GPS units are compatible, and so we can transmit telemetry and other sensor data. Eventually adding receive capability with a device such as the NRX1, or a DTMF decoder would allow for remote control.

    Current Status: Waiting for parts to arrive.

  44. This comment has been removed by the author.

  45. Javi,
    I'm not sure if the RadioShield can also perform AFSK demodulation. Can you verify that for me?

    Then, simply wiring pin ( 6 or 7 ? ) of NRX1 to RadioShield's RX pin will just work?

    I'm going to use the receiver at my side not to the balloon. So I don't mind the power consumption.

    I'm just happy we have a third person contributing to this project :)

  46. Hi,

    First i want to thank you for your great work :-)

    I have a problem with rebuilding the trackuino. I am successfully receiving the ax25 packets, but it's not interpreting my GPS signal. I only get:


    What NMEA Sentences does it expect? This is a typical Output of my GPS in the Living Room with no satellites in view. Does it matter if there is a fix? I tried it outdoors too with fix, but the result was the same.


    The GPS is an Haicom HI-203E

    I think that it's connected right. I connected TX from GPS to RX Pin0 on my arduino, and RX via the diode method to the TX Pin1 on the Arduino.

    I hope you can understand my question, my english is not very good. I would be very very happy if you could help me :)

  47. martine185-

    In my testing with this firmware, it will always output an APRS packet at the specified interval, but if you don't have a GPS fix the location shows up as all zeros. You can have it running and when the GPS data becomes valid, it will start sending out APRS packets with proper location information.

  48. martine185:

    In that particular snippet, the "V" in the $GPRMC sentence (after the 2nd comma) indicates that the GPS doesn't have a valid fix yet (A=active, V=inValid). Try leaving the GPS outdoors a bit longer (some GPSs may take up to 5 minutes).

    If your GPS takes too long to fix, see if it has the so-called "assisted mode". If it does, you can upload the ephemerides of the next 7 days and it will improve the time to fix greatly...

    Also, your GPS doesn't seem to be reporting the speed/course data (after the 7th and 8th commas), but that shouldn't be the root of your problem.

  49. martine185: I remember I made a sketch to verify that the GPS was properly connected and the Arduino was receiving data. I uploaded it here: gpsdump.pde.

    Connect the GPS to pins rxPin, txPin and you should see GPS data on the IDE's serial console.

  50. Thanks for that, now i know that the GPS is connected properly.

    I only changed mySerial.begin(9600) to mySerial.begin(4800) since my GPS puts out at 4800 baud/s

    Does your trackuino want a 9600 bps signal? And if yes, is there a way to give it 4800 bps?

  51. @Digital:

    I will try again with a Fix then. Thanks.

  52. Sure, open the sketch, look for Serial.begin(9600) and change it there.

  53. I changed the mySerial.begin() to 4800, the Serial.begin is fine, because i can change the baud rate in the arduino IDE.

    So i'm getting valid gps data. But when i connect it to Arduino Digital Port 0 (RX) (and upload the software wuth an "make upload" it doesn't work. I have still only zeroes.

    Valid GPS Data gathered with your sketch is like that:







    Do you have any ideas? Should it work with that kind of data?

  54. I mean replacing 9600 with 4800 in the trackuino code (trackuino.cpp if you downloaded the gcc-avr bundle or trackuino.pde on the IDE). It's somewhere around the setup() function.

  55. Javi, I almost finished my APRS box.

  56. Javi hello again,

    I just got the radioshield. It decodes the aprs fine. But there is an issue. I'm testing the whole stuff at my home. The HX1's 300mW are heard too loud from the radioshield and that makes it not to decode anything. Now I'm thinking of buying another module same as HX1 but with lower output. Example:

  57. Hey kon, it's been a while! Your box looks great! As for the RF issues... when I was a kid my parents gave me an R/C car as a present and I remember that the car wouldn't work if the transmitter was too close to it. So... try moving the the devices further apart? To be honest, I'm terrible at RF, so I don't have the slightest idea what your problem might be... :)

  58. Javi you'd better join #highaltitude at I'm there the last 2-3 months. People help a lot.

  59. I see this is designed for a ATMega328, is there any I can make this work with a Mega2560?

  60. EcoMan: good question... I've never tried myself, but I believe the atmega2560 is a superset of the 328 in terms of cpu and ram, so it should be doable after reviewing and maybe porting all the 328-specific routines that use registers to access the hardware directly.

  61. Hi,
    I'm trying to make my own balloon tracker based on the Trackduino, using the Venus and the HX1. I have a question about the HX1 input.

    What exactly is the waveform into the HX1 supposed to consist of? Serial data at CMOS logic levels? Analogue waveform consisting of 1200Hz and 2400Hz waves at 0..5v amplitude? PWM emulation of the analogue waveform? I can't seem to find any documentation that unambiguously states it?

    Many thanks for any help.