Smart IOT Propane Pedestal capable of tracking propane level as well as detecting any propane leaks. Integration with Amazon Alexa.
Things used in this project
Story
Intro
We wanted to make a IOT device to reflect our love for grilling and that is why we made The Smart IOT Propane Pedestal. The device is capable of monitoring the weight of the tank as well as detecting any propane leaks. This all requires creating an Alexa Smarthome Skill, an AWS Lambda function and Shiftr.io to communicate with the MKR1000.
Weight Monitoring
Using (4) 50kg Load Sensors in a Wheatstone Bridge arraignment a Load Cell Amplifier, Logic Level Converter, and Arduino MKR1000 we set up a scale similar to your average digital bathroom scale.
Sparkfun has documented hookup guides that should be referenced.
Arduino IDE Sketch we used the sketch example referenced in the spark fun hookup guide for the load cells titled HX711.ino
https://github.com/sparkfun/HX711-Load-Cell-Amplifier
https://github.com/bogde/HX711
GAS Leak Detection
A Sparkfun LPG Sensor was also connected to the Logic Level Converter and Arduino MKR1000 to provided basic gas leak monitoring rather then varying levels we kept it simple using T/F either gas is detected or its not. With more time we plan on setting certain thresholds to increase accuracy.
Arduino IDE Sketch/Hookup – we used the code example referenced below:
LPG sensor
Pedestal Housing
The pedestal housing consists of two aluminium pans details available in CAD file. We had these fabricated for us by our friends at www.FuseFab.com out of aluminum sheet metal.
The inner pan is where the hardware components were located and the load cell’s were mounted on top of 3d printed feet to allow for enough room underneath for our Arduino MKR1000, LPG Sensor, LoadCellAmp, LogicLevelConverter, etc. A smaller circular plate was placed atop for the propane tank to sit on.
Tank in pedestal
Inner pan housing hardware components
Inside view
Custom parts and enclosures
Schematics
Code
Lambda Function
float gas, currentWeight, double propaneLevel
def MAX_WEGHT = 36.6
def TARE_WEIGHT = 16.6
def lambda_handler(event, context):
# TODO implement
return 'Hello from Lambda'
def isDetected(gas):
if (gas > 0)
result = True
print("Gas Leak Detected!")
else:
result = False
return result
print(isDetected(x))
def checkLevel(currentWeight):
if (currentWeight <= MAX_WEGHT):
propaneLevel = currentWeight - TARE_WEIGHT
else
print("Careful, your tank is too full!")
return propaneLevel
print("The current level")
Amazon Skill
JavaScript
{
"languageModel": {
"intents": [
{
"name": "AMAZON.CancelIntent",
"samples": []
},
{
"name": "AMAZON.HelpIntent",
"samples": []
},
{
"name": "AMAZON.StopIntent",
"samples": []
},
{
"name": "GetPropane",
"samples": [
"check propane",
"tell me propane",
"get propane",
"get current propane",
"check current propane"
],
"slots": []
}
],
"invocationName": "check propane"
}
}
INo
C#
File Transfer: PropaneMeasurement.ino
#include <WiFi101.h>
#include <MQTTClient.h>
#include <Bridge.h>
#include "HX711.h"
const char ssid[] = "";
const char pass[] = "";
#define DOUT 3
#define CLK 2
HX711 scale(DOUT, CLK);
char username[] = "";
char password[] = "";
char clientID[] = "";
float calibration_factor = -11100;
WiFiClient net;
MQTTClient client;
unsigned long lastMillis = 0;
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, pass);
scale.set_scale();
long zero_factor = scale.read_average();
// Note: Local domain names (e.g. "Computer.local" on OSX) are not supported by Arduino.
// You need to set the IP address directly.
client.begin("broker.shiftr.io", net);
client.onMessage(messageReceived);
connect();
}
void connect() {
Serial.print("checking wifi...");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(1000);
}
Serial.print("\nconnecting...");
while (!client.connect("arduino", "try", "try")) {
Serial.print(".");
delay(1000);
}
Serial.println("\nconnected!");
client.subscribe("/hello");
// client.unsubscribe("/hello");
}
void loop() {
client.loop();
Serial.print(scale.get_units(), 1);
Serial.print(" lbs");
Serial.print(" calibration_factor: ");
Serial.print(calibration_factor);
Serial.println();
if (!client.connected()) {
connect();
}
// publish a message roughly every second.
if (millis() - lastMillis > 1000) {
lastMillis = millis();
client.publish("/hello", "world");
}
}
void messageReceived(String &topic, String &payload) {
Serial.println("incoming: " + topic + " - " + payload);
}