- Important info!

MicroModem is now discontinued, and I will not be producing any more units for sale. All information on this page is historical and for reference purposes.

If you want a complete, pre-built unit, please have a look at OpenModem instead. It offers a much more powerful feature-set, is easier to use, and is the platform I will be developing in the future.

While I will not be producing more MicroModems or developing the firmware further, all resources for MicroModem, including software, schematics, build-info and source-code will be kept available for existing installations, and for any users that still want to build their own MicroModems.

If you want to build your own AFSK1200 modem, MicroModem is still a very viable option, since it is easy to build, and very well documented. It is also incredibly stable, with many units in the field running for years at a time without issues.

What is it?

MicroAPRS is an APRS firmware for my open source AFSK1200 modem, MicroModem. By flashing the firmware to a MicroModem or a compatible build, you can use it to send and receive APRS packets. On this page you can find general usage information and the latest pre-compiled firmware images.


  • Send and receive APRS packets with almost any radio
  • Easy to use input and output connections (standard 3.5mm TRS jack in version with case)
  • PTT trigger functionality
  • Transmit and receive LEDs
  • Supports running with open squelch
  • Supports KISS serial protocol
  • KISS firmware supports packets up to 564 bytes
  • Supports a simple serial protocol for easy use with Arduinos and the like
  • Full P-persistent CSMA support in KISS mode

Can I buy it?

Yes! If you don't feel like building it yourself, I sell a completed version flashed with the MicroAPRS firmware of your choice, fully tested and ready to go. Just visit my shop and browse through the options! Buying the modem from me helps me fund continued development of the firmware and hardware.

Download Latest Firmware

There's currently two versions of the APRS firmware available, a version using KISS and a version using SimpleSerial. Take your pick, download, flash and enjoy! If you have the old version of the hardware, select the 5V reference build of your chosen version. If you have the new hardware version (greater than 2.0 printed on the PCB), select the 3.3V reference build.

You can flash the firmware with avrdude or similar programs. Using avrdude, the command would look something like:

avrdude -p m328p -c arduino -P /dev/ttyUSB0 -b 115200 -U flash:w:MicroAPRS.hex

Changing settings in KISS mode

Most KISS compatible software supports changing the preamble time (called TX delay in some programs), tail time, persistence and slot time parameters over the serial connection.
It's important to note that some programs (Xastir, for example) will reset the modem when connecting to it, and then immediately send configuration commands. This has the unfortunate effect that the configuration commands are sent to the bootloader, instead of the booted firmware. If your program does not allow you to disable resetting or to set a delay for sending the configuration commands, you can manually disable the reset functionality by connecting a resistor of around 100 ohms between the VCC and DTR pins. This will ensure that the modem is not reset, even if the host program sends a reset command.

KISS General Info

When running the KISS version of MicroAPRS, packets are sent to and from the modem in KISS serial format. The kiss interface is running at 9600 bps by default. Simply point your software at the connected serial port and you should be good to go. MicroAPRS supports a subset of the KISS configuration commands. At the moment only TXDELAY and TXTAIL are implemented by the firmware. Please note that TXDELAY will set the packet preamble time! This is not standard behaviour, but since there is no standard way of setting the preamble through KISS, this was more useful than just setting the "silent" delay before a packet is transmitted. The CSMA parameters can also be set via KISS.

SimpleSerial General Info

Commands are sent to the modem over a serial connection. To connect to the modem, use 9600 baud, 8N1. Generally, the first character of your command specify what you want to do, such as setting an option or sending a packet. For example, you can send a packet with the content "Hi APRS" by sending "!Hi APRS" to the modem. The "!" character specifies that all following data should be treated as packet content, and be sent out. But please note that "Hi APRS" is not really a valid APRS packet, even though it will be sent out, digipeated and such just fine. It just doesn't follow any "supported" packet format.

SimpleSerial commands

Command Description
!<data> Send raw packet
@<cmt> Send location update (cmt = optional comment)
#<msg> Send APRS message
c<call> Set your callsign
d<call> Set destination callsign
1<call> Set PATH1 callsign
2<call> Set PATH2 callsign
sc<ssid> Set your SSID
sd<ssid> Set destination SSID
s1<ssid> Set PATH1 SSID
s2<ssid> Set PATH2 SSID
lla<LAT> Set latitude (NMEA-format, eg 4903.50N)
llo<LON> Set latitude (NMEA-format, eg 07201.75W)
lp<0-9> Set TX power info
lh<0-9> Set antenna height info
lg<0-9> Set antenna gain info
ld<0-9> Set antenna directivity info
ls<sym> Select symbol
lt<s/a> Select symbol table (standard/alternate)
mc<call> Set message recipient callsign
ms<ssid> Set message recipient SSID
mr<ssid> Retry last message
ma<1/0> Automatic message ACK on/off
ps<1/0> Print SRC on/off
pd<1/0> Print DST on/off
pp<1/0> Print PATH on/off
pm<1/0> Print DATA on/off
pi<1/0> Print INFO on/off
v<1/0> Verbose mode on/off
V<1/0> Silent mode on/off
w<XXX> Set preamble time in ms
W<XXX> Set transmission tail time in ms
S Save configuration
L Load configuration
C Clear configuration
H Print configuration

SimpleSerial Examples

To set your callsign to XX1YYY-5, and then save the configuration, send these three commands:


To send an APRS message to ZZ5ABC-1 with the content "Hi there!", send these commands:

#Hi there!

To send a location update, with the comment "MicroAPRS", you can do something like this:


To send an APRS message to ZZ5ABC-1 with the content "Hi there!", using a raw packet, send this command:

!:ZZ5ABC-1 :Hi there!{01

Here's an example of how to send a location update with power, height and gain information, using a raw packet:

!=5230.70N/01043.70E-PHG2410Arduino MicroAPRS

Connecting to a Radio

You will need to connect the Audio In port of the modem to the speaker output of your radio, and the Audio Out port of the modem to the input of your radio. Most handheld radios will need microphone level audio on the input port, otherwise the transmitted audio will distort, making packets hard to decode. You should also also connect GND from your radio (usually the GND pin of the speaker jack) to the GND port of the modem. The PTT circuit works by closing a switch (using a MOSFET) between the PTT+ and PTT_GND pins. Most Kenwood-style handhelds will have +3v on the ground pin of the MIC jack, that will trigger PTT when connected to the ground pin on the SPK jack.

42 thoughts on “MicroAPRS

  1. Hi there, just to let you know I have the micromodem up and running.
    I would like to know if can connect the micro modem to a icom HT or a mobile radio.
    Please let me know, thanks.

  2. Hi.
    I want to download KISS MicroAPRS firmware: 3.3V reference / 5V reference and SimpleSerial MicroAPRS firmware: 3.3V reference / 5V reference But no download Link to download again.
    thank you very much

    1. Hi there!
      The download links are right on this page, under the Download section. Are you having problems downloading them? Could you explain what is going wrong?

  3. Hi
    It is possible to buy “Ready to go” with APRS code inside ?
    and can you provide wiring with an arduino Mini (serial tx-rx) ?

    1. Hi there!
      Sure, I ship the modems built, tested and loaded with APRS firmware as standard 🙂

  4. Hi!
    I have just built the MicroModem and I’m using the MicroAPRS firmware.
    Since there is almost zero APRS traffic where I live, I connected one of my Baofengs (UV-82) to send using APRSDroid in VOX mode. The MicroModem is connected to my other Baofeng (UV-5R) and when the volume is at the maximum, it decodes the messages and shows it nicely both in cutecom and xastir. I have built the “777a080” version of your git repo, both for serial and for KISS. I guess that the 5V/3.3V reference means if the 5V or 3.3V pin on the Arduino is used against the A0. I’m using Arduino Nano and 5V, so I built for 5V reference.
    But now to the strange thing. Today I made a “field test” where I went to a bigger city nearby to try it out, because there’s more APRS traffic there. The strange thing is that when the device was up and running, I could hear APRS traffic in my radio that was not connected to the MicroModem but the radio that was connected to the MicroModem did not even open (the receiver LED on the radio did not lit up). I switched radios, so the other one was connected to the MicroModem, but the result was the same, the radio that was connected to the MicroModem did not receive anything but I could hear a lot of traffic on the radio that was not connected to the MicroModem.
    Do you have any idea what the source of this problem could be? It seems that the MicroModem is somehow changing the radio’s behavior.

    1. It might have something to do with the UV-5R getting another ground reference.
      I just realized that when having the UV-5R in its charger cradle while on, the performance decreses noteciably. Just by lifting it up from the cradle and I get a lot of traffit, putting it in again and I get almost nothing.
      @markqvist, I see you use a UV-5R in your youtube clips. Have you experienced such issues and do you have any comments?
      Thanks for a great product!

      1. Hmm, that’s very strange! I have never experienced anything like that before. As you saw, I also have a couple of UV-5Rs. One of them I use as my primary APRS station, and I have been using it sitting in it’s charging cradle for months at a time connected to a MicroModem with no problems, and plenty of packets coming trough. I really hope you figure out what is causing it! If you do, please share the knowledge!

        1. I was now trying my UV-82, and had the same problem with the cradle. As I got a US version of AC/DC adapter when I bought the UV-5R, I have used the EU adapter I got with the UV-82 for both of my Baofeng HTs (same specs but different model numbers).
          Now I found my US to EU converter and tried the AC/DC adapter I got with the UV-5R and I found out that my UV-82 works much much better using this AC/DC adapter!
          The bad adapter model is: A-88
          The good adapter model is: 480-10050-E.S
          As I have written before, I have also had some problems when I did a field test on battery only, but I don’t know if that was an USB ground issue as I used MicroAPRS with another computer (a Dell laptop). Right now it seems that my UV-82 opens a lot when connected to a RPi, both with and without the 480-10050-E.S AC/DC adapter.

  5. Mark:
    I want to be sure I am working with the correct and latest version to implement a serial modem. the MicroModemGp (loaded 2-3 months ago from July 2015) is the latest?
    Its a little confusing because the note at the bottom of that page says it is NOT Arduino IDE compatible? I thought the latest version was Arduino IDE compatible. Sorry please help clear up my confusion. Where can I find the Arduino serial version? And then maybe you can show me exactly how to enable CSMA without KISS 🙂 Thanks

  6. Mark,
    Thank you immensely for generously sharing your fine work. I’m really impressed with your über-slick Bell 202 modem in software! As I’m trying to learn from your source code, and having a problem with the outcome of the resulting binary, I am hoping that you can comment. With your pre-built .hex file, my Nano on a breadboard transmits and receives just great! However, when I build the binary (Mac OS X using the latest CrossPack-AVR tools) the resulting .hex file doesn’t seem to result in the PTT line being driven high or FSK being generated via the four resistors when I try to transmit something. The menu system works fine (I’m building with the appropriate KISS define commented out and Simple Serial definition uncommented in ‘defines.h’), but when testing on the same hardware that worked flawlessly with your pre-built image, there is no transmit. I didn’t try receive yet so can’t comment on that.
    Do you have any ideas what might be amiss? Your makefile doesn’t seem to set any optimizations or other defines that perhaps your development system’s IDE is passing along during the make operation. My .hex file is some 41 bytes smaller than your pre-made one for the same 3.3v with Simple-Serial functionality (56,141 vs 56,182 bytes). Perhaps there is a interrupt table or something else not being built in mine. ??
    And one last question, if I may: I cannot for the life of me find where your function “AFSK_transmit()”, in AFSK.c, is being called from.!? I’m building from the current master branch revision at your MicroAPRS GitHub page, btw. When I called that function from main(), just to test, the PTT does go high as expected but still no output on the 4-bit DAC. I’m puzzled.
    Thanks so much. -Paul

  7. Mark,
    I built the MicroAPRS source on both a Mac OSX host and also on a Windows XP host with the same result. Although your pre-compiled binary file (intel hex) for the Simple Serial 3.3v version of code works fine on my hardware, the ones that I compiled with the same options are both end up identical when a diff is done but they are both 41 bytes shorter than your .hex file. When running they received FSK data fine, and the Simple Serial protocol menus function as expected, but the hardware doesn’t send it out the 4bit DAC for some reason (those bits are all low as is the PTT output bit).
    I’m wondering if the source on your GitHub page is broken and the pre-built binaries are from a different, good build? Or is there something that you suspect I may be doing wrong in my building of the binary from source?
    Thanks, Paul

    1. Hi Paul
      The precompiled ones should be from current source, but I’ll have a look. There was some recent changes by other contributors to the codebase that might have changed something I was not aware of. I’ll let you know!

      1. In the meantime, try an earlier commit from the github repo and see if that builds and works

  8. I built various versions and clearly found that the code changes committed on Oct 2, 2015 have broken the D-to-A and PTT functionality. There are numerous bugs in the code as a result of someone trying to make the code more portable / maintainable… but blowing it with wrongly understood bitwise boolean operations. I can only surmise that the code was checked back in without first testing it. Email me if you want specifics as I know where a few of the biggest smoking guns are. Or I can litter the comments section here further, if you prefer.

  9. Hello there namesake!
    While the KISS mode and the SimpleSerial modes are obviously mutually exclusive, have you thought about implementing the latter within the former using the SetHardware (0x06) command? I don’t suppose implementing it that way would make the firmware size much bigger but on the other hand would allow for the MicroAPRS to be configured even in KISS mode.
    Or perhaps you could implement a SetHardware command to drop into SimpleSerial mode and add a command in the SimpleSerial parser to activate the KISS mode in turn?
    I wonder if any existing product may have already used something like this so there would be some kind of de facto standard for this already.
    This idea reminds me of the +++/ATO commands of the modems.

    1. Hi Mark!
      I actually have thought of that. It would be a nice feature have, and would save having to flash firmwares to change functionality, but I’ve been holding off on it for two reasons, one being, as you mention, that there doesn’t really seem to be a standard about how to do this with KISS commands. At least I haven’t really been able to find any consensus on it.
      The other reason is a bit more technical. While there should easily be enough flash space to include all of the functionality in one firmware file, there’s a much larger constraint on RAM, and thus I need to be very conservative when allocating buffers and variables in the code. The two firmware variants have slightly different input and output “pipelines”, and the 2K RAM limit simply doesn’t cut it for allocating everything at once, and then just switching back and forth between the modes. This obviously entails needing to do quite a bit of memory management when switching back and forth, and I’ve not really wanted to go down that path 😉 Not yet at least. If I really feel the need for a head-scratcher I might fork the firmware and try and implement a combined one 🙂
      I concur though, it would be really neat!

  10. Mark,
    Great job one the software! I have a question about implementing and parsing received strings/messages. Do you have any examples using the simple serial firmware?

    1. Hi John,
      Thanks a lot! Unfortunately I don’t have any examples on hand of that. I know it can be a bit daunting with string buffers and such on the arduino. What specifically are you having trouble with?

  11. Hi Mark,
    My trouble was not being able to find decent examples of APRS decoding. However, I’ve now discovered LibAPRS – Thanks so much for doing this – and sorry for wasting the bandwidth!

  12. Hey Mark,
    I was wondering if it’s possible to do this sort of thing with a blind connection to the audio jack in a radio. For instance would it be possible to setup a Raspberry Pi or something similar with a cable [0] connecting to it’s audio port and your software running in the system?
    I’m more of a software person so I don’t know much about interfacing with hardware but doing something like that is far less intimidating for me and I’d love to setup a few services that could use this sort of ARPS setup. Do you think this is doable and do you think your software would work for that use case?
    [0] – https://store.mobilinkd.com/products/kenwood-wouxun-baofeng-tnc-cable

  13. Hi I have built the microAPRS and flashed it with the simple Serial firmware and it works! But, I have a problem that when I was testing it, I tested it with the radio antenna off so as not to cause interference. When I put the antenna on and try to send a packet, the PTT button doesn’t turn off untill after a long timeout period. Do you know what could be causing this? I’m using a Baofeng UV-5R. Thanks.

    1. Try to move the radio a little further away from the modem, or add some ferrite beads to the cables between modem and the radio. The RF is probably inducing a bit of voltage in the lines, and thus keeping the PTT transistor open.

  14. Mark,
    This is a very nice looking APRS modem. I’m wondering, though, if it could be used for communicating with digital satellites that have APRS digipeaters (primarily the ISS and NO-84). Can your modem be set up to receive all APRS messages (monitor mode)? Can your modem be set up to use connectionless operation (unproto)? These are both needed for communicating with digital satellites using APRS. – Thanks!

  15. @Brian. Might be kinder to your radio to use a dummy load – you never know how well protected the finals are 🙂 73

  16. hi!
    We want to communicate with the smartphone’s audio port.
    I wonder if you can communicate with your MicroModem.
    Please answer as soon as possible.
    Thank You..

    1. In theory, it should work, but I have not tried this myself yet. Maybe I will give it a try to test it out.

    2. Ok, I ran some tests, and while I would say that it is possible, it is not very practical, unfortunately. It seems there is a lot of digital noise filtering on cell phone lines, and very often, the modulated audio signal will simply get filtered out by the network. I was able to “cheat” the filtering by adding a few clean sine tones just before sending the data, but it was in no way perfect.
      Over analogue phone lines, the modems should work perfectly, but over digital cell phone lines with filtering it just doesn’t work well.

  17. I’m trying to get to takeoff with this, but as usual I study it closely. I noticed on one page you had sent LAT LONG co-ordinates to a modem and then looked at APRS.FI and could see your modem. Perhaps not you, but was done. IF a laptop or win tablet had a gps in the ups port, wouldn’t it be possible to get software to do that job ? I have an expensive UPS GPS and wondered if there were any software packages which co-ordinate the GPS, Laptop, and your modem ?

    1. Hi Michael
      Yes, there are various software packages that can do what you are talking about. I mostly use Linux, so I have been using the program “Xastir” for this. You can connect GPS and Modem and the software will coordinate it all. There is also a Windows program called “UI-View” for the same purposes, but I have not really used it myself, so I am not sure about what features it has, but I think it will also do what you want.

      1. OK, I’ll check out UI-View and also try again with a laptop with Linux loaded, trying Xastir. I felt stumped with the Linux laptop because either I was trying to load software and doing something wrong, or it has a problem with the Linux I loaded. Probably the first suggestion as I do not know Linux.

  18. Hi Mark – I need some help regarding the files on your GitHub. I know I can upload one of the .HEX firmware images. But I’d really like my students to see the underlying library and sketch files – kind of “getting their hands in the engine” rather than just getting in the car and turning the key. I can see all the files in your GitHub repository – stuff like AFSK.h and ax.25.h. But I’m just not sure how it all goes together. If I was uploading a sketch from scratch, say something to blink a series of LEDs, I would have a sketch that referenced a series of library files. But I don’t see anything that’s “the sketch” that I upload to the Arduino. Am I missing something?
    — Markus K1FIG

  19. Hi Mark,
    I have a question regarding APRS paths in modem settings:
    1. Is it possible to use just a single path (i.e. only WIDE1-1) in MicroAPRS?
    2. For some reason I am not able to change PATH2 SSID – option “s2”. As an example, setting “s21” still results in WIDE2-2 path.

    1. Hi Mike
      Regarding question 2, that’s probably a bug, I’ll look into it. As far as I remember, there’s no way to use a path with only one component. That’s a bit weird in hindsight, but I’ll look into implementing it next time I’m working on the code. Thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *