Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kfowlks/c1c6ce3c79033e9d49b0db5ec1b97bdc to your computer and use it in GitHub Desktop.
Save kfowlks/c1c6ce3c79033e9d49b0db5ec1b97bdc to your computer and use it in GitHub Desktop.
Arduino Scale with MQTT
/*
By: Kevin Fowlks
TODO:
Add manufacturer name
Add product type
Add weight units i.e. lbs or kg
Add device id
//https://github.com/esp8266/Arduino
*/
#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>
#include "HX711.h"
#include <SerialLCD.h>
#include <Wire.h>
#include <math.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#define CLK D6 //0
#define DOUT D7 //1
#define BTN D2
ADC_MODE(ADC_VCC);
HX711 scale(DOUT, CLK);
/* ESP8266 Set the ADC to read the VCC via the Analog pin
ADC_MODE(ADC_VCC);*/
float calibration_factor = -9375;
float current_avg_value = 0.0;
float last_avg_value = 0.0;
float drift = 0.200;
float threshold_weight = 5.0;
float offset_value = 68.9;
long counter = 0;
long debouncing_time = (1000000*2); //Debouncing Time in Milliseconds
long scale_on_time = (45*1000000); // 20 Secs
volatile unsigned long last_micros;
volatile unsigned long cnt;
volatile unsigned long start_micros;
const char* mqtt_server = "yanknpaste.com";
const char* mqtt_username = "<MQTT_BROKER_USERNAME>";
const char* mqtt_password = "<MQTT_BROKER_PASSWORD>";
const char* mqtt_topic = "sensors/scale/weight";
boolean runonce = false;
const long tts = 100000;
// W 85.38MM W
// H 48.80MM L
// Constructor. Parameters: rows, columns, baud/i2c_address, interface (RS232, I2C, SPI)
SerialLCD lcd(2,40,9600,RS232);
WiFiClient espClient;
PubSubClient client(espClient);
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
//Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("ESP8266Client")) {
//Serial.println("connected");
} else {
Serial.print("failed, rc=");
//Serial.print(client.state());
//Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void callback(char* topic, byte* payload, unsigned int length) {
lcd.off();
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
}
void Interrupt() {
Serial.print("Button Down");
cnt++;
lcd.print( "SETUP");
//delay(10);
}
void debounceInterrupt() {
if((long)(micros() - last_micros) >= (debouncing_time * 1000)) {
Interrupt();
last_micros = micros();
}
}
void setup() {
lcd.init();
lcd.setBacklightBrightness(1); // 1 is off for this lcd
lcd.off();
WiFi.mode(WIFI_OFF);
WiFi.forceSleepBegin();
delay(1);
pinMode(BTN, INPUT_PULLUP);
attachInterrupt(BTN, debounceInterrupt, CHANGE);
// scale.power_down();
// scale.get_scale();
// scale.set_scale(calibration_factor); //Adjust to this calibration factor
// scale.tare(); //Reset the scale to 0
start_micros = micros();
//long zero_factor = scale.read_average(); //Get a baseline reading
//Serial.print("Zero factor: "); //This can be used to remove the need to tare the scale. Useful in permanent scale projects.
//Serial.println(zero_factor);
//delay(5000);
//lcd.home();
//lcd.setCursor(1, 1);
//lcd.print(zero_factor);
//wifiManager.setDebugOutput(false);
//wifiManager.setBreakAfterConfig(true);
//wifiManager.autoConnect("kktravel", "hampton14");
//wifiManager.autoConnect("AutoConnectAP");
//wifiManager.autoConnect();
}
void loop() {
current_avg_value = ((scale.get_value(10)) / calibration_factor) - offset_value;
float diff = floorf(current_avg_value - last_avg_value);
if ( current_avg_value < threshold_weight && runonce == false )
{
WiFi.forceSleepBegin();
delay(1);
lcd.setBacklightBrightness(1);
lcd.off();
scale.power_down();
ESP.deepSleep(tts,WAKE_RF_DEFAULT);
delay(500);
}
else
{
if ( runonce == false )
{
runonce = true;
lcd.on();
lcd.home();
lcd.setBacklightBrightness(2);
// Set Contrast
lcd.setContrast(40);
lcd.home();
lcd.setCursor(1, 1);
lcd.print( "H E L L O");
lcd.setCursor(2, 1);
lcd.print(cnt );
delay(1500);
lcd.clear();
}
lcd.home();
lcd.print( current_avg_value, 1);
lcd.print(" lbs");
if ( diff < drift )
{
counter++;
if ( counter > 4 )
{
if ( current_avg_value > threshold_weight )
{
StaticJsonBuffer<144> jsonBuffer;
char buffer[144];
char buffer2[10];
char buffer3[10];
float pwr = ESP.getVcc() / 1000;
dtostrf(current_avg_value, 3, 2, buffer2);
dtostrf(pwr, 3, 2, buffer3);
JsonObject& root = jsonBuffer.createObject();
root["id"] = "3C1AAE90-E318-11E5-A837-0800200C9A66";
//JsonArray& data = root.createNestedArray("body");
//JsonArray& data2 = data.createNestedArray("body");
//data.add(double_with_n_digits(48.756080, 6));
root["weight"] = buffer2;
root["unit"] = "lbs";
root["pwr"] = buffer3;
//root["manufacturer"] = "fowlks";
//root["model"] = "OSCALE";
root.printTo(buffer, sizeof(buffer));
WiFi.forceSleepWake();
delay(800);
WiFi.begin("kktravel", "hampton14");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
lcd.print(".");
}
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
if (!client.connected()) {
reconnect();
}
client.loop();
client.publish(mqtt_topic, buffer);
client.disconnect();
WiFi.disconnect();
lcd.setCursor(2, 1);
lcd.print( "MQTT Send Data" );
delay(1500);
// Set Contrast
//lcd.clear();
lcd.setBacklightBrightness(1);
lcd.off();
//runonce = false;
ESP.deepSleep(tts,WAKE_RF_DEFAULT);
delay(500);
}
counter = 0;
}
}
else
{
counter = 0;
}
last_avg_value = current_avg_value;
/* if the loop has run for 60 seconds force a deep sleep*/
if(((long)(micros() - start_micros) >= (scale_on_time)) && current_avg_value < threshold_weight )
{
lcd.clear();
lcd.home();
lcd.print( "B Y E");
delay(1500);
lcd.setBacklightBrightness(1);
lcd.off();
scale.power_down();
ESP.deepSleep(tts,WAKE_RF_DEFAULT);
delay(500);
}
scale.power_down();
yield();
scale.power_up();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment