Accéder au contenu principal

A simple temperature and humidity MQTT sensor for Home Assistant, based on Arduino MKR1000

This article describes a way to create and manage multiple very simple temperature and humidity sensors based on Arduino MKR1000, and being able to send their information to Home Assistant.

The Arduino MKR1000 is a pretty cool device, which has an integrated Wifi chip, optimized for low power consumption. This post is not addressing the power aspect, but keep in mind that a possible enhancement of the presented configuration could be to leverage the low power and sleep mode possibilities, in order to run the sensor on battery, instead of having it constantly plugged in.

Without taking that into consideration, my requirements were the following:
- To be able to plug in a sensor in each room of my home, connected to my Wifi network;
- To read humidity and temperature every few minutes;
- To collect all data on a pre-configured Home Assistant server;
- To be able to re-connect automatically, whenever an Internet, wifi or power outage occurs (and in my place, you can expect all the 3 to happen regularly in random order ;-).


Hardware setup

I have selected the DHT22 sensor for this setup. It is not extremely precise (but more than the DHT11 for example, as it can read decimals), but it is good enough for reading room temperatures and humidity, while still being quite cheap.

Here is my hardware setup:
  • Arduino MKR1000
  • led
  • 220k ohms resistor (for led)
  • DHT22 sensor
  • 10k ohms resistor (for DHT222)


It's a very simple setup. The DHT22 is connected to pin 6. Notice the 10k resistor on pin 2 of the sensor connected to the 5V. I have added a simple led on pin 2 (with a 220k ohms resistor), in order to be lighten up when a Wifi/MQTT connection is initiated. Basically, if the led is blinking, it means it is sending out a MQTT payload. If it is staying lit up, it means that it is trying to connect still, indicating either a Wifi issue, or a MQTT server (Home Assistant issue).

Home Assistant setup

The goal of this setup is to communicate to a MQTT server. I have chosen to use Home Assistant as an on premise MQTT server, but basically, you could use the same setup to communicate with any MQTT server, located at your place or even in the cloud, as long as the IP address of the server accessible from your sensor.

To properly configure your Home Assistant as a MQTT server, please follow: https://home-assistant.io/components/mqtt/



Here is the code to add to your "configuration.yaml" file in the "sensor" section:
- platform: mqtt
    name: "MKR Humidity"
    state_topic: "MKR1000_1/humidity"
    unit_of_measurement: "%"
- platform: mqtt
    name: "MKR Temperature"
    state_topic: "MKR1000_1/temperature"
    unit_of_measurement: "°C"

Please note the the "MKR1000_1" should be the unique device ID you give to your sensor. You can of course have several devices, with different IDs (for instance MKR1000_1, MKR1000_2, MKR1000_3, etc...), and refer them in your "configuration.yaml" file. You will see in the Code section how to set that up in your code for each device. The two parameters "/humidity" and "/temperature" are the so-called MQTT topics, which are basically data you publish and read from you MQTT sensor. For a more detailled MQTT walkthrough, you can refer to https://www.baldengineer.com/mqtt-tutorial.html.

Code

#include <WiFi101.h>
#include <DHT.h>
#include <PubSubClient.h>
#define mqtt_server "192.168.0.xx" // Home Assistant IP address
#define mqtt_user "homeassistant" // Home assistant user name
#define mqtt_password "your_home_assistant_password" // Home Assistant password
#define DEVICE_ID "MKR1000_1" // give a unique name to your device
//MQTT topics: humidity and temperature
String humidity_topic;
String temperature_topic;
#define LED 2 // Send data led pin
#define READ_DELAY_MS 60000 // 1 mn between reads (in milliseconds)
#define DHTPIN 6 //Pin of your DHT sensor
#define DHTTYPE DHT22
DHT dht(DHTPIN,DHTTYPE,30);
int ledState = 0;
int status = WL_IDLE_STATUS;
WiFiClient espClient;
char ssid[] = "your_SSIDD"; // your wifi SSID
char pass[] = "your_SSID_password"; // your wifi password
PubSubClient client(espClient);
void setup() {
pinMode(LED,OUTPUT);
Serial.begin(9600);
humidity_topic = String(DEVICE_ID) + "/humidity";
temperature_topic = String(DEVICE_ID) + "/temperature";
setup_wifi();
client.setServer(mqtt_server, 1883);
delay(200);
}
void setup_wifi() {
delay(10);
ledToggle();
// We start by connecting to a WiFi network
while (status != WL_CONNECTED){
Serial.println("Attempting to connect to WiFi");
status = WiFi.begin(ssid,pass);
}
Serial.println("connected to WiFi ");
ledToggle();
}
void reconnect() {
int mqttFailuresNumber = 0;
ledToggle();
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect(DEVICE_ID, mqtt_user, mqtt_password)) {
Serial.println("connected");
} else {
if (mqttFailuresNumber==3) {
//reset wifi if too many mqtt failures
mqttFailuresNumber = 0;
//re-initialize the Wifi connection, whatever happened
WiFi.end();
status = WiFi.begin(ssid,pass);
} else {
mqttFailuresNumber++;
Serial.println(mqttFailuresNumber);
}
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
ledToggle();
}
long lastMsg = 0;
float temp = 0.0;
float hum = 0.0;
float diff = 1.0;
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
long now = millis();
if (now - lastMsg > READ_DELAY_MS) {
ledToggle();
lastMsg = now;
float newTemp = dht.readTemperature();
float newHum = dht.readHumidity();
if(!isnan(newTemp)) {
temp = newTemp;
Serial.print("Temperature:");
Serial.println(String(temp).c_str());
client.publish(temperature_topic.c_str(), String(temp).c_str(), true);
}
if(!isnan(newHum)) {
hum = newHum;
Serial.print("Humidity:");
Serial.println(String(hum).c_str());
client.publish(humidity_topic.c_str(), String(hum).c_str(), true);
}
ledToggle();
}
}
// change the wifi connetcion led status
void ledToggle(){
if (ledState == 0){
digitalWrite(LED,HIGH);
delay(10);
ledState = 1;
} else {
digitalWrite(LED,LOW);
delay(10);
ledState = 0;
}
}
view raw gistfile1.txt hosted with ❤ by GitHub






Commentaires

Posts les plus consultés de ce blog

Introduction of an IT Project Management Methodology in a fast-growing company

This article from the PMI Knowledge Shelf explains the rationale behind the creation of an in-house, customized project management methodology, iMAP, at a rapidly growing pharmaceutical company. The authors also describe the priorities that were selected to start with its implementation: a solid project initiation, a clear project life cycle, a special attention to risk management, a first step in reporting standardization, and specific attention to the activities necessary for the transition to operations. They provide an overview of their approach to IT project governance and how a defined project management methodology is the key for its success. https://docs.google.com/file/d/0B40T8ZW4GEUJNmYxMTJhY2YtODY3Mi00NWEwLWExZDMtMmNlMGNiZTUyZWEw/edit