The Hive Monitoring project (Part 2)
Hey! In my last post I tried to describe my hardware setup. This contains the sensors that I used, which device and how it is wired together. Now it will be interesting, because we get it to run so that I get sensor data from it.
The IDE I use
Yes for my wemos it is right to use the Arduino IDE. But I like VSCode as IDE, so I try to find out a way to develop code for the arduino device with vscode.
And there I got one PlatformIO (opens new window).
This IDE contains the following features:
- Debugger
- Intellisense
- Multi projects workflow
- Build-In Terminal with custom Platform IO CLI
- Build-In Serial Port Monitor
And the special one
- IT integrated in Several IDE's also in vscode
Nice I have ma ideal IDE figured out, now let's get it on to install it.
Install platform IO in VSCODE
There is a handy documentation for the installation (opens new window)on the PlatformIO site.
I repeat the complex installation here 😉
- Open VSCode
- Search for the PlatformIO IDE (opens new window)extension
- Install Platform IO IDE extension
Image from Platform IO
Pew... that was stressful. 😉
Configuring the IDE
Before we can start to develop the code that will be placed on the Wemos board. We must setup the IDE to tell it that it must produce a binary especially for this board.
First of All create a new directory and open vscode
For now we have a emty directory and it is now time to create the Platform IO Project. This will contains the information about the used platform (our Wemos D1 Mini). There exists a wizard in PIO that will help us. Create a new project from the PIO homepage after this you will promoted to enter the used device and framework. We search then Wemos d1 mini and use arduino as framework.
The communication Infrastructure
Before we can start I must tell you that in the communication between host and IOT device will always (or the most time) by done by a message bus system. So I use Mosquitto as mqtt- server for this. This is a light server that can be easily configured, and support the actual mqtt protocol standards.
The Framework that I use
So one word about the framework that I use and why. So I didn't want to reinvent the wheel, then I looked about a toolset for my requirements. This tool must support the following requirements:
- Deep Sleep
- MQTT Communication (standardized)
- Over the air update (Firmware / configuration)
- Nice energy management support
So i will make it short. In the end I came to the Homie-esp8266 (opens new window)Framework. This has a huge support of all this requirements.
Let's go ... with the basics
Now after the project was create we can go and type some code to run it on our device. the source will come into the src
folder. I created a file called node-wifi-mqtt-homie.cpp
in it.
Why this name? This has an historical reason. Because before the PIo era I programmed it within the Ardunio-IDE. so the file name was reserved 😉.
In this file i got to main methods:
void setup(){
}
and
void loop(){
}
In the setup()
there are the initialize methods in it. Be care full, the reset watchdog is very angry if there will be code executed that takes longer as 500 ms. So keep it reduced to the minimized set of methods.
In the loop()
function comes the main code. That usually will be executed. Like measuring the temperatures and so on.
Let's go... with the requirements
So I owning some devices, so I must add some third party libaries to this project.
This is how it is done:
After the installation, it will be located in the libary folder. When you did this the first time you will notice that there will be create a MAKEFILE
that contains the reference to the added libary.
So now you know how to add a libary, then you must add the following to the project:
Libary Name | Purpose |
---|---|
HX711 | This is the required module for the Weight cell A/D converter |
DallasTemperature | This will be the preferred libary for the use of the Temperature sensor. |
RunningMedian | This is a helper tool that compute a median value for the given metrics of the weight cell. |
So now the libaries a assigned, now we must tell pio, what to build...
Because you cannot run a WeMos build on a small PyCom module. Because this has a different set of machine command. So there must be defined the target in PIO. For this exists the file platformio.ini
in the root folder of the project.
For example, my file has the following content:
; Build darget
[env:esp12e]
; Platform to build
platform = espressif8266
; the device that will be used
board = d1_mini
; using the arduino system code
framework = arduino
; Adding Buildflags to indicate the low_memory use
build_flags = -D PIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY
; Adding dependency to Homie, and ArduinoJson with the version 5.13.4 (BEcause the newer one contains some bugs actually)
lib_deps = Homie
ArduinoJson@5.13.4
; set the speed of the serial monitor
monitor_speed = 115200
; set the compat mode to strict
lib_compat_mode = strict
done?... so now...
Let's go... coding 🎉
Now after the basics now be clear (or not? write me in the comments below...) I can go to my code. But first some Todo's... what must the code do?
- Configuration must be read from the config file
- Measure the temperature
- Measure the Weight
- Sending the Data to the MQTT Server
- Going into the powersave mode (DeepSleep)
pew.. so start with the first bullet point.
Set the configuration
The configuration mus be set from the config file. I knew that Homie has a support for configuration (opens new window)(luckily with json). I created in the root folder a subfolder homie
. In this there will be create the config.json
with my configuration:
{
"wifi": {
"ssid": "Ponyhof",
"password": "XXXXXXXXXXXXX"
},
"mqtt": {
"host": "192.168.178.201",
"port": 1886,
"auth": true,
"username": "sascha",
"password": "XXXXXXXXXXXXX"
},
"name": "dev-device",
"ota": {
"enabled": true
},
"device_id": "dev-device",
"settings": {
"sleepTime": 3600,
"sendInterval": 3600,
"weightOffset": 244017,
"kilogramDivider": 22.27
}
}
for further explanation I will direct you to the complete guide (opens new window)of Homie 😉.
Interesting will be the Area settings
This holds the settings that I will use in my program.
The Code itself
So instead to create the code line by line. There exists a github Repo (opens new window)for this... ehm... yes project 😃. This contains the complete sourcecode to measure the temperature, the weight and the battery state. Thanks to Homie ESP, it is easy to setup the transport to the mqtt Server.
So instead to go though every line I will comment some party of it.
Just clone the repo and bring it on your device. With the wiring of the provious post it will work fine.
Deep Sleep
The Deep Sleep function is the one, that is a must have function. Otherwise the battery will be empty in a short time. So there exists the normal call to the deep sleep (see the homie Spec for calling deep Sleep). Also there is a deep sleep called when the runtime of the code takes too long. Then it will go automatically go to sleep and send the data in the next interval.
void max_run()
{
++runtime_s;
if (runtime_s == RUNTIME_MAX)
{
Homie.getLogger() << "DEBUG: Max. runtime of " << RUNTIME_MAX << "s reached, shutting down!" << endl;
SLEEP_TIME = sleepTimeSetting.get();
Homie.getLogger() << "✔ Preparing for " << SLEEP_TIME << " seconds sleep" << endl;
Homie.prepareToSleep();
}
}
Sending to MQTT
The data will not be send by a method called from me. Instead it will be called when I am finished with the work. So this will help me to not implement any error handling or retry patterns. It's very simple.
But we must define what to send. Especially I must declare the Nodes to send.
HomieNode weightNode("weight", "weight");
HomieNode temperatureNode0("temperature0", "temperature");
HomieNode temperatureNode1("temperature1", "temperature");
HomieNode batteryNode("battery", "volt");
HomieNode batAlarmNode("battery", "alarm");
HomieNode jsonNode("data", "__json__");
With this configuration the Homie know on with topic the data will be set. In the MQTT Server it then look like this:
So How do we set data to this nodes? It's very simple. Here I will send the measurement from the temperature sensor to the first temperature node.
temperatureNode1.setProperty("degrees").setRetained(false).send(String(temperature1));
Working with the data
So when the data is on the servicebus, we must work with it. Because the servicebus is only a service layer for me not a database. For me it was enought to forward the data to the hiveeyes project (opens new window). This portal is an open source portal and deliver (for private use only) a portal to send the messages to. So there is mine too.
The data will be there stored in a influx Database. This is a special database especially for timeseries. So perfect for this scenario.
As frontend there is Grafana. This will visualize the data from the Influx DB perfectly.
Here is an example
You can decide if you want to send it to the open Data pool, or you can host your own infrastructure (This will be described in my next post).
Conclusion
So with this post I want to show you how I create with minimal effort a huge benfit in measuring the weight, temperature and also the battery level.
The main part will be the visual presentation in Grafana like this weight level against the amount of precipitation
Or the Batterylevel:
Please leave me a comment below, any suggestions are welcome ! 😃