Case study
SMS relay to Azure IoT Hub
LilyGo T-Call A7670 firmware that takes incoming SMS off the modem and posts each message to Azure IoT Hub, with a queue so a burst does not drop on the floor.
SMS → A7670 → FreeRTOS queue → HTTPS → Azure IoT Hub
- Record
- Public repository
- Stack
- A7670, ESP32, Azure IoT Hub, FreeRTOS
- Hardware
- LilyGo T-Call A7670 · ESP32 with PSRAM · SIMCom A7670
- Links
- GitHub
The problem
An SMS that only sits in the modem is useless to the rest of the system. The board has to notice the message as it arrives, survive a short burst, and hand a clean payload to Azure without blocking the UART while the HTTPS call runs.
What I built
Firmware for the LilyGo T-Call A7670. TinyGSM drives the SIMCom A7670. New SMS arrives as a +CMT unsolicited result, not as a poll of stored messages. The ESP32 parses the sender, the network timestamp, and the body, then pushes an SmsData struct onto a FreeRTOS queue of 16.
After one quiet second with no new SMS, the loop drains the queue and posts each item to the Azure IoT Hub device endpoint over HTTPS. The JSON fields are msgId, sender, timestamp, and message.
Decisions
Direct delivery (AT+CNMI) means the firmware sees the SMS as the modem receives it. The queue is there so a handful of messages can land while a POST is still in flight. The one-second quiet window batches a burst instead of opening a socket per character.
Startup is a real modem sequence: power and PWRKEY, testAT with a retry, wait for SIM_READY, register on the network, bring up data, then set text mode and delete anything already stored. An optional AT dump can be compiled in when the modem misbehaves.
The Azure hostname, device id, and SAS token are build-time secrets. They are not copied onto this site.
Pins
Modem UART is GPIO 26 and 27 at 115200. Reset, PWRKEY, board power, and ring are GPIO 5, 4, 12, and 33. Battery ADC is GPIO 35.