This guide shows how to connect the TTGO T-Call ESP32 SIM800L board to the Internet using a SIM card data plan and publish/subscribe to a cloud MQTT broker without using Wi-Fi. The cloud MQTT Mosquitto broker will be installed on a Digital Ocean server. We’ll also use Node-RED to visualize the readings and control the outputs from anywhere. The board will be programmed using Arduino IDE.
With this setup, you can monitor and control your ESP32 from anywhere in the world, and the ESP32 doesn’t need to be connected to a wireless router because it connects to the internet using a SIM card data plan.
Introducing the TTGO T-Call ESP32 SIM800L
The TTGO T-Call is an ESP32 development board that combines a SIM800L GSM/GPRS module. You can get if for approximately $11.
Besides Wi-Fi and Bluetooth, you can communicate with this ESP32 board using SMS or phone calls and you can connect it to the internet using your SIM card data plan. This is great for IoT projects that don’t have access to a nearby router.
Important: the SIM800L works on 2G networks, so it will only work in your country, if 2G networks are available. Check if you have 2G network in your country, otherwise it won’t work.
To use the capabilities of this board you need to have a nano SIM card with data plan and a USB-C cable to upload code to the board.
The package includes some header pins, a battery connector, and an external antenna that you should connect to your board.
However, we had some issues with that antenna, so we decided to switch to another type of antenna and all the problems were solved. The following figure shows the new antenna.
Project Overview
The idea of this project is to connect your ESP32 to a Cloud MQTT broker to subscribe to an MQTT topic and publish sensor data to MQTT topics. The ESP32 doesn’t need to have access to a router via Wi-Fi, because it connects to the internet using a SIM card data plan.
In a previous project, we created our own server with a database to plot sensor readings in charts that you can access from anywhere in the world.
In this project, we’ll publish sensor readings to a server via MQTT and we’ll use Mosquitto broker. You can publish your sensor readings to any other cloud broker.
In summary, here’s how the project works:
- The T-Call ESP32 SIM800L board is connected to the internet using a SIM card data plan.
- The T-Call ESP32 SIM800L board publishes the sensor readings via MQTT and the readings are displayed in Node-RED Dashboard.
- Through Node-RED Dashboard, you can press buttons to send on and off commands to control the ESP32 GPIOs.
We’ll be using a BME280 sensor, but you can use any other sensor that best suits your needs.
Cloud MQTT Broker
You can search for a free cloud MQTT broker, however we’ll be using our own cloud MQTT broker. We recommend using Digital Ocean with MQTT Mosquitto Broker, because it can handle all the project requirements. We’ll also use Node-RED software to visualize the readings in gauges and publish MQTT messages to the ESP32.
- Run Your Cloud MQTT Mosquitto Broker (access from anywhere using Digital Ocean)
- Access Node-RED Dashboard from Anywhere (using Digital Ocean)
Prerequisites
1. ESP32 add-on Arduino IDE
We’ll program the ESP32 using Arduino IDE. So, you need to have the ESP32 add-on installed in your Arduino IDE. Follow the next tutorial, if you haven’t already.
2. Preparing your Cloud MQTT Broker
In this project we’ll show you how to exchange data via MQTT using a cloud MQTT broker.
We’ll be using our own cloud MQTT broker. However, if you find a free MQTT broker with all your desired features it will also work…
If you want to follow this exact project, you should follow the next two tutorials to prepare your own server and Node-RED software.
- Run Your Cloud MQTT Mosquitto Broker (access from anywhere using Digital Ocean)
- Access Node-RED Dashboard from Anywhere (using Digital Ocean)
The ESP32 is publishing temperature readings every 30 seconds on the esp/temperature and esp/humidity topics. It’s subscribed to these two topics esp/output1 and esp/output2 to update the state of the output LEDs.
Having Node-RED running, go to your server IP address followed by :1880.
http://cloud-mqtt-broker-ip-address:1880
Wire your nodes as shown below:
Finally, deploy your flow (press the button on the upper right corner).
Alternatively, you can go to Menu > Import and copy the following to your Clipboard to create your Node-RED flow.
[{"id":"a2c394d8.1544e8","type":"mqtt in","z":"537cca59.c4a014","name":"","topic":"esp/temperature","qos":"2","datatype":"auto","broker":"18f874c0.4a464b","x":140,"y":1020,"wires":[["6907217e.f39bf"]]},{"id":"b83c2ecf.8ab94","type":"mqtt in","z":"537cca59.c4a014","name":"","topic":"esp/humidity","qos":"2","datatype":"auto","broker":"18f874c0.4a464b","x":130,"y":1100,"wires":[["c92e354e.a27d48"]]},{"id":"ee844c66.3eda2","type":"mqtt out","z":"537cca59.c4a014","name":"","topic":"esp/output1","qos":"1","retain":"","broker":"18f874c0.4a464b","x":330,"y":1180,"wires":[]},{"id":"54540fba.e5877","type":"mqtt out","z":"537cca59.c4a014","name":"","topic":"esp/output2","qos":"1","retain":"","broker":"18f874c0.4a464b","x":330,"y":1260,"wires":[]},{"id":"56080a9a.c7bba4","type":"ui_switch","z":"537cca59.c4a014","name":"","label":"Output 1","tooltip":"","group":"1539f836.ed9378","order":0,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":120,"y":1180,"wires":[["ee844c66.3eda2"]]},{"id":"417bd6d1.1d1468","type":"ui_switch","z":"537cca59.c4a014","name":"","label":"Output 2","tooltip":"","group":"1539f836.ed9378","order":0,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":120,"y":1260,"wires":[["54540fba.e5877"]]},{"id":"6907217e.f39bf","type":"ui_gauge","z":"537cca59.c4a014","name":"","group":"1539f836.ed9378","order":2,"width":0,"height":0,"gtype":"gage","title":"Temperature","label":"Celsius Degrees","format":"{{value}}","min":"-10","max":"40","colors":["#00b500","#e6e600","#ca3838"],"seg1":"","seg2":"","x":350,"y":1020,"wires":[]},{"id":"c92e354e.a27d48","type":"ui_gauge","z":"537cca59.c4a014","name":"","group":"1539f836.ed9378","order":2,"width":0,"height":0,"gtype":"gage","title":"Humidity","label":"%","format":"{{value}}","min":"0","max":"100","colors":["#93dae6","#0074cc","#002561"],"seg1":"","seg2":"","x":340,"y":1100,"wires":[]},{"id":"18f874c0.4a464b","type":"mqtt-broker","z":"","name":"","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"1539f836.ed9378","type":"ui_group","z":"","name":"Dashboard","tab":"38becbd0.c13714","order":1,"disp":true,"width":"6","collapse":false},{"id":"38becbd0.c13714","type":"ui_tab","z":"","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]
3. SIM Card with data plan
To use the TTGO T-Call ESP32 SIM800L board, you need a nano SIM card with a data plan. We recommend using a SIM card with a prepaid or monthly plan, so that you know exactly how much you’ll spend.
4. APN Details
To connect your SIM card to the internet, you need to have your phone plan provider APN details. You need the domain name, username and password.
In my case, I’m using vodafone Portugal. If you search for GPRS APN settings followed by your phone plan provider name, (in my case its: “GPRS APN vodafone Portugal”), you can usually find in a forum or in their website all the information that you need.
I’ve found this website that can be very useful to find all the information you need.
It might be a bit tricky to find the details if you don’t use a well known provider. So, you might need to contact your provider directly.
5. Libraries
You need to install these libraries in your Arduino IDE to proceed with this project: Adafruit_BME280, Adafruit_Sensor, TinyGSM, and PubSubClient. Follow the next instructions to install these libraries.
Installing the Adafruit BME280 Library
Open your Arduino IDE and go to Sketch > Include Library > Manage Libraries. The Library Manager should open.
Search for “adafruit bme280 ” on the Search box and install the library.
Installing the Adafruit Sensor Library
To use the BME280 library, you also need to install the Adafruit_Sensor library. Follow the next steps to install the library in your Arduino IDE:
Go to Sketch > Include Library > Manage Libraries and type “Adafruit Unified Sensor” in the search box. Scroll all the way down to find the library and install it.
Installing the TinyGSM Library
In the Arduino IDE Library Manager search for TinyGSM. Select the TinyGSM library by Volodymyr Shymanskyy.
Installing the PubSubClient Library
Search for PubSubClient and scroll down. Select the PubSubClient library by Nick O’Leary.
After installing the libraries, restart your Arduino IDE.
Parts Required
To build this project, you need the following parts:
- TTGO T-Call ESP32 SIM800L
- USB-C cable
- Antenna (optional)
- BME280 sensor module (Guide for BME280 with ESP32)
- 2x LEDs
- 2x 220 ohm resistors
- Breadboard
- Jumper wires
You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!
Schematic Diagram
Wire the BME280 sensor and two LEDs to the T-Call ESP32 SIM800L board as shown in the following schematic diagram.
We’re connecting the BME280’s SDA pin to GPIO 18 and the SCL pin to GPIO 19.
Code
Copy the following code to your Arduino IDE but don’t upload it yet. First, you need to make some modifications to make it work.
/*
Rui Santos
Complete project details at https://RandomNerdTutorials.com/esp32-cloud-mqtt-broker-sim800l/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
*/
// Select your modem:
#define TINY_GSM_MODEM_SIM800 // Modem is SIM800L
// Set serial for debug console (to the Serial Monitor, default speed 115200)
#define SerialMon Serial
// Set serial for AT commands
#define SerialAT Serial1
// Define the serial console for debug prints, if needed
#define TINY_GSM_DEBUG SerialMon
// set GSM PIN, if any
#define GSM_PIN ""
// Your GPRS credentials, if any
const char apn[] = ""; // APN (example: internet.vodafone.pt) use https://wiki.apnchanger.org
const char gprsUser[] = "";
const char gprsPass[] = "";
// SIM card PIN (leave empty, if not defined)
const char simPIN[] = "";
// MQTT details
const char* broker = "XXX.XXX.XXX.XXX"; // Public IP address or domain name
const char* mqttUsername = "REPLACE_WITH_YOUR_MQTT_USER"; // MQTT username
const char* mqttPassword = "REPLACE_WITH_YOUR_MQTT_PASS"; // MQTT password
const char* topicOutput1 = "esp/output1";
const char* topicOutput2 = "esp/output2";
const char* topicTemperature = "esp/temperature";
const char* topicHumidity = "esp/humidity";
// Define the serial console for debug prints, if needed
//#define DUMP_AT_COMMANDS
#include <Wire.h>
#include <TinyGsmClient.h>
#ifdef DUMP_AT_COMMANDS
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, SerialMon);
TinyGsm modem(debugger);
#else
TinyGsm modem(SerialAT);
#endif
#include <PubSubClient.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
TinyGsmClient client(modem);
PubSubClient mqtt(client);
// TTGO T-Call pins
#define MODEM_RST 5
#define MODEM_PWKEY 4
#define MODEM_POWER_ON 23
#define MODEM_TX 27
#define MODEM_RX 26
#define I2C_SDA 21
#define I2C_SCL 22
// BME280 pins
#define I2C_SDA_2 18
#define I2C_SCL_2 19
#define OUTPUT_1 2
#define OUTPUT_2 15
uint32_t lastReconnectAttempt = 0;
// I2C for SIM800 (to keep it running when powered from battery)
TwoWire I2CPower = TwoWire(0);
TwoWire I2CBME = TwoWire(1);
Adafruit_BME280 bme;
#define IP5306_ADDR 0x75
#define IP5306_REG_SYS_CTL0 0x00
float temperature = 0;
float humidity = 0;
long lastMsg = 0;
bool setPowerBoostKeepOn(int en){
I2CPower.beginTransmission(IP5306_ADDR);
I2CPower.write(IP5306_REG_SYS_CTL0);
if (en) {
I2CPower.write(0x37); // Set bit1: 1 enable 0 disable boost keep on
} else {
I2CPower.write(0x35); // 0x37 is default reg value
}
return I2CPower.endTransmission() == 0;
}
void mqttCallback(char* topic, byte* message, unsigned int len) {
Serial.print("Message arrived on topic: ");
Serial.print(topic);
Serial.print(". Message: ");
String messageTemp;
for (int i = 0; i < len; i++) {
Serial.print((char)message[i]);
messageTemp += (char)message[i];
}
Serial.println();
// Feel free to add more if statements to control more GPIOs with MQTT
// If a message is received on the topic esp/output1, you check if the message is either "true" or "false".
// Changes the output state according to the message
if (String(topic) == "esp/output1") {
Serial.print("Changing output to ");
if(messageTemp == "true"){
Serial.println("true");
digitalWrite(OUTPUT_1, HIGH);
}
else if(messageTemp == "false"){
Serial.println("false");
digitalWrite(OUTPUT_1, LOW);
}
}
else if (String(topic) == "esp/output2") {
Serial.print("Changing output to ");
if(messageTemp == "true"){
Serial.println("true");
digitalWrite(OUTPUT_2, HIGH);
}
else if(messageTemp == "false"){
Serial.println("false");
digitalWrite(OUTPUT_2, LOW);
}
}
}
boolean mqttConnect() {
SerialMon.print("Connecting to ");
SerialMon.print(broker);
// Connect to MQTT Broker without username and password
//boolean status = mqtt.connect("GsmClientN");
// Or, if you want to authenticate MQTT:
boolean status = mqtt.connect("GsmClientN", mqttUsername, mqttPassword);
if (status == false) {
SerialMon.println(" fail");
ESP.restart();
return false;
}
SerialMon.println(" success");
mqtt.subscribe(topicOutput1);
mqtt.subscribe(topicOutput2);
return mqtt.connected();
}
void setup() {
// Set console baud rate
SerialMon.begin(115200);
delay(10);
// Start I2C communication
I2CPower.begin(I2C_SDA, I2C_SCL, 400000);
I2CBME.begin(I2C_SDA_2, I2C_SCL_2, 400000);
// Keep power when running from battery
bool isOk = setPowerBoostKeepOn(1);
SerialMon.println(String("IP5306 KeepOn ") + (isOk ? "OK" : "FAIL"));
// Set modem reset, enable, power pins
pinMode(MODEM_PWKEY, OUTPUT);
pinMode(MODEM_RST, OUTPUT);
pinMode(MODEM_POWER_ON, OUTPUT);
digitalWrite(MODEM_PWKEY, LOW);
digitalWrite(MODEM_RST, HIGH);
digitalWrite(MODEM_POWER_ON, HIGH);
pinMode(OUTPUT_1, OUTPUT);
pinMode(OUTPUT_2, OUTPUT);
SerialMon.println("Wait...");
// Set GSM module baud rate and UART pins
SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
delay(6000);
// Restart takes quite some time
// To skip it, call init() instead of restart()
SerialMon.println("Initializing modem...");
modem.restart();
// modem.init();
String modemInfo = modem.getModemInfo();
SerialMon.print("Modem Info: ");
SerialMon.println(modemInfo);
// Unlock your SIM card with a PIN if needed
if ( GSM_PIN && modem.getSimStatus() != 3 ) {
modem.simUnlock(GSM_PIN);
}
// You might need to change the BME280 I2C address, in our case it's 0x76
if (!bme.begin(0x76, &I2CBME)) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
SerialMon.print("Connecting to APN: ");
SerialMon.print(apn);
if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
SerialMon.println(" fail");
ESP.restart();
}
else {
SerialMon.println(" OK");
}
if (modem.isGprsConnected()) {
SerialMon.println("GPRS connected");
}
// MQTT Broker setup
mqtt.setServer(broker, 1883);
mqtt.setCallback(mqttCallback);
}
void loop() {
if (!mqtt.connected()) {
SerialMon.println("=== MQTT NOT CONNECTED ===");
// Reconnect every 10 seconds
uint32_t t = millis();
if (t - lastReconnectAttempt > 10000L) {
lastReconnectAttempt = t;
if (mqttConnect()) {
lastReconnectAttempt = 0;
}
}
delay(100);
return;
}
long now = millis();
if (now - lastMsg > 30000) {
lastMsg = now;
// Temperature in Celsius
temperature = bme.readTemperature();
// Uncomment the next line to set temperature in Fahrenheit
// (and comment the previous temperature line)
//temperature = 1.8 * bme.readTemperature() + 32; // Temperature in Fahrenheit
// Convert the value to a char array
char tempString[8];
dtostrf(temperature, 1, 2, tempString);
Serial.print("Temperature: ");
Serial.println(tempString);
mqtt.publish(topicTemperature, tempString);
humidity = bme.readHumidity();
// Convert the value to a char array
char humString[8];
dtostrf(humidity, 1, 2, humString);
Serial.print("Humidity: ");
Serial.println(humString);
mqtt.publish(topicHumidity, humString);
}
mqtt.loop();
}
Before uploading the code, you need to insert your APN details, SIM card PIN (if applicable) and your cloud MQTT server details.
How the Code Works
Insert your GPRS APN credentials in the following variables:
const char apn[] = ""; // APN (example: internet.vodafone.pt) use https://wiki.apnchanger.org
const char gprsUser[] = ""; // GPRS User
const char gprsPass[] = ""; // GPRS Password
In our case, the APN is internet.vodafone.pt. Yours should be different. We explained previously how to get your APN details.
Enter your SIM card PIN if applicable:
const char simPIN[] = "";
You also need to type the cloud MQTT server details in the following variables. It can be your own cloud MQTT domain or any other MQTT server that you want to use.
const char* broker = "178.XXX.XXX.XXX"; // Public IP address or domain name
const char* mqttUsername = "REPLACE_WITH_YOUR_MQTT_USERNAME";
const char* mqttPassword = "REPLACE_WITH_YOUR_MQTT_PASSWORD";
The ESP32 is subscribed to the esp/output1 and esp/output2 topics to update the outputs with the latest value:
const char* topicOutput1 = "esp/output1";
const char* topicOutput2 = "esp/output2";
The ESP32 publishes the temperature and humidity readings to these topics esp/temperature and esp/humidity every 30 seconds:
const char* topicTemperature = "esp/temperature";
const char* topicHumidity = "esp/humidity";
The code is heavily commented so that you understand the purpose of each line of code.
The following lines define the pins used by the SIM800L module:
#define MODEM_RST 5
#define MODEM_PWKEY 4
#define MODEM_POWER_ON 23
#define MODEM_TX 27
#define MODEM_RX 26
#define I2C_SDA 21
#define I2C_SCL 22
Define the BME280 I2C pins. In this example we’re using GPIO 18 and GPIO 19.
#define I2C_SDA_2 18
#define I2C_SCL_2 19
Define a serial communication for the Serial Monitor and another to communicate with the SIM800L module:
// Set serial for debug console (to Serial Monitor, default speed 115200)
#define SerialMon Serial
// Set serial for AT commands (to SIM800 module)
#define SerialAT Serial1
Configure the TinyGSM library to work with the SIM800L module.
#define TINY_GSM_MODEM_SIM800
Include the following libraries to communicate with the SIM800L.
#include <Wire.h>
#include <TinyGsmClient.h>
And the MQTT library and the BME280 sensor libraries:
#include <PubSubClient.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
Instantiate an I2C communication for the SIM800L (battery power management IC).
TwoWire I2CPower = TwoWire(0);
And another I2C communication for the BME280 sensor.
TwoWire I2CBME = TwoWire(1);
Adafruit_BME280 bme;
Initialize a TinyGsmClient for internet connection.
TinyGsmClient client(modem);
setup()
In the setup(), initialize the Serial Monitor at a baud rate of 115200:
SerialMon.begin(115200);
Start the I2C communication for the SIM800L module and for the BME280 sensor module:
I2CPower.begin(I2C_SDA, I2C_SCL, 400000);
I2CBME.begin(I2C_SDA_2, I2C_SCL_2, 400000);
Setup the SIM800L pins in a proper state to operate:
pinMode(MODEM_PWKEY, OUTPUT);
pinMode(MODEM_RST, OUTPUT);
pinMode(MODEM_POWER_ON, OUTPUT);
digitalWrite(MODEM_PWKEY, LOW);
digitalWrite(MODEM_RST, HIGH);
digitalWrite(MODEM_POWER_ON, HIGH);
Initialize a serial communication with the SIM800L module.
SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
Initialize the SIM800L module and unlock the SIM card PIN if needed.
SerialMon.println("Initializing modem...");
modem.restart();
// Unlock your SIM card with a PIN if needed
if (strlen(simPIN) && modem.getSimStatus() != 3 ) {
modem.simUnlock(simPIN);
}
Initialize the BME280 sensor.
if (!bme.begin(0x76, &I2CBME)) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
Finally, in the setup() is where we’ll actually connect to the internet. The following lines connect the module to the internet:
SerialMon.print("Connecting to APN: ");
SerialMon.print(apn);
if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
SerialMon.println(" fail");
ESP.restart();
}
else {
SerialMon.println(" OK");
}
mqttConnect()
The mqttConnect() function is responsible to connect your board to the MQTT broker using username and password. It also subscribes the ESP32 to the esp/output1 and esp/output2 MQTT topics.
boolean mqttConnect() {
SerialMon.print("Connecting to ");
SerialMon.print(broker);
// Connect to MQTT Broker without username and password
//boolean status = mqtt.connect("GsmClientN");
// Or, if you want to authenticate MQTT:
boolean status = mqtt.connect("GsmClientN", mqttUsername, mqttPassword);
if (status == false) {
SerialMon.println(" fail");
ESP.restart();
return false;
}
SerialMon.println(" success");
mqtt.subscribe(topicOutput1);
mqtt.subscribe(topicOutput2);
return mqtt.connected();
}
loop()
In the loop(), there’s a timer that publishes the temperature and humidity readings to your MQTT broker every 30 seconds.
long now = millis();
if (now - lastMsg > 30000) {
lastMsg = now;
// Temperature in Celsius
temperature = bme.readTemperature();
// Uncomment the next line to set temperature in Fahrenheit
// (and comment the previous temperature line)
//temperature = 1.8 * bme.readTemperature() + 32; // Temperature in Fahrenheit
// Convert the value to a char array
char tempString[8];
dtostrf(temperature, 1, 2, tempString);
Serial.print("Temperature: ");
Serial.println(tempString);
mqtt.publish(topicTemperature, tempString);
humidity = bme.readHumidity();
// Convert the value to a char array
char humString[8];
dtostrf(humidity, 1, 2, humString);
Serial.print("Humidity: ");
Serial.println(humString);
mqtt.publish(topicHumidity, humString);
}
mqttCallback()
In the mqttCallback() function, the ESP32 receives the MQTT messages of the subscribed topics. Accordingly to the MQTT topic and message, it turns the outputs on or off:
void mqttCallback(char* topic, byte* message, unsigned int len) {
Serial.print("Message arrived on topic: ");
Serial.print(topic);
Serial.print(". Message: ");
String messageTemp;
for (int i = 0; i < len; i++) {
Serial.print((char)message[i]);
messageTemp += (char)message[i];
}
Serial.println();
// Feel free to add more if statements to control more GPIOs with MQTT
// If a message is received on the topic esp/output1, you check if the message is either "true" or "false".
// Changes the output state according to the message
if (String(topic) == "esp/output1") {
Serial.print("Changing output to ");
if(messageTemp == "true"){
Serial.println("true");
digitalWrite(OUTPUT_1, HIGH);
}
else if(messageTemp == "false"){
Serial.println("false");
digitalWrite(OUTPUT_1, LOW);
}
}
else if (String(topic) == "esp/output2") {
Serial.print("Changing output to ");
if(messageTemp == "true"){
Serial.println("true");
digitalWrite(OUTPUT_2, HIGH);
}
else if(messageTemp == "false"){
Serial.println("false");
digitalWrite(OUTPUT_2, LOW);
}
}
}
Upload the Code
After inserting all the necessary details, you can upload the code to your board.
To upload code to your board, go to Tools > Board and select ESP32 Dev module. Go to Tools > Port and select the COM port your board is connected to. Finally, press the upload button to upload the code to your board.
Note: at the moment, there isn’t a board for the T-Call ESP32 SIM800L, but we’ve selected the ESP32 Dev Module and it’s been working fine.
Demonstration
Open the Serial Monitor at baud rate of 115200 and press the board RST button.
First, the module initializes and then it tries to connect to the internet. Please note that this can take some time (in some cases it took almost 1 minute to complete).
After connecting to the internet, it will connect to your MQTT broker.
In this example, it publishes new sensor readings every 30 seconds, but for testing purposes you can use a shorter period of time.
Then, open a browser and type your server domain on the /ui URL. You should see the charts with the latest sensor readings and the toggle switches to control the outputs.
Troubleshooting
If at this point, you can’t make your module connect to the internet, it can be caused by one of the following reasons:
- The APN credentials might not be correct;
- The antenna might not be working properly. In our case, we had to replace the antenna;
- You might need to go outside to get a better signal coverage;
- Or you might not be supplying enough current to the module. If you’re connecting the module to your computer using a USB hub without external power supply, it might not provide enough current to operate.
Wrapping Up
We hope you liked this project. In our opinion, the T-Call SIM800 ESP32 board can be very useful for IoT projects that don’t have access to a nearby router via Wi-Fi. You can connect your board to the internet quite easily using a SIM card data plan.
You may also like the following projects:
- $11 TTGO T-Call ESP32 with SIM800L GSM/GPRS (in-depth review)
- ESP32/ESP8266 Insert Data into MySQL Database using PHP and Arduino IDE
- ESP32/ESP8266 Plot Sensor Readings in Real Time Charts – Web Server
- ESP32 Web Server with BME280 – Advanced Weather Station
Learn more about the ESP32 with our resources:
- Learn ESP32 with Arduino IDE (Course)
- MicroPython Programming with ESP32 and ESP8266 (eBook)
- More ESP32 Projects and Tutorials
Thanks for reading.
Great Project.
Where I live we have 2G till april2025 so it is worth considering.
LTE-M or Lora May seem options with a longer future…… but then again who knows what technology will be available in 5 years
As 2G is being phased out slowly globally, are there any options for 3G?
I have a couple projects in Africa that would require 3G upgrades. I haven’t seen any boards that support this yet.
Hi.
There are some 4G solutions like the SIM7600CE module.
But it is an expensive module.
Regards,
Sara
You can use the new LILYGO TTGO T-SIM7000G ESP32 module, it already has the mqtt protolo on board with at command
Thanks Josue, I’ll look into it.
Hi, could you help me?
I made a schedule based on this to connect to Wunderground, but I am trying a problem, after a while the message sending stops. If you restart the ESP32 via USB, the sending returns, but by programming it remains locked and without sending messages. I realized that the connection step with the operator is the step that presents the error. Have you seen anything like that?
Hi,
Love it!
How could we send images via the SIM through the ESP32 CAM project? (instead of using wifi/bluetooth).
What kind of connection and reprogramming would be necessary?
Thanks 🙂
Congratulations on the project, fantastic.
What should I do on this project to monitor through Domoticz?
Thanks.
NEED HELP!!
Node-RED give errror imported unrecognised types:
ui_switch
ui_gauge
ui_group
ui_tab
How to update Node-red for all gauges and imputs?
Hi.
Make sure you have installed Node-RED dashboard: https://randomnerdtutorials.com/getting-started-with-node-red-dashboard/
Regards,
Sara
Might Library be wrong? It keeps falling in the apn part and it restarts always.I use external power supply,I changed my antenna i use like yours.I can send and receive SMS with your previous code.ı checked the page about apn settings.
Hi,
if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
SerialMon.println(” fail”);
}
this function takes sometimes takes even 1 minute.In the code,How can I break if statement, if it takes more than 10 seconds ?
Thanks.
Any help?
Hi,
I followed this tutorial but I am facing an issue.
subscribed to a topic and receiving the data published on that only if the length of the data is less than 256Bytes, if its greater than unable to receive data.
Tried to increase the RXbufferSize of ESP32 which is used for AT, but still not resolved.
Thanks
Hello i cant use mqtt esp32 ttgo with deep sleep, i don’t now why the code send data two o tre times and then don´t send anything then works .
Hi,I wanna ask you something.Let s say I have 10 ttgo t call.For those,Do I have to have 10 cloud server from Digital Ocean or can I do it with 1 server?
Hi.
You can have only one cloud server from the Digital Ocean.
All boards then connect to the same server.
Regards,
Sara
I have a webpage .
mqtt.connect(“ws://ip_adress”);
with this way web server and esp communicate.
let s say i click the button in web browser publishes ‘5’ with topic name “data1” ,then all ESP32 ‘s receives the data ‘5 ‘ with topic name “data1” ,right? Wouldn’t it be a problem?
Hi.
The boards will only receive messages from topics they are subscribed to.
Regards,
Sara
Thanks.I have 2 more questions.1.How many topics can we define?Are there any limitation? 2.let s say I have 100 esp32 sim800l.For those,which pln I have to choose in Digital Ocean? Plan,Cpu Options…
Hi.
I don’t think there are any limitations for the number of topics.
As for the Digital Ocean options, it is always better to start with the most basic program, and then upgrade if needed.
Regards,
Sara
Thank you.
Hi..
I am using same module but my MQTT broker is a REYAX. My module is not connect to my broker and give error rc=-2.
Please advice how to resolve ?
Hello Sara,
Is it possible to control the ESP’s gpio’s outputs? Do you think to release a tutorial for this?
Thank you.
Excuse me, I just realezed that you have already released it. Great tutorial, Thank you again.
Hello, may i know what are the problems that you faced with the antenna that you changed, because i have the same antenna
Hi thanks for the great effort. I am having trouble connecting to the mqtt broker (hivemq) the module shows mqtt not connected. I used password and username correctly and also select for that in the code. The goes is connecting only the broker that’s not connecting. Please any help
Hello!! Good tutorial. Its possible do the same but with DHT 21?? I didnt find information about that.
Best Regards
Hello, Thanks for this nice article. I have a question. How do I change the mqtt connection to go over esp-wifi or over gsm(sim800)?
Hello!
In my project it`s not working, I have this message:
Stack smashing protect failure!
abort() was called at PC 0x400de1f4 on core 1
To my knowledge, 2G does not transmit the MQTT protocol. Is this true?
Hi
Your write was useful. My device worked as the same manner.
But is it support QoS 1 or 2 and how to declare it in publish.
thanks in advance
Hi
your code works perfect and thanks.
but is the same module capable of supporting 8883 secure post.
Just a confirmation about requirement of SSL support for tinygsmclient