Introduction: Arduino Based GSM/SMS Remote Control Unit

! ! ! N O T I C E ! ! !

Due to the local cellphone tower being upgraded in my area, I am no longer able to use this GSM module. The newer tower no longer supports 2G devices. Therefore, I can no longer give any support for this project.

With such a wide range of GSM modules available for the hobbyist, most of us ended buying one. I purchased a SIM800L module locally, and ended up playing with the different commands of the module.

Using the Arduino Uno and the Arduino IDE, I was able to turn my ideas into reality. This did not come easy, with the SINGLE BIGGEST ISSUE being the limitation of only 2KB SRAM. After a lot of research on the internet and different forums, I was able to overcome this limitation.

Different programming techniques, a much better understanding of the Arduino compiler, and using the SIM card and EEPROM for additional memory, saved this project. After some changes to the code, a stable prototype was build and tested over a period of a week.

A drawback of the limited SRAM was that the unit could not be fitted with a display and user keys. This resulted in a complete rewrite of the code. With no user interface, the only option left to continue with the project, was to make use of SMS messages to configure the unit, as well as the users.

This turned out to be an exciting project, and more futures were added as the development continued.

My main goal was to stick with the Arduino Uno, or in this case, the ATMEGA328p, and not use any surface mount components. This will make is easier for the general public to copy and build the unit.

Specification of the unit:

  • A maximum of 250 users can be programmed on the unit
  • Four digital outputs
  • Four digital inputs
  • Each output can be configured as a PULSE or ON/OFF output
  • Output pulse duration can be set between 0.5 .. 10 seconds
  • Each input can be configured to trigger on OFF to ON changes.
  • Each input can be configured to trigger on ON to OFF changes
  • Each input delay time can be set between 0 seconds and 1 hour
  • SMS messages for changes on the Inputs can be send to 5 different users
  • Names and status text for each input can be set by the user
  • Names and status text for each output can be set by the user
  • Unit can be configured to receive SIM card balance messages via USSD messaging.
  • All users can request I/O status updates of the unit
  • All users can control individual outputs via SMS messages
  • All user can control individual outputs by calling the unit

Safety Features

  • Initial setup of the unit can only be done while at the unit.
  • Initial setup can only be performed by the MASTER USER
  • Initial setup commands are automatically disabled after ten minutes.
  • Only calls and SMS messaged from known users can control the unit
  • Users can only operate the outputs assigned to them by the MASTER USER

Other Features

  • Calls to this unit is free, as the call never gets answered.
  • When the unit is called, the call will only drop after 2 seconds. This is confirmation to the caller that the unit responded to the call.
  • If the SIM card service provider supports USSD messages, balance inquiries can be made by the MASTER USER. The USSD message containing the balance, will then be forwarded to the MASTER USER.

Step 1: Power Supply

To ensue that the unit can be connected to standard security systems (alarm systems, electric garage doors, electric gate motors), the unit will be powered from 12V DC which is normally available on such systems.

Power is applied on 12V IN and 0V terminals, and is protected by a 1A fuse. Additional 12V OUT terminals are available, and is also protected by the fuse.

Diode D1 protect the unit against reverse polarity connections on the 12V lines.

Capacitors C1 and C2 filters out any noise present on the 12V supply lines. The 12V supply is used to power the relays of the unit.

The 5V supply consist of a LM7805L voltage regulator, and output a stable +5V needed for the SIM800L GSM module, as well as the micro processor. Capacitors C3 and C4 filters out any noise that might be present on the +5V supply line. Relative large size electrolytic capacitors were used, as the SIM800L GSM module does use quite a bit of power when transmitting.

No heat sink is required on the voltage regulator.

Step 2: Digital Inputs

The digital input signals are all 12V, and must be interfaced with the 5V micro controller. For this, opto couplers are used to isolate the 12V signals from the 5V system.

The 1K input resistor limits the input current to the opto coupler to around 10mA.

Due to space limitations, no space was available on the PC Board for 5V pull-up resistors. The micro controller is set up to enable the input pins weak pull-ups.

With no signal present on the input (LOW) of the opto coupler, no current will flow through the opto coupler LED. Thus the opto coupler transistor is switched off. The weak pull-up of the micro controller will pull up the collector to almost 5V, and will be seen as a logic HIGH by the micro controller.

