Im using a mega, I2C LCD, motion sensor, MPU-6050
Sketch measures the angle converts it to a percentage and displays it on the LCD but only after motion senser's out pin goes high
Problem is after a few hours it will stop reading the angle. Ive tried a button reset on the mega ive unplugged power still no change
I have found If I upload another sketch then upload this one it will start working.
Whats going on
*/
#include<Wire.h>
#include <LiquidCrystal_I2C.h>
#define MPU_addr 0x68
#define LCD_addr 0X3F
#define MOTION_SENSOR_PIN A0 // Set it to an actual pin;
LiquidCrystal_I2C lcd(0x3f, 16, 2);
const int motionThreshold = 512; // Adjust it to your needs (lower -> easier to trig; higher (1024 max) -> harder to trig)
const int lowerAngle = 5; // Angle corresponding to 0%
const int upperAngle = 30; // Angle corresponding to 100%
const int angleCorrection = 0; // This value 'll be added to an angle read
const long updateRate = 1000; // Time between updates of the information on the LCD while its ON (in milliseconds); set to -1 if you don't want it to be updated
const long displayTime = 1ul * 60ul * 1000ul; // How long to keep the LCD ON (in milliseconds)
int currentAngle = 0;
bool isActive = false;
long activeTimer = 0;
long updateTimer = 0;
long debugTimer = 0;
void configureMPU() {
Wire.begin();
Wire.beginTransmission(MPU_addr);
Wire.write(0x68);
Wire.write(0);
Wire.endTransmission(true);
}
bool checkMotion() {
return analogRead(MOTION_SENSOR_PIN) >= motionThreshold;
}
void updateData() {
currentAngle = getXAngle() + angleCorrection; // Read, adjust and save the latest data
}
int getXAngle() {
const int minVal = 265;
const int maxVal = 402;
int16_t AcX, AcY, AcZ, Tmp, GyX, GyY, GyZ;
// Sending a erquest
Wire.beginTransmission(MPU_addr);
Wire.write(0x3B);
Wire.endTransmission(false);
Wire.requestFrom(MPU_addr, 14, true);
// Reading the current values
AcX = Wire.read() << 8 | Wire.read();
AcY = Wire.read() << 8 | Wire.read();
AcZ = Wire.read() << 8 | Wire.read();
// Mapping from raw values to degrees
int xAng = map(AcX, minVal, maxVal, -90, 90);
int yAng = map(AcY, minVal, maxVal, -90, 90);
int zAng = map(AcZ, minVal, maxVal, -90, 90);
// Extracting an angle of interest
return RAD_TO_DEG * (atan2(-yAng, -zAng) + PI);
}
void displayData(int angle) {
lcd.clear();
int value = map(angle, lowerAngle, upperAngle, 0, 100);
value = value > 200 ? 0 : constrain(value, 0, 200);
// Header
lcd.setCursor(0, 0);
lcd.print("Shit Level");
// Information
lcd.setCursor(0, 1);
lcd.print("Midnight ");
lcd.print(value);
lcd.print("%");
// Print to the serial too
Serial.println("Level " + String(angle));
}
void setup() {
Serial.begin(9600);
// Setup the LCD
lcd.init();
lcd.noDisplay();
lcd.noBacklight();
configureMPU();
}
void loop() {
if (millis() - debugTimer >= 5000) {
debugTimer = millis();
}
if (!isActive && checkMotion()) { // If everything is OFF and motion detected
isActive = true; // Update the flag
// Reset timers
activeTimer = millis();
updateTimer = millis();
// Read and dispay the current data
lcd.display();
lcd.backlight();
updateData();
displayData(currentAngle);
}
if (isActive) { // If the system is ON
if (millis() - activeTimer >= displayTime) { // Check if the time is up and turn everything OFF
isActive = false; // Update the flag
lcd.noDisplay(); // Disable the LCD
lcd.noBacklight();
return; // Exit the current cycle to prevent unnecessary data updates
}
if (updateRate != -1 && millis() - updateTimer >= updateRate) { // Check if its time to update the data
updateTimer = millis(); // Reset the corresponding timer
// Read and dispay the current data
updateData();
displayData(currentAngle);
}
}
}