Last active
August 18, 2017 22:39
-
-
Save ScottSmith95/f1a8948609abeb66809a3a3836fef932 to your computer and use it in GitHub Desktop.
Client for waste receptacle.
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
// Libraries | |
#include <ESP8266WiFi.h> // https://github.com/esp8266/Arduino | |
#include <ESP8266WiFiMulti.h> | |
#include <PubSubClient.h> // https://github.com/knolleary/pubsubclient/ | |
#include <Wire.h> | |
#include <LiquidTWI.h> // https://github.com/Stephanie-Maks/Arduino-LiquidTWI | |
#include <HX711.h> // https://github.com/bogde/HX711 | |
// Some immutable global definitions/constants | |
#define mqtt_server "mediatedspaces.net" // Class server. | |
#define mqtt_user "hcdeiot" // Shared class login info. | |
#define mqtt_pass "esp8266" | |
#define PrintToSerial | |
// Some objects to instantiate | |
HX711 landfill(14, 12); | |
HX711 recycling(13, 15); | |
HX711 compost(0, 16); | |
LiquidTWI lcd(0); | |
ESP8266WiFiMulti WiFiMulti; | |
WiFiClient wifi; | |
PubSubClient client(wifi); | |
// Global variables | |
unsigned long previousMillis; | |
const char* espUUID = "worldZERO/demo"; // Create UUID for *this* device. (Prefixes posted messages.) | |
const int ledPin = 2; | |
float landfill_kg = 0; | |
float recycling_kg = 0; | |
float compost_kg = 0; | |
float cmp_sensitivity = 0.2; | |
/** | |
* Set scale calibrations and tare. | |
*/ | |
void setup_scales() { | |
Serial.println("Setting up scales, remove all weight from scales."); | |
delay(300); | |
landfill.set_scale(-102000.0); | |
landfill.tare(); | |
delay(100); | |
recycling.set_scale(-102000.0); | |
recycling.tare(); | |
delay(100); | |
compost.set_scale(-102000.0); | |
compost.tare(); | |
Serial.println("Completed setting up scales."); | |
// power_down_scales(); | |
} | |
void power_down_scales() { | |
landfill.power_down(); | |
recycling.power_down(); | |
compost.power_down(); | |
} | |
void power_up_scales() { | |
landfill.power_up(); | |
recycling.power_up(); | |
compost.power_up(); | |
} | |
void setup_wifi() { | |
delay(10); | |
unsigned long timeout = millis(); | |
unsigned long timeoutLength = 10000; // Wait ten seconds before failing. | |
WiFiMulti.addAP("University of Washington", ""); | |
WiFiMulti.addAP("My Home Network", "homeiswheretheheartis"); | |
Serial.println(); | |
Serial.print("Connecting WiFi..."); | |
while (WiFiMulti.run() != WL_CONNECTED) { | |
Serial.print("."); | |
delay(500); | |
if (millis() - timeout > 5000) { | |
break; | |
} | |
} | |
if (WiFi.isConnected()) { | |
Serial.printf("\nConnected to %s\n", WiFi.SSID().c_str()); | |
Serial.print("Local IP address: "); | |
Serial.println(WiFi.localIP()); | |
Serial.println(); | |
} else { | |
Serial.printf("\nWiFi not connected. Current status code: %d\n", WiFi.status()); | |
} | |
} | |
// Pacemaker for regulating heartbeat. | |
void heartBeat(float tempo) { | |
static int hbeatIndex = 1; // this initialization is not important | |
static long heartBeatArray[] = { 50, 100, 15, 1200 }; | |
static long prevMillis; | |
if ((millis() - prevMillis) > (long)(heartBeatArray[hbeatIndex] * tempo)) { | |
hbeatIndex++; | |
if (hbeatIndex > 3) hbeatIndex = 0; | |
if ((hbeatIndex % 2) == 0) { // modulo 2 operator will be true on even counts | |
digitalWrite(ledPin, HIGH); | |
} else { | |
digitalWrite(ledPin, LOW); | |
} | |
prevMillis = millis(); | |
} | |
} | |
// Callback function to run when a message is recieved. | |
void callback(char* topic, byte* payload, unsigned int length) { // Set up params for function. | |
Serial.print("Message arrived ["); | |
Serial.print(topic); | |
Serial.print("] "); | |
for (int i = 0; i < length; i++) { | |
Serial.print((char)payload[i]); // Print to Serial character-by-char. | |
} | |
Serial.println(); | |
} | |
// Runs when MQTT server is disconnected. | |
void reconnect() { | |
// Loop until we're reconnected | |
while (!client.connected()) { | |
Serial.print("Attempting MQTT connection… "); | |
// Attempt to connect | |
if (client.connect(espUUID, mqtt_user, mqtt_pass)) { // Connect as unique device to class server. | |
Serial.println("connected.\n"); | |
digitalWrite(ledPin, HIGH); | |
} | |
// What to do when something goes wrong. | |
else { | |
Serial.print("failed, rc="); | |
Serial.print(client.state()); | |
Serial.println(" try again in 5 seconds"); | |
// Wait 5 seconds before retrying | |
delay(5000); | |
} | |
} | |
} | |
/** | |
SETUP | |
Initiates WiFi connection, | |
configures sensors, | |
and connects to MQTT server, registering callbacks. | |
*/ | |
void setup() { | |
Serial.begin(9600); | |
setup_wifi(); | |
pinMode(ledPin, OUTPUT); | |
lcd.begin(16, 2); | |
lcd.print(" worldZERO"); | |
// lcd.setBacklight(LOW); | |
client.setServer(mqtt_server, 1883); | |
client.setCallback(callback); | |
setup_scales(); | |
} | |
void pub_message(char* type, float weight) { | |
char message[50]; // Reserve 50 chars for message. | |
// int int_weight = (int) weight; | |
char str_weight[7]; | |
dtostrf(weight, 6, 1, str_weight); | |
// Format JSON string for MQTT publishing. | |
lcd.setBacklight(HIGH); | |
lcd.print(type); | |
lcd.setCursor(0, 1); | |
lcd.print(str_weight); | |
sprintf(message, "{\"uuid\": \"%s\", \"type\": \"%s\", \"weight\": \"%s\"}", espUUID, type, str_weight); | |
#ifdef PrintToSerial | |
Serial.println(message); | |
#endif | |
client.publish(espUUID, message); | |
} | |
/** | |
LOOP | |
Check for data to MQTT server every 5 seconds. | |
*/ | |
void loop() { | |
unsigned long currentMillis = millis(); | |
heartBeat(1.0); | |
client.loop(); | |
if (!client.connected() && WiFi.isConnected()) { | |
reconnect(); // Run reconnect func if client is disconnected. | |
} | |
// Wait five seconds between reports (non-blocking). | |
if (currentMillis - previousMillis > 5000) { | |
// power_up_scales(); | |
lcd.setBacklight(LOW); | |
lcd.clear(); | |
#ifdef PrintToSerial | |
Serial.println(); | |
Serial.println(); | |
Serial.print("Landfill: "); | |
Serial.print(landfill.get_units(5)); | |
Serial.print("/"); | |
Serial.println(landfill_kg); | |
Serial.print("Recycling: "); | |
Serial.print(recycling.get_units(5)); | |
Serial.print("/"); | |
Serial.println(recycling_kg); | |
Serial.print("Compost: "); | |
Serial.print(compost.get_units(5)); | |
Serial.print("/"); | |
Serial.println(compost_kg); | |
Serial.println(); | |
#endif | |
// Only post and update saved value if change is significant. | |
if (landfill.get_units() - landfill_kg > cmp_sensitivity) { | |
landfill_kg = landfill.get_units(20); // Update saved value. | |
pub_message("landfill", landfill_kg); // Post to MQTT. | |
} | |
if (recycling.get_units() - recycling_kg > cmp_sensitivity) { | |
recycling_kg = landfill.get_units(20); | |
pub_message("recycling", recycling_kg); | |
} | |
if (compost.get_units() - compost_kg > cmp_sensitivity) { | |
compost_kg = compost.get_units(20); | |
pub_message("compost", compost_kg); | |
} | |
// power_down_scales(); | |
previousMillis = currentMillis; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment