Testing the dronecell or other GSM modem

In this page you will find information about testing and using the dronecell or another GSM modem with APM's new AP_Modem library

The current code is still in early development, is buggy and requires some experience to compile and deploy. But, it works and it allows telemetry to flow over TCP or UDP anywhere around the world, directly from your drone!


- APM1 or APM2 can be used. The code is different slightly, so test each separately

- A dronecell or any other AT-command compatible modem

- A data-plan SIM card

- (Optional) Dynamic DNS or fixed IP for convenience

Skills: You will need to be able to compile the ardupilot-mega code from source and install it on the hardware. 

1 Getting the hardware

If you do not have a dronecell, you can try buying one online from diydrones or another store. You might find it difficult to source one. 

Other than the dronecell, you could try another GSM module. The closest is the Arduino GSM shield sold on Amazon which includes a SIM900 GSM module, which is the same brand as the dronecell modem. 

The code should work for any GSM modem that supports AT commands. The only changes would be in the init_script. If you are brave, try another type of GSM/GPRS modem.

SIM Card: Need a compatible GSM network. I personally use the T-Mobile pre-paid SIM card with $2 per day cost (for any day it is tuned on) and up to 200MB of data. It cost me only $10 to buy, all cash, no contract, no names, no addresses ;-)

2. Getting the software [UPDATED x 2]

The software is available as a new branch of the code, based on ArduCopter2.6 and ArduPlane2.4. (ie, the current master branch).

Using GIT

If you are familiar with git, you can pull the modem_test branch from google and compile it, from here:


You will need to checkout the modem_test branch

git checkout modem_test

then compile and install

Download a pre-compiled HEX file to flash

ArduCopter 2.6

Downloading Manually  [ This approach is no longer practical ]

3. Preparing the hardware

The dronecell comes with a default speed of 38400. Other modems may be set to 9600, or any other speed. The APM1 telemetry port is at 57600. So the two must match. You have three options:

a) Change SERIAL3_BAUD to 38400  in ardupilot code. My libraries respect whatever you set and will work with it. Then the dronecell will work. But xbees won't. So you will have to swap the speed in the code back and forth between 38400 and 57600 to use other radios.

b) A better option is to set the dronecell to 57600 permanently. Connect to dronecell serial to a serial2USB (FTDI) cable a terminal (the one in Arduino IDE will do) and change it to 57600. If you don't have an FTDI cable, you can slave the modem to any Arduino board by connecting it to TX0 and RX0 and then running an empty script ("Basic" in ArduinoIDE). 

Commands are:


changes speed to 57600


writes the change to memory permanently.

c) If option (b) is too complex, then you can also do the following... do (a) to have APM able to speak to the dronecell at 38400. Then change the init_script (in Cellular_Modem.cpp) and add the following in the fifth or sixth line (doesn't matter really exactly where, just after the initial 4 commands):



That will have the APM tell the dronecell to switch baud rates. The rest of the script will fail (APM is still trying to talk 38400 at this point, but the dronecell is now listening at 57600). Change the SERIAL3_BAUD back to 57600, and now dronecell (and everything else) speak 57600. 

4) Configuring the Software

You will need to make changes to the settings to reflect your SIM card provider

Open AP_Modem.h and find these lines:

#define VAL_APN         "internet" // value for the APN
#define VAL_USER        "" // value for the user name
#define VAL_PW          ""      // value for the password

The settings above are the ones that worked for the T-mobile SIM card. Most SIM cards no longer use a "username" and "password" to log onto the data network, so those usually remain blank. The APN is carrier specific, though many use "internet" as the APN, so try that.


Once you've made the changes, compile and install the code.

5. Connecting the modem

You will need to connect the modem to the telemetry port. Look at the instructions for Xbee, and see where the telemetry port is on your board. If you already use Xbee, this is easy ;-)

Connect RX, TX and GND to the modem. I can't remember if it is TX->TX or TX->RX, but if the modem isn't responding, try switching around. Having an FTDI cable to troubleshoot or an extra Arduino will help a lot.


A GSM modem will draw up to 2.0-2.5A in bursts when transmitting. You cannot power it from the APM. You probably cannot power it from an ESC BEC, though you could try. I power it from a 10A rated BEC (Castle BEC). You can also use a separate battery and BEC to power it. Whatever you do, you need to meet two requirements:

1) provide at least 2.5A clean power at 5V

2) power modem and APM from same power*

* They must share a GND for the TTL to work. If you have two power sources and share a GND, you may create a weird path through your board from one power source to the other. *ZAP*. Easier to run both off a sufficiently strong BEC or battery.


6. Set the parameters [NEW]



MDM_BLIND 1.000000 -- Set to 1, to dial blindly. Set to 0 to validate the modem response

MDM_DEBUG 0.000000 -- Set to 1 for debug messages on the console 

MDM_ENABLED 1.000000 - Enable

MDM_IP1 192.000000  - First byte of IP address
MDM_IP2 168.000000 - Second byte of IP address
MDM_IP3 0.000000
MDM_IP4 161.000000 - Fourth byte...

MDM_PORT 14550.000000  - Port number 

MDM_PROTO 0.000000 - Protocol - UDP=0, TCP=1

MDM_RATE 115.000000 - Serial speed - short form (1=1024,2,4,9,19,38,57,115=115200)

MDM_SERIAL 3.000000 - Serial port (0 is Serial/console, 3 is Serial3/telemetry)

MDM_STATE 0.000000 - Don't change, used to see what state we're in

7. Setup the GCS

The GCS will need to connect to the Internet with a public IP address and the ability to receive traffic on UDP/14550 (or if you changed that, whatever you set). The IP address must be fixed or have a dynamic DNS name, or you will have to set it in the code each time you re-connect. I use a dynamic DNS for convenience. For testing, a fixed IP will work fine. 

Make sure the port is open on any firewalls or gateways and the traffic can get through. 

With Mission Planner, you will set it to UDP and to listen on port 14550.

8. Start the APM

If you are connected on the USB, you will see the modem initialization in ridiculous line-by-line detail (if debug is on). It looks like this:

Init ArduCopter V2.6-modem

Free RAM: 4096
FW Ver: 118

load_all took 67us

--MODEM starting on Serial 3 @ 115200 baud
Press ENTER 3 times for CLI

ublox update:35: gps read timeout 3662 0


9. Success (??)

If all goes well, here's what should happen:

- Your APM starts up

- The APM sends the init script to the modem

- The modem establishes an Internet link and then start copying traffic (bridging) over UDP or TCP. 

- The APM sends Telemetry data, once it is done initializing. 

- The telemetry data flows through the modem, across the Internet and to the UDP port. This takes about 30sec to a minute to start arriving the first time. 

Wait for a bit for the flow to start, then start MP and tell it to listen on UDP 14550. If all goes well, it will say "Getting parameters" and then connect in the usual way.

You will notice about a 2 second "lag" between activity on the drone and activity on the GCS. You move the drone, the horizon moves on the GCS two seconds later. That is because of the latency introduced by the Internet routers. It can be optimized (and will), but will always be a bit lagged compared to line-of-sight speed-of-light radios. However, despite the latency, the system is not losing packets at 57600 and the flow is consistent and good. So except for joystick flying, you can do your mission planning, PID tuning and such easily over IP.

Comments, questions or support requests below. 


You need to be a member of Telemetry over cellular IP to add comments!

Comment by Tommy Larsen on July 23, 2012 at 10:09am


I'm up and running with my system now :) 

I connect this  RN-174 to this onboard 3g router

I do have a non-firewalled APN SIM card. Set Mission Planner to TCP, enter IP and port and connected :)

Comment by Gundeep on July 17, 2012 at 3:10am