With 12V applied (HIGH) to the input of the opto coupler, around 10mA will flow through the opto coupler LED. Thus the opto coupler transistor will be turned on. This will pull down the collector to almost 0V, and will be seen as a logic LOW by the micro controller.

Note that the input seen by the micro controller is inverted compared to the 12V input.

Normal code to read the input pin looks as follow:

boolean Input = digitalRead(inputpin);

To correct for the inverted signal, use the following code:

boolean Input = !digitalRead(inputpin); // NOTE the ! in front of the read

Now, the input seen by the micro controller will correspond to the input on the 12V input.

The final input circuit consists of 4 digital inputs. Each input is is connected to terminals on the PC Board.

Step 3: Digital Outputs

Normally, with a circuit driving only a minimum number of relays, the best way is to use a transistor driver circuit as shown. It is simple, low cost, and effective.

The resistors provide pull-down to ground, and transistor base current limitation. The transistor is used to increase the current available to drive a relay. With only 1mA drawn from the micro controller pin, the transistor can switch a load of 100mA. More than enough for most types of relays. The diode is a fly-back diode, protecting the circuit from high voltage spikes during relay switching. The added advantage of using this circuit, is that the relay operating voltage can be different from the voltage of the micro controller. Thus, instead of using a 5V relay, one can use any DC voltage of up to 48V.

Introducing the ULN2803

The more relays a project requires, the higher the component count. This will make the PCB design more difficult, and might use up valuable PCB space. But using a transistor array, like the ULN2803, will definitely assist in keeping the PCB size small.
The ULN2803 is ideally suited for 3.3V and 5V inputs from a micro controller, and can drive relays up to 48V DC. This ULN2803 has 8 individual transistor circuits, each circuit fitted with all the components required to switch a relay.

The final output circuit consist of a ULN3803, driving 4 12V DC output relays. Each contact of the relay is available on the PC Board termnals.

Step 4: Micro Controller Oscillator

Oscillator Circuit

The micro controller needs an oscillator to function correctly. To keep to the Arduino Uno design, the circuit will make use of the standard 16MHz oscillator. Two options are available:


This method uses a crystal connected to two loading capacitors. This is the most common option.


A resonator is basically a crystal and two loading capacitors in a single 3-pin package. This reduces the amount of components, and increase the available space on the PC Board.

To keep the component count as low as possible, I opted to use a 16MHz resonator.

Step 5: Indication LEDs

What will any circuit be without some LEDs? Provision was made on the PC Board for 3mm LEDs.

1K resistors are used to limit the current through the LED to less than 5mA, When using 3mm high-bright LEDs, the brightness is excellent.

For easy interpretation of the status LEDs, two colors are used. By combining the two LEDs with flashing indications, quite a lot of information can be obtained from only two LEDs.


The red LED is used to indicate fault conditions, long delays, any incorrect commands.

Green LED

The green LED is used to indicate healthy and/or correct inputs and commands.

Step 6: Micro Processor Reset Circuit

For security reasons, some of the functions of the unit is only available in the first 10 minutes after powering up the unit.

With a reset button, power to the unit does not need to be switched off to reset the unit.

How it works

The 10K resistor will keep the RESET line close to 5V. When the button is pressed, the RESET line will be pulled to 0V, thus keeping the micro controller in reset. When the button is released, the RESET line returns to %v, resterting the micro controller.

Step 7: SIM800L Module

The heart of the unit is the SIM800L GSM module. This module uses only 3 I/O pins on the micro controller.

The module interfaces to the micro controller via a standard serial port.

  • All commands to the unit is sent via the serial port using standard AT commands.
  • With an incoming call, or when a SMS is received, the information is sent to the micro controller via the serial port using ASCII text..

To save space, the GSM module is connected o the PC Board via a 7-pin header. This makes removal of the GSM module easy. This also enable the user to easily insert/remove the SIM card at the bottom of the module.

An active SIM card is required, and the SIM card must be able to send and receive SMS messages.

Setup of the SIM800L GSM module

On powering up the unit, the GSM module reset pin is pulled low for a second. This ensures that the GSM module only starts up after the power supply has stabilized. The GSM module takes a couple of seconds to reboot, so wait 5 seconds before sending any AT commands to the module.

To ensure that the GSM module is configured to communicate correctly with the micro controller, the following AT commands are used during startup:


used to determine if a GSM module is available


