SIM 800L GSM/GPRS module

Written by: Niklas Graniittiaho

I have done research about SIM800L GSM/GPRS module and how to wire it to Arduino UNO. SIM800L is a cellular module which allows GPRS transmission, sending and receiving text messages (SMS) and making and receiving voice calls. You can can connect two antennas to it. First is made of wire (which you solder directly to the module), second antenna yo can connect with IPX connector. This (IPX)antenna has better perfomance than the antenna made of wire. If you use IPX antenna you can put put your module to a metal box, as long as the antenna is outside. SIM800L supplies voltage from 3.4V to 4.4V and recomended voltage is 4V. Module support frequencies 850/950/1800 and 1900 MHz and can work in temprature range from -40 to + 85 ° C,
which is enough to our project.

I found several ways how people have connected SIM800L to Arduino. Roland on has used Li-Po (Lithium polymer battery) in his configuration. The battery is connected to GND (ground) pin on Arduino and the other wire from the battery is connected to SIM800L. SIM800L is connected to digital pins 2,3 and 4 on Arduino. This configuration is a closed elecrical circuit.

On they have also used Li-Po (Lithium polymer battery) in their configuration, but there is also a NPN transistor and a resistor. The battery is connected to the NPN transistor, which is connectedto the resistor and SIM800L module. The SIM800L module is connected to the battery and digital pins 10 and 11 on Arduino. To me this configuration seems to be too complicated, because SIM800L supports the voltage value (3.7V), which the battery gives. There is no need to change the voltage value with a resistor.

On they don´t use battery or other components in the middle of connecting SIM800L and Arduino. They have connected SIM800L directly to pins 5V, GND (ground), 1 and 2 on Arduino. Using 5V pin to connect SIM800L
is a bit risky because that is out of supported voltage range and could lead to overheating of SIM800L module. But according to description on this site 5V pin in “Arduino generate current from 500mA -1 Amp which gives a maximum power of 5 Watts.”.
This amount of watts qualifies from recommended power and there is no risk of overheating. For that reason we will probably try this setup in our project. We have two SIM800L modules, so if one will break that wont be a problem.


Back end: Python, Flask and MySQL

For our web server, we are using Ubuntu 16.04 with Apache, MySQL and Python/Flask as the back end. We did not install the environment ourselves, but are using a configuration created earlier by the Nuotiovahti-project( although running on Haaga-Helia’s server.

The plan is fairly straightforward: We have an Arduino, which will be connecting to our server every hour, sending the freshly collected sensor data to Mosquitto, functioning as MQTT broker on our server. We then have a Python script which subscribes to the MQTT feed, and writes it to MySQL database. Finally, we have another Python script which gets the newest readings from the database and uses Flask to pass them to browser in JSON format. Don’t worry if the above seems like a bunch of jargon, I will be expanding on it below with code examples, hopefully in a way that will be easier to understand.

MQTT is a lightweight protocol designed to minimize the number of packets… uh… Let’s start over. If you’re using a webbrowser, you’re connecting to each website using HTTP. That means that each time you click a link, multiple things happen: First, your browser and the server perform a handshake(basically acknowledging each other and making sure there is, in fact, a connection between the two). Then, your browser requests data, which is sent over in a bunch of distinct packets(that is, small bursts of data). Finally, the browser acknowledges the packets that arrived(to make sure it actually got ALL the data). After some time the connection is closed and if you click on another link to the server, you have to go through all of that again. With MQTT, the connection only needs to be opened once, when the client first connects to the broker. After that, the client only needs to send or receive data(depending on whether it’s publishing or subscribing to topics) and there’s no handshaking involved. If the amount of data sent at once is small, this reduces the CPU and data link overhead quite a bit(which translates into power savings in our case – quite important for a device that’s battery-operated). Mosquitto is the MQTT broker we are using on our server.

This is what the code for subscribing to MQTT feeds looks like on Python. Thanks to the power of libraries, the actual code is less than a dozen lines long, with the rest being white space and comments.

Dealing with MySQL was a bit trickier. Initially, we had three fields in the Lumivahti-table: mysql


The first field showed time, in the form of HH:MM:SS, and the other two showed snow depth and temperature, respectively. However, this left me with a bit of a problem: namely, since the database would have the results from a long period of time, there is no easy way to access the most recent result.

DROP TABLE Lumivahti;

Let’s start over. I ended up recreating the table with time-field containing UNIX timestamp in integer format instead(I’m fairly certain the integer in question is 32-bits – let’s hope no-one will be using this code in 20 years…). It took some work to figure out the best way to do this(mostly because I’m not very familiar with SQL) and the end result may not be pretty(I’m fairly certain this is NOT the best way to do this), but it works:


As you can see, the command SELECT * FROM Lumivahti ORDER BY time DESC LIMIT 1; returns only the most recent result. This is what the resulting Python code that retrieves the data and passes it to the browser in JSON format looks like at the moment. Due to incomplete javascript this has not yet been fully tested.

Sensors and libraries

So we’re past the planning phase and have finally acquired the components. Time to start testing them!


The end product will most likely use ESP8266, but for testing and development, we use Arduino Uno. It’s faster, and at this stage we don’t need to worry about power consumption.


The sensors you can see in this picture are HC-SR04 ultrasonic distance sensor(on the left) and DS18B20 temperature sensor(attached directly to the Arduino). The initial readings seemed fairly accurate, as well.


Once we actually measured the distance, though, we got some odd readings. And despite double checking the formula(x=(t*10/2)/vsound where speed of sound = 331.3+0.606*t) the numbers we were getting were still too low! After several measures, we found that multiplying the distance by 1.25 got us numbers that were accurate within a centimeter. The initial calibration was done on a hard floor. The next step was to test on the snow. Unfortunately due the lack of suitable surface to stabilize the arduino(and the attached laptop) on, we were not able to determine whether we were getting accurate numbers. However, a cursory study of the numbers showed that some of them were off the chart! We were getting numbers in excess of 30 meters when the surface was approximately 1 meter away. And the sensor itself is only accurate for up to 5 meters. Hmm. Once the package is finished, it will most likely be standing less than 2 meters from the surface. Therefore, any numbers much higher than that must be erroneous. while(distance>300){measure the distance again}. In retrospect, this really seems like an ugly hack, and I will at least need to add some code to make sure the loop doesn’t keep running indefinitely if something goes wrong, but at least it filters out the noise, so we won’t find our website telling us that there is currently -28 meters of snow out there. That would be embarrassing. However, we still need to calibrate the sensor on snow to see if the results we get are relatively accurate.


This picture better shows the layout of our testing setup. As you can see, the thermometer is connected to digital pins 8, 9 and 10, while HC-SR04 has it’s power pin connected to 5V power, ground pin connected to ground, trigpin connected to digital pin 13 and echopin connected to digital pin 12. Most sources on DS18B20 will claim that it requires a pull-up resistor. While that is true, they ignore the fact that Arduino has an internal pull-up resistor that can easily be taken advantage of. Josh Levine has thankfully tested this, and provides a modified OneWire library that makes it easy to use.

That’s it for this week, we are still waiting for our GSM module so we can test our server. If it does not arrive, we will at least have the first drafts of our website to show.

For the sourcecode, see


Lumivahti is a multi-disciplinary IoT-project with the goal to create a prototype for a service that provides accurate and up-to-date data about the snow situation and weather at skiing trails. We’re a team of three third-year students from Haaga-Helia information technology programme working in partnership with Virtual Outdoors Finland.

The Plan

We are still in the process of formalizing the project plan and examining the options. Based on examining several similar projects as well as our past experiences, we currently believe the best course of action is to use ESP8266 or ESP32 based platform to collect and process the data from the sensors which is then sent to a VPS(virtual private server) via HTTP which then handles the input and publishes it on a website. The snow depth is to be measured via ultra-sonic distance sensor. This is the initial configuration we will attempt to evaluate. A Raspberry Pi-based platform is an alternative we are considering, but there are concerns that the higher power consumption and the lack of power saving sleep and hibernate states will make in non-viable for a battery powered device(these concerns are largely based on the information available on Project Nuotiovahti, which demonstrates a similar project with Raspberry Pi achieving a battery life of less than two days on a 30000 mAh battery).

The Team

Niklas Graniittiaho – Team Leader

Juuso Puroila

Sources and Inspiration