Menu

Hey, if you like MicroModem, you should check out my newest project, RNode!

What is it?

MicroModem is an open-source implementation of a 1200-baud AFSK / Bell 202 modem on the popular ATmega328p microprocessor. MicroModem can be used for things like ham radio APRS, AX.25, TCP/IP over SLIP, experimentation with mesh-networks, long-range wireless communication with sensors (Or friends! Or strangers!). It basically comes in two flavors: Prebuilt or DIY.

It is simple enough that, if you have some basic electronics experience, you can understand and build it yourself with a few components and an Arduino. You can also get a more advanced and prebuilt, fully tested MicroModem directly from me. I manufacture them personally, to the highest quality.

Please note that the resources listed here for building your own MicroModem are for an earlier, more simple version, than the one I currently offer for sale. While the two modems are functionally identical, the version I offer for sale has some technical refinements, and is implemented as an integrated board with MCU, USB and everything on one board, measuring only 3×5 cm.

Can I buy it?

Yes! If you don’t feel like building it yourself, I sell a completed version flashed with the 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.

Resources

Firmware downloads

There’s currently several different pre-compiled firmwares available for MicroModem. 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.

How do I build it myself?

If you want to build MicroModem yourself, you should have a look at the GitHub repository for MicroModem. It contains all the source-code, schematics, PCB layout, documentation and everything you need to get started. If you’re not familiar with GitHub and just want to get going, here’s the basic resources:

If you want to use this for APRS, take a look at MicroAPRS, the APRS firmware for MicroModem

The general-purpose firmware

The MicroModemGP firmware is ideal if you want to build your own applications running over radio, or just want to experiment. It lets you send packets over almost any radio with up to 792 bytes of data per packet. This means you can also use SLIP to use the modem as an TCP/IP interface. The MicroModemGP firmware features forward error correction (12,8-hamming code), 12-byte interleaving, and CRC checksumming on all packets. It should be easy to expand the protocol to support addressing and routing, encryption, or whatever you find useful. If you have a cool idea but aren’t sure how to go about it, let me know and I will try and help! The protocol was written as an example of how to implement a basic protocol with error correction.

Don’t expect live video-streaming and rocking out to DI.fm over this though. This is only 1.2 kilobits per second. Loading Hackaday Retro took around 15 minutes when I tried. If you’re not using TCP/IP you will have better throughput than that though. But TCP/IP works fine for very simple synchroneous-style connections (like: connect to server -> send request -> wait for response -> send another request -> receive another response -> disconnect). Anything complicated, and you will get a lot of packet loss!

Other Notes

I designed MicroModem to be as simple an introduction to digital wireless communication as possible, while still being very flexible and functional. Micromodem will let you learn the basics in how to build digital wireless systems from scratch, and also offer an interesting platform to build further projects on. I hope you will find it educational and useful!

The source code for the modem firmware is very heavily commented, and should be easy to understand. In fact there is more comments than actual code most places. Some of the concepts can be a little daunting just from looking at the code, but it is actually all quite simple, when taken one step at a time. If you have any questions, drop me a comment here and I will try to help out.

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. The PTT connector supplies a logic-level PTT signal. If you can trigger your radios PTT like this, use this connector instead.

81 thoughts on “MicroModem”

I am currently working on light communication system, will be open-source of course that and will probably adapt MicroModem for communication. For this however no AFSK is needed, just serial transmission. Any thoughts how the most input/output serialized data to MicroMode without changing the rest?

Hi Musti!
That sounds really interesting! Can you tell me a bit more about how it’s going to work? Are you going to have serial communication between two modems, directly over a wire connection, or is it still going to be over radio? Also, what kind of communication do you want to send? Is it mostly human communication, or machine data?

the idea is very simple, sending UART data across a distance with light. i have prototyped the system by sending 1200baud UART, modulating a laser and picking it up on the other end with a photodetector. Using it directly is however a problem with reliability, random bit losses etc, so forward error correction is required.

Instead of implementing this from scratch I believe MicroModem could be used, changing the AFSK part for serial bit output at about 1200baud, possibly with configurable 1 and 0 duration. Since all encoding and data processing is already done, only swapping the AFSK encoding with serial encoding should be required. Any thoughts how to best approach this?

Ah, I understand now! I misunderstood first, thinking you meant “light” as in the opposite of “heavy” 😉
That’s a very cool project! Great that it was actually working with direct UART! But yes, I can imagine there will be some loss. You should take a look at the MP1 protocol implementation in MicroModem, it has everything you need, Forward Error Correction, 12-byte interleaving and even compression if you want that (using heatshrink lib). It would be pretty simple to adapt it to just take input from the UART serial instead of from the AFSK modem. Take a look at it, and let me know if you have any questions!

Exactly my thoughts, MP1 appears to be perfect for this. Since you are working on rewriting the code away from BertOS, I would like to make my implementation on that, for it to be compatible in future. The aim is really to change only the AFSK part and leave as much as possible unchanged. Please let me know if there is any way I can start working on this before you release the code, privately of course.

Hi Musti!
The code is out now and compiles on various MCUs, without any BertOS dependencies 🙂 If you want compatibility with the Arduino IDE, have a look at the source for the Arduino library, otherwise you should probably go with the MicroAPRS firmware source, since it is more structured, and it should be pretty easy to rip out the AFSK part and just use that.

I’d really love to help you write a robust protocol with error correction, checksumming and maybe compression, but I’m taking a break over the holidays here, so I probably won’t get much done. I might give it a go in january though, if time permits 🙂

Hi Serge!
Thanks a lot! Yes, I will definitely include that as an option in both the MicroAPRS firmware and the Arduino library. Since they are both pretty new at the moment, I will wait a little until it is tested some more to add more features. There’s might be a few more bugs here and there, so I want to be confident that the base software is working perfectly before adding more exciting stuff 🙂

Question: For testing I uploaded the APRS firmware to an Arduino. It works nicely, although on my first impression the decoding is only achieved with a very clear signal (S9+).

I noticed in your layout you reference AREF to +3.3V, the input pin is centered at half of this (1.65V). Can you shortly explain (to a non-C programming master 😉 ) how you trigger the signals and at what voltage you assume your crossing-point (i.e. interrupt is driven)? I would find it promising to know this data, because we can center our signals exactly on that point and maybe decoding rate is going up?!

I’ve been looking for web server solution, wired or wireless, and the micromodem looks perfect! I originally looked at the ESP8266 but the micro doesn’t seem to have enough resources for what I need.

Do you know how much of the Atmel flash/ram is currently used for the SLIP/KISS implementation? I’d like to have it read a few sensor data inputs and present the data as a webpage to a host connected via usb-serial. Do you think it would all fit?

I guess along those lines, I have a vague understanding of SLIP, but I’m not really sure what KISS is or if it can be removed to make room for more web pages. Which files implement SLIP? Is KISS a common protocol that’s needed to run on top of SLIP?

Also, I know it’s a loaded question depending on many factors, but do you know as a rough ballpark how much current the micromodem board takes when it wakes up to communicate a few KBs over serial and then goes back to sleep?

Did you work out the method for a digital (not AFSK) interface.
I would like to try this with digital modems I have. First try will be with the Sunrise VHF module which has a 1200 baud digital input option. But they don’t do any processing internally – its up to the user.

Is the functionality there to use the traditional converse mode? Which is a one to one station connect, or one to one via a digi or another station. If not i’m sure it wouldn’t be too difficult for me implement..

The other mode is general packet sending, or one to many type protocol. Which is what aprs is, but this would be for packet sending. From the sound of it, it already does this now..

Thanks, and what are the chances of getting one of these? I see they are both out of stock.. which is good in a way..

I have a few applications I’d be interested in setting up, our club helps alot with public events, and are always looking for more reliable and better ways of doing things.

