(Probably) The Cheapest way to add SMS to an Arduino

Update 2010-11-19: Sorry everyone who's been waiting around for the library. It turned out to take up too much RAM when it was done (almost all of an Atmega328) so I'm going to have to get some assistance in paring it down from a colleague. BorgMcz has also contacted me to point out that RXD and TXD are reversed on the schematics below. Until I can replace the images, switch RXD and TXD on the PL2303 pads if you build this circuit.

Update 2010-10-19: Since this was posted to HackADay, I might as well pimp the project that this is being built for (indirectly):Team 9.99's N-Prize entry. We're planning on testing some of our systems on a high altitude balloon this week and this SMS system will be used with a GPS for backup tracking.

Update 2010-10-18: I'm working on a library for this device which will probably be released this week or next. Check back for updates or send me an e-mail if you'd like to be notified when it's released.

If you'd like to send or recieve SMS messages from an Arduino (or any other microcontroller, for that matter) there are a number of commercial offerings that vary a great deal in price and features offered (the linked offerings range from about $60 USD to over $400 USD).

A common hobbyist solution to this problem is to use an old cell phone with a serial cable. Phones with a straightforward RS232 interface are becoming harder to find, and RS232 or USB both add extra parts to interface using TTL serial with a microcontroller like the Arduino.

While browsing one of my favourite places to waste money recently I came across an item that caught my eye: A $25 USD delivered USB GSM modem. The DealExtreme forums indicated that the device identified as a Prolific PL2303 USB to serial adapter, which I suspected meant that the GSM modem's serial bus would be exposed internally.

And the trick is?

SKU12057, as it turns out, is simply a PL2303 IC packaged with some (convenient) interfacing circuitry and a BenQ M32 GSM/GPRS module.

The interface between the PL2303 IC and the M32 module is plain old 3.3v TTL serial, something that the Arduino is more than capable of driving with a minimum of external components. Because we're going to be converting a USB peripheral to TTL serial here we also get a 3.3v regulated power supply for the M32 for free.

The necessary modifications to the modem

The SKU12057 modem needs to be modified to expose its internal TTL serial interface in order to connect it directly to the Arduino.

Open the case by removing the two screws and unclipping the single plastic clip. The circuit modification is very simple and consists of de-soldering the PL2303 IC and running signals from its (now vacant) pads back to the Arduino. If you have trouble de-soldering SMT ICs like this I highly recommend the technique of soldering a lump of 10 amp single strand copper wire across all the pins on both sides of the IC. This lets you heat all the pins along each side at once and lift each entire side off in one go.


Fig 1. An inexcusably poor photo of the modification necessary to the modem. The only camera I had available was a Genius M501 waiting to be dismantled for a high altittude balloon flight.

The rest of the circuit

Because the modem operates at 3.3v, a level shifter needs to be built for the M32's RXD signal. This can be as simple as:


Fig 2. Just about any small signal diode is fine. If the circuit is unreliable make sure your diode has a forward voltage drop of less than 0.8 volts as this is close to the documented Vinputlow voltage of the M32 module.

There are a large number of ways in which a 3.3v input can be interfaced to a 5v output and many alternative designs are available on the web.

In this configuration the 10K resistor pulls up the voltage at the RXD pin to 3.3v unless the Arduino pin is outputting a "low" signal, in which case current will flow across the diode and pull the RXD pin low as well. The 3.3v can be obtained from the Arduino's onboard 3.3v regulator (as I have done) but would probably be better obtained from the pad previously used for VDD_232 on the SKU12057 board. Pin 4 on the PL2303 provides this signal and it is no doubt present elsewhere on the board.

The TXD signal from the M32 module can be connected directly to an Arduino IO pin as it is greater than the minimum voltage required to register as "high" for the Arduino's pin in input mode.

Here is the basic completed schematic I used while testing:


Fig 3. The connections between Arduino and GSM module.


Fig 4. A clearer diagram of the connection points on the SKU12057 board.

The software

I'm currently developing a more complete library to drive this board, but this example adapted from the NewSoftSerial library is a good way to test if the modified board works:

#include <NewSoftSerial.h>

NewSoftSerial m32_serial(2, 3); // Order is input pin, output pin

void setup() {
  Serial.begin(9600);
  Serial.println("Arduino has booted.");
  m32_serial.begin(9600);
}

void loop() {
  if (m32_serial.available()) {
      Serial.print((char)m32_serial.read());
  }
  if (Serial.available()) {
      m32_serial.print((char)Serial.read());
  }
}

You may need to press enter a few times to let the M32 lock on to your baud rate as it auto-detects the baud rate at startup. Once you start recieving "OK" responses you know the modem has detected the baud rate.

At this point you can use standard AT commands to send and recieve SMS messages, check the status of the cell network connection and so on. For example, sending a simple SMS might look something like this:

AT                     # Check if the modem is alive
AT+CREG?               # Returns 0,1 if the network is registered
AT+CSQ                 # Check signal strength. 39 is the highest.
AT+CSMP=1,,0,0         # Set the modem in to plain text message mode
AT+CMGF=1              # Use ASCII encoded text messages
AT+CSCA="+64220227672" # Set the "message center" address. Get this from your network
                         provider, this address is for 2Degrees Mobile in NZ.
AT+CMGS="+64xxxxxxxxx" # The destination number to send the SMS to
Your-message-text      # Your message text, terminated with a Ctrl+Z or ASCII character 26

Caveats

There are a couple of small issues with the SKU12057 board in this application.

Your serial implementation will need to wait a few hundred milliseconds (I haven't determined exactly how many yet, 500 seems to be safe though) after issuing a command before issuing another.

I'm not entirely convinced that the antenna included with the unit is really optimally matched to the task of GSM radio or indeed to the M32 module itself. It seems to be basically a metal stub on a length of thin wire. Further investigation here is required.

The modem seems to misbehave if command echo is disabled (ATE0), so your serial parser may need to handle the commands it sends being echoed back to it.

There was no shielding in the unit I recieved and voltage spikes of up to a volt mysteriously appeared on my breadboard while testing. Add shielding or construct your circuit carefully if this is a problem.

Check the modem supports the same frequencies as your local carriers! This modem will only handle 900/1800/1900Mhz, of which only 900 and 1800Mhz are supported locally.

Further information

Don't forget to re-use the PL2303 in another project :)

[ICO]NameLast modifiedSizeDescription

[DIR]Parent Directory  -  
[IMG]Annotated image of PCB with modifications.jpg19-Oct-2010 00:50 156K 
[IMG]Annotated image of PCB with modifications.png18-Oct-2010 22:51 499K 
[IMG]Complete schematic.png19-Oct-2010 00:53 16K 
[IMG]Complete schematic.svg18-Oct-2010 23:44 19K 
[IMG]Diagram of SKU12057 PCB.png19-Oct-2010 00:54 18K 
[   ]NewSoftSerial GSM Modem Test.pde19-Oct-2010 00:10 342  
[   ]PL2303 Datasheet.pdf19-Oct-2010 00:27 49K 
[IMG]Photo of PCB with modifications.jpg18-Oct-2010 22:31 82K 
[IMG]Schematic for level converter.png19-Oct-2010 00:52 5.7K 
[IMG]Schematic for level converter.svg18-Oct-2010 23:44 10K 

Apache Server at finch.am Port 80