I'm been racking my brain at this for hours and cannot figure out why this behavior is happening. For what it's worth, I am pretty new to Arduino. I have a program that keeps track of how many beers are left in a keg by using an accelerometer attached on the tap handle. When it is in a certain range, the program starts counting down the ounces remaining in the keg. This is output on a 16x2 LCD screen. This part all works well.
Where I am struggling is to get a "lastPour" value. I am trying to see how many ounces are being poured while in the while loop. This sounds really easy but for some reason it's not working. What seems to be happening is the program does not stay in the while loop. It instead runs the program loop (as well as the the while loop) over and over. It doesn't stay in the while loop even though the "Z_out" value is staying in the right value to keep it in the while loop. The only reason I can think of is because I am using I2C for the acceleromter and the LCD display and the Arduino can't read from the accelerometer while displaying values to the LCD screen at the same time and therefore the accelerometer Z_out value is being reset somehow. That or there is an issue with the hardware. I don't know.
The program, without going into the while loop shows this on serial output (which is normal):
Xa= 0.02 Ya= -0.04 Z_out: 0.95
RESET TRIGGERED
Z Out outside of loop: 0.95
Last pour: 1
However, the program, while going into the while loop and keeping the accelerometer at the value in which the while loop should NOT be breaking (e.g. the Z_out value is staying at -.50 or so), the program sees Z_out as 1.00 and continues to run the entire program in a loop, breaking the while loop. I am not sure why the Z_out is being reset to 1.0 in the while loop, when it is clearly showing the correct value before and after the while loop finishes.
Xa= 0.03 Ya= 0.05 Z_out: 0.96
RESET TRIGGERED
Z Out outside of loop: 0.96
Last pour: 1
Xa= 1.01 Ya= -0.22 Z_out: 0.06
Temp pour: 1
Z Out in loop: 1.00
RESET TRIGGERED
Z Out outside of loop: 1.00
Last pour: 1
Xa= 0.89 Ya= -0.28 Z_out: -0.50
Temp pour: 1
Z Out in loop: 1.00
RESET TRIGGERED
Z Out outside of loop: 1.00
Last pour: 1
Xa= 0.90 Ya= -0.27 Z_out: -0.54
Here is the actual program:
//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;
float tiltAngle=0.1;
int ouncesRemaining = 992;
int maxPony = 992;
int tempPour = 0;
int lastPour = 0;
int beersRemaining;
int pintsRemaining;
float kegRemaining = 100;
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
void setup() {
lcd.begin();
Serial.begin(9600);
Wire.begin(); //Initate wire library
//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);
}
void loop() {
// ===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;
// Prints out accelerometer stats to serial
Serial.print("Xa= ");
Serial.print(X_out);
Serial.print(" Ya= ");
Serial.print(Y_out);
Serial.print(" Z_out: "); //This is the measurement we want
Serial.println(Z_out);
delay(150);
//LCD Display Setup
//Top row, left: ounces remaining
if (ouncesRemaining == maxPony){
lcd.setCursor(0,0);
lcd.print("Oz: ");
lcd.setCursor(3,0);
lcd.print(maxPony);
}
else if (ouncesRemaining <= 99 && ouncesRemaining >=10){
lcd.setCursor(0,0);
lcd.print("Oz: ");
lcd.setCursor(5,0);
lcd.print(" ");
lcd.setCursor(3,0);
lcd.print(ouncesRemaining);
}
else if (ouncesRemaining <= 9 && ouncesRemaining >=1){
lcd.setCursor(0,0);
lcd.print("Oz: ");
lcd.setCursor(4,0);
lcd.print(" ");
lcd.setCursor(3,0);
lcd.print(ouncesRemaining);
}
else if (ouncesRemaining <= 0){
lcd.setCursor(4,0);
lcd.print(" ");
lcd.setCursor(3,0);
lcd.print("0");
}
else {
lcd.setCursor(0,0);
lcd.print("Oz: ");
lcd.setCursor(5,0);
lcd.print(" ");
lcd.setCursor(3,0);
lcd.print(ouncesRemaining);
}
//Bottom row, left: pints left
if (pintsRemaining <= 99 && pintsRemaining >=10){
lcd.setCursor(0,1);
lcd.print("Pints: ");
lcd.setCursor(6,1);
lcd.print(pintsRemaining);
}
else if (pintsRemaining <= 9 && pintsRemaining >=1){
lcd.setCursor(0,1);
lcd.print("Pints: ");
lcd.setCursor(7,1);
lcd.print(" ");
lcd.setCursor(6,1);
lcd.print(pintsRemaining);
}
else if (pintsRemaining <= 0){
lcd.setCursor(7,1);
lcd.print(" ");
lcd.setCursor(6,1);
lcd.print("0");
}
else{
lcd.setCursor(0,1);
lcd.print("Pints: ");
lcd.setCursor(6,1);
lcd.print(pintsRemaining);
}
//Top row, right: keg remaining (percent)
if (kegRemaining == 100){
lcd.setCursor(12,0);
lcd.print(kegRemaining);
lcd.setCursor(15,0);
lcd.print("%");
}
else if (kegRemaining <= 99 && kegRemaining >=10){
lcd.setCursor(12,0); //Clear leftover 1 from 100%
lcd.print(" "); //Clear leftover 1 from 100%
lcd.setCursor(13,0); //Top row, right, percent of keg left
lcd.print(kegRemaining);
lcd.setCursor(15,0);
lcd.print("%");
}
else if (kegRemaining <= 9 && kegRemaining >=1){
lcd.setCursor(13,0); //Clear leftovers from double digits
lcd.print(" "); //Clear leftovers from double digits
lcd.setCursor(14,0); //Top row, right, percent of keg left
lcd.print(kegRemaining);
lcd.setCursor(15,0);
lcd.print("%");
}
else if (kegRemaining == 0){
//Don't go into negatives
lcd.setCursor(14,0); //Top row, right, percent of keg left
lcd.print("0");
}
delay(250);
while (Z_out <= tiltAngle){
Wire.requestFrom(ADXL345, 6, true); // Read 6 registers total, each axis value is stored in 2 registers
Z_out = ( Wire.read()| Wire.read() << 8); // Z-axis value
Z_out = Z_out/256;
ouncesRemaining=(ouncesRemaining - 1);
tempPour=(tempPour + 1);
lastPour=tempPour;
//These prints are for troubleshooting
Serial.print("Temp pour: "); //Should always be 0 since gets reset after while loop
Serial.println(tempPour);
Serial.print("Z Out in loop: "); //Should always be 0 since gets reset after while loop
Serial.println(Z_out);
delay(dlyBeerPour);
}
//Reset tempPour
tempPour=0;
//Prints for troublsehooting
Serial.println("RESET TRIGGERED ");
Serial.print("Z Out outside of loop: "); //Should always be 0 since gets reset after while loop
Serial.println(Z_out);
Serial.print("Last pour: ");
Serial.println(lastPour);
delay(1000);
//Convert ounces to beers, pints, and percentage of keg remaining
beersRemaining=(ouncesRemaining/12);
pintsRemaining=(ouncesRemaining/16);
kegRemaining=((float)ouncesRemaining/992 * 100);
}