Fall detection using MPU6050 and sim900a

493 views Asked by At

I am trying to make fall detection using MPU6050, SIM900a, and Arduino Nano. after uploading the code to Arduino, the serial monitor show me this: serial monitor output

this is the code that I have tried,

 #include <SoftwareSerial.h> // Library for using software serial communication
    
    //______________________sms part_____________________________________________
    
    SoftwareSerial SIM900(7, 8); // rx, tx
    char c = ' '; // variable to store the data from the sms module 
    
    //_______________________MPU part_______________________________________________________
    #include <Wire.h>
    const int MPU_addr=0x68;  // I2C address of the MPU-6050
    int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;
    float ax=0, ay=0, az=0, gx=0, gy=0, gz=0;
    
    //int data[STORE_SIZE][5]; //array for saving past data
    //byte currentIndex=0; //stores current data array index (0-255)
    boolean fall = false; //stores if a fall has occurred
    boolean trigger1=false; //stores if first trigger (lower threshold) has occurred
    boolean trigger2=false; //stores if second trigger (upper threshold) has occurred
    boolean trigger3=false; //stores if third trigger (orientation change) has occurred
    
    byte trigger1count=0; //stores the counts past since trigger 1 was set true
    byte trigger2count=0; //stores the counts past since trigger 2 was set true
    byte trigger3count=0; //stores the counts past since trigger 3 was set true
    int angleChange=0;
    
    void setup(){
      randomSeed(analogRead(0));
      Serial.begin(9600);// baudrate for serial monitor
        while (!Serial) {
        ; // wait for serial port to connect. Needed for Native USB only
      }
       
      SIM900.begin(9600); // baudrate for GSM shield
      Serial.println(" Logging time completed!");
      delay(1000); // wait for 5 seconds
      
      Wire.begin();
      Wire.beginTransmission(MPU_addr);
      Wire.write(0x6B);  // PWR_MGMT_1 register
      Wire.write(0);     // set to zero (wakes up the MPU-6050)
      Wire.endTransmission(true);
     
    }
    
    void loop(){
    
    //______________________________________MPU_________________________________________
      mpu_read();
      //2050, 77, 1947 are values for calibration of accelerometer
      // values may be different for you
      ax = (AcX-2050)/16384.00;
      ay = (AcY-77)/16384.00;
      az = (AcZ-1947)/16384.00;
    
      //270, 351, 136 for gyroscope
      gx = (GyX+270)/131.07;
      gy = (GyY-351)/131.07;
      gz = (GyZ+136)/131.07;
    
    
      // calculating Amplitute vactor for 3 axis
      float Raw_AM = pow(pow(ax,2)+pow(ay,2)+pow(az,2),0.5);
      int AM = Raw_AM * 10;  // as values are within 0 to 1, I multiplied 
                             // it by for using if else conditions 
    
     Serial.println(AM);
     //Serial.println(PM);
     //delay(500);
    
       if (trigger3==true){
         trigger3count++;
         //Serial.println(trigger3count);
         if (trigger3count>=10){ 
            angleChange = pow(pow(gx,2)+pow(gy,2)+pow(gz,2),0.5);
            //delay(10);
            Serial.println(angleChange); 
            if ((angleChange>=0) && (angleChange<=10)){ //if orientation changes remains between 0-10 degrees
                fall=true; trigger3=false; trigger3count=0;
                Serial.println(angleChange);
                  }
            else{ //user regained normal orientation
               trigger3=false; trigger3count=0;
               Serial.println("TRIGGER 3 DEACTIVATED");
            }
          }
       }
      if (fall==true){ //in event of a fall detection
        Serial.println("FALL DETECTED");
        MakeCall;
        delay(100000);
      
        fall=false;
       // exit(1);
        }
        
      if (trigger2count>=6){ //allow 0.5s for orientation change
        trigger2=false; trigger2count=0;
        Serial.println("TRIGGER 2 DECACTIVATED");
        }
      if (trigger1count>=6){ //allow 0.5s for AM to break upper threshold
        trigger1=false; trigger1count=0;
        Serial.println("TRIGGER 1 DECACTIVATED");
        }
      if (trigger2==true){
        trigger2count++;
        //angleChange=acos(((double)x*(double)bx+(double)y*(double)by+(double)z*(double)bz)/(double)AM/(double)BM);
        angleChange = pow(pow(gx,2)+pow(gy,2)+pow(gz,2),0.5); Serial.println(angleChange);
        if (angleChange>=30 && angleChange<=400){ //if orientation changes by between 80-100 degrees
          trigger3=true; trigger2=false; trigger2count=0;
          Serial.println(angleChange);
          Serial.println("TRIGGER 3 ACTIVATED");
            }
        }
      if (trigger1==true){
        trigger1count++;
        if (AM>=12){ //if AM breaks upper threshold (3g)
          trigger2=true;
          Serial.println("TRIGGER 2 ACTIVATED");
          trigger1=false; trigger1count=0;
          }
        }
      if (AM<=2 && trigger2==false){ //if AM breaks lower threshold (0.4g)
        trigger1=true;
        Serial.println("TRIGGER 1 ACTIVATED");
        }
    //It appears that delay is needed in order not to clog the port
      delay(100);
    }
    
    //______________________________MPU raeding________________________
    
    void mpu_read(){
      Wire.beginTransmission(MPU_addr);
      Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
      Wire.endTransmission(false);
      Wire.requestFrom(MPU_addr,14,true);  // request a total of 14 registers
      AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)    
      AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
      AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
      Tmp=Wire.read()<<8|Wire.read();  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)  
      GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
      GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
      GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
      }
    
    
    //______________________________________GSM module calling function________________
     
    void MakeCall()
    {
       SIM900.println("ATD+*********;"); // ATDxxxxxxxxxx; -- watch out here for semicolon at the end!!
      Serial.println("Calling  "); // print response over serial port
      delay(20000); //wait 
    }