I tried the above method, but the APM Planner could not connect to my drone.

My computer connects to the internet through a DSL Modem (Router). Therefore I don't have a direct public IP Address but only an internal IP. Could this be a problem? 

Comment by Alex on July 8, 2012 at 11:54am

I think the idea of settinge verythign up on your server as a cloud is a great idea!  Should also make things much easier for people to setup aswell!  As for the privacy, I think as long as you warn people what information you will see, then they can choose if they want to use it or not..

Have you made any progress with this?

Comment by Andreas M. Antonopoulos on July 4, 2012 at 11:24am

It will take me several days to get that done (won't take long, but have several other things going on right now). 

In the mean time, I would suggest bench-testing it on ArduCopter to get the modem and GCS working. 

This code is really not ready for flight testing - it is very immature. I need more bench testing to find the bugs before we are ready for flights, just my suggestion.

Comment by Asaak on July 4, 2012 at 11:10am


Thanks for answering!!

Yes I use GIT ( GUI interface for windows, and I do a clone from modem_test branch ). I compile Arduplane so maybe it is why it is not working. I want to try it on my bixler, so please, if you have a moment can you make it possible??

I will try problem 2 solution as soon as I can compile it!


Comment by Andreas M. Antonopoulos on July 4, 2012 at 10:10am

Hi Asaak!

Sorry for the delay

1) I have no idea what is going on with the compiling of AP_Modem. 

Did you get it with git? If so, did you do the "git checkout modem_test"?

Are you compiling for copter? Plane does not have the modem code yet, just copter. Try it on copter, if it works I can move it to plane.

2) The parameter is for numeric IP, not domain name (can't pass strings in parameters). So in your case you will have to modify the code to replace the IP with your dyndns

Comment by Asaak on July 4, 2012 at 9:17am

still stuck...please help me with my two problems...as I said:

1- compiling OK but no inclusion fo the library AP_Modem

2- If I succeed with problem number 1 and I am able of compiling the modified firmware which use AP_Modem library, how can I introduce an ip such myplane.dyndns.org using the 4byte address format for that purpose?

Sorry for asking for help so many times but I have been willing to test this for so many time and now that I can I found this problems!

Thanks again!

Comment by Asaak on July 3, 2012 at 11:12am

Still no success..compiling again and again and works fine..but it is because I am not using files included in AP_Modem directory...any ideas?

Thank you very much!

Comment by Asaak on July 3, 2012 at 8:27am

Sorry it is me again but...it appears to me that AP_Modem it is not used anywhere in the code...that is why I can introduce errors in AP_modem .h/.cpp files and nothing happens..

Comment by Asaak on July 3, 2012 at 8:19am

Hi everybody!!

After beeing busy for a few weeks I am able to start testing. I've got two questions:

1.- I am able to checkout the branch modem_test. However when I compile it using arduino IDE, I found that AP_Modem does not appear, not the .h / .cpp or the directory. This is why I can introduce some random chars on this fiels and ardupilot.pde will compile succesfully. What am I missing??

2 .- If I have a dyndns account configured and I want to use it instead of a fixed IP, how can i introduce this ip...I mean..there are 4 variables for each of the 4 bytes of the Ip..but if I have something like..myplane.dyndns.org ...how can I set it up on APM PLanner?

Thanks guys!

Comment by Andreas M. Antonopoulos on July 1, 2012 at 3:11pm


- You can work with 38400, 57600 is just... faster.

- Yes, just leave the VAL_USER and VAL_PW empty and fill the VAL_APN. 

- Each reboot puts the modem back to the stored baud rate (you store it to permanent memory with AT&W)

- I don't know what AT+IPR=0 does. I don't think Dronecell has autobaud anything. 

Comment by Andreas M. Antonopoulos on July 1, 2012 at 10:26am

Perhaps I need to write a little sketch that cycles through all baud rates, trying to get a response from the modem. Then as soon as it does, get the modem to switch rates and reset it. That way, the hardest part which is setting the initial rate might be easier. 

Comment by Andreas M. Antonopoulos on July 1, 2012 at 10:24am

Veikko, excellent. That means the IPR=57600 didn't work previously. Now that you confirmed operation at 38400, you can repeat the process to switch baud to a faster rate. Replace the init string with just the IPR and &W and see if it works?

Also, the CSTT sets the APN, username and password. Did you get the correct APN to use from your ISP? The default is APN=internet, user="", password="". That works with some carriers, but not all. You need to ask them what APN to use and if it needs a username and password. Then the CSTT won't fail ;-)

Comment by Andreas M. Antonopoulos on June 30, 2012 at 11:24am


Try changing "MDM_BLIND" to 0. 

Blind means that the APM sends the commands "blindly" and does not look at the modem response. I have not tested it recently but previously, the MDM_BLIND = 0 option will evaluate the modem response (numeric 0 or alpha "OK"), and will display the response on the debug screen (it adds "modem sent" responses after the "we sent" commands). 

Try it and see how it goes. To troubleshoot the connection between the modem and APM, it is best to use a FTDI cable to "eavesdrop" on the traffic. 

On the ground side, the GCS will listen to port 14550 on *all* interfaces, so you don't need to worry about that (In network speak it means it sets up a listener on which attaches to all IP interfaces)

The problem is likely on the Dronecell side. Try turning off blind commands and see if you get some better debug information on what is going on. Good luck!

Comment by Tommy Larsen on June 28, 2012 at 1:22pm

@Veikko, this is gr8! Keep us informed about the result :)