You can use MicroModem for one-to-one converse mode. The MicroAPRS KISS firmware is really just a KISS-compatible TNC firmware, so it will work for anything that talks KISS over the serial port. I did test this out with AWG Packet Engine on Windows at some point, and it worked fine 🙂 The converse mode is not built directly into the firmware though (but could be, if someone wants to implement it).

This little Dorji like device is inexpensive and different from the dorji in one interesting way. It can accept digital packets.
I’m more a radio guy than an arduino guy (although I’ve made great strides in the last 2 months thanks to this threads motivation) , how would one modify the code to output the processed digital data via uart, and not as an afsk. Thanks

I only implemented the HDLC and KISS stuff to enable the transfer of sensor data from remote sections of my irrigation system by sharing the wiring the valves use. As with many things, this got superseded by new technology (in my case nrf24l01+ modules).

I still add stuff to BeRTOS on occasion, the nrf driver I’ve implemented is in regular use on both AVR and STM32 micros as are an I2C LCD driver. The modular features of BeRTOS are attractive as is the cross CPU support.

Hi Robin!
Thanks for dropping by! And thanks for your contributions to BertOS. BertOS has been a great help for me in underestanding a lot of stuff about µC programming. And I’ve probably studied your code more than most 🙂 Thanks a lot for all the stuff you’ve contributed. There’s many things I wouldn’t have been able to understand without your code.

Hi!
I haven’t actually tried it yet, but I did implement the possibility to use many alternative baudrates; 300, 960, 1600 and 2400 baud are all supported. Please note that I have only tested these locally though, and not even over a radio for some of them. So while it is possible, I make no gaurantees it will work in the real world with a HF APRS signal, but please do try and report back!

You will need to compile the firmware from source for that feature. You just need to change one line in the code. Have a look here:

Today I tried different baudrates by wiring two modems directly together. The only two baudrates I can use in this way are 1200 and 960. I recognized when I set the baudrate to 300 the RX led is always on (maybe due to the high sampling rate of 9600 compared to the low rf baudrate?).

Did anyone else got this modem to work on HF with 300 baud? What is about FSK with 9k6?
73 de Stephan DG1BGS

Hi, I was hoping for a schematic for the pre-assembled MicroModem you sell – specifically HW REV: c2.4 board. We are using that board in our payload, and having a premade schematic would be really helpful. Thanks!

Hi Mark, I am trying to get Micro Modem GP running on a ATmega328 with 8Mhz clock and 3,3VDC. I dont get anything in or out of the serial port. I cloned this software https://github.com/markqvist/MicroModemGP. I have changed F_CPU to 8000000 and changed MCU to m328. Do you have any tips for me?

Hi Øystein
I think 8MHz will be too low a clock to run MicroModemGP 🙁 It’s already more or less pushing the limits of the ATmega328 quite significantly at 16Mhz (the ADC is being driven out-of-spec already to achieve a fast enough sample rate). You might be able to pull it off by using a lower baudrate, but you might need to manually tune the ADC setup in the AFSK_hw_init funciton in AFSK.c.

The firmware is not going to output anything over serial until it gets a valid packet, but to verify that serial is working, if you connect an LED to the TX_LED pin, you should see it light up after sending some serial data. Pretty sure the serial driver should work fine even though it has the chip running at 8MHz, it’s using the AVR-libc setbaud utils, which are frequency independent.

I would like to use the Micromodem to instead drive a set of ultrasonic transducers for underwater communications. I was thinking of using a 40kHz transducer for the mark (ones) and 25kHz for the space (zeros), so I don’t need the Micromodem to output FSK. I just need it to output standard async UART but with the rest of the communication protocol and FEC intact. Would this be easily doable?

Interesting idea! Certainly doable, but if it’s easy will probably depend on a lot of things 😉
You could modify the source-code for the MicroModemGP firmware quite easily to just toggle one of two output pins for the mark/space sequence instead of the full tone synthesis, and then letting those pins control the on/off state of the transducers through a transistor. I’m guessing the transducers are just providing some kind of output voltage when they detect their specified tone, so piping this into an analog input pin, you could scrap most of the demodulation code, and just use a threshold value for each input pin to serve as an input in AFSK.h. Something like changing this line:

