Skip to main content
Making

Getting Connected Using a GSM Module

By August 7, 2024No Comments

Introduction

When sensing spatially varying environmental data such as air pollution or air temperature, one option is to employ a mobile sensor, thus avoiding the challenges of deploying an array of spatially distributed static sensors. With a mobile sensor a variety of locations can then be surveyed on foot, or by bicycle or car. However, if a connected sensor system is envisaged, rather than a data logger, then maintaining connectivity involves its own challenges – WiFi is unlikely to offer comprehensive coverage of outdoor spaces and currently LoRa coverage is patchy. Therefore, utilizing the cellular network seems the most viable option.

GSM Modules

There are a variety of cellular breakout boards available, and this example uses a board based on the SIM800L, which are cheap and readily available. This module uses the GSM network and 2.5 G GPRS for data connectivity, which although dated as a technology is still supported on UK cell networks. The SIM800L chip itself requires a power supply of between 3.4 V and 4.4 V and operates at 3.3 V TTL levels. Some breakout boards include an onboard 5V regulator and level shifter so that the module can be driven directly by a 5V microcontroller; other SIM800L breakout boards lack such refinements. In this example we will use a basic module using the latter configuration. A very useful resource for working with the SIM800L mode can be found on LastMinuteEngineers.com here.

Wiring up

The following schematic is based on the resource mentioned above and uses an Arduino UNO and a basic SiM800L module (without regulator and no level shifter). It uses a voltage divider consisting of a 10 kΩ resistor and 20 kΩ resistor to reduce the Arduino’s Tx level to a level acceptable for the SIM800L. A battery of the appropriate voltage (3.4 V – 4.4 V) is used to power the SIM800L module. A Lithium Polymer battery (nominal voltage 3.7V) with a capacity greater than 1000 mAh is an option, alternatively 3 x NiMH AA batteries (2000mAh) worked well. The capacity of the battery is important as it must be able to supply high burst currents of up to 2 Amps required by the GSM module when transmitting. To aid this a 1000μF capacitor was added across the power rails.

Figure 1 Circuit for a ‘bare bones’ SIM800L GSM Module (i.e. no onboard regulator, no level shifter)

AT Commands

Communication between the microcontroller and the GSM module is via the AT command set and serial communication. Hence the Tx pin of the microcontroller is connected to the Rx pin of the GSM module and vice versa. The relevant AT command set can be found here.

The following commands are a typical sequence to make a HTTP POST request to upload sensor data to a server. The second and third AT commands ensure any previous requests are terminated cleanly.

 

AT                                                                                                           Check connection, should respond OK

AT+CIPSHUT                                                                                      Deactivate GPRS PDP Context

AT+SAPBR=0,1                                                                                   Close bearer

AT+SAPBR=3,1,”Contype”, “GPRS”                                               Set bearer parameters

AT+SAPBR=3,1,”APN”, “giffgaff.com”                                          Set bearer parameters

AT+SAPBR=1,1                                                                                   Open bearer

AT+SAPBR=2,1                                                                                   Query bearer

AT+HTTPINIT                                                                                    Initialize HTTP service

AT+HTTPSSL=1                                                                                 Set HTTP to use SSL

AT+HTTPPARA=”CID”,1                                                                 Set the bearer profile identifier

AT+HTTPPARA=”URL”, “<your-actual-url>”                              Set your URL

AT+HTTPPARA=”CONTENT”, “application/json”                      Set content type

AT+HTTPDATA=14,10000                                                             Set POST data length and timeout period

gsmSerial.println(“{\”value\”:25.5}”);                                          Send the payload to upload

AT+HTTPACTION=1                                                                        Specify the HTTP method (POST)

AT+HTTPREAD                                                                                 Read the HTTP response

AT+HTTPTERM                                                                                 Terminate the HTTP service

AT+SAPBR=0,1                                                                                   Close the bearer

 

Example Code

Some Arduino example code for making a HTTP POST request is shown below. This code use the Arduino Software Serial library to provide the serial communication with the GSM module. The example has been tested by uploading some dummy data to a cloud-based IoT aggregator service (io.adafruit.com).

#include <SoftwareSerial.h>

int TIME_OUT_READ_SERIAL = 20000;