Comment by Tommy Larsen on June 27, 2012 at 2:59pm

Veikko: As i said, just call your provider and use the VPN "problem". Then they most likely (Which cell provider doesn't wanna customer using VPN that requires more bandwidth ..$$$) give you their open APN name.

Comment by Andreas M. Antonopoulos on June 27, 2012 at 2:39pm

So here's a question for comments and feedback:

I am planning on offering a cloud service that makes MAVLink-over-IP on the Internet much easier. It will act as a dynamic DNS server, a connection point for DroneCell/modem and GCS, and possibly offer other features (a web-based moving map for smartphones), log capture etc.

The one issue with this solution is that it will mean that your flight data, location and everything will get recorded by my cloud service. I am trying to balance convenience with privacy. 

So my question: Would you use an online service for this type of solution, or would you be too worried about privacy issues?

PS. Assume service is free and open source, as it will be.

Comment by Andreas M. Antonopoulos on June 27, 2012 at 2:36pm

Veikko, in that case go with Tommy's suggestion. Call the carrier and tell them their damn mobile card doesnt work with your company's VPN. See if they suggest a fix or a different plan or something.

The third and final solution (and possible where we will end up) is to use a proxy in the "cloud", to handle both the IP address issues (dynamic IP -> dynamic DNS) and the port forwarding issue. Essentially we can make both sides do "outgoing", with a proxy on the Internet handling both ends as a server.

If this doesn't work:


and this doesn't work


then this will

DC -> proxy <- GCS

Comment by Andreas M. Antonopoulos on June 27, 2012 at 2:33pm

@Tommy, that depends on the mobile ISP used on the dronecell. I am looking at the possibility that Veikko (or others) have two different mobile carriers, one with a strict policy, one without.

So if one of the two works, switch SIM cards or switch the connection-initiation direction and you have a solution.

I do like your suggestion though: call up the carrier and tell them your VPN requires incoming UDP packets...

Comment by Tommy Larsen on June 27, 2012 at 2:30pm

Andreas: You will experience the same problem actually, when you try to "call" the drone from your GCS. There will still be a closed connection on the drone. There will always be one incoming connection. An open APN is the only solution when you use sim card in both ends.

© 2020   Created by Chris Anderson.   Powered by

Badges  |  Report an Issue  |  Terms of Service