I was following this app note http://www.ti.com/jp/lit/an/slaa136a/slaa136a.pdf. The schematic on page 4 shows the driver and receiver circuits I was thinking of using. I would use a dual buffer with complementary tristate pins (SN74LVC2G241) both tied to UART TX to gate either 40KHZ or 25kHz oscillators on/off to transducer driver.

On the receiver side, I would invert the space data after low-pass filter and logical AND that with the mark data to get recovered data stream.

Good afternoon .. I apologize for the translation. I want to use your development in conjunction with a mobile phone .. But the amplitude of the audio signal from the phone is very small max 1.5 volts .. and the modems do not work, although through the connection 3 wires work very well .. can be somewhere to fix in the code to make it work ???? Tell me please … Thank you …

Sorry to disturb but I’m kinda confused reading the schematics. Wasn’t it common having a dot where two crossing wires are connected with each other? Or is this just oldschool and nowadays if there’s one wire ending somewhere at an other wire, it’s automatically assumed as connected and crossing wires are just crossing and NC?

Please have mercy – I’ve learned all this about 20 years ago or so 😉

I’m planning to wire this up using some Arduino pro mini – almost as big in size as the HC-06 is 😀

You’re totally right, that is probably the most “correct” way to do it 😉 Looking at the schematic again, I guess I’ve taken a few liberties on that front, although I have been consistent, in that I’ve omitted junction dots where a wire connects directly to the pin of a component or chip (where red meets green in the colors of the schematic). Either way, it should be easy enough to decipher it all, since no wires are crossing in the schematic, so you can safely assume that anything “touching” graphically, is also physically connected. Feel free to post if you run into doubts while assembling it 🙂

I’ve been accepting the challenge studying your schematics and see what makes sense and what not 😉 D4 via R4, C1 to GND was quite a challenge but thanks to VK3DAN’s homepage and TinkerCAD work I was able to verify that R7 and C1 are indeed parallel 🙂

I can’t wait to teach my Yaesu FT-8900 doing APRS. I was trading my FTM-400XDE with builtin APRS for the 8900R because I wanted to work 10m also and “building some bolt-on APRS-functionality can’t be that hard”….haha 😉 Now APRSdroid connected to the bluetooth TNC looks like the sexiest option of all 🙂 I love our hobby! <3

Hi!, awesome project. I would like to build one myself with a modified firmware to support GPS and analog sensing from an analog sensor.
I’m getting confused with all the different MicroModem and MicroARPS firmware versions, could you please give me a help.

I would like to implement the modem and the GPS&Sensors using the same microcontroller. From the schematics it seem that there are available digital an analog pins to accomplish this.
Where could I find the source code used in this version? Is it the same published on the MicroAPRS github?

Hi Daniel!
Yes, the source code for MicroAPRS is the one available on github. To clear things up, there’s basically two different _hardware_ versions of MicroModem, the version I sell in my shop, and a slightly simpler version that’s easier to build if you’re just getting started.

I would definitely recommend that you start building the “easy” version first. Lay out the circuit on a breadboard, and then you can use an Arduino Uno or similar as the controller. You then just connect Arduino pins according to the schematic. When you have built it, I would suggest putting the “MicroAPRS SimpleSerial” firmware on the Arduino, since this will allow you to easily test if everything is working as it should, by connecting to the Arduino over a serial connection and sending some commands.

When you have verified that the hardware is working, you can start making your own APRS firmware. For that I would suggest you use LibAPRS. That way you can program your GPS/sensor functions in the Arduino IDE, and still use all the APRS functions from the “full-fledged” MicroAPRS firmware. You can read more about LibAPRS here: https://unsigned.io/projects/libaprs/

Hi Gents
I’m quite new with Arduino and also APRS.
I would like to know if the MicroModem can give me the “on air frame” with the original format such as : “F5HPE-1>APOTU0,F6KOP-3*,WIDE2-1,qAR,F8KGD-3:!4832.00N/00317.00EjTest Test Test Test ”
I’m looking for some stuf who can give me such frame.
I’m don’t want to use a software like Dierwolf and so.
I need a Modem.
Many thanks for your attention.
Fred

