Electronic sensors are part of many digital devices that we use every day, such as our smartphones, computers, and cars.
A sensor is a device that collects some information of any kind (usually a physical quantity), which a computing unit can then use to make any decision and interact consequently in the physical world. Some real-world examples can be the accelerometers, which are mounted on every smartphone and which allow the screen visualization to be correctly oriented every time we move the phone, or, for example, the oil pressure sensor of a car, which can help diagnose any motor problem.
Another interesting example is sensors used for environmental monitoring. Environmental monitoring consists of any kind of data logging regarding a specific environment, which usually comprehends temperatures, pressures, humidity, and so on. This can relate to a local environment, like our home, or a remote environment, intended as any remote place outside our home network.
In this article, we are going to see this later example and, therefore, how it is possible to connect our temperature sensor realized in the previous article: Temperature measurement? Never so easy with STM32 and MCP9808! with a SIM800L GSM cellular modem, in order to make a remote temperature sensor, which can be read through SMS.
But what is a cellular modem? This will be explained in the next chapter.
What is a cellular modem?
A cellular modem module is an integrated component used in all cases in which cellular communication is necessary, such as our smartphones. With a cellular modem, it is basically possible to send and receive SMS, make phone calls, and even navigate the Internet.
Several module types based on different mobile communications technologies, such as 2G, 3G, or 4G, are available on the market (Table 1).
These modules can usually be easily interfaced with every microcontroller using interfaces like UART or SPI.
While UART is still the most used choice for GSM and GPRS modems since a small data rate is expected, SPI remains the most used choice for LTE modems, where high performances are requested.
Communication to the cellular modem is done through a specific string-based protocol, named AT commands. A brief explanation of these commands will be given in another chapter.
Usually, a cellular modem includes the complete software stack for the telephone section, SMS handling and internet connection, simplifying the integration with embedded systems as much as possible.
Let’s now examine the modem model, the SIM800L, that we are going to use for this project in more detail.
SIM800L module modem
SIM800L is a very well-known and common cellular modem module. It is often seen on embedded system projects where a phone/internet connection is required and no other networks are available (e.g., Wi-Fi).
The module is very well known among professionals and hobbyists and can be easily bought from several microelectronics vendors on the internet. I bought my sample from AZ delivery at this link: https://www.az-delivery.de/products/azdelivery-sim800l-gsm-gprs-modul-mit-antenne-fur-arduino
Here follows a picture of the module, of both top and bottom views (Image 1):
As is possible to see from the picture, the cellular modem module is soldered over a small evaluation board, where pins can be accessed through the side pin strips. Not all the module pins have been connected for easy access, but only a small subset allows the use of the basic modem functionalities since the whole number of pins is very high. Two different antennas are included in the kit. The slot where the SIM card must be inserted can be seen from the bottom view. Cellular modules require a SIM card like the same one we use on our smartphones. Any working SIM card with enough credit for basic operation can be used here. Please note that the slot is suitable for hosting micro-SIM card format only, but adapters can be easily found.
Here follows a macro-schematic of the evaluation board from AZ delivery, showing the pinout (Image 2):
The module will be interfaced to an STM32 using a classical UART, through AT commands. The pins for the UART are the RXD and TXD.
A speaker can be connected to a microphone to make and receive calls. The speaker can be connected to SPKP and SPKN pins, while the microphone can be connected to MICN and MICP pins. These two interfaces are differential. The antenna can be connected to the ANT input. Relevant to mention is that the cellular modem works with a nominal voltage of around 4 volts (VCC-GND). The modem is quite demanding in terms of absorbed current, therefore the module can’t be supplied directly from the evaluation board and an external power supply is necessary. A power supply able to deliver peaks of 2 Amperes at 4 volts would be enough.
SIM800L Modem AT Commands
AT commands (or Hayes commands) consist of a command set made up of a series of small text strings, which, combined, can trigger the execution of specific operations on modems, like phone calls, SMS sending and receiving, or data transmission over the Internet.
A very good introduction to the topic can be found here: https://en.wikipedia.org/wiki/Hayes_command_set, while a complete command set valid for the SIM800L can be found here: https://www.elecrow.com/wiki/images/2/20/SIM800_Series_AT_Command_Manual_V1.09.pdf
Let’s start! Setup the hardware
After this introduction, we can now set up the hardware. The cellular modem will be connected to an STM32 Nucleo-64 evaluation board, which is already well-introduced in this post: Using the USB Serial Port on the STM32 Nucleo-64 board.
The following picture shows the complete electrical schematic of our project (Image 3) and also a picture of my actual setup (Image 4).
The schematic is relatively simple, using two UARTs and one I2C. The I2C is used to read the MCP9808 temperature sensor, while one UART is used for debugging (Serial port), and the other is connected to the SIM800L modem. Relevant is the power connection of the modem, which must be provided from an external power supply at 4 volts, and the reset pin, which is used at startup to reset the modem before the initialization, which can be any free GPIO pin of the STM32. In my project, I configured it over the pin PA8.
Another relevant point is that all the involved grounds should be obviously connected together (E.g., the Evaluation board and the external power supply).
Get the software
You can now download the whole project from GitHub here: https://github.com/EmbeddedEspresso/remote_temp. This is an STM32CubeIDE project, so you can compile it and start debugging it over the STM32.
The software is organized in several state machines, one for each specific handling, such as I2C or UART modem communication. A block schematic of the software and a brief description of every handler are followed (Image 5).
All the state machines are initialized and executed from the main, as shown in the following code snippet of the main.c file:
/* Initialize all the software state machines */
UartModemHdlrInit(&huart1);
UartDebugHdlrInit(&huart2);
ModemHdlrInit();
DebugHdlrInit();
AppHdlrInit();
TempSensorHdlrInit();
while (1)
{
/* Main software handler */
UartModemHdlrRun();
UartDebugHdlrRun();
ModemHdlrRun();
DebugHdlrRun();
AppHdlrRun();
LedAliveRun();
TempSensorHdlrRun();
}
As previously mentioned, all software modules are state machine-based and designed to offer a re-entrant and non-blocking implementation.
The execution time of every “Run” function call is the smallest possible since all the states are small and designed not to incur any waiting loop mechanism (e.g., non-blocking hardware access).
SIM800L Modem and Debug UART drivers
The UART drivers have been completely rewritten, so the standard-generated STM HAL drivers have not been used. The reason for that was to obtain a non-blocking implementation that could exploit polling as much as possible.
The UART used for debug has a complete polling implementation, where every hardware access is handled through a specific switch case state, allowing a nonblocking re-entrant implementation; performance is not a must for this driver, so no particular care has been given to optimization.
The story is instead a bit different for the UART used for the SIM800L modem communication. While the command sent from the microcontroller does not suffer from performance issues, we cannot say the same for the data received from the modem. We cannot control the modem itself in terms of generated data. It is also impossible to forecast when the modem will send any data because of unsolicited commands, usually triggered by random events and not by a specific microcontroller request; therefore, an interrupt solution has been adopted (Image 6).
The receiving buffer for the modem UART also has special handling for ensuring fixed formatting of the received strings, automatically removing on reception every command separator a part from \r (\n, if present, will be automatically removed).
SIM800L Modem handler
The modem handler consists of the complete SIM800L commands and initialization handling. This handler takes care of performing a complete modem initialization and handling all other commands. It offers an interface based on several APIs to simplify integrations of upper functional layers.
The module is quite scalable, allowing you to add commands or APIs easily. Here is a list of the offered APIs:
- ModemHdlrGetSignalLevel: allows to read the current signal reception level of the modem.
- ModemHdlrGetDateTime: allows to get the current date and time from the connected telephone cell.
- ModemHdlrSendSMS: Send an SMS to a specific number.
- ModemHdlrReadSMS: Read a received SMS from the modem local storage.
- ModemHdlrDeleteSMS: Delete a specific SMS or the whole SMS memory.
Debug handler
This handler allows to manage some real-time debugging, which is mainly helpful to monitor the application and the monitor status. This module does not offer any external API, and it simply prints some menus where some commands can be issued to the modem. It also allows you to do a direct modem debugging session. To reach the menu is enough to type ‘m’ in the Putty console. Here follows a screenshot (Image 7) of the debug menu, where the command for getting the modem signal level was requested:
Temperature sensor handler
This is a simple module that handles the temperature sensor, including also the I2C communication. The used I2C drivers comes from the STM HAL package and are therefore blocking during transmission and reception of data. While this would not be maybe the best solution for a final product, it can be safely used in our demo test, where all the execution timings for each task have been monitored. Once the temperature is sampled, a variable with the latest value is updated. The variable can be accessed from the other modules through a specific API: TempSensorGetValue.
Application handler
In this module, we have the real logic of the software. The application will check if any SMS has been received, and if so, it will look in the text content to identify the string “Get Temperature”. When the string is detected, the temperature will be returned by SMS to the same number that made the request (Image 8).
Test the SIM800L GSM modem connectivity
As a first test to prove that we realized the electronic circuit correctly, we will test the connection with the cellular modem and then see if we can send or receive commands.
Exploiting the functionality “Direct Modem Debugging” of the debugging menu will allow us to develop a sort of bridge in which the STM32 behaves as a pass-through between the two used UARTS, the debug UART and the modem UART.
The solution is pretty easy. It basically consists of forwarding every received byte from the modem UART to the debug UART and vice versa.
Now, we can connect the board to a PC through the USB port and use a serial port terminal to test our code. For this example, I will use Putty, which can be downloaded here. Once opened, the tool will show the following configuration window (Image 8).
Once the correct parameters are selected, like the right COM port or the right speed, we can click Open to start the serial port session.
Start the project from Run->Debug. From the Putty console, we can then reach the menu, typing ‘m’ and then typing again 5 to activate the “Direct modem debugging” functionality: from now on, every typed character will be forwarded to the modem (Image 11).
Let’s now send some commands to the modem. We can start with the classical AT, which is basically used only for testing modem connection and then checking the SIM Card status to see if a PIN is required or not (Image 12):
As the picture shows, the modem answered positively to the command AT with an OK and with no errors to the command “AT+CPIN?” which questions the SIM Card pin status. Apparently, the SIM Card does not require any PIN code activation in this case and can be used for SMS or Internet. We can now proceed with the next chapter and finally test the complete project.
Ready to test your SIM800L GSM sensor?
Once the previous test has been executed successfully, we can assume that our modem is correctly connected to our STM32. We can now quit the direct debugging mode by typing ‘q’ and restart the application completely by using the option ‘6’ Restart application. The initialization will start, as shown in the picture (Image 13).
During the initialization, many debug strings will be printed, allowing us to understand the current software status. Relevant are the unsolicited “Call Ready” and “SMS Ready,” which basically indicate to the software that the modem is ready to be used for SMS and calls.
In the meanwhile, also the temperature logging from the sensor is showed.
Once the initialization is finished, the software is ready to receive an SMS requesting the current temperature. Let’s send an SMS with the text “Get Temperature” from our smartphone to the cellular modem’s phone number and monitor the logged output from Putty (Image 14).
As soon as the software detects an incoming message (unsolicited +CMTI), the message is read and its content analyzed. If the content matches the string “Get Temperature”, then a new SMS is created with the current temperature as text and the receiver phone number set at the same number as the requester.
The debug string “SMS sent successfully” will indicate that the SMS has been correctly sent. Here follows a screenshot from my phone of the sent and received message (Image 15):
Conclusion
This article shows how the SIM800L modem can be easily interfaced to an STM32 to make an SMS-based temperature sensor. Of course, SMS is no longer the most used data transmission technology, but it is still a good solution, considering the relatively small data rate.
The SIM800L modem also supports a 2G internet connection. Therefore, a possible project extension would be to extend the Modem Handler by adding support for internet commands, allowing the temperature information to be sent directly to a server that can collect the data and offer a graph visualization interface.