Radio Frequency Temperature Sensor for (Arduino OUT,...

24
instructables Radio Frequency Temperature Sensor for (Arduino OUT, Raspberry Pi IN) by NathanSegers At our second home, we have a few refrigerators and freezers, but we cannot monitor their temperature from our primary residence. That is why I decided to monitor it via a web interface on a Raspberry Pi. But then comes the next problem ... My temperature sensors are too short to go from both the Refrigerator AND the Freezers to the Raspberry Pi. Luckily, the invention of Radio Frequency and Micro controllers makes it easier for us. This tutorial is written to guide you through all the steps, from the basics to the more advanced features of this project. The project itself was an assignment for my school, but will eventually be used in the field. The whole project cost a total of €160 I was unlucky with shipping costs from the USA, and I paid extra for faster shipment through some suppliers. You can download my complete Arduino and Python code via Github. On Github, you can also find the Fritzing scheme's from the next step, and a complete Database Export. Radio Frequency Temperature Sensor for (Arduino OUT, Raspberry Pi IN): Page 1

Transcript of Radio Frequency Temperature Sensor for (Arduino OUT,...

Page 1: Radio Frequency Temperature Sensor for (Arduino OUT, …segersnathan.be/.../2017/11/FreegoMonitor-Instructables.pdf · 2017-11-16 · instructables Radio Frequency Temperature Sensor

instructables

Radio Frequency Temperature Sensor for (Arduino OUT, Raspberry Pi IN)

by NathanSegers

At our second home, we have a few refrigerators andfreezers, but we cannot monitor their temperaturefrom our primary residence. That is why I decided tomonitor it via a web interface on a Raspberry Pi.

But then comes the next problem ... My temperaturesensors are too short to go from both the RefrigeratorAND the Freezers to the Raspberry Pi. Luckily, theinvention of Radio Frequency and Micro controllersmakes it easier for us.

This tutorial is written to guide you through all thesteps, from the basics to the more advanced featuresof this project.

The project itself was an assignment for my school,but will eventually be used in the field.

The whole project cost a total of €160 I was unluckywith shipping costs from the USA, and I paid extra forfaster shipment through some suppliers.

You can download my complete Arduino and Pythoncode via Github. On Github, you can also find theFritzing scheme's from the next step, and a completeDatabase Export.

Radio Frequency Temperature Sensor for (Arduino OUT, Raspberry Pi IN): Page 1

Page 2: Radio Frequency Temperature Sensor for (Arduino OUT, …segersnathan.be/.../2017/11/FreegoMonitor-Instructables.pdf · 2017-11-16 · instructables Radio Frequency Temperature Sensor

Download (https://cdn.instructables.com/ORIG/FJE/BH6B/J44FIJZ2/FJEBH6BJ44FIJZ2.xlsx)

Step 1: Materials I Used

In the first step I will explain all the components I used in this project.

RECEIVER PART

1 Raspberry Pi 3 B1 Breadboard1 T-Cobbler (optional, but recommended)

- 1 Flat-cable for the T-cobbler (Required if chosen for T-cobbler)

1 Radio Frequency Receiver (433 MHz)At least 3 Male-Male Jumper cables (Female-Male if you prefer to work without the T-Cobbler)

INCLUDED IN MOST RASPBERRY PI PACKAGES1 SD-Card (Min. 8GB)

1 5V Power Supply (Micro-USB)

NOT INCLUDED IN PACKAGE AND OPTIONAL

UDP Cable (You can also work via Wi-Fi, but Ethernet is recommended, I will use thisin the tutorial)

HDMI Cable + HDMI compatible screen (Not required, I used it because I had itavailable)

TRANSMITTER PART

http://www.instructables.com/ORIG/FJE/BH6B/J44FIJZ2/FJEBH6BJ44FIJZ2.xlsx…

(https://cdn.instructables.com/ORIG/FJE/BH6B/J44FIJZ2/FJEBH6BJ44FIJZ2.xlsx)

Radio Frequency Temperature Sensor for (Arduino OUT, Raspberry Pi IN): Page 2

Page 3: Radio Frequency Temperature Sensor for (Arduino OUT, …segersnathan.be/.../2017/11/FreegoMonitor-Instructables.pdf · 2017-11-16 · instructables Radio Frequency Temperature Sensor

(Depending on your amount of fridges / freezers you want to monitor, you need to change the amounts, 1 set foreach. I used 2 sets)

2 Arduino UNO's2 Breadboards2 Radio Frequency Transmitters (433 MHz)2 DS18B20 Waterproof temperature sensors2 4.7kOhm resistors (I used 2 10kOhm resistors in parallel to equal one 4.7kOhmresistor)2 5V Arduino Power SuppliesAt least 4 Male-Male Jumper cables (For Breadboard to Arduino)A bunch of Breadboard cables(You can changes these to Male-Male jumper cables as well, but I prefer not to)

INCLUDED IN ARDUINO PACKAGE2 USB cables

Plug boxes - Depending on the situation, you might need a plug box, or more. I use these to poweron the Arduino at the same moment.

NOTE: In some countries, specific Radio Frequency modules are prohibited, please take care when buying these.Check the correct specifications.

Tools

Scissors to cut wiresHeat shrink to isolate wiresHeat source to warm up the heat shrinkSoldering IronSoldering TinKnife to punch holes & cut plastic

Step 2: Working With the Breadboards

These pictures are made with the Fritzing tool and shows the setup for both the Receiving and Transmitting end ofour project.

ReceiverThe Receiving part is the easiest of both. Following the data sheet of the RF transmitter, we note the following pinlay-out

GND - DO - LO - VCC VCC - GND - GND - ANT

GND goes to the (-)-part of the breadboardVCC goes to the (+)-part of the breadboardDO = Digital Output, this is where your data will be stored, connect this to the RX-pin of your

Radio Frequency Temperature Sensor for (Arduino OUT, Raspberry Pi IN): Page 3

Page 4: Radio Frequency Temperature Sensor for (Arduino OUT, …segersnathan.be/.../2017/11/FreegoMonitor-Instructables.pdf · 2017-11-16 · instructables Radio Frequency Temperature Sensor

Raspberry PiLO = Linear Out, this can be ignoredANT = Antenna, This should be around 13 cm's of curled up wire, you can easily curl up anelectrical wire around a pencil to make the curled up wire.

TransmitterThe Transmitter part is a bit more tricky, as we will also include the sensor here. The screenshot of the Fritzingbreadboard scheme should contain sufficient information to build it correctly.

For the Transmitters, you do not have to use a twisted antenna, but it is recommended to make it a bit longer(30cm) for a longer range of data. If you increase the voltage level on the Transmitter, the power of the signal willalso increase. But please note that our Arduino Uno cannot give more than 5V for the Digital Output pin we haveput it on. If you prefer to use a voltage level higher than 5V, please try working with a Transistor and an externalpower supply ranging from 5V to 12V maximum.

You might wonder why we connect the VCC of the Transmitter to a Digital Output pin on the Arduino, and not justto the 5V of the Arduino, like we did with the VCC of the Receiver.

For this I will explain a little bit about Radio Frequency Transmitters.

When a Transmitter has no data to send, it will send noise. This noise is caught up by the receiver as junk data.When a Transmitter has useful data to send, it will send it out with no problem. It would not be a problem to justignore the junk data, and wait for meaningful data to be sent through, and only work with that. The annoying partstarts when we have a second Transmitter that sends out data when the other one is asleep. Note that asleep forthe transmitter means that it will send out noise / junk data. One solution would be to disable the transmitter via theDigital Output pin. If you send a high signal to the Digital Output, the transmitter will go on, if you send a lowsignal, the transmitter will shut down.

Examples of this will follow in the Arduino code.

DS18B20Back again to the rest of the scheme. The Waterproof Temperature Sensor DS18B20 requires a resistor of4.7kOhm to be put in parallel over the Data and 5V wires. Since I do not have any 4.7kOhm resistors, I used 210kOhm resistors again in parallel, this halves the value and makes sure you still have enough. Now you canconnect the yellow wire of the sensor to any of the digital Arduino pins via the use of a Jumper cable. I had tosolder the wires of my sensor to a pin so that I can place it in the breadboard. It is recommended to also isolate thewires with some heat shrink if you have that available.

Repeat this whole procedure for every sensor you need. For me, one sensor means one refrigerator / freezer.When your devices are close enough to one another, you could try combining multiple sensors through oneArduino or even another microcontroller. The choice is your own.

When you are all ready with connecting the wires and components, we will now proceed to the next step which willinclude the coding for Arduino.

Radio Frequency Temperature Sensor for (Arduino OUT, Raspberry Pi IN): Page 4

Page 5: Radio Frequency Temperature Sensor for (Arduino OUT, …segersnathan.be/.../2017/11/FreegoMonitor-Instructables.pdf · 2017-11-16 · instructables Radio Frequency Temperature Sensor

1. Raspberry Pi Setup 1. Arduino setup

1

1

Radio Frequency Temperature Sensor for (Arduino OUT, Raspberry Pi IN): Page 5

Page 6: Radio Frequency Temperature Sensor for (Arduino OUT, …segersnathan.be/.../2017/11/FreegoMonitor-Instructables.pdf · 2017-11-16 · instructables Radio Frequency Temperature Sensor

1. Cutting wires2. Soldering tin

1. Radio Frequency Receiver2. 2 10k resistors in Parallel3. Soldered but not unisolated wires

Step 3: Writing the Arduino Code

In this step I will guide you through the special parts of my code.

Basic understanding of Arduino (C) code is required. You should have already have installed Arduino for this step.If not, you can follow the guidelines on the official Arduino website where you can buy Arduino's, download theArduino IDE and learn the basics of Arduino.

One-wireFor the Arduino code, I have used only 1 library. The one to read the digital values of the One-Wire TemperatureSensor. An Example code of the DS18x20 is available under "Edit" -> "Examples" -> "One-Wire". If you do not seethis example, check if you have installed the One-Wire library. If not, you can find everything on this webpage. Ihave modified this code a bit to only include the parts we need. Feel free to keep the complete example if you like.

The rest of the code is not that difficult. Although, I have a few remarks to give about the choice of specific parts.For the sensor data to come through correctly, I have chosen to send the data a total of 30 times each loop. Thedata can be sent through Serial.print() as long as we will read the Serial in our Python script later on. Everythingyou print through the Serial Monitor will also be sent wirelessly over the Radio Frequency and will end up throughthe TX and RX pin on the Raspberry Pi.

Data packageI wrote a small function to loop n amount of times to build up a package. One package contains 3 parts Thepreamble, the data value and the checksum

The preamble is just an ID we add to identify the package content to the correct sensor.

I incremented the data value with 50 (degrees) to make sure it's a positive value, as in Binary, a

1

2

12

3

Radio Frequency Temperature Sensor for (Arduino OUT, Raspberry Pi IN): Page 6

Page 7: Radio Frequency Temperature Sensor for (Arduino OUT, …segersnathan.be/.../2017/11/FreegoMonitor-Instructables.pdf · 2017-11-16 · instructables Radio Frequency Temperature Sensor

negative value looks differently.The checksum is calculated by using the XOR operator on the value. A checksum is necessary tomake sure that the data came through valid.

The choice of XOR'ing the value with 11 was made by googling a bit and through the help of my teacher who toldme it is a good value for the checksum. To test if your checksum is good, you can check if your results differenough with the data value.

An example of a wrong data value and checksum would be the following package:

[Data, Data, Checksum] ® [6, 3, 9]

In this example, the Checksum is calculated based on adding up the previous data values. On the receiving end,we could again add them both up, and hope to receive the same checksum.But what if one of the values is wrong? Then the Checksum isn't the same any more [6, 3, 9] ® [7, 3, 9]And what if both the Checksum and the data come through wrong? [6, 3, 9] ® [7, 3, 10]Now, the checksum is still correct, but they both came through wrong, and the data is thus incorrect.

To avoid this, we choose an operation a bit more complex then just adding all the data values.

BitshiftingThe next special thing in my code would be the bitshifting for the data package.

unsigned long val = preamble; // The first element in our byte_sequence

val = (((val << 8) | value) << 8) | checksum; // the other elements with bitshifting and OR operator

Basically, what I did is I took the preamble and I put it in a data type of unsigned long. This allows me to add apackage consisting of 3 bytes (24 bits)

As I mentioned before, the first byte contains the preamble, the second the data and the third the checksum.In my example, I will be using the values 01010101 as the preamble (Decimal: 85). the value of temperaturesensor will be 01001110 (Decimal: 78, this equals a temperature of 28, since I added 50) and a checksum of01000101 (Decimal 69).

In binary, the leading zero's are removed, so all of these bytes would transform to 1010101 1001110 and 1000101respectively. If we want to add these 3 in one line, we have to perform some shifting and or operations.

1. The first step in the operation would be to shift the preamble 8 bits to the left. That way we become0101010100000000 (For the sake of completion, I will keep the leading zeros)

2. The second step is to add the data line to this. since the data line contains 0000000001001110 wecan OR it to the previous 2 bytes. We will now become 0101010101001110.

3. The third step is to shift this 8 bits to the left again. The result is 010101010100111000000004. We only need to OR our checksum to this, and then we have the complete sequence. It's as easy

as that. The OR'ing gives me a result of 010101010100111001000101.5. This is now our final sequence, luckily, you do not have to do this yourselves, as your Arduino

microcontroller can do all this work for you with the use of the code above.

In the next steps we will decode this sequence again in Python with the necessary checks.

One last thing - Delays

Radio Frequency Temperature Sensor for (Arduino OUT, Raspberry Pi IN): Page 7

Page 8: Radio Frequency Temperature Sensor for (Arduino OUT, …segersnathan.be/.../2017/11/FreegoMonitor-Instructables.pdf · 2017-11-16 · instructables Radio Frequency Temperature Sensor

Our Arduino programs might start running at the same time, if they booted together. To avoid interference in thewireless radio frequency transmission, we have to make sure they are asynchronous all the time.

I made sure that one sensor starts after 10 seconds, the other one starts after 30 seconds. If you increase thenumber of Arduino's you are going to use, please recalculate the delays.

Once you have uploaded your code to both Arduino's, you can continue to the next step where we will perform thesetup of the Raspberry Pi.

Radio Frequency Temperature Sensor for (Arduino OUT, Raspberry Pi IN): Page 8

Page 9: Radio Frequency Temperature Sensor for (Arduino OUT, …segersnathan.be/.../2017/11/FreegoMonitor-Instructables.pdf · 2017-11-16 · instructables Radio Frequency Temperature Sensor

Step 4: Raspberry Pi Part

For this part of the tutorial, basic knowledge of Linux commands is required.I will start off with a clean install of Raspbian (NOOBS) which is free to download and use.

To access your Raspberry Pi through the command line, you will have to know your IP-Address. Depending onyour router setup, you can find it there. A second option would be to make use of the APIPA address by pluggingan Ethernet Cable from your Raspberry Pi to an Ethernet Port on another computer. If you have a HDMI screenand cable available, it is very easy to setup everything that way. The choice is yours.

I use PuTTY to access my Raspberry Pi through the CLI (Command Line Interface)

First of all, you will want to make a new user for your Raspberry Pi, as the default one is totally not safe. I will referyou to the documentation on the Raspberry Pi website.

Serial enablingOnce you are logged in to your new user account, you will have to perform the command

sudo raspi-config

This blue screen will popup. Use the keyboard arrows to navigate to the 5th option "Interfacing options"

Selecting the 6th option Serial will allow you to access the serial connection necessary for the data transmission.

You will have to reboot the Raspberry Pi after performing the previous commands.

sudo reboot now

That should do the trick.

MySQL databaseNow, for the data storage we will have to install MySQL. This tutorial can guide you through the basics. Pleaseremember your settings, as you will need them a few times. For my project, I created one user with only thenecessary privileges, to be prepared against hackers. NEVER use your root account for the database connectionon the website.

Now that we are still here, we will install Flask-Mail already. This allows us to send emails from the Flaskapplication to an email address. The following commands should be enough to install Flask-Mail.

git clone https://github.com/mattupstate/flask-mail.gitcd flask-mailsudo python setup.py installsudo pip install Flask-Mail --upgrade

The next step will guide you through the decoding of the sensor values from Arduino in Python.

Radio Frequency Temperature Sensor for (Arduino OUT, Raspberry Pi IN): Page 9

Page 10: Radio Frequency Temperature Sensor for (Arduino OUT, …segersnathan.be/.../2017/11/FreegoMonitor-Instructables.pdf · 2017-11-16 · instructables Radio Frequency Temperature Sensor

Step 5: Writing the Python Code on the Raspberry Pi

For this part of the tutorial, I will explain the basics of my Python script and what some parts do.I used PyCharm for remote developing on my Raspberry Pi. There are plenty of tutorials on how to get started withthat.

You can find my code on my Github repository.

The ScriptThe script itself is made out of 3 parts

1. Setup2. Reading data3. Processing data

The setup parts includes necessary classes and sets some variables to use later

The things you will want to personalize are the preambles.

# These are the preambles we set in Arduino! (01010101, 00101001)preambles = {1: 85, 2: 41}

These preambles are the same values you put on your Arduino codes. If you have changes those, change theseas well.

The most important thing of the code is also in the setup:

ser = serial.Serial("/dev/serial0", 1200)

This allows our Python script to read the Serial input.

Reading the dataReading the data is being looped almost the entire time of the script.

Basically what we do is, we read the lines from the serial input, and we check its content.If its content is decode-able to bits, we can probably work with it. Otherwise, it is junk data and we can ignore it.

Once we have the byte sequence from the serial input, we can start decoding it. This involves some more bitshifting and bit operations, now only in 3 steps.

Radio Frequency Temperature Sensor for (Arduino OUT, Raspberry Pi IN): Page 10

Page 11: Radio Frequency Temperature Sensor for (Arduino OUT, …segersnathan.be/.../2017/11/FreegoMonitor-Instructables.pdf · 2017-11-16 · instructables Radio Frequency Temperature Sensor

1. For the preamble, we will shift our data line 16 bits to the right, so that we only have the LeastSignificant Byte remaining. We will do an AND with the hexadecimal value 0xFF which correspondswith a whole byte of 1 (11111111). If we AND that, we can extract it from it's original byte. It is notnecessary to perform the AND operation, but for the sake of completion we will do it.

2. For the data byte, we will do the same, but we will only shift the sequence 8 bits to the right. For thispart, the AND operation is mandatory.

3. The checksum is the easiest part, as we do not need to shift it, we just have to do the ANDoperation for a third time.

Next comes a sub-part of the reading part: validation.

This is not part of the code's core, as it still happens during the reading phase.The validation performs the same checksum operation: XOR'ing the data byte with 11 and confirming that it isequal to our checksum byte. If it is equal, we can subtract the 50 degrees we added to the data byte, to make it toit's original value again.

To work with all the values later, I added every temperature to a list in the dictionary sensor_data.We will also want to know which sensor we are currently reading data from. So performing a reverse lookup of theKey based on the Value in the dictionary Preambles will give us a 1 when the preamble equals 85 and 2 when it's41. If none of those preambles are found, the data is invalid.

In my case, my data does not have to be that accurate, so I told my script to move to the next state, once 15 / 20data packages are correct. You can increase or decrease this amount based on the accuracy you want. The longerthe range you are transmitting data, the bigger the chance is to receive corrupted data. Interference between otherdevices could also decrease the chance of valid data.

Processing the dataThe next stage of our script is the data processing. In this phase, we will check the list of our sensor data again, tomake sure it's still enough. We will then take the average value. It should always be the same, but our data couldcontain some data from a previous reading (5 from the previous, 10 from the current), so we will take the averageof those values. In case there should be a mistake during the reading of the temperature during the Arduino part ofthe code, we would also find that any higher values would be excluded now.

After the data is checked, we will send it to the database, linking the value to the sensor ID.

In this part of the code, we will also check if we have any mails to send to alert us of a temperature that's too hot.To do this, you will have to access the Flask code which we will explain in one of the next steps.Checking whether or not the temperature is too high or not, I search for the previous condition of the sensor, beforeI added the value. After I added the value I check if the sensor condition is changed or not. They changedynamically through the use of a trigger in the MySQL Database, more in the next step.

After we have done all this, we will start this loop all over again, waiting for the data to be read out.

In the next step, I will guide you through my database setup, triggers, functions and procedures.

Radio Frequency Temperature Sensor for (Arduino OUT, Raspberry Pi IN): Page 11

Page 12: Radio Frequency Temperature Sensor for (Arduino OUT, …segersnathan.be/.../2017/11/FreegoMonitor-Instructables.pdf · 2017-11-16 · instructables Radio Frequency Temperature Sensor

Step 6: The Database Part

For the database, I chose to work with MySQL, this is a free to use service, and is easy to implement into ourFlask Python application.

I used the MySQL Workbench application on my computer to access my database. You might have to changesome settings in your MySQL configuration files to be able to remotely access your database. I also made oneuser for myself, that is not the Root user, but it can perform a lot of actions I need. I also created the "Website"user, which only has the necessary privileges for the website.

OverviewIn the attachment, you can watch a screenshot of the layout of the relations between the 5 tables. Not that theemail_recipients table is the only table with no relationship to the sensors table. This is because it's mainly therefor settings, and has nothing to do with the actual sensor readings.

The tablesA quick guide through my tables, what they're for and what they contain.

Sensors - This is the main table and allows you to add more sensors. They have a name andlocation to know which one you're talking about. The last temperature we have measured gets putinto this as well. Our max_good temperature and alarm temperature are settings that can bechanged later. They decide which condition the sensor is in. There are 3 conditions -> Good,Warning! and Alert!!. More about this later.Sensorvalues - This table is the one that gets updated every time a sensor value is processed bythe script in the previous step. The datetime gets automatically set to the current time with a trigger.Another trigger makes sure that the last entered value gets updated in the previous table "sensors".We don't want to worry about that any more. More about triggers later on in this step.Sensorconditions - Good, Warning! and Alert!! are the three sensor conditions a sensor canhave. Note the relationship is a one-on-one relation. Thus meaning that 1 sensor can only have 1condition. Which seems logical to me. I have added a third column named"sensorconditions_bootstrap_value". This allows me to access to correct CSS class when we stylethe webpage for this. More later.Alarms - Last but not least, we want to know when a device ( fridge / freezer ) gets too hot. So wewill keep track of the alarms. We will monitor the moment the alarm was set, but also the momentthe alarm stopped again. Maybe we can make some statistics later on.

ViewsSince our table of Sensors contains a lot of numbers, and the date it is added, it would be nice to link it to thesensorconditions table, so that we always have a view what the numbers 1, 2 or 3 actually mean. I did this with asmall JOIN statement. But since I will be accessing this data a lot, all at once, I wrote a view function to do this.That way I can always execute the view and get the data I want.

Radio Frequency Temperature Sensor for (Arduino OUT, Raspberry Pi IN): Page 12

Page 13: Radio Frequency Temperature Sensor for (Arduino OUT, …segersnathan.be/.../2017/11/FreegoMonitor-Instructables.pdf · 2017-11-16 · instructables Radio Frequency Temperature Sensor

CREATE

ALGORITHM = UNDEFINED DEFINER = `admin`@`%` SQL SECURITY DEFINERVIEW `sensor_overview` AS SELECT `S`.`sensor_id` AS `sensor_id`, `S`.`sensor_name` AS `sensor_name`, `S`.`sensor_location` AS `sensor_location`, `S`.`sensor_max_good_temperature` AS `sensor_max_good_temperature`, `S`.`sensor_alarm_temperature` AS `sensor_alarm_temperature`, `S`.`sensor_last_temperature` AS `sensor_last_temperature`, `SC`.`sensorcondition_value` AS `sensorcondition_value`, `SC`.`sensorconditions_bootstrap_value` AS `sensorconditions_bootstrap_value` FROM (`sensors` `S` JOIN `sensorconditions` `SC` ON ((`S`.`sensor_condition` = `SC`.`sensorcondition_id`))) ORDER BY `S`.`sensor_id` DESC

You can of course customize this a lot to your own needs.

I used a view to customize a join of Alarms and Sensors as well.

NOTE: Views can be a good alternative for security reasons. You can limit the privileges of your MySQL accountto only be able to view the SQL Views. This prevents any malicious user to execute any faulty SQL statementsyou want to avoid.

ProceduresIn one of the next steps, I will guide you through my process of building the website. During the HTML part, Idecided to build my own Graph line-chart. To get all these data, I wrote a procedure that gives me everything Iwant. During the execution of the query, you can state which sensor_id you want, and how many days you want toinclude in your graph.

( During my testing phase, I chose to always print the last 20 days of data, but when I reset my database and Iinserted real data, I came to the conclusion that I won't have 20 days of data during my first 3 weeks. So I had torewrite a lot of this procedure, to make it fail proof for that. )

The procedure exists of a few steps:

1. Declaring variables2. Creating temporary table3. Selecting the dates4. Inserting the data into the temporary table

I will not go into much detail but I will show you one of the SQL statements as a teaser. The rest of my code canbe found in the FreegoMonitor_SQL_Dump.sql on my Github page.

INSERT INTO tmp(`date`, `avg_sensor_value`) VALUES (adddate(start_date, loop_counter), freegomonitor.get_avg_temperature_by_date(sensor_id, adddate(start_date, loop_counter)));

This looks like one hell of a complex statement, but it is in fact not that difficult. In one of the previous SQL queries,I searched for the start_date we need (Last entered day minus the amount of loops), then we increment it with 1each loop, with the adddate() function of MySQL. After that I call upon the power of theget_avg_temperature_by_date() function I wrote myself. More about that in a minute.We loop this INSERT INTO-statement the right amount of times we asked for.

Radio Frequency Temperature Sensor for (Arduino OUT, Raspberry Pi IN): Page 13

Page 14: Radio Frequency Temperature Sensor for (Arduino OUT, …segersnathan.be/.../2017/11/FreegoMonitor-Instructables.pdf · 2017-11-16 · instructables Radio Frequency Temperature Sensor

FunctionsI cannot say too much about the functions, as they are not very special. On my webpage, I wanted to show somestatistics of the temperature sensors. Mainly, the Average, the Maximum and the Minimum values. So I wrote asmall function to give me what I wanted.

I also made sure I could search for the Average temperature on one particular date, instead of the whole period. Ijust added a WHERE clause to that function. I can call this function by giving the sensor_id I want + the date in theformat "2017-01-01" for example.

SELECT AVG(sensorvalues_value) FROM sensorvalues WHERE sensor_id = input_sensor_id AND datetime LIKE concat(input_date, "%");

TriggersThe last thing I did in my MySQL Database was adding some Triggers. If you are not familiar with the idea oftriggers, they are mainly used to automate some tasks, and perform actions AFTER or BEFORE another action.

I chose to automate the setting of the current datetime BEFORE inserting my sensorvalues data.

I also have an AFTER INSERT trigger which allows me to check the condition of my temperature sensor.

- If my newly added temperature is below the max_good_temperature the condition is set to 1 which equals Good.

- If the temperature is between the max_good_temperature and the alarm_temperature, I will set it to 2 which isWarning! in my case.

- The 3rd value is Alert!! which only comes up when the temperature is above the alarm_temperature setting.

The second part of my trigger updates the sensor_last_temperature column in the sensors table to make sure Ireally have the last one.

To automate my alarms, I worked with an AFTER UPDATE trigger on Sensors. Whenever a sensor condition ischanged to 3, the Python code added a line to Alarms. I chose to combine the Python code with the MySQL, andthe trigger on this table makes sure that an alarm stops when the condition is Good again.

That would be all there is to say about my database. An in depth view of the queries I used will be available in oneof the next steps.

I will now guide you through my webpage, built with HTML, CSS, Javascript and Python with the use of Flask.

Radio Frequency Temperature Sensor for (Arduino OUT, Raspberry Pi IN): Page 14

Page 15: Radio Frequency Temperature Sensor for (Arduino OUT, …segersnathan.be/.../2017/11/FreegoMonitor-Instructables.pdf · 2017-11-16 · instructables Radio Frequency Temperature Sensor

1. Note that Email_recipients is the only table that has no relation to sensors.

1

Radio Frequency Temperature Sensor for (Arduino OUT, Raspberry Pi IN): Page 15

Page 16: Radio Frequency Temperature Sensor for (Arduino OUT, …segersnathan.be/.../2017/11/FreegoMonitor-Instructables.pdf · 2017-11-16 · instructables Radio Frequency Temperature Sensor

Step 7: Time for Webdesign - FLASK

In the attached screenshots of my webpage, you can see the site in action with some test data. At this verymoment, I am making use of this project, but the sensors are not attached to the fridge. They are lying around myhouse, a few feet away from me. This also explains the high temperatures.

Flask & Jinja2For rendering my pages, I have used the framework Flask which is Python based and allows to render HTMLtemplates with the use of Jinja2 - a template framework. This combination allows me to use some powerful Pythoncodes and integrate them on the webpage. The routing system Flask uses makes the use of .htaccess - for thepeople who might know that - unnecessary.

As I mentioned in one of the first steps of this tutorial, I have included the library Flask-mail through which I cansend emails from my Python code. If you might have skipped that part, please do so now. We will need it to sendour alert emails, and the contact script.

The code itself should be quite clear, once again, this can be found on my Github webpage.

Jinja2 filtersI just want to clear one thing out, that I struggled with quite a bit.

As you can see in the screenshots above, in my graph, I have written the dates in the format 'DD-MM', but in myDatabase, I have a datetime column in the format of "YYYY-MM-DD HH:MM:SS". I had to enable a jinja filter asfollowing:

def datetimeformat(value, format='%d-%m'): return value.strftime(format)jinja2.filters.FILTERS['datetimeformat'] = datetimeformat

This allows me to execute a Python function called datetimeformat() that formats my datetime. I can call thisfunction like this:

value|datetimeformat

In the following step, I will quickly explain the choice of my HTML and CSS markup.

Radio Frequency Temperature Sensor for (Arduino OUT, Raspberry Pi IN): Page 16

Page 17: Radio Frequency Temperature Sensor for (Arduino OUT, …segersnathan.be/.../2017/11/FreegoMonitor-Instructables.pdf · 2017-11-16 · instructables Radio Frequency Temperature Sensor

Step 8: Time for Webdesign - HTML & CSS

For my HTML and CSS styling, I chose to work with the frameworks of Bootstrap. I have customized my ownBootstrap files, as to include only the necessary parts. You can visit my customization through this link. If youprefer to just use my code, that's also fine, I have not modified any of the customized Bootstrap CSS or Javascriptfiles, so it should be the same. But if you want to add more functionalities to the website, you should considergetting your own custom files.

HTMLA short note about my HTML:

Every screen is made out of the header, which includes the Logo I made and the navigation on the right.In the footer, I provided space for the contact form, which only appears once you have logged in with yourpassword.

For the moment, I haven't made the option for multiple user accounts, but I have protected the webpage with apassword, so it cannot be reached by anyone. There are plans for this in the future.

I chose to work with "boxmodels". This is a term for boxes friend of mine used when they introduced me to webdevelopment a few years ago. I continued the concept. Basically, I always have a box that consists of a header, asection and optionally a footer. By giving it the class boxmodel, they stick together nicely through the use of myCSS styling. Inside these boxmodel headers, I can give a small title about what's in that box.

The boxmodels allow for easy grouping of data and I can easily modify the positions as well.

CSSThe CSS shouldn't require too much of an explanation, as you can mostly see what everything does.

The most important parts of the styling is done by Bootstrap. I only added my own boxmodels, header andnavigation customization, the footer and I added some margins on the left and right of the page.

The custom CSS I wrote is available in my style.css file located under css in the static folder of my Flask project.

The most CSS is used for the graph, which requires quite a bit markup:

Grid linesRadio Frequency Temperature Sensor for (Arduino OUT, Raspberry Pi IN): Page 17

Page 18: Radio Frequency Temperature Sensor for (Arduino OUT, …segersnathan.be/.../2017/11/FreegoMonitor-Instructables.pdf · 2017-11-16 · instructables Radio Frequency Temperature Sensor

Polygons ® RectanglesData circles & Data linesAxesLabels

GraphI always like to use libraries to do things for me, so that I do not have to reinvent them, but some of those requirequite a bit of work to implement. So one evening, I decided to check out SVG tutorials on line-graphs or scatter-diagrams. I tried it out and it worked quite OK, and extremely easy to implement. A quick tutorial how I did it.

SVG elements aren't used on a daily basis by any beginning web designer I reckon. So I will quickly comment onthe SVG elements.

SVG-tagwill be your overall parent element where you will style the width and height of your graph.

G-tag is kind off like a Div element. It allows you to group elements, you can give them ID's and classes just likeany other tag.

Inside of a G element you will see 4 other child elements in my graph.

1. Polygon ® A polygon is an element with a variable amount of corners. In my case, I make arectangle, so I need 4 corners. The way this SVG element works is by providing coordinates ofevery corner.

2. Line ® Line elements basically draw a small line from one coordinate to another.3. Circle ®® A circle does what it says, it generates a circle. You will have to provide the coordinates

of the center, and the radius of the circle.4. Text ®® Nothing as useful as good ol' text. This required no more than the coordinates of the start.

<line x1="40" x2="40" y1=10" y2="325"></line>

<polygon points="40,10 40,325 815,325 815,10"></points>

<circle cx="100" cy="100" r="3"></circle>

<text x="2" y="325"></text><br>

As I wrote just above this paragraph, you will notice the graph is divided into a few different parts. I will guide youover every one of these 5 parts real quick.

Axes

On a line-graph, you have 2 axes, the X and Y. These will be your horizontal and vertical base-line respectively.Note: You will need to put your labels underneath the X and to the left of the Y-axis, as you will want them to beread. This is why you cannot put your X and Y to the complete lefthand-corner side of the SVG element. So Idecided to move them up a bit.

Polygons

The polygons I used are 3 rectangles. They will provide us with a coloured background for the chart. Bootstrapprovides us with colours for Success, warning and danger. These colours represent our 3 conditions of the

Radio Frequency Temperature Sensor for (Arduino OUT, Raspberry Pi IN): Page 18

Page 19: Radio Frequency Temperature Sensor for (Arduino OUT, …segersnathan.be/.../2017/11/FreegoMonitor-Instructables.pdf · 2017-11-16 · instructables Radio Frequency Temperature Sensor

sensors. Thus they can also be used in the chart to show when a temperature would be in the danger zone.The ending Y-coordinate is calculated based on the value from the database. If my alert_temperature is forexample 12°C and my max_temperature value is set to 15, then that means the top 3 Y-coordinates should becoloured danger red.Since the chart starts at Y-coordinate 10, we can already add 10 to our calculation. We alsoknow that the space between 2 lines equals 10 dots as well. So we come up with the formula:

((max_temperature - current_sensor[4]) * 10) + 10

in which current_sensor[4] equals our sensor_alert_temperature column from the sensors table, thus 12 in ourexample.

We will do the same for the warning part of the chart. This will start from the previously calculated danger-Y-Coordinate and go all the way to the good-Y-Coordinate.

Grid

Next element on our list is the grid. I made up a grid based on the previous calculations, and I put it in a loop, sothat we can easily update the values for future releases. Vertically, I build up 20 lines for my 20 dates. Thecalculations start from 15 dots on the X-axis, and adds 40 dots every line.

Horizontally, I wanted to give every fifth line a more visible colour. The lines in between don't need these, it's justeasier to read all the values if you have the full grid. I just manipulated the for-loop to do this. Every element thatcan be divided by 5 (15, 10, 5, 0, -5, -10, -15) gets a white line with opacity 0.7. All the others get a sub_line classwhich sets their opacity to 0.2

Labels

Our labels titles are static, they start near the beginning of their corresponding axis.The label values (the dates (x) and the temperatures (y) ) are also calculated based on their number. A trick to"remove" all values between 2 main lines is to put their position to the far left, off the grid. I pushed them to the x-value -1000 so that they won't show up on the graph itself.

Data

Last but not least is the data. These circles have a radius of 3, their position is calculated based on their data-value. If the temperature is 12, the position is set to the corresponding y-coordinate of 12. If it's the first element, itgets put on the first vertical line on the x-axis.

I also let my graph draw a line between one dot and the next, so you have a nice line diagram.

That's basically all there is to tell about my graph. I have plans to update the graph and make it more dynamic, sothat you can scroll through time, zoom in on specific periods of time, but that is for future releases.

The next step will be the last one of the front-end side, although it's actually website back-end ...

Radio Frequency Temperature Sensor for (Arduino OUT, Raspberry Pi IN): Page 19

Page 20: Radio Frequency Temperature Sensor for (Arduino OUT, …segersnathan.be/.../2017/11/FreegoMonitor-Instructables.pdf · 2017-11-16 · instructables Radio Frequency Temperature Sensor

Step 9: Time for Webdesign - Using the Database in Flask

This part of the tutorial will explain you how to access your MySQL database using Flask and Python.

Mysql_controllerIn order to use MySQL in Python, you have to install the controller. You can easily do this by selecting thecorresponding package in PyCharm. You can also do it through the command line interface.

pip3 install mysql-controller

Depending on the version, you might have to specify an older version if yours doesn't work. They might containerrors.

DbClass.pyIn my Github code, you can find a folder called model inside the Web parent folder. This directory always includesmy classes I write for Python code. Inside you will find the DbClass.py script. This one allows the connection to bemade to the database and provides us with the ability to perform queries.

As I mentioned earlier, it is possible to rewrite your queries so that you only execute views and procedures insteadof UPDATE, DELETE, SELECT and INSERT INTO scripts, for optimized Database Security.

After you initialized your database connection, you can start writing queries.

Every query I write is for one purpose only. When it's a SELECT query, I will return a list of results back to avariable I declared in my Flask script. I can then use that result variable for different actions. (Building up the tablewith my sensors, gathering my graph data ...)

You can experiment with other versions of DbClasses you might find on the internet, you can even rewrite thisquery to optimize it's security.

Radio Frequency Temperature Sensor for (Arduino OUT, Raspberry Pi IN): Page 20

Page 21: Radio Frequency Temperature Sensor for (Arduino OUT, …segersnathan.be/.../2017/11/FreegoMonitor-Instructables.pdf · 2017-11-16 · instructables Radio Frequency Temperature Sensor

Step 10: Finishing Off

To finish off the project, you could 3D Print some niceboxes to put the Arduino's in. Or create your own withdifferent other DIY projects available on Instructablesor somewhere else.

I chose not to do that, since I want to develop theproject even further for a future releases, and thatwould require some more testing, other setups andwould potentially increase the size of my box.

Since we had a few boxes at home - a bit overkill,size-wise - I decided to put it in one of those, they areeasy to disassemble, and I can move it around easily.I poked a small hole inside the top plastic lid to put

the Antenna through. One corner of the lid wasremoved to put all the cables through as well.

The same goes for your Raspberry Pi. You could useone of the available Raspberry Pi cases, which mightnot look as good as your Raspberry Pi, but at leastit's covered.

I chose to keep my Raspberry Pi in a case that allowsa flat cable to go through it, so that I can access theGPIO pins and keep the Raspberry Pi closed. Butthat's your choice.

Radio Frequency Temperature Sensor for (Arduino OUT, Raspberry Pi IN): Page 21

Page 22: Radio Frequency Temperature Sensor for (Arduino OUT, …segersnathan.be/.../2017/11/FreegoMonitor-Instructables.pdf · 2017-11-16 · instructables Radio Frequency Temperature Sensor

Step 11: How to Use?

You might be wondering, how do I use this application?

It's not that difficult to start using it.

The first time you will be deploying this project, you will have to position your Arduino's with the temperaturesensors in the correct place. Depending on the strength of the power supply on the Transmitters and the length ofthe Antenna, the distance between your Raspberry Pi and Arduino's.

Position the Arduino's so that the antenna's are facing the Raspberry Pi Receiving antenna.Plug both your Arduino's and your Raspberry Pi into a power supply. Power them both at the sametime if possible. Through the use of one or more plug boxes.Depending whether you use Wireless or Ethernet, plug your UTP cable from a router/modem toyour Raspberry Pi's Ethernet port.Surf to the IP Address you have received.

If you do not have immediate access to the IP address of the Raspberry Pi - becauseyou moved it after building it - search for it using a HDMI compatible screen and cable

If you have correctly built the database, you should have setup a few Alert Email Recipients. If youhaven't done that, head over to the database and add a few into the corresponding table.

If you don't have access to the database, you will notice that the alarms are added tothe alarms page.

After a few minutes you should receive your first data in the homepage of the website. If it does notappear, try moving the sensor or the Raspberry pi closer, and check the Antenna's.If you receive an email telling you the temperature of one of your sensors became too hot, do notpanic, if you check the source of sudden heath change, fix that and the temperature drops, you havesolved the problem.

Radio Frequency Temperature Sensor for (Arduino OUT, Raspberry Pi IN): Page 22

Page 23: Radio Frequency Temperature Sensor for (Arduino OUT, …segersnathan.be/.../2017/11/FreegoMonitor-Instructables.pdf · 2017-11-16 · instructables Radio Frequency Temperature Sensor

Radio Frequency Temperature Sensor for (Arduino OUT, Raspberry Pi IN): Page 23

Page 24: Radio Frequency Temperature Sensor for (Arduino OUT, …segersnathan.be/.../2017/11/FreegoMonitor-Instructables.pdf · 2017-11-16 · instructables Radio Frequency Temperature Sensor

Step 12: Problems I Faced

I have encountered quite a few problems during thewhole process.

When I started this project, I had no idea how mydata would be transmitted from my Transmitter to myReceiver over Radio Frequency. I Googled quite a bitand talked to one of my professors telling me I shouldsearch for Manchester encoding. During a whileprocess of trying to get the Manchester library forArduino to work, I accidentally found out my SerialMonitor of my Arduino can be sent Wirelessly throughRadio Frequency.

When I noticed that, I began sending packages ofdata through the Serial.print() of my Arduino.Only then did I notice I could never send a wholebunch of data in different lines, because they couldcome up in another sequence, or there could beinterference of another transmitter at the same time.So I decided to put it all in one line, and it worked finefor quite some time.

Then when I showed my code to another professor,he told me I could modify and optimize my code withlittle effort. It would require the Preamble, Data valueand CRC (Cyclic Redundancy Check) to be in binaryand be sent over the Serial Monitor where it can beeasily decoded in Python. I managed to do this aftermodifying 90% of my code.

The second problem was: What if my Arduino'spower up at the exact same time, after - let's say - apower shutdown? That was when I decided to add arandom sleep to set both Arduino's on an

asynchronous time schedule.

I already stated in one of the past steps, that myTransmitters should be turned off, in order to notcause any interference. This was also one of theproblems that bugged me the most, but I found thesolution which was explained in the same part of thetutorial.

Before I began this project, I already had a few thingsin mind I had to take care of, once I started theproject. But during the whole developing phase, thesethings began to slip my mind. In the last week I finallythought I forgot something, and I quickly made sure itwas possible.One of these things was to make sure that I also geta notification in case my Raspberry Pi would poweroff. Otherwise I wouldn't get a notification that mysensor data is too hot. I found a free tool calledUptimerobot which notifies me when my website isunreachable. I have configured this to my ownaccount, so you will have to do the same in order toget these emails.During a demo, you will not get this, because youhave to make an account

While I was testing the data with the graph, my scriptwould crash, because my MySQL procedure onlyworked with at least 20 dates in the data, which didn'thappen any more after I flushed the data, thus thedata would fail to be requested and the script wouldcrash.

Step 13: The End

This was all, it was so much fun working on this project, and I hope to continue and expand it later this summer.

If you have any questions regarding this project, feel free to leave a comment below or contact me.

Radio Frequency Temperature Sensor for (Arduino OUT, Raspberry Pi IN): Page 24