Hi Fred
MicroModem can do what you are after. The default firmware will output frames in KISS format over the serial / USB connection. This is the standard serial format used by most programs. If you want a more readable format like you write up above, there is several options.

– You can use the SimpleSerial firmware, it has different options for how to output incoming frames over the serial / USB connection. If you buy a pre-made modem from me, I can flash the firmware of your choice on the modem.

– You can stick with the default firmware, and use another program on the computer that talks to the modem in KISS mode, and then outputs the frames to a log file, or directly to screen.

What is best for you will depend on your use case. If in doubt, I’ll be happy to help you figure it out. Just send me a mail on mark at unsigned dot io, or reply here.

HI Mark,
Many thanks for your prompt answer back.
So, if I understand correctly, I could use the SimpleSerial Firmware and flash my existing Arduino UNO, input the audio in A0 port and get all frame (from scratch) on Serial port?
Later on, my own application could manage the frame?

At the present time, all the Sketch I tested are using LibAPRS and none of them can at least read the Audio going through the A0 port (via Resitors and capa). I can see the audio going inot A0, but no decoding.

My Target is to make a my own prototype running with my application. Where can I download SimpleSerial?
Many thanks
Fred

Yes, that is correct. SimpleSerial can be configured over the serial connection with a variety of simple commands. On this page https://unsigned.io/projects/microaprs/ you can download precompiled versions of the SimpleSerial firmware, and there is also documentation on all the commands you can use.

But LibAPRS should also be able to decode just fine. Are you sure that you have made the input circuit correctly? A common mistake is to forget to apply the DC bias voltage to the resistor part. First the input audio goes through the capacitor to only get the AC component, and then the AC is biased with 1.5 volts, to make it readable by the Arduino analog input (it can only read positive voltage, not AC, so that’s why we need to apply the bias). If your bias input is 3 volts, the two resistors will make the bias 1.5 volts. You will also need to apply 3 volts to the AREF (analog reference) port of the Arduino, otherwise it will have the input referenced incorrectly.

Yep, that’s probably it. That schematic looks like he had to make some modifications because he didn’t have exactly the right parts on hand. Also, the very first version of MicroModem used a 5V reference, but it was much less accurate than the way it is set up now.

One other question:
If I programm my UNO with AVRdude and Simpleserial, later on can I reverse and program more other sketch ? or with AVRdude the firmware update is non-reversible and for ever?
Cheers.

Fine.!!!!
I connected the 3.3. output to the AREF and changes my setting in my sketch as
#define ADC_REFERENCE REF_3V3
But it doesn’t decode. Now I’think I haven’t enough AUDIO input signal.
What Audio signal voltage needs your device?
I have only 1Vpp.
Is that enough?
Wha’t if you delivery Schedule for one MicroModem?
Cheers

Hmm, 1v should be plenty. The modems I make start decoding around 150 mV, with best decode starting from around 350 mV, and they will still decode at over 2V peak-to-peak. I don’t know what could be wrong… You could post a couple of photos of your setup on the forum, maybe I or someone else can see what’s wrong.

If you want to buy a MicroModem, you are of course very welcome! I have plenty in stock, and I can ship today. Depending on where you are in the world, you will have it in a 2-4 days usually. I also ship it with the firmware of your choice, so just let me know.

// LibAPRS.h comes from http://unsigned.io and is used verbatim
// SOftwareSerial.h allows you to talk to the GPS while still maintaining
// use of the other serial lines.
// TinyGPS.h just runs the GPS.

boolean gotPacket = false;
AX25Msg incomingPacket;
uint8_t *packetData;
// set up a couple variables for when we last transmitted.
// aprs spec is around 10 minutes or so (faster if your speed is faster)
// but probably not more than once per minute.
long lastUpdate=0;
int Updatedelay=60; //delay between packets in seconds.