//Create software serial object to communicate with SIM800L
SoftwareSerial gsmSerial(2, 3); //SIM800L Tx & Rx is connected to Arduino #2 & #3


void setup(){
  delay(10000);
  Serial.println("Starting...");
  pinMode(RESET_PIN, OUTPUT);
  digitalWrite(RESET_PIN, HIGH);
  
  //Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
  Serial.begin(9600);
  initializeGPRS();
}

void loop(){
  testPostRequest();
  delay(100000); 
}

void initializeGPRS(){
  
  //Begin serial communication with Arduino and SIM800L
  gsmSerial.begin(38400);
  while(!gsmSerial){
    Serial.println("Waiting...");
  }
  Serial.println("Connected...");
  sendCommand("AT");
  Serial.println(readSerial());
 
  sendCommand("AT+CIPSHUT");
  Serial.println(readSerial());
  
  sendCommand("AT+SAPBR=0,1");
  Serial.println(readSerial());
  
  sendCommand("AT+SAPBR=3,1,\"Contype\",\"GPRS\"");
  Serial.println(readSerial());
  
  sendCommand("AT+SAPBR=3,1,\"APN\",\"giffgaff.com\"");
  Serial.println(readSerial());
  
}


void testPostRequest(){ 
  sendCommand("AT+SAPBR=1,1");
  Serial.println(readSerial());
  
  sendCommand("AT+SAPBR=2,1");
  Serial.println(readSerial());
  
  sendCommand("AT+HTTPINIT");
  Serial.println(readSerial());

  sendCommand("AT+HTTPSSL=1");
  Serial.println(readSerial());
  
  sendCommand("AT+HTTPPARA=\"CID\",1");
  Serial.println(readSerial());
  
  sendCommand("AT+HTTPPARA=\"URL\",\"https://io.adafruit.com/api/v2/androidjet/feeds/test/data?x-aio-key=aio_ZQUf88G1j17SbTuyw2C0Gzyedlfr\"");
  Serial.println(readSerial());
  
  sendCommand("AT+HTTPPARA=\"CONTENT\",\"application/json\"");
  Serial.println(readSerial());
  
  sendCommand("AT+HTTPDATA=14,10000");
  Serial.println(readSerial());
  gsmSerial.println("{\"value\":25.5}");
  delay(5000);
  
  sendCommand("AT+HTTPACTION=1");
  Serial.println(readSerial());
  delay(5000);
  
  sendCommand("AT+HTTPREAD");
  Serial.println(readSerial());
  
  sendCommand("AT+HTTPTERM");
  Serial.println(readSerial());

  sendCommand("AT+SAPBR=0,1");
  Serial.println(readSerial());
}



void sendCommand(const char* command) {
  Serial.print("C: ");
  Serial.println(command);
  gsmSerial.println(command);
  delay(1000);
}


String readSerial(){
  long timeOld = millis();
  while (!gsmSerial.available() && !(millis() > timeOld + TIME_OUT_READ_SERIAL)){
      delay(10);
  }
  String str;
  while(gsmSerial.available()){
    if (gsmSerial.available() > 0){
        str += (char) gsmSerial.read();
    }
  }
  return str;
}

The code worked reliably with a 3xNiMH AA battery pack (2000 mAh) but less so when powered by a 1000 mAh Lithium Polymer battery – so you have been warned! The sketch was also tested successfully using a 5V SIM800L breakout board including onboard regulator and level shifter.  Somewhat surprisingly, this module could be powered directly by the Arduino UNO 5V pin provided the 1000μF capacitor was added between the power lines to act as a current reservoir. In addition, there are numerous Arduino libraries available for the SIM800L allowing a more elegant and perhaps more robust implementation; these include the TinyGSM libary, GSMSim libary and the Sim800L-Arduino-Library-revised.

 

Summary

This blog post has explored the use of cheap 2.5G GPRS GSM modules to provide data connectivity for real-time mobile sensor systems. These modules, based on the SIM800L chip, can provide satisfactory results providing proper attention is paid to their transient current demands. It should be noted that although 2.5G GPRS is currently still supported by UK cell networks, it is planned to be phased out by 2033, so projects needing long term longevity should look at 4G-enabled modules, such as those based around the SIM A7670E.