I have spent a lot of time working with various microcontrollers and equipping them with numerous sensors and wireless technologies.
Until now, I have avoided cellular connectivity because I didn’t want to pay for a regular SIM card just for a DIY project that serves only as a fun gadget or for simple sensor data.
Recently, however, I discovered IoT SIM cards. These are basically standard SIM cards for which you pay a one-time fee of €10–20 and get a fixed data volume (typically 0.5–2 GB) for 5–10 years.
That sounds extremely little, but if you rely on MQTT, you can actually get very far with it. Depending on the transmission interval, that data volume can last for many years.
So I ordered the Lilygo T-SIM. This board features:
- GPS
- Cellular (SIM7000 module)
- Battery holder for a 18650 cell
- Charging electronics for direct use with a solar panel
This makes it perfect for sensor data or a GPS tracker.
Getting Started
20 days later, the T-SIM and the IoT SIM card arrived.
Setting it up was easier than expected because Lilygo provides extensive example code.
I combined the example MQTT client code with the GPS test example code. The result is a GPS tracker that transmits the following data via MQTT to any broker at a configurable interval:
- Current time (in UNIX format)
- Battery voltage
- Coordinates (latitude, longitude)
For testing, you can use the servers from HiveMQ.
Requirements
- Arduino IDE
- Board selection: ESP32 Dev Kit
- Module: SIM7000
- APN of the SIM card provider
- MQTT server (e.g., HiveMQ or own server)
Example Code
#define TINY_GSM_MODEM_SIM7000
#define TINY_GSM_RX_BUFFER 1024
#include <TinyGsmClient.h>
#include <PubSubClient.h>
#include <Arduino.h>
#include <Wire.h>
#define SerialMon Serial
#define SerialAT Serial1
#define GSM_PIN ""
const char apn[] = "Your-APN";
const char gprsUser[] = "";
const char gprsPass[] = "";
const char* broker = "Your MQTT Server";
const char* topicTelemetry = "Your MQTT Topic";
const char* clientID = "Your Client ID";
#define UART_BAUD 9600
#define PIN_TX 27
#define PIN_RX 26
#define PWR_PIN 4
#define LED_PIN 12
#define BAT_ADC_PIN 35
// Send interval in milliseconds (here: 5 minutes)
const unsigned long SEND_INTERVAL_MS = 300000;
#define DBG(x) SerialMon.println(x)
TinyGsm modem(SerialAT);
TinyGsmClient client(modem);
PubSubClient mqtt(client);
// Helper functions: timestamp, distance calculation, modem control, GPS control ...
// (fully included in the original code)
void setup() {
SerialMon.begin(115200); delay(10);
pinMode(LED_PIN, OUTPUT); digitalWrite(LED_PIN, HIGH);
pinMode(BAT_ADC_PIN, INPUT);
modemPowerOn();
SerialAT.begin(UART_BAUD, SERIAL_8N1, PIN_RX, PIN_TX);
SerialMon.println("Initializing modem and network...");
delay(10000);
if (!modem.testAT()) {
SerialMon.println("Modem not responding, restarting...");
modemRestart();
}
SerialMon.println("Waiting for network...");
if (!modem.waitForNetwork(60000L)) SerialMon.println("No network available.");
else SerialMon.println("Network found.");
SerialMon.println("Setting NB-IoT mode...");
modem.sendAT("+CMNB=2");
modem.waitResponse(2000L);
SerialMon.print("Connecting to APN: "); SerialMon.println(apn);
if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
SerialMon.println("NB-IoT connection failed.");
} else {
SerialMon.println("NB-IoT connected.");
}
mqtt.setServer(broker, 1883);
}
void loop() {
// Check connection, optionally activate GPS, collect data, send via MQTT
// (fully included in the original code)
}
How It Works
- The device connects to the cellular network via NB-IoT.
- GPS data is retrieved until a fix is obtained.
- Time information is preferably taken from GPS, or alternatively from GSM.
- The battery is monitored and the voltage is included in the payload.
- The data is sent as JSON via MQTT to the defined server.
- Optionally, distance checks are performed so new data is sent only when sufficient movement occurs.
Conclusion
With an affordable IoT SIM card, a Lilygo T-SIM7000, and a bit of code adjustment, you can build a battery-powered, solar-supported GPS tracker that can reliably deliver data via MQTT for many years.