Arduino GSM Modules
Introduction
GSM (Global System for Mobile Communications) modules allow your Arduino projects to connect to cellular networks, enabling wireless communication over long distances without relying on WiFi or Bluetooth. These modules serve as a bridge between your Arduino and the cellular network, allowing your projects to send/receive SMS messages, make calls, and even connect to the internet using GPRS technology.
GSM modules are essential components for remote IoT applications where traditional connectivity options aren't available. Whether you're building a remote weather station, a vehicle tracking system, or a smart agricultural monitor, GSM modules provide the connectivity necessary for your Arduino to communicate with the world.
Common GSM Modules for Arduino
Several GSM modules are popular in the Arduino community:
- SIM800L - Compact, affordable module supporting quad-band GSM/GPRS
- SIM900 - Reliable module with voice, SMS, and data capabilities
- SIM7600 - Advanced module supporting 4G LTE
- A7 - Cost-effective module with GPS functionality included
Let's examine how these modules work and how to integrate them with Arduino.
How GSM Modules Work
GSM modules function similarly to mobile phones, requiring a SIM card with an active cellular plan. Here's a simplified overview of their operation:
The communication between Arduino and GSM modules typically occurs via:
- Serial Communication (UART) - The most common method
- SPI - For higher speed applications
- I²C - Less common but supported by some modules
Hardware Setup
Components Needed:
- Arduino board (Uno, Mega, Nano, etc.)
- GSM module (SIM800L, SIM900, etc.)
- SIM card with active plan
- Power supply (GSM modules often require 3.7-4.2V and can draw high current)
- Connecting wires
- Antenna (usually included with the module)
Typical Wiring for SIM800L:
SIM800L Pin | Arduino Pin | Notes |
---|---|---|
VCC | External 3.7-4.2V | Not from Arduino's 5V! |
GND | GND | Common ground |
RXD | Digital Pin 3 | Connected to Arduino TX |
TXD | Digital Pin 2 | Connected to Arduino RX |
RST | Digital Pin 4 | Reset pin (optional) |
⚠️ Important Notes:
- GSM modules can draw up to 2A during transmission peaks, so a dedicated power supply is recommended
- Logic level conversion may be needed between 5V Arduino and 3.3V GSM module
- Most GSM modules operate at 3.7-4.2V (LiPo battery voltage range)
Software Libraries
Several libraries simplify working with GSM modules:
- Official Arduino GSM Library - For Arduino GSM Shield
- TinyGSM - Versatile library supporting multiple modules
- SIM800L Library - Specifically for SIM800L modules
Let's look at how to use the TinyGSM library, as it supports many common modules.
Installing TinyGSM Library
In the Arduino IDE:
- Go to Sketch > Include Library > Manage Libraries
- Search for "TinyGSM"
- Click Install
Basic Examples
1. Testing Communication
First, let's verify that we can communicate with the GSM module using AT commands:
#include <SoftwareSerial.h>
// Create software serial object to communicate with SIM800L
SoftwareSerial SIM800L(2, 3); // RX, TX
void setup() {
// Start serial communication with Arduino and computer
Serial.begin(9600);
Serial.println("Testing GSM module communication...");
// Start serial communication with Arduino and SIM800L
SIM800L.begin(9600);
delay(1000);
Serial.println("Sending AT command...");
SIM800L.println("AT");
delay(1000);
// Read and print the module's response
while(SIM800L.available()) {
Serial.write(SIM800L.read());
}
}
void loop() {
// Forward any response from module to Serial Monitor
if (SIM800L.available()) {
Serial.write(SIM800L.read());
}
// Forward commands from Serial Monitor to module
if (Serial.available()) {
SIM800L.write(Serial.read());
}
}
Expected output when the module is properly connected:
Testing GSM module communication...
Sending AT command...
OK
2. Sending an SMS Message
Let's create an example that sends an SMS message:
#include <SoftwareSerial.h>
// Create software serial object to communicate with SIM800L
SoftwareSerial SIM800L(2, 3); // RX, TX
void setup() {
// Initialize Serial Monitor
Serial.begin(9600);
Serial.println("SIM800L SMS Test");
// Initialize SIM800L
SIM800L.begin(9600);
delay(1000);
// Test AT command
Serial.println("Testing AT command...");
SIM800L.println("AT");
updateSerial();
// Set SMS text mode
Serial.println("Setting SMS mode...");
SIM800L.println("AT+CMGF=1");
updateSerial();
// Send SMS
Serial.println("Sending SMS...");
SIM800L.println("AT+CMGS=\"+1234567890\""); // Replace with recipient's phone number
updateSerial();
SIM800L.print("Hello from Arduino!"); // SMS message content
SIM800L.write(26); // ASCII code for CTRL+Z to send message
Serial.println("Message sent!");
}
void loop() {
updateSerial();
}
void updateSerial() {
delay(500);
// Forward messages from SIM800L to Serial Monitor
while (SIM800L.available()) {
Serial.write(SIM800L.read());
}
// Forward commands from Serial Monitor to SIM800L
while (Serial.available()) {
SIM800L.write(Serial.read());
}
}
3. Connecting to the Internet using GPRS
This example shows how to connect to the internet and make an HTTP request using TinyGSM:
#include <TinyGsmClient.h>
#include <SoftwareSerial.h>
// Define the pins
#define RX_PIN 2
#define TX_PIN 3
#define RESET_PIN 4
// Your GPRS credentials (leave empty if not needed)
const char apn[] = "your_apn"; // APN (example: internet.vodafone.pt)
const char user[] = ""; // User
const char pass[] = ""; // Password
// Server details
const char server[] = "example.com";
const char resource[] = "/index.html";
const int port = 80;
// Initialize serial communication
SoftwareSerial SerialAT(RX_PIN, TX_PIN);
// Initialize GSM modem
TinyGsm modem(SerialAT);
TinyGsmClient client(modem);
void setup() {
// Set console baud rate
Serial.begin(9600);
delay(10);
// Set GSM module baud rate
SerialAT.begin(9600);
delay(3000);
// Reset the modem (optional)
pinMode(RESET_PIN, OUTPUT);
digitalWrite(RESET_PIN, LOW);
delay(1000);
digitalWrite(RESET_PIN, HIGH);
delay(3000);
// Restart the module
Serial.println("Initializing modem...");
modem.restart();
// Print modem info
String modemInfo = modem.getModemInfo();
Serial.print("Modem Info: ");
Serial.println(modemInfo);
// Unlock your SIM card with a PIN if needed
// modem.simUnlock("1234");
// Connect to GPRS
Serial.print("Connecting to APN: ");
Serial.println(apn);
if (!modem.gprsConnect(apn, user, pass)) {
Serial.println("Failed to connect to GPRS");
return;
}
Serial.println("GPRS connected!");
// Make an HTTP GET request
Serial.print("Connecting to ");
Serial.println(server);
if (!client.connect(server, port)) {
Serial.println("Failed to connect to server");
return;
}
Serial.println("Making HTTP GET request...");
client.print(String("GET ") + resource + " HTTP/1.1\r
");
client.print(String("Host: ") + server + "\r
");
client.print("Connection: close\r
\r
");
// Wait for server response
unsigned long timeout = millis();
while (client.connected() && millis() - timeout < 10000L) {
while (client.available()) {
char c = client.read();
Serial.print(c);
timeout = millis();
}
}
Serial.println();
// Disconnect from server
client.stop();
Serial.println("Server disconnected");
// Disconnect from GPRS
modem.gprsDisconnect();
Serial.println("GPRS disconnected");
}
void loop() {
// Your code here (if needed)
}
Real-World Applications
1. Remote Weather Station
A weather station that collects environmental data and sends it via SMS or uploads it to a server:
#include <TinyGsmClient.h>
#include <SoftwareSerial.h>
#include <DHT.h>
// Define the pins
#define RX_PIN 2
#define TX_PIN 3
#define DHT_PIN 7
#define DHT_TYPE DHT22
// Initialize components
SoftwareSerial SerialAT(RX_PIN, TX_PIN);
TinyGsm modem(SerialAT);
DHT dht(DHT_PIN, DHT_TYPE);
// GPRS credentials
const char apn[] = "your_apn";
const char user[] = "";
const char pass[] = "";
// Thingspeak server details
const char server[] = "api.thingspeak.com";
const char resource[] = "/update?api_key=YOUR_API_KEY"; // Replace with your API key
const int port = 80;
void setup() {
Serial.begin(9600);
SerialAT.begin(9600);
dht.begin();
// Initialize modem
Serial.println("Initializing modem...");
modem.restart();
Serial.println("Setup complete. System will read sensors and upload data every hour.");
}
void loop() {
// Read sensor data
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
if (isnan(temperature) || isnan(humidity)) {
Serial.println("Failed to read from DHT sensor!");
delay(60000);
return;
}
Serial.print("Temperature: ");
Serial.print(temperature);
Serial.print("°C, Humidity: ");
Serial.print(humidity);
Serial.println("%");
// Connect to GPRS and upload data
if (uploadSensorData(temperature, humidity)) {
Serial.println("Data uploaded successfully!");
} else {
Serial.println("Failed to upload data!");
}
// Wait for 1 hour before next reading
delay(3600000);
}
bool uploadSensorData(float temp, float humidity) {
// Connect to GPRS
Serial.println("Connecting to GPRS...");
if (!modem.gprsConnect(apn, user, pass)) {
Serial.println("GPRS connection failed");
return false;
}
Serial.println("GPRS connected!");
// Connect to ThingSpeak
TinyGsmClient client(modem);
Serial.print("Connecting to ");
Serial.println(server);
if (!client.connect(server, port)) {
Serial.println("Server connection failed");
modem.gprsDisconnect();
return false;
}
// Prepare the data string
String dataString = String(resource) + "&field1=" + String(temp) + "&field2=" + String(humidity);
// Make HTTP GET request
Serial.println("Sending data...");
client.print(String("GET ") + dataString + " HTTP/1.1\r
");
client.print(String("Host: ") + server + "\r
");
client.print("Connection: close\r
\r
");
// Wait for server response
unsigned long timeout = millis();
while (client.connected() && millis() - timeout < 10000L) {
while (client.available()) {
char c = client.read();
Serial.print(c);
timeout = millis();
}
}
Serial.println();
// Disconnect
client.stop();
modem.gprsDisconnect();
return true;
}
2. GPS Tracker with SMS Control
A vehicle or asset tracker that reports location via SMS and accepts command messages:
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
// Define the pins
#define GSM_RX 2
#define GSM_TX 3
#define GPS_RX 4
#define GPS_TX 5
// Initialize serial communications
SoftwareSerial gsmSerial(GSM_RX, GSM_TX);
SoftwareSerial gpsSerial(GPS_RX, GPS_TX);
TinyGPSPlus gps;
// Phone number to receive alerts
const String AUTHORIZED_NUMBER = "+1234567890"; // Replace with your number
// Variables for GPS data
float latitude = 0, longitude = 0;
bool locationValid = false;
unsigned long lastLocationUpdate = 0;
void setup() {
Serial.begin(9600);
gsmSerial.begin(9600);
gpsSerial.begin(9600);
Serial.println("GPS Tracker with SMS Control");
// Initialize GSM module
initGSM();
// Set SMS mode to text
gsmSerial.println("AT+CMGF=1");
delay(500);
// Configure GSM to forward SMS when received
gsmSerial.println("AT+CNMI=2,2,0,0,0");
delay(500);
Serial.println("System ready!");
}
void loop() {
// Update GPS data
while (gpsSerial.available() > 0) {
if (gps.encode(gpsSerial.read())) {
updateGPSData();
}
}
// Check for incoming SMS
if (gsmSerial.available()) {
String response = gsmSerial.readString();
Serial.println("GSM Response: " + response);
// Check if this is an incoming SMS
if (response.indexOf("+CMT:") >= 0) {
// Extract the sender number
int phoneNumberStart = response.indexOf("\"+") + 1;
int phoneNumberEnd = response.indexOf("\",\"", phoneNumberStart);
String sender = response.substring(phoneNumberStart, phoneNumberEnd);
// Extract the message content
int messageStart = response.indexOf("\r
", phoneNumberEnd) + 2;
String message = response.substring(messageStart);
message.trim();
Serial.println("SMS from: " + sender);
Serial.println("Message: " + message);
// Process commands if from authorized number
if (sender == AUTHORIZED_NUMBER) {
processCommand(message);
}
}
}
// If no GPS data received for 5 minutes, try to reset
if (millis() - lastLocationUpdate > 300000) {
Serial.println("GPS timeout - no data received for 5 minutes");
// You could implement a reset procedure here
lastLocationUpdate = millis();
}
}
void initGSM() {
Serial.println("Initializing GSM module...");
gsmSerial.println("AT");
delay(1000);
gsmSerial.println("AT+CMGF=1");
delay(1000);
}
void updateGPSData() {
if (gps.location.isValid()) {
latitude = gps.location.lat();
longitude = gps.location.lng();
locationValid = true;
lastLocationUpdate = millis();
Serial.print("GPS Location: ");
Serial.print(latitude, 6);
Serial.print(", ");
Serial.println(longitude, 6);
}
}
void processCommand(String command) {
command.toLowerCase();
if (command == "location" || command == "where") {
sendLocationSMS();
} else if (command == "status") {
sendStatusSMS();
} else if (command == "help") {
sendHelpSMS();
} else {
// Unknown command
sendSMS(AUTHORIZED_NUMBER, "Unknown command. Send 'help' for available commands.");
}
}
void sendLocationSMS() {
if (locationValid) {
String message = "Current location: ";
message += "https://maps.google.com/maps?q=";
message += String(latitude, 6);
message += ",";
message += String(longitude, 6);
sendSMS(AUTHORIZED_NUMBER, message);
} else {
sendSMS(AUTHORIZED_NUMBER, "GPS location not available yet.");
}
}
void sendStatusSMS() {
String message = "System status:
";
message += "GPS Fix: " + String(locationValid ? "Yes" : "No") + "
";
if (locationValid) {
message += "Lat: " + String(latitude, 6) + "
";
message += "Lon: " + String(longitude, 6) + "
";
}
message += "Uptime: " + String(millis() / 60000) + " minutes";
sendSMS(AUTHORIZED_NUMBER, message);
}
void sendHelpSMS() {
String message = "Available commands:
";
message += "- location: get current position
";
message += "- status: get system status
";
message += "- help: show this message";
sendSMS(AUTHORIZED_NUMBER, message);
}
void sendSMS(String number, String message) {
Serial.println("Sending SMS to " + number + ": " + message);
gsmSerial.println("AT+CMGF=1"); // Set SMS text mode
delay(500);
gsmSerial.print("AT+CMGS=\"");
gsmSerial.print(number);
gsmSerial.println("\"");
delay(500);
gsmSerial.print(message);
gsmSerial.write(26); // ASCII code for CTRL+Z to send message
delay(5000); // Wait for the message to be sent
Serial.println("SMS sent");
}
Common Challenges and Troubleshooting
Power Supply Issues
GSM modules require a stable power supply capable of handling current spikes:
- Problem: Module resets during transmission
- Solution: Use a dedicated power supply with at least 2A capacity and adequate capacitors
Network Connectivity Problems
- Problem: Unable to connect to the network
- Solution:
- Check signal strength with
AT+CSQ
command - Ensure the antenna is properly connected
- Try placing the antenna near a window or outdoor area
- Verify the SIM card works in a mobile phone
- Check signal strength with
AT Command Communication Failures
- Problem: No response from the module
- Solution:
- Double-check TX/RX connections (they should be crossed)
- Verify baud rate settings
- Use a level shifter if connecting a 5V Arduino to a 3.3V module
Temperature Considerations
GSM modules can get hot during operation:
- Problem: Module overheating
- Solution: Add heat sinks and ensure proper ventilation in your enclosure
Advanced Techniques
Using Sleep Mode to Save Power
For battery-powered applications, you can use sleep modes:
// Put GSM module to sleep
void sleepGSM() {
gsmSerial.println("AT+CSCLK=2");
delay(500);
}
// Wake up GSM module
void wakeGSM() {
// Send any AT command to wake up
gsmSerial.println("AT");
delay(1000);
// Disable sleep mode
gsmSerial.println("AT+CSCLK=0");
delay(500);
}
Creating an HTTP Server
You can turn your Arduino + GSM module into a simple HTTP server:
// This code is conceptual and would need to be integrated with the appropriate GSM library
void setupServer() {
// Set up IP connection
gsmSerial.println("AT+CIPMUX=1"); // Enable multiple connections
delay(1000);
// Start server on port 80
gsmSerial.println("AT+CIPSERVER=1,80");
delay(1000);
Serial.println("Server started!");
}
// Handle incoming connections
void handleConnections() {
if (gsmSerial.available()) {
String response = gsmSerial.readString();
if (response.indexOf("+IPD") >= 0) {
// Parse connection ID
int connectionId = response.charAt(response.indexOf("+IPD") + 5) - '0';
// Send HTTP response
String httpResponse = "HTTP/1.1 200 OK\r
Content-Type: text/html\r
\r
";
httpResponse += "<html><body><h1>Arduino GSM Server</h1>";
httpResponse += "<p>Temperature: 25.5C</p>"; // Add your sensor data here
httpResponse += "</body></html>";
// Send the HTTP response
gsmSerial.print("AT+CIPSEND=");
gsmSerial.print(connectionId);
gsmSerial.print(",");
gsmSerial.println(httpResponse.length());
delay(500);
gsmSerial.print(httpResponse);
delay(1000);
// Close the connection
gsmSerial.print("AT+CIPCLOSE=");
gsmSerial.println(connectionId);
}
}
}
Summary
GSM modules open up a world of possibilities for Arduino projects, allowing them to connect to cellular networks for wireless communication virtually anywhere with cellular coverage. In this guide, we've covered:
- The basics of GSM modules and how they work
- Hardware setup and considerations
- Essential software libraries
- Basic examples for SMS and internet connectivity
- Real-world applications including a weather station and GPS tracker
- Common challenges and troubleshooting tips
- Advanced techniques for power saving and creating HTTP servers
GSM technology enables your Arduino projects to communicate from remote locations without traditional internet infrastructure, making it ideal for IoT applications in agriculture, remote monitoring, tracking, and security systems.
Additional Resources
To continue learning about Arduino GSM modules:
-
Official Arduino GSM Library Documentation: Explore the official documentation for more examples and advanced usage.
-
TinyGSM GitHub Repository: Visit the TinyGSM GitHub page for comprehensive examples and updates.
-
AT Command Reference: Learn the standard AT command set for GSM/GPRS modules to unlock more advanced functionality.
Exercises
-
SMS Control System: Create a system that can control an LED or relay via SMS commands.
-
Data Logger: Build a data logger that collects sensor readings and uploads them to a web server periodically.
-
Alert System: Develop a system that monitors a sensor (e.g., temperature) and sends an SMS alert when a threshold is exceeded.
-
Two-Way Communication: Create a project where two Arduino+GSM systems can communicate with each other via SMS.
-
GSM Weather Station: Extend the weather station example to include more sensors and create a complete remote monitoring solution.
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)