Well, it’s looking OK, I think, but is that all the code? There is no main loop? I’d be happy to help more, but maybe it’s better if you send me an email. Could you write me a few lines explaining what the goal of your program is, and maybe attach the source code file?

Mark;
I just ordered two of the MicroModems. I hope that I can make them work in my un-conventional application.
All I need to do with this board is receive AFSK/Bell202 modem tones and output the digital component to another device such as a digital RF Transmitter that will send the data to an Alphanumeric paging receiver.
I do not need any type of handshake or control mechanisim. Just continuous operation of analog Receive to Digital output.
I would prefer that the board be powered by 12 Vdc but I will try to work around this.
If I can get this to work for me. I will be in the market for about 50 of the modems.
Thank you.
Cary

Hi Cary
Thanks for your order, it is on its way to you! What you’re describing is definitely possible, but it is going to require a few modifications to the firmware, since it is normally expecting AX.25 framing and checksums, and will not pass data unless these match. If you’re looking at an order around that size, I can help you with a custom firmware to go along with it. I’d need a few more details though, so if you can send me an email at mark at unsigned dot io, we can work out a solution for you.

This might be obvious to everyone else, but it wasn’t to me. The directions talk about flashing the Arduino using AVRdude. At first I thought I needed to install this as a separate application. Turns out, AVRdude is part of the Arduino IDE – so in theory, it’s already there. (I’m using a Mac OS, so not sure if things work differently on other platforms.)
FYI,
— Markus

I`m a proud owner of two micromodems.
One works as a traditional KISS TNC, one as a RX only KISS TNC for monitoring.
For that modem i have an Arduino-sketch, but unfortunately my C/C++ skills
are very limited – I`m not (not yet) able to transfer the sourcecode of micromodem into a
working .ino file.
If i would have such a sketch, i think i would be able to “isolate” th pure TX funktion.
So my question:
Does anybody have done this before and made a working sketch for a micromodem KISS TNC ?

The precompiled .hex works perfect, but since i want to improve my knowledge i`d like to do this
within the Arduino environment.

Hello Micha!
Did you have a look at LibAPRS? If not look here: https://unsigned.io/libaprs/
It is an Arduino library I wrote that includes the RX and TX functions, modulation/demodulation routines and all that stuff in a way that is easy to include in an Arduino sketch. It does not have any KISS functionality build in, but if you want to add it, that part should be easy enough to copy from the MicroAPRS source code.

I know that there was someone else who wanted to do what you want at some point, and I think he succeeded, but I cannot remember who it was 😉 Maybe you can find something by digging through the comments and forum.

thanks for you reply.
Of course i had a look into LibAPRS and of course i tried to add KISS.c and KISS.h
to a new project.
But unfortunately my knowledge of variables and the use of them in C is (still) limited.
I will ask all people around me…
If i have found a solution, i will make it public via Github and i will post it here.

Simple said it`s the “microaprs-3v-kiss-latest.hex” as an Arduino sketch.
Since i had a lot of work (modifying the LibAPRS etc and i think hamspirit al thingnd
open source is a helpful thing, i published the sketch on Github:

Hi Micha
Great work! Thanks for sharing this and putting it on Github! I’m sure it will be very useful for others wanting to do the same. I will direct people to your sketch when they ask for something like it as a starting point.

Since the MicroAPRS firmware is licensed under GPLv3, as a minimum you _must_ also license your derivative work under GPLv3. In Github this is very easy to do, just use the “Add a license” button in your repo.

I would also be very happy if you add the following header to the files you copied directly from my repository:

For a project with simple RX and TX modules we thought about to modify the micromodem code
to produce and to listen to a simple stream of bits.
We want to transmit and receive with simple ASK (amplitude shift keying)
We sucsessfully modified other codes using simple PWM to switch a pin low at space and high at mark.
We didn`t manage to do this with the AFSK.c in the LibAPRS 🙁
Also we tried to bypass the ADC with a simple digitalRead function to decode the Bits coming in (i think they come as NRZ).