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 large packets (up to 792 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.


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.

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.


25 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!

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>