Created
December 29, 2018 17:34
-
-
Save kfowlks/c1c6ce3c79033e9d49b0db5ec1b97bdc to your computer and use it in GitHub Desktop.
Arduino Scale with MQTT
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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