//Libs to add (for OLED)
//Adafruit_GFX.h
//Adafruit_SSD1306.h
//#include <Math.h>
// 'kegBWCV', 128x64px
const unsigned char epd_bitmap_kegBWCV [] PROGMEM = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x3f, 0xf6, 0x1c, 0x3e, 0xc3, 0xc0, 0x6f, 0xef, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x3f, 0xf0, 0x08, 0x1e, 0x01, 0xe0, 0x67, 0xcf, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x01, 0xf1, 0xc7, 0x9e, 0x3c, 0xf3, 0xe7, 0xcf, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x01, 0xf3, 0xe7, 0xde, 0x7c, 0xf3, 0xf3, 0x9f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x3f, 0xf3, 0xef, 0xde, 0x7c, 0xf3, 0xf3, 0x9f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x3f, 0xf3, 0xef, 0xde, 0x7e, 0xf3, 0xf3, 0x9f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x3f, 0xf3, 0xef, 0xde, 0x7c, 0xf3, 0xf9, 0x3f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x3f, 0xf3, 0xef, 0xde, 0x7c, 0xf3, 0xf9, 0x3f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x3f, 0xf3, 0xef, 0xde, 0x3c, 0xf3, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0xf3, 0xef, 0xde, 0x01, 0xf8, 0x7c, 0x7f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0xf3, 0xef, 0xde, 0x43, 0xf8, 0x7c, 0x7f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x07, 0xe0, 0x3f, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x60, 0x07, 0x00, 0x30, 0x07, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x7f, 0xfe, 0x7c, 0x63, 0xc7, 0x3e, 0x31, 0xe3, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0xff, 0xfe, 0x7c, 0x63, 0xe7, 0x3e, 0x31, 0xf3, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x7f, 0xfe, 0x7c, 0x63, 0xe7, 0x3e, 0x31, 0xe3, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x7f, 0xfe, 0x7c, 0x63, 0xe7, 0x3e, 0x31, 0xe3, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x7f, 0xfe, 0x7c, 0x63, 0xe7, 0x3e, 0x31, 0xe3, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x7f, 0xfe, 0x7c, 0x63, 0xe7, 0x3e, 0x31, 0xe3, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x60, 0x3e, 0x7c, 0x63, 0xe7, 0x3e, 0x31, 0xe3, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x63, 0x9e, 0x7c, 0x63, 0xe7, 0x3e, 0x31, 0xe3, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x63, 0x9e, 0x7c, 0x63, 0xe7, 0x3e, 0x31, 0xe3, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x63, 0x9e, 0x7c, 0x63, 0xff, 0x3e, 0x31, 0xe3, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x63, 0x9e, 0x7c, 0x63, 0xef, 0x3e, 0x31, 0xe3, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x63, 0x9e, 0x7c, 0x63, 0xef, 0x3e, 0x31, 0xe3, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x63, 0x9e, 0x7c, 0x63, 0xff, 0x3e, 0x31, 0xe3, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x63, 0x9e, 0x7c, 0x63, 0xe7, 0x3e, 0x31, 0xe3, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x63, 0x9e, 0x7c, 0x63, 0xe7, 0x3e, 0x31, 0xe3, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x60, 0x3e, 0x7c, 0x63, 0xe7, 0x3e, 0x31, 0xe3, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x7f, 0xfe, 0x7c, 0x63, 0xe7, 0x3e, 0x31, 0xe3, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x7f, 0xfe, 0x7c, 0x63, 0xe7, 0x3e, 0x31, 0xe3, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x7f, 0xfe, 0x7c, 0x63, 0xe7, 0x3e, 0x31, 0xe3, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x7f, 0xfe, 0x7c, 0x63, 0xe7, 0x3e, 0x31, 0xe3, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0xff, 0xfe, 0x7c, 0x63, 0xe7, 0x3e, 0x31, 0xf3, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x7f, 0xfe, 0x7c, 0x63, 0xc7, 0x3e, 0x31, 0xe3, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x60, 0x07, 0x00, 0x30, 0x07, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x07, 0xe0, 0x3f, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};
//Remove these since cloud variables:
int kegRemaining = 100; //MAKE THIS INT NOT FLOAT so percent shows 97% and not 97.34&
int lastPour;
int ouncesRemaining = 996; //End of program sets this via cloud variables (default to pony if cant see cloud?)
int pintsRemaining;
//To ADD:
//#include "thingProperties.h" //Connect to Arduino cloud
//Accelerometer variables
#include <Wire.h> //Wire library for I2C communication on acceleromter
int ADXL345 = 0x53; //The ADXL345 sensor I2C address
float X_out, Y_out, Z_out; // Accelerometer outputs
//Keg Pour Variables
int dly;
int dlyBeerPour=500; //This needs to be calculated with how many ounces of beer flow on a pour
float tiltAngle=-1000; //Need to find out the tilt angle value that corresponds to a beer being poured
int maxPony = 661;
int maxQuarter = 992;
int maxHalf = 1984;
int tempPour = 0;
int kegSize = 661; //DONT SET TO ANY NUMBER FOR ARDUINO CLOUD
int beersRemaining;
//OLED
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
void setup() {
Serial.begin(9600);
//Check if display works
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
else{
Serial.println("Display is good");
}
Wire.begin(); //Initate wire library
/*
// Connect to Arduino IoT Cloud
initProperties();
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
setDebugMessageLevel(2);
ArduinoCloud.printDebugInfo();
*/
//Set ADXL345 Accelerometer in measuring mode
Wire.beginTransmission(ADXL345); //Start communicated with devices
Wire.write(0x2D); // Access/talk to POWER_CTL Register - 0x2D
//Enable measurement
Wire.write(8); // (8dec -> 0000 1000 binary) Bit D3 High for measuring enable
Wire.endTransmission();
delay(250);
display.clearDisplay();
//REMOVE THIS ALSO:
ouncesRemaining=maxQuarter;
kegSize=maxQuarter;
}
void loop() {
//ArduinoCloud.update();
// ===Read accelerometer data=== //
Wire.beginTransmission(ADXL345);
Wire.write(0x32); // Start with register 0x32 (ACCEL_XOUT_H)
Wire.endTransmission(false);
Wire.requestFrom(ADXL345, 6, true); // Read 6 registers total, each axis value is stored in 2 registers
X_out = ( Wire.read()| Wire.read() << 8); // X-axis value
X_out = X_out/256; //For a range of +-2g, we need to divide the raw values by 256, according to the datasheet
Y_out = ( Wire.read()| Wire.read() << 8); // Y-axis value
Y_out = Y_out/256;
Z_out = ( Wire.read()| Wire.read() << 8); // Z-axis value
Z_out = Z_out/256;
//OLED Display (Keg Remaining Percent)
if (kegRemaining <= 100 && kegRemaining >=1){
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
oledDisplayCenter("hey");
display.print(kegRemaining);
display.print("%");
//display.display();
Serial.println("Board disconnected from Arduino IoT Cloud");
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(20, 55);
display.print("WiFi Disconnected");
display.display();
delay(1500);
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(20, 55);
display.print("WiFi Disconnected");
display.display();
}
else if (kegRemaining <= 0){
//Display bitmap image
display.clearDisplay();
display.drawBitmap(0, 0, epd_bitmap_kegBWCV, 128, 64, 1);
display.display();
delay(3000);
//Show normal 0%
display.clearDisplay();
display.setTextSize(3);
display.setTextColor(WHITE);
display.setCursor(50, 25); //Second row is vertical placement
display.print("0%");
display.display();
delay(3000);
//Scroll saying empty
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 10);
//display.println("Keg is empty");
display.display();
delay(3000);
//display.startscrollright(0x00, 0x0F);
//delay(3000);
//display.stopscroll();
//display.display();
//delay(3000);
}
//REMOVE THIS FOR ARDUINO CLOUD, JUST TESTING SINCE ACCEL ISNT WORKING IN SIMMY
//ouncesRemaining=(ouncesRemaining - 150);
Serial.print("Ounces Remaining ");
Serial.println(ouncesRemaining);
Serial.print("Keg Remaining ");
Serial.println(kegRemaining);
delay(500);
while (Z_out <= tiltAngle){
//start counting/timer and log to somewhere: log to variable will work but poweroff will reset it. otherwise need ot add microsd/database/etc. refer to "WhileLoopWithLED (L17) project"
Wire.beginTransmission(ADXL345);
Wire.write(0x32); // Start with register 0x32 (ACCEL_XOUT_H)
Wire.endTransmission(false);
Wire.requestFrom(ADXL345, 6, true); // Read 6 registers total, each axis value is stored in 2 registers
X_out = ( Wire.read()| Wire.read() << 8); // X-axis value
X_out = X_out/256; //For a range of +-2g, we need to divide the raw values by 256, according to the datasheet
Y_out = ( Wire.read()| Wire.read() << 8); // Y-axis value
Y_out = Y_out/256;
Z_out = ( Wire.read()| Wire.read() << 8); // Z-axis value
Z_out = Z_out/256;
//Need to get the delay math OR the "-1" match correct on pours. How many seconds of the tilt being in the correct zone correlates to an ounce.
//This assumes 1 ounce is pourced per second.
ouncesRemaining=(ouncesRemaining - 1);
tempPour=(tempPour + 1);
lastPour=tempPour;
delay(dlyBeerPour);
}
//Reset tempPour (keep lastPour)
tempPour=0;
//delay(500);
//Convert ounces to beers, pints, and percentage of keg remaining
beersRemaining=(ouncesRemaining/12);
pintsRemaining=(ouncesRemaining/16);
kegRemaining=((float)ouncesRemaining/kegSize * 100); //*new, changed hardcoded 992 to kegSize
}
/*
Since CloudSwitch is READ_WRITE variable, onCloudSwitchChange() is
executed every time a new value is received from IoT Cloud.
void onCloudSwitchChange() {
if (cloudSwitch == 1){
Serial.println("Sixth/Pony");
ouncesRemaining=maxPony;
kegSize=maxPony;
}
else if (cloudSwitch == 2){
Serial.println("Quarter");
ouncesRemaining=maxQuarter;
kegSize=maxQuarter;
}
else if (cloudSwitch == 3){
Serial.println("Half");
ouncesRemaining=maxHalf;
kegSize=maxHalf;
}
else {
Serial.println("Can't connect to cloud. Setting to Pony"); //Can't connect to internet, set to pony as defeault
ouncesRemaining=maxPony;
kegSize=maxPony;
}
}
*/
void oledDisplayCenter(String text) {
int16_t x1;
int16_t y1;
uint16_t width;
uint16_t height;
display.getTextBounds(text, 0, 0, &x1, &y1, &width, &height);
// display on horizontal and vertical center
display.clearDisplay(); // clear display
display.setCursor((SCREEN_WIDTH - width) / 2, (SCREEN_HEIGHT - height) / 2);
display.println(text); // text to display
display.display();
}