#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
#define CALIBRATION_DATA_VOLUME 3// 校准时读入多少个数据
#define ALPHA 0.9 // 定义一个常数,用于低通滤波器的权重

// 定义一个类,用于操作MPU6050
class MPU6050 {
 private:
    Adafruit_MPU6050 *myMpu;// 定义一个指针,指向Adafruit_MPU6050对象
    float base_x, base_y, base_z;// 定义一个变量,用于存储基准加速度方向
    float angle_threshold = 0.5;// 定义一个变量,用于设置夹角的阈值(单位为弧度)
    float filtered_x, filtered_y, filtered_z; // 定义一个变量,用于存储滤波后的加速度方向
  public:
    // 构造函数,传入一个Adafruit_MPU6050对象
    MPU6050(Adafruit_MPU6050 &mpu) {
      myMpu = &mpu;
    }

    // 初始化函数,返回是否成功
    bool begin() {
      // 初始化mpu模块
      if (!myMpu->begin()) {
        Serial.println("Failed to start MPU6050");
        return false;
      }
      // 设置加速度计量程为+-8G
      myMpu->setAccelerometerRange(MPU6050_RANGE_8_G);
      // 设置陀螺仪量程为+-500度/秒
      myMpu->setGyroRange(MPU6050_RANGE_500_DEG);
      // 设置滤波器带宽为21Hz
      myMpu->setFilterBandwidth(MPU6050_BAND_21_HZ);
      // 调用calibrate函数,计算并存储基准加速度方向
      calibrate();
      return true;
    }

    // 检测函数,返回是否倒地
    bool detect() {
      // 获取加速度计数据
      sensors_event_t a, g, temp;
      myMpu->getEvent(&a, &g, &temp);
      // 计算加速度向量和基准向量的夹角(单位为弧度)
      float angle = acos((a.acceleration.x * base_x + a.acceleration.y * base_y + a.acceleration.z * base_z) / (sqrt(a.acceleration.x * a.acceleration.x + a.acceleration.y * a.acceleration.y + a.acceleration.z * a.acceleration.z) * sqrt(base_x * base_x + base_y * base_y + base_z * base_z)));
      // 判断是否倒地
      if (angle > angle_threshold) {
        Serial.println("yes!");
        return true;
      } else {
        Serial.println("No!");
        return false;
      }
    }

 

    // 定义一个函数,用于计算并存储基准加速度方向
    void calibrate() {
      // 初始化base_x, base_y, base_z为0
      base_x = 0;
      base_y = 0;
      base_z = 0;

      // 获取CALIBRATION_DATA_VOLUM次加速度计数据,每次间隔0.1s,并累加到base_x, base_y, base_z中
      for (int i = 0; i < CALIBRATION_DATA_VOLUME; i++) {
        sensors_event_t a, g, temp;
        myMpu->getEvent(&a, &g, &temp);
        base_x += a.acceleration.x;
        base_y += a.acceleration.y;
        base_z += a.acceleration.z;
        delay(100);
      }

      // 计算base_x, base_y, base_z的平均值,并存储在base_x, base_y, base_z中
      base_x /= CALIBRATION_DATA_VOLUME;
      base_y /= CALIBRATION_DATA_VOLUME;
      base_z /= CALIBRATION_DATA_VOLUME;
    }

    bool detecte(){
        sensors_event_t a, g, temp;
        myMpu->getEvent(&a, &g, &temp);
        // 计算加速度向量和基准向量的夹角(单位为弧度)
        float angle = acos((a.acceleration.x * base_x + a.acceleration.y * base_y + a.acceleration.z * base_z) / (sqrt(a.acceleration.x * a.acceleration.x + a.acceleration.y * a.acceleration.y + a.acceleration.z * a.acceleration.z) * sqrt(base_x * base_x + base_y * base_y + base_z * base_z)));
        // 判断是否倒地
        if (angle > angle_threshold) {
          Serial.println("Fall detected");
          return 1;
        } else {
          Serial.println("Stand detected");
          return 0;
        }
    }
};




Adafruit_MPU6050 mpu;
MPU6050 myMpu(mpu);




void setup() {
  Serial.begin(115200);
  myMpu.begin();
}

void loop() {
  // 获取加速度计数据
  myMpu.detecte();
  delay(500);
}


$abcdeabcde151015202530354045505560fghijfghij
esp:VIN
esp:GND.2
esp:D13
esp:D12
esp:D14
esp:D27
esp:D26
esp:D25
esp:D33
esp:D32
esp:D35
esp:D34
esp:VN
esp:VP
esp:EN
esp:3V3
esp:GND.1
esp:D15
esp:D2
esp:D4
esp:RX2
esp:TX2
esp:D5
esp:D18
esp:D19
esp:D21
esp:RX0
esp:TX0
esp:D22
esp:D23
vcc1:VCC
gnd1:GND
vcc2:VCC
gnd2:GND
imu1:INT
imu1:AD0
imu1:XCL
imu1:XDA
imu1:SDA
imu1:SCL
imu1:GND
imu1:VCC
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r