Since I got into Home Automation System, I have always wanted a central system with as much as information about me starting from my food habit to each and everything that can be measured or collected. You can say that it is greatly influenced by JARVIS of Iron Man which came around my Engineering days. Coming to the topic, I recently managed to connect a regular bathroom weighing scale to my Home Automation System (OpenHAB) using MQTT. So basically this post is all about how to do that.

For the weighing scale, I went with a cheap bathroom scale that comes around rupees 600 and readily available in Amazon or Flipkart in India. You might think why not to use a smart scale already available like the MI Scale, that also features a lot of other parameters like body fat etc. It is due to issues like, not all the scale comes with open API (I have not checked all scales though..), and I wanted full control.

Sadly though the scale I got doesn’t have any easy to connect interface or port to connect external microcontrollers or to fetch data. That’s why I had to connect an external Load Cell amplifier to the load cells available in the scale. I used the HX711 load cell amplifier module. The load cells the scale came with have three terminals and are connected in a bridge. The HX711 load cell amplifier has two input channels, and the bridge can be straightaway connected to the S+, S-, E+, and E- pins of the module by using only one channel. The scale

has a PCB that has marked the above-said pins making the connections easy. To interface with microcontroller HX711 comes with a serial interface having Data and Clock pins. If you want to know in detail check the datasheet of the amplifier. It comes with 24-bitresolution. To interact with the amplifier using Arduino, I used the HX711 library by bogde with an Arduino UNO. The sketch with the UNO is used to calculate the calibration factor to fetch weight from the amplifier. You can find the sketch from here . Check the video for detail. I used UNO as it is pretty easy to program, you can use the same sketch with ESP8266/ WeMOS though.

After obtaining the calibration factor and getting the accurate weight in the serial terminal, it was time for connecting the amplifier to the WeMOS module and publish the data using MQTT. If you are new to MQTT and want to learn about this, you can check this article. To publish weight data using MQTT, first I tried the pubsub library by Nick O’Leary which I use abundantly in my home automation nodes, but sadly that did not work, and the Wemos crashed repeatedly. Then I moved to the asyncmqtt library by Marvin ROGER which served the purpose.

As shown in the video you can use MQTTLens a chrome app to view MQTT messages. But make sure you have a broker installed in your network to enable MQTT messages. If you don’t have one you can simply use mosquitto MQTT broker, and it is available for all sort of operating system, and the installation is also pretty easy. Check out the video below on this for detail. The complete sketch is provided below.

You can certainly let me know if it can be upgraded in some ways. Cheers!!!!!

Code

#include <ESP8266WiFi.h> #include <Ticker.h> #include <AsyncMqttClient.h> #include "HX711.h" #define WIFI_SSID "home_wg" #define WIFI_PASSWORD "omisoksbwn" #define MQTT_HOST IPAddress(192, 168, 0, 7) #define MQTT_PORT 1883 //Calibration factor for HX711 #define CAL_FACTOR 11280.00 //This value is obtained using the caliberation sketch #define CONV_FACTOR 0.453592 #define DOUT 13 #define CLK 15 #define RED_L 12 #define YELLOW_L 14 #define _CON_DELAY 20000 #define _THRESHOLD_WEIGHT 20 #define _DETECTION_DELAY 7000 AsyncMqttClient mqttClient; Ticker mqttReconnectTimer; WiFiEventHandler wifiConnectHandler; WiFiEventHandler wifiDisconnectHandler; Ticker wifiReconnectTimer; HX711 scale(DOUT, CLK); int detection_time = 0; double lastWeight; char publishValue[10]; double measured_weight ; boolean break_weight_loop=true; IPAddress ip(192, 168, 0, 114); IPAddress gateway_dns(192, 168, 0, 1); void connectToWifi() { Serial.println("Connecting to Wi-Fi..."); WiFi.config(ip, gateway_dns, gateway_dns); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); } void onWifiConnect(const WiFiEventStationModeGotIP& event) { Serial.println("Connected to Wi-Fi."); connectToMqtt(); } void onWifiDisconnect(const WiFiEventStationModeDisconnected& event) { Serial.println("Disconnected from Wi-Fi."); mqttReconnectTimer.detach(); // ensure we don't reconnect to MQTT while reconnecting to Wi-Fi wifiReconnectTimer.once(2, connectToWifi); } void connectToMqtt() { Serial.println("Connecting to MQTT..."); mqttClient.connect(); } void onMqttConnect(bool sessionPresent) { Serial.println("Connected to MQTT."); Serial.print("Session present: "); Serial.println(sessionPresent); } void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) { Serial.println("Disconnected from MQTT."); if (WiFi.isConnected()) { mqttReconnectTimer.once(2, connectToMqtt); } } void setup() { scale.set_scale(CAL_FACTOR); scale.tare(); scale.power_down(); pinMode(RED_L,OUTPUT); pinMode(YELLOW_L,OUTPUT); Serial.begin(115200); Serial.println(); Serial.println(); wifiConnectHandler = WiFi.onStationModeGotIP(onWifiConnect); wifiDisconnectHandler = WiFi.onStationModeDisconnected(onWifiDisconnect); mqttClient.onConnect(onMqttConnect); mqttClient.onDisconnect(onMqttDisconnect); mqttClient.setServer(MQTT_HOST, MQTT_PORT); connectToWifi(); //Caliberation of HX711 } void loop() { scale.power_up(); measured_weight = scale.get_units(10) * CONV_FACTOR; //If you want average weight you can pass the num of iterations in get_units() if (measured_weight > _THRESHOLD_WEIGHT && ((millis() - detection_time) > _CON_DELAY)) { //Checking millis to avoid repeated publish // mqttClient.disconnect(); break_weight_loop=true; Serial.println("Weight detected."); digitalWrite(RED_L, HIGH); detection_time = millis(); while (break_weight_loop) { delay(40); lastWeight = scale.get_units()* CONV_FACTOR; if (lastWeight < _THRESHOLD_WEIGHT) { break_weight_loop = false; digitalWrite(RED_L, LOW); } else measured_weight=lastWeight; if (((millis() - detection_time) > _DETECTION_DELAY)) { break_weight_loop = false; digitalWrite(RED_L, LOW); digitalWrite(YELLOW_L, HIGH); sprintf(publishValue, "%f", measured_weight); yield(); mqttClient.publish("home/bathroom/scale/weight", 1, true, publishValue); } } } scale.power_down(); delay(2000); analogWrite(YELLOW_L, 50); if(((millis() - detection_time) > _CON_DELAY)) { delay(500); digitalWrite(YELLOW_L, LOW); } }

Repository