zinnet yazıcı
/
BMA220
j
bma220.cpp
- Committer:
- zinnetyazicii53
- Date:
- 2019-08-25
- Revision:
- 0:d861e7a56281
File content as of revision 0:d861e7a56281:
#include "bma220.h" I2C i2c(I2C_SDA, I2C_SCL); Serial dbug(USBTX, USBRX); BMA220::BMA220(){ G[0].Ax=0; G[0].Ay=0; G[0].Az=0; } bool BMA220::begin(void){ resetvalue=readRegister(SOFTRESET_REG); // change mode if (resetvalue == 0xFF) { // was in reset mode, is in operation mode now resetvalue = readRegister(SOFTRESET_REG); // sensor should be in reset mode now } if (resetvalue != 0x00) { return false; } // sensor should be in reset mode resetvalue = readRegister(SOFTRESET_REG); if (resetvalue != 0xFF) { // sensor was not in reset mode return false; } return true; } bool BMA220::set(uint8_t reg, uint8_t value){ char ach_i2c_data[2]; ach_i2c_data[0]=reg; ach_i2c_data[1]=value; if(i2c.write(BMA220_ADDR, ach_i2c_data, 2, false)==0) return true; else return false; } bool BMA220::read(uint8_t reg, uint8_t *pvalue){ char data=reg; if(i2c.write(BMA220_ADDR, &data, 1, true)!=0) return false; if(i2c.read(BMA220_ADDR, &data, 1, false)==0) { *pvalue=(uint8_t) data; return true; } else return false; } void BMA220::setRegister(uint8_t reg, uint8_t value){ if(set(reg, value)){return;} dbug.printf("Error: Register Not Set\n"); } int8_t BMA220::readRegister(uint8_t reg){ uint8_t pvalue; char data=reg; i2c.read(BMA220_ADDR, &data, 1); pvalue=(uint8_t) data; if(read(reg, &pvalue)){return pvalue;} dbug.printf("Error: Register Not read\n"); return pvalue; } void BMA220::readAcceleration(int sensitivity){ G[1].Ax=G[0].Ax; G[1].Ay=G[0].Ay; G[1].Az=G[0].Az; //Acc After= Acc Before this->Ax=((float)readRegister(XAXIS))/sensitivity; this->Ay=((float)readRegister(YAXIS))/sensitivity; this->Az=((float)readRegister(ZAXIS))/sensitivity; // Calculate Roll and Pitch (rotation around X-axis, rotation around Y-axis) // Pitch (rho) is defined as the angle of the X-axis relative to ground. Roll (phi) is defined as the angle of the Y-axis relative to the ground. Theta is the angle of the Z axis relative to gravity.” int r= atan(Ay / sqrt(pow(Ax, 2) + pow(Az, 2)))*180/PI; int p= atan(Ax / sqrt(pow(Ay, 2) + pow(Az, 2)))*180/PI; int t=atan(sqrt(pow(Ax, 2) + pow(Ay, 2))/Az)*180/PI; // Low-pass filter this->roll=r;//(0.94*this->roll)+0.06*r; this->pitch=p;//(0.94*this->pitch)+0.06*p; this->theta=t;//(0.94*this->theta)+0.06*t; G[0].Ax=Ax; G[0].Ay=Ay; G[0].Az=Az; //Acc Before=Present Acc FallDetection(); } void BMA220::FallDetection(){ Calculate_Q1(); Calculate_Q2(); Calculate_Q3(); /*Serial.println("Q0: "); display(Quanterion_2_Matrix(this->Q[0])); Serial.println("Q1: "); display(Quanterion_2_Matrix(this->Q[1])); Serial.println("Q2: "); display(Quanterion_2_Matrix(this->Q[2]));*/ std::vector<std::vector<float> > Q; Q.resize(4, std::vector<float>(4)); Q=MatrixMult(MatrixMult(Quanterion_2_Matrix(this->Q[0]), Quanterion_2_Matrix(this->Q[1])), Quanterion_2_Matrix(this->Q[2])); this->Q_result1.q0=Q[0][0]; this->Q_result1.q1=Q[1][0]; this->Q_result1.q2=Q[2][0]; this->Q_result1.q3=Q[3][0]; this->Q_result2.q0=Q[3][3]; this->Q_result2.q1=-1*Q[2][3]; this->Q_result2.q2=Q[1][3]; this->Q_result2.q3=-1*Q[0][3]; //result1.display(); //result2.display(); } void BMA220::Calculate_Q1(){ float theta1=atan(G[0].Az/ sqrt(pow(G[0].Ax, 2) + pow(G[0].Ay, 2)))*180/PI; float sin_alpha=(-1*(G[0].Ay/ sqrt(pow(G[0].Ax, 2) + pow(G[0].Ay, 2))))*180/PI; float cos_alpha=(G[0].Ax/ sqrt(pow(G[0].Ax, 2) + pow(G[0].Ay, 2)))*180/PI; this->Q[0].q0=cos(theta1/2); this->Q[0].q1=sin(theta1/2)*sin_alpha; this->Q[0].q2=sin(theta1/2)*cos_alpha; this->Q[0].q3=0; } void BMA220::Calculate_Q2(){ float theta2=(atan((2*G[1].Ay)/G[1].Ax)-atan((2*G[0].Ay)/G[0].Ax))*180/PI; this->Q[1].q0=cos(theta2/2); this->Q[1].q1=0; this->Q[1].q2=0; this->Q[1].q3=sin(theta2/2); } void BMA220::Calculate_Q3(){ float theta3=-1*atan(G[1].Az/ sqrt(pow(G[1].Ax, 2) + pow(G[1].Ay, 2)))*180/PI; float sin_beta=(-1*(G[1].Ay/ sqrt(pow(G[1].Ax, 2) + pow(G[1].Ay, 2))))*180/PI; float cos_beta=(G[1].Ax/ sqrt(pow(G[1].Ax, 2) + pow(G[1].Ay, 2)))*180/PI; this->Q[2].q0=cos(theta3/2); this->Q[2].q1=sin(theta3/2)*sin_beta; this->Q[2].q2=sin(theta3/2)*cos_beta; this->Q[2].q3=0; } std::vector<std::vector<float> > BMA220::Quanterion_2_Matrix(const Quanterion &Q){ std::vector<std::vector<float> > result; result.resize(4, std::vector<float>(4)); result[0][0]=Q.q0; result[0][1]=-1*Q.q1; result[0][2]=-1*Q.q2; result[0][3]=-1*Q.q3; result[1][0]=Q.q1; result[1][1]=Q.q0; result[1][2]=-1*Q.q3; result[1][3]=-1*Q.q2; result[2][0]=Q.q2; result[2][1]=Q.q3; result[2][2]=Q.q0; result[2][3]=-1*Q.q1; result[3][0]=Q.q3; result[3][1]=-1*Q.q2; result[3][2]=Q.q1; result[3][3]=Q.q0; return result; } float BMA220::getAcceleration_X() const{ return Ax; } float BMA220::getAcceleration_Y() const{ return Ay; } float BMA220::getAcceleration_Z() const{ return Az; } float BMA220::getPitch() const{ return pitch; } float BMA220::getRoll() const{ return roll; } float BMA220::getTheta() const{ return theta; } float BMA220::getMag() const{ return sqrt(pow(Ax, 2) + pow(Ay, 2)+ pow(Az, 2)); } void BMA220::reset(void) {; resetvalue = readRegister(SOFTRESET_REG); if (resetvalue == 0x00){ // BMA220 is in reset mode now. Reading soft reset register // again, brings the sensor back to operation mode. resetvalue = readRegister(SOFTRESET_REG); } }