---
# System prepended metadata

title: 'Raspberry pi Weather Station, Using The SenseHAT board.'

---

# Raspberry pi Weather Station, Using The SenseHAT board.
---

Student: Jens Andreasson Ja225hv

Estimated project time: 3-4 hours

This project was was created to create a local weather station at the local rc-racetrack that racers can utilize to both see if it's worth the trip for the day and/or want to change setups related to the sensor readings. A few problems regarding heat radiation from the processor near the temperature sensor had to be corrected in this project before it could be finalized.


This weather station project started as idea to be a more accurate indicator on the weather situation at the local rc-racetrack. The reason being that the is located in the rural area outside the city. With the track being on the outskirts of the city the forecast sometimes gives a false understanding on what weather a racer can expect when planning their day at the track. 

# **Material Used In This Project**

* Raspberry pi 3       $35
* SenseHAT             $30
* Micro SD card (32 GB) $9
Total cost USD: $ 74 
(excluding delivery and usb cable)
All products are available on the Amazon marketplace which makes this project available internationally.

The raspberry pi together with the SenseHAT is a versatile combination that is very easy to install and quickly opens up lots of possibilities for the user to utilize. It´s wireless connectivity range and energy usage can however be limited because of the power consumption has, together with its short wifi range. 

In this project, only humidity- and temperature sensor was of interest which could open up the possibility to buying two separate sensors rather than buying the SenseHAT.This however could make it a lil bit harder to wire.


# **Computer Setup**

The pi in this project is run as an Secure sheel (SSH) through the windows command prompt. If you don´t know how to set your pi up as an SSH i recommend you take a look at this tutorial: https://www.youtube.com/watch?v=nZyyfJYOhbM
The tutorial also shows how you can connect to the pi through command prompt.
One thing to keep in mind is that if you terminate the SSH connection with the terminal, the script will stop running. Don't fret. there is a workoaround. First you need to install screen by writing the following line in the terminal: sudo apt-get install screen.
This will let you keep the script running in the background so you can come back to it later. To see how you can activate the functionality in the terminal, i highly recomend this youtube video:https://www.youtube.com/watch?v=fuRZpGRDl40&ab_channel=JasperCox

OS for the raspberry: raspberry pi OS lite without the desktop. The installation software can be found on the raspberry pi homepage here. https://www.raspberrypi.com/software/
With the raspberry pi lite OS, you will already have python. Although, you might have to install pip separately to make data streamer work. (Keep reading to see how to install pi)

The data is streamed to the following website: https://www.initialstate.com
The site requires you to sign up before and create a streaming key before you can start using it. After youve set everything up on the site i recommend that you head over to github, where you can install the streamer and pip.
https://github.com/initialstate/python_appender
The page also gives instructions on how you can use basic commands when streaming your data. This can be useful if you want to modify the code at a later stage. 

# **Code Functionality**

This section will focus on explaining the more technical part of the code as well as points of interest. 
The full code is available with comments at the end of this tutorial.

During the project a curveball was thrown at me at the courtesy of the laws of thermodynamics. This was because the Pi processor is located close to the temperature sensor and gave the otherwise good quality sensor false readings.
A function was found to negate these readings and works as follows.
```
def get_cpu_temp():
        res = os.popen("vcgencmd measure_temp").readline()
        t = float(res.replace("temp=","").replace("'C\n",""))
        return(t)
```
First row reads temperature line from operating system.
Second row creates a float after having replaced temp and C\n with none. Without replacing the strings the text would crash when trying to create a float.
What you get back is the cpu temperature that later can be used to get a more fair temperature reading.

To minimize the data packets sent the code also includes an 'if' sequence that only gets activated after two hours which is 7200 seconds.

```
 if index == 7200: 
                                
    logger.log("Current temperature", round_temp_corr) 
    logger.log("Current humidity", humidity) 
    index = 0 
```
In short, when the number inside the while loop adds up to 7200 the the code will be activated and will send both temperature and humidity to the initialstate server.
After the code has been executed and the files sent it will then reset itself so the timer can start over again.
It is worth mentioning that sending the data less frequently will reduce both power drain as well as lowering the bandwith usage. I do recomend the pi to be connected to a single phase power outlet because of it´s high power drawing processor that requires 2.5 amps and 5 volts to not trigger the low voltage warning message.

# **Connectivity**

The pi is lacking in wireless data transfer capability if compared to pycom devices. But it does offer the possibility to send the data through Wifi using the 2,4 Ghz bandwith.
The data is sent through the TCP transport protocol through an HTTP request.


# **Result**

The end result in this project effectively creates a device that lets the user collect data regarding temperature and humidity at an open location that can offer single phase outlet as well as a WiFi connection.
Because of the functional led lamps that can showcase data, it could be a good idea to place the device that is visible for people.
The raw solution is seen in the picture below.

![](https://i.imgur.com/eFBALXk.jpg)
[Picture taking during the first successful test]

![](https://i.imgur.com/JCeBJLC.jpg)
[Picture showing the scrolling screen in effect]


The presented data on the initial state page can be displayed in a multitude of different ways. It is mostly up to the user, to decide how they want to display the data.
In this project, three different tiles were used. The two on the left shows the current temperature with a thermometer icon, and the current humidity with circular icon that fills up from the bottom depending on the humidity. On the right, a simple graph displays the temperature change over time.

![](https://i.imgur.com/r4DNX5Z.jpg)
[This picture was taken during the final test and thus have a shorter between data transmission which can be seen by looking at the time axis]


Initial state offers the customer both free and paid subscription plans where the free one used in this project only stores your data for 24-hours. The paid counterpart does give the user storage up to one whole year.

# **Discussion and Complete code**

The end product meet this projects demand: 
Collecting and sending weather information containing the current temperature and humidity.

The product itself does have some obvious drawbacks that could be solved by:

Using an IoT oriented device that can provide more capable forms of data transferring, such as LoRa or GSM network. These solutions would enable the user to place the device remotely without the need of any nearby internet access.

A separation of the sensor and the computing unit would have more than likely taken away the need for recalculating the sensor value in order to get a correct value. Sadly the reality of using the SenseHAT board addon will place the sensor above the pi processor which will affect the sensor readings, unless recalculated.
A workaround could be done by the usage of jumper cables that will allow for a farther distance between sensor and heat generating components.
It is however more labour intensive during the assembly phase, but its a valid workaround if the user prefers a more practical solution rather than a software based solution.

Finally, the code is free for anyone to use and modify as you wish. 

```
#!/usr/bin/python

from sense_hat import SenseHat
from ISStreamer.Streamer import Streamer
import time
import sys
import os

def get_cpu_temp(): # Function that returns current cpu temp
        res = os.popen("vcgencmd measure_temp").readline()
        t = float(res.replace("temp=","").replace("'C\n",""))
        return(t)

sense = SenseHat()
logger = Streamer(bucket_name="Sense hat data", access_key="Insert your access key from inital state here")
sense.clear # Clears all stored data on start up, including the led screen

index = 0

try:
        while True:
                temp = sense.get_temperature_from_humidity() # Gets temperature data from the sensor unit

                temp_cpu = get_cpu_temp() # Calls on a function that fetches cpu temp.

                humidity = sense.get_humidity() # Fetches humidity data from humidity sensor.
                humidity = round(humidity, 1) # Rounds the number to nearest value.

                temp_corr = temp - ((temp_cpu-temp)/1.5) # Corrects the temperature reading by mitigating the heat
                # radiation from the processor and what the temp sensor reads.

                round_temp_corr = round(temp_corr) # Rounds the temperature in C

                temp_message = str(round_temp_corr) + "C"
                # Prepares a message that shows the temperature on the SenseHAT

                sense.show_message(temp_message, scroll_speed=0.5)
                # Shows the message on the SenseHAT at desired scroll speed

                
                index = index + 10 # Adds ten to the total amount until it reaches 7200. This is because it takes about 10 sec for the message to scroll by on the led screen.

                if index == 7200: # This code has an index unit that adds 5 to the sum after each iteration.
                                # When the index number reaches 7200, it sends the data to the initalstate webserver.
                        logger.log("Current temperature", round_temp_corr) # Logged temperature data.
                        logger.log("Current humidity", humidity) # Logged humidity data.
                        index = 0 # This resets the index to zero which resets the timer.

except KeyboardInterrupt:
        pass

```