Polling this command until the GSM module is registered on the cellphone network


Set SMS message mode to ASCII


If SMS avaialble, send SMS details to GSM module serial port


Delete any SMS messages stored on the SIM card


Set the phone book of the GSM module to the SIM card

AT+COPS=2, then AT+CLTS=1, then AT+COPS=0

Set GSM module time to cellphone network time

Wait 5 seconds for time to be set


Enable USSD messaging function

Step 8: The Micro Controller

The micro controller is a standard AtMega328p, the same as used on the Arduino Uno. The code is thus comparable with both. To allow for easy on-board programming, a 6-pin programming header is available on the PC Board.

The different sections of the unit is connected to the micro processor, and includes the following:

  • Four digital inputs
  • Four digital outputs
  • The oscillator
  • Two indication LEDs
  • Reset circuit
  • SIM800L GSM module

All communications to and from the GSM module is done using the SoftwareSerial() function. This method was used to free up the main serial port for the Arduino IDE during the development phase.

With only 2KB of SRAM, and 1KB of EEPROM, there is not enough memory to store more than a couple of users that can be linked to the unit. To free up the SRAM, all the user information is stored on the SIM card on the GSM module. With this arrangement, the unit can cater for up to 250 different users.

Configuration data of the unit is stored into EEPROM, thus seperating user data and system data from each other.

There are still several spare I/O pins available, However, the option of adding a LCD display and/or keyboard was not possible due to the large amount of SRAM used by the SoftWareSerial() receive and transmit buffers,

Because of the lack of any type of user interface on the unit, all settings and users are programmed using SMS messages.

Step 9: Optimising SRAM Memory

Quite early in the development stage, the Arduino IDE reported low SRAM memory when compiling the code. Several methods were used to overcome this.

Limit the data received on the serial port

The GSM module will report all messages to the micro controller the serial port. When receiving some SMS messages, the total length of the received message can be in excess of 200 characters. This can quickly consume all of the SRAM available on the AtMega chip, and will cause stability problems.

to prevent this, only the first 200 characters of ANY message receive from the GSM module will be used. The example below shows how this is done by counting the received characters in variable Counter.