the configuration of MPU050

VCC --- 5V in arduino
GND ----GND
SCL ----A5
SDA----A4
INT ----- D2

The serial monitor should show some numbers first but instead of showing numbers trigger 1 activated and disactivate automatically and I didn't even touch it . No matter how much I throw the MPU6050, trigger 2 and 3 are not activated. all the three trigger must be activated to make the sim900a module make a call.

what could be the reason ? could be the code or the hardware connection. here is a picture of the MPU position in case it could be the problem. MPU6050 position

edit: i have tried this code but all the values show zero values

 #include <MPU6050.h>

/*
    MPU6050 Triple Axis Gyroscope & Accelerometer. Simple Gyroscope Example.
    Read more: http://www.jarzebski.pl/arduino/czujniki-i-sensory/3-osiowy-zyroskop-i-akcelerometr-mpu6050.html
    GIT: https://github.com/jarzebski/Arduino-MPU6050
    Web: http://www.jarzebski.pl
    (c) 2014 by Korneliusz Jarzebski
*/

#include <Wire.h>


MPU6050 mpu;

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

  // Initialize MPU6050
  Serial.println("Initialize MPU6050");
  while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
  {
    Serial.println("Could not find a valid MPU6050 sensor, check wiring!");
    delay(500);
  }
  
  // If you want, you can set gyroscope offsets
  // mpu.setGyroOffsetX(155);
  // mpu.setGyroOffsetY(15);
  // mpu.setGyroOffsetZ(15);
  
  // Calibrate gyroscope. The calibration must be at rest.
  // If you don't want calibrate, comment this line.
  mpu.calibrateGyro();

  // Set threshold sensivty. Default 3.
  // If you don't want use threshold, comment this line or set 0.
  mpu.setThreshold(3);
  
  // Check settings
  checkSettings();
}

void checkSettings()
{
  Serial.println();
  
  Serial.print(" * Sleep Mode:        ");
  Serial.println(mpu.getSleepEnabled() ? "Enabled" : "Disabled");
  
  Serial.print(" * Clock Source:      ");
  switch(mpu.getClockSource())
  {
    case MPU6050_CLOCK_KEEP_RESET:     Serial.println("Stops the clock and keeps the timing generator in reset"); break;
    case MPU6050_CLOCK_EXTERNAL_19MHZ: Serial.println("PLL with external 19.2MHz reference"); break;
    case MPU6050_CLOCK_EXTERNAL_32KHZ: Serial.println("PLL with external 32.768kHz reference"); break;
    case MPU6050_CLOCK_PLL_ZGYRO:      Serial.println("PLL with Z axis gyroscope reference"); break;
    case MPU6050_CLOCK_PLL_YGYRO:      Serial.println("PLL with Y axis gyroscope reference"); break;
    case MPU6050_CLOCK_PLL_XGYRO:      Serial.println("PLL with X axis gyroscope reference"); break;
    case MPU6050_CLOCK_INTERNAL_8MHZ:  Serial.println("Internal 8MHz oscillator"); break;
  }
  
  Serial.print(" * Gyroscope:         ");
  switch(mpu.getScale())
  {
    case MPU6050_SCALE_2000DPS:        Serial.println("2000 dps"); break;
    case MPU6050_SCALE_1000DPS:        Serial.println("1000 dps"); break;
    case MPU6050_SCALE_500DPS:         Serial.println("500 dps"); break;
    case MPU6050_SCALE_250DPS:         Serial.println("250 dps"); break;
  } 
  
  Serial.print(" * Gyroscope offsets: ");
  Serial.print(mpu.getGyroOffsetX());
  Serial.print(" / ");
  Serial.print(mpu.getGyroOffsetY());
  Serial.print(" / ");
  Serial.println(mpu.getGyroOffsetZ());
  
  Serial.println();
}

void loop()
{
  Vector rawGyro = mpu.readRawGyro();
  Vector normGyro = mpu.readNormalizeGyro();

  Serial.print(" Xraw = ");
  Serial.print(rawGyro.XAxis);
  Serial.print(" Yraw = ");
  Serial.print(rawGyro.YAxis);
  Serial.print(" Zraw = ");
  Serial.println(rawGyro.ZAxis);

  Serial.print(" Xnorm = ");
  Serial.print(normGyro.XAxis);
  Serial.print(" Ynorm = ");
  Serial.print(normGyro.YAxis);
  Serial.print(" Znorm = ");
  Serial.println(normGyro.ZAxis);
  
  delay(10);
}

what could be the reason?

0

There are 0 answers