Sketch stops measuring angle

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);
    }
  }

}

@Patty0465, your topic has been moved to a more suitable location on the forum.

You might be hanging the i2c bus. If there is noise, it can get in a stuck state and block indefinitely. A reset/power cycle should clear it. The latest version of the wire library does have a timeout feature you could use. You should also be checking the return value of endTransmission() to make sure it was successful. Sprinkle in a few debug print statements (or put them on the LCD if not connected to your PC)

This code is complete nonsense, but unfortunately, can be found in many places on the web.

  // 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);

I recommend this tutorial for measuring pitch and roll angles.

Thanks bih64
a reset or power off does not solve the problem I have to load another sketch and then load this one that keeps freezing. Im using Cat5 and only 12 feet of wire

This page How to reliably restart Arduino when connected to a battery backed RTC (real time clock) module covers how to check you IC2 bus is not blocked

Only 12 Feet? Yikes. I2C should be measures in inches/mm. For more reliability, you might consider adding chips to boost the signal.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.