// scan for data from software serial port
  RxString = "";
  Counter = 0;
    delay(1);  // short delay to give time for new data to be placed in buffer
    // get new character
    RxChar = char(;
    //add first 200 character to string
    if (Counter < 200) {
      Counter = Counter + 1;

Reducing Serial.print() code

Although handy during development, the Arduino Serial Monitor can use up a lot of SRAM. The code was developed using as few as possible Serial.print() code. One a section of code has been tested to work, all Serial.print() code was removed from that part of the code.

Using Serial.print(F(("")) code

A lot of information normally displayed on the Arduino Serial Monitor makes more sense when descriptions are added. Take the following example:

Serial.println("Waiting for specific actions");

The string "Waiting for specific actions" is fixed, and can not change.

During compilation of the code, the compiler will include the string "Waiting for specific actions" in the FLASH memory.

Additionally, the compiler sees that the string is a constant, used by the "Serial.print" or "Serial.println" instruction. During boot-up of the micro, this constant is also placed into SRAM memory.

By using the "F" prefix in Serial.print() functions, it tells the compiler that this string is only available in FLASH memory. For this example, the string contains 28 characters. This is 28 bytes that can be freed up in SRAM .

Serial.println(F("Waiting for specific actions"));

This method also applies to the SoftwareSerial.print() commands. As the GSM module works on AT commands, the code contains numerous SoftwareSerial.print("xxxx") commands. Using the "F" prefix freed up almost 300 bytes of SRAM.

Do not use the hardware serial port

After code debugging, the hardware serial port was disabled by removing ALL Serial.print() commands. This freed up a few extra bytes of SRAM.

Without any Serial.print() commands left in the code, an additional 128 bytes of SRAM was made available. This was done by removing the hardware serial port from the code. This fred up the 64 byte transmit and 64 byte receive buffers.

// Serial.begin(9600);    // hardware serial port disabled

Using EEPROM for strings

For each input and output, three strings needed to be saved. They are the channel name, string when channel is on, and string when channel is off.

With a total of 8 I/O channels, their will be

  • 8 strings containing the channel names, each 10 characters long
  • 8 strings containing the channel On description, each 10 characters long
  • 8 strings containing the channel Off description, each 10 characters long

This ads up to 240 bytes of SRAM. Instead of storing these strings in SRAM, they are stored in EEPROM. This freed up an additional 240 bytes of SRAM.

Declaring string with the correct lengths

Variable are normally declared at the beginning of the code. A common mistake when declaring a string variable, is that we do not declare the string with the correct number of characters.

String  GSM_Nr       = "";
String  GSM_Name     = "";
String  GSM_Msg      = "";

During startup, the micro controller will not allocate memory in SRAM for these variables. This can later cause instability when these strings are used.

To prevent this, declare the strings with the correct number of characters the string will use in the software.

String  GSM_Nr       = "1000000000";
String  GSM_Name     = "2000000000";
String  GSM_Msg      = "3000000000";

Notice how I did not declare the strings with the same characters. If you declare these strings all with say "1234567890", the compiler will see the same string in the three variables, and only allocate enough memory in the SRAM for one of the strings.

Step 10: Software Serial Buffer Size

In the following code, you will notice that up to 200 characters can be read from the software serial port.

// scan for data from software serial port
  RxString = "";
  Counter = 0;
    delay(1);  // short delay to give time for new data to be placed in buffer
    // get new character
    RxChar = char(;
    //add first 200 character to string
    if (Counter < 200) {
      Counter = Counter + 1;

This requires a buffer of at least 200 bytes for the software serial port as well. by default, the software serial port buffer is only 64 bytes. To increase this buffer, search for the following file:


Open the file with a text editor, and change the buffer size to 200.

* Definitions

#ifndef _SS_MAX_RX_BUFF
#define _SS_MAX_RX_BUFF 200
 // RX buffer size

Step 11: Making the PC Board

The PC Board was designed using the freeware version of Cadsoft Eagle (I believe the name has changed).

  • PC Board is a single sided design.
  • No surface mount components are used.
  • All components are mounted onto the PC board, including the SIM800L module.
  • No external components or connections are required
  • Wire jumpers are hidden beneath components for a cleaner look.

I use the following method to make PC Boards:

  • The PC Board image is printed on Press-n-Peel using a laser printer.
  • The Press-n-Peel is then placed on top of a clean piece of PC Board, and secured with some tape.
  • The PC Board image is then transferred from the Press-n-Peel to the blank PC Board by passing the board through a laminator. For me, 10 passes works best.
  • After the PC Board cooled down to room temperature, the Press-n-Peel is slowly lifted from the board.
  • The PC Board is then etched using Ammonium Persulphate crystals dissolved in hot water.
  • After etching, the blue Press-n-Peel and black toner is removed by cleaning the etched PC Board with some acetone.
  • The board is then cut to size with a Dremel
  • Holes for all the through-hole components are drilled using a 1mm drill bit.
  • The terminal screw connectors are drilled using a 1.2mm drill bit.

Step 12: Assembly of the PC Board

Assembly is done by adding the smallest components first, and working your way up to the largest components.

All components used int this Instructable, excluding the SIM800 module, was sourced from my local supplier. Thinks to them for always having stock. Please have a look at their South African websie :

NOTE! First soldering the two jumpers located under the ATMEGA328p IC.

The order is as follow:

  • Resistors and diode
  • Reset button
  • IC Sockets
  • Voltage regulator
  • Header pins
  • Small capacitors
  • LEDs
  • Fuse holder
  • Terminal blocks
  • Relays
  • Electrolytic capacitors

Before inserting the IC's, connect the unit to 12V, and test all voltages to be correct.

Finally, using some clear lacquer, cover the copper side of the PC Board to protect it from the elements.

When the lacquer has dried, insert the ICs, but leave the GSM module until the AtMega has been programmed.

Step 13: Programming the AtMega328p

# # Firmware Upgrade to Version 3.02 # #

Enabled SMS to be sent to MASTER USER when power is restored to device.

I am using an Arduino Uno with a programming shield to program the unit. For more information on how to use an Arduino Uno as a programmer, refer to this Instructable:

Arduino UNO As AtMega328P Programmer

The GSM module needs to be remove from the PC Board to gain access to the programming header. Take care not to damage the antenna wire when removing the GSM module.

Connect the programming cable between the programmer and the unit using the programming header on the PC Board., and upload the sketch to the unit.

The external 12V supply is not needed to program the unit. The PC Board will be powered from the Arduino via the programming cable.

Open the attached file in the Arduino IDE, and program it to the unit.

After programming, remove the programming cable, and insert the GSM module.

The unit is now ready for use.

Step 14: Connecting the Unit

All connections to the unit is made via the screw terminals.

Powering the Unit

Ensure you have inserted a registered SIM card in the GSM module, and that the SIM card is able to send and receive SMS messages.

Connect a 12V DC power supply to the 12V IN and any of the 0V terminals. Once powered up, the red LED on the PC Board will turn on. In about a minute, the GSM module should have connected to the cellphone network. The red LED will turn off, and a red LED on the GSM module will flash rapidly.

Once this stage has been reached, the unit is ready to be configured.

Input Connections

The digital inputs works on 12V. To turn a input on, 12V needs to be applied to the input. Removing the 12V will turn the input off.

Output Connections

Each output consists of a change-over contact. Wire up each contact as required.

Step 15: Initial Setup

Initial setup of the unit must be carried out to ensure that all parameters are set to factory defaults, and the SIM card configured to accept user information in the correct format.

As all commands are SMS based, you will need another phone to perform the setup.

For the initial setup, you need to be at the unit.

Set the MASTER USER telephone number

As only the MASTER USER can configure the unit, this step must be carried out first.

  • The unit must be powered.
  • Press and release the Reset button, and wait for the red LED on the PC Board to turn off.
  • The NET LED on the GSM module will flash rapidly.
  • The unit is now ready to accept the initial setup commands. This must be carried out within 10 minutes.
  • Send a SMS message containing MASTER,description to the unit telephone number.
  • If received, the green LED on the PC Board will flash twice.
  • The MASTER USER has now been programmed.

Restore the unit to Factory Defaults

After the MASTER USER has been programmed, the settings of the unit must be set to the factory defaults.

  • Send a SMS message with only CLEARALL to the unit telephone number.
  • If received, the green and red LED on the PC Board will flash alternatively once a second. The unit has been restored with the factory default settings.
  • All settings have been restored to factory defaults.
  • Press and release the Reset button to reboot the unit.

Formatting the SIM Card

The last step is to erase all information stored on the SIM card, and configure it for use in this unit.

  • Press and release the Reset button, and wait for the red LED on the PC Board to turn off.
  • The NET LED on the GSM module will flash rapidly.
  • The unit is now ready to accept the initial setup commands. This must be carried out within 10 minutes.
  • Send a SMS message with only ERASESIM to the unit telephone number.
  • If received, the green LED on the PC Board will flash tree times.

The unit has now been configured, and is ready for use.

Step 16: SMS Commands

There are three different type of commands used by the unit. All commands ae send via SMS, and are all in the following format:

COMMAND, , , , ,

  • All commands, except the NORMAL USER commands are case sensitive.
  • Parameters are not case sensitive.

Initial Setup Commands


The phone number of the SMS sender is used as the MASTER USER phone number. a Description for the unit can be added here.


Reset the unit to factory defaults


Erase all data from the SIM card


Reboot the unit

MASTER USER Commands for configuring the unit


Set specific channels to have PULSED, TIMED or LATCHING outputs. t is time duration in minutes for TIMED outputs


Set specific channels to PULSED outputs. If not set, channels will be set as LATCHING outputs.

Sets the pulsed output duration in seconds (0 .. 10s)


Set channels that must trigger, and send a SMS message when the state changes from OFF to ON


Set channels that must trigger, and send a SMS message when the state changes from ON to OFF


Sets the input delay time for detecting status changes in seconds


Set each input channel's name, on text and off text


Set each output channel's name, on text and off text

Add,location,number, Calloutputs,SMSoutputs,inputs

Add user to SIM card at memory 'location', with output and input channels assigned to the user


Delete user from SIM card memory 'location'


Will pulse output with the name ChannelName

ChannelName,onText, or ChannelName,offText

Will turn output On/Off with the name of ChannelName, and onText/offText

Normal User Commands for controlling the unit

Request I/O status update. Status SMS will be send to the originator.


Will pulse output with the name ChannelName


Will turn the output On with the name of ChannelName, and status text onText

Will turn the output Off with the name of ChannelName, and status text offText

For a more details description of the commands, please refer to the attached PDF document.

Microcontroller Contest 2017

Participated in the
Microcontroller Contest 2017