Dezibot 4
MotionDetection.cpp
Go to the documentation of this file.
1 #include "MotionDetection.h"
2 #include <math.h>
3 
5  handler = new SPIClass(FSPI);
6 };
7 
9  pinMode(34,OUTPUT);
10  digitalWrite(34,HIGH);
11  handler->begin(36,37,35,34);
12  // set Accel and Gyroscop to Low Noise
13  this->writeRegister(PWR_MGMT0,0x1F);
14  //busy Wait for startup
15  delayMicroseconds(250);
16  //set accelconfig
17  this->writeRegister(0x21,0x05);
18  //set Gyroconfig
19  this->writeRegister(0x20,0x25);
20  //set Gyro Filter
21  this->writeRegister(0x23,0x37);
22  //Enable Gyro and Acceldata in FIFO
23  this->initFIFO();
24 };
26  this->writeRegister(PWR_MGMT0,0x00);
27 };
29  IMUResult result;
33  return result;
34 };
36  IMUResult result;
37  result.x = readRegister(GYRO_DATA_X_HIGH) <<8;
38  result.x |= readRegister(GYRO_DATA_X_LOW);
39  result.y = readRegister(GYRO_DATA_Y_HIGH)<<8;
40  result.y |= readRegister(GYRO_DATA_Y_LOW);
41  result.z = readRegister(GYRO_DATA_Z_HIGH)<<8;
42  result.z |= readRegister(GYRO_DATA_Z_LOW);
43  return result;
44 };
46  int16_t raw_temperatur = readRegister(REG_TEMP_HIGH)<<8;
47  raw_temperatur |= readRegister(REG_TEMP_LOW);
48  return raw_temperatur/128 +25;
49 };
50 
52  return readRegister(WHO_AM_I);
53 };
54 
55 bool MotionDetection::isShaken(uint32_t threshold ,uint8_t axis){
56  IMUResult measurment1;
57  IMUResult measurment2;
58  uint count = 0;
59  for(uint i = 0;i<20;i++){
60  measurment1 = this->getAcceleration();
61  delayMicroseconds(10);
62  measurment2 = this->getAcceleration();
63  if(
64  (((axis && xAxis) > 0) && (abs(abs(measurment1.x)-abs(measurment2.x))>threshold)) ||
65  (((axis && yAxis) > 0) && (abs(abs(measurment1.y)-abs(measurment2.y))>threshold)) ||
66  (((axis && zAxis) > 0) && (abs(abs(measurment1.z)-abs(measurment2.z))>threshold))){
67  count++;
68  }
69  delayMicroseconds(15);
70  }
71  return (count > 6);
72 };
73 
74 void MotionDetection::calibrateZAxis(uint gforceValue){
75  this->gForceCalib = gforceValue;
76 };
77 
79  uint tolerance = 200;
80  IMUResult reading = this->getAcceleration();
81  bool flipped = reading.z < 0;
82  float accelrationStrenght = sqrt(reading.x*reading.x+reading.y*reading.y+reading.z*reading.z);
83  //check if reading is valid
84  if (abs(accelrationStrenght-this->gForceCalib) > tolerance ){
85  //total accelration is not gravitational force, error
86  return Orientation{INT_MAX,INT_MAX};
87  }
88 
89  //calculates the angle between the two axis, therefore value between 0-90
90  int yAngle;
91  int xAngle;
92  if(reading.z != 0){
93  yAngle = atan(float(reading.x)/reading.z)*180/3.1415+0.5;
94  xAngle = atan(float(reading.y)/reading.z)*180/3.1415+0.5;
95  } else {
96  yAngle = 90*(reading.x > 0) - (reading.x < 0);
97  xAngle = 90*(reading.y > 0) - (reading.y < 0);
98  }
99 
100  //shift quadrants depending on signum
101  //esp is facing down (normal position)
102  if (reading.z > 0){
103  if(reading.y < 0){
104  xAngle = xAngle+180;
105  } else{
106  xAngle = -1*(180-xAngle);
107  }
108 
109  if(reading.x < 0){
110  yAngle = yAngle+180;
111  } else{
112  yAngle = -1*(180-yAngle);
113  }
114  //yAngle = -1*yAngle-90;
115  }
116 
117 
118  return Orientation{xAngle,yAngle};
119 
120 };
121 
123  if (this->getAcceleration().z > 0){
124  return Flipped;
125  }
126  Orientation Rot = this->getTilt();
127  Serial.println(Rot.xRotation);
128  Serial.println(Rot.xRotation == INT_MAX);
129  if ((Rot.xRotation == INT_MAX)){
130  return Error;
131  }
132  if(abs(abs(Rot.xRotation)-abs(Rot.yRotation))>tolerance){
133  //determine which axis is more tiltet
134  if (abs(Rot.xRotation)>abs(Rot.yRotation)){
135  //test if dezibot is tilted left or right
136  if (Rot.xRotation > 0){
137  return Right;
138  } else {
139  return Left;
140  }
141  } else {
142  //test if robot is tilted front or back
143  if (Rot.yRotation > 0){
144  return Front;
145  } else {
146  return Back;
147  }
148  }
149  } else {
150  //dezibot is (with tolerance) leveled
151  return Neutral;
152  }
153 };
154 
155 uint8_t MotionDetection::cmdRead(uint8_t reg){
156  return (CMD_READ | (reg & ADDR_MASK));
157 };
158 uint8_t MotionDetection::cmdWrite(uint8_t reg){
159  return (CMD_WRITE | (reg & ADDR_MASK));
160 };
161 
162 uint8_t MotionDetection::readRegister(uint8_t reg){
163  handler->beginTransaction(SPISettings(frequency,SPI_MSBFIRST,SPI_MODE0));
164  digitalWrite(34,LOW);
165  uint8_t result;
166  result = handler->transfer(cmdRead(reg));
167  result = handler->transfer(0x00);
168  digitalWrite(34,HIGH);
169  handler->endTransaction();
170  return result;
171 };
172 
174  uint8_t result = 0;
175  switch(bank){
176  case(MREG1):
177  this->writeRegister(BLK_SEL_R,0x00);
178  break;
179  case(MREG2):
180  this->writeRegister(BLK_SEL_R,0x28);
181  break;
182  case(MREG3):
183  this->writeRegister(BLK_SEL_R,0x50);
184  break;
185  }
186  this->writeRegister(MADDR_R,reg);
187  delayMicroseconds(10);
188  result=this->readRegister(M_R);
189  delayMicroseconds(10);
190  this->resetRegisterBankAccess();
191  return result;
192 };
193 
194 void MotionDetection::writeToRegisterBank(registerBank bank, uint8_t reg, uint8_t value){
195  while((this->readRegister(MCLK_RDY))&0x08!=0x08){
196  Serial.println("CLK not rdy");
197  delay(100);
198  }
199  uint8_t result = this->readRegister(PWR_MGMT0);
200  Serial.print("MADDR_W: ");
201  Serial.println(readRegister(MADDR_W));
202  //set Idle Bit
203  this->writeRegister(PWR_MGMT0,result|0x10);
204  switch(bank){
205  case(MREG1):
206  this->writeRegister(BLK_SEL_W,0x00);
207  break;
208  case(MREG2):
209  this->writeRegister(BLK_SEL_W,0x28);
210  break;
211  case(MREG3):
212  this->writeRegister(BLK_SEL_W,0x50);
213  break;
214  }
215  this->writeRegister(MADDR_W,reg);
216  this->writeRegister(M_W,value);
217  delayMicroseconds(10);
218  this->writeRegister(PWR_MGMT0,result&0xEF);
219  Serial.print("MADDR_W: ");
220  Serial.println(readRegister(MADDR_W));
221  this->resetRegisterBankAccess();
222 };
223 
225  this->writeRegister(BLK_SEL_R,0x00);
226  this->writeRegister(BLK_SEL_W,0x00);
227  this->writeRegister(MADDR_R,0x00);
228  this->writeRegister(MADDR_W,0x00);
229 };
230 
232  delay(60);
233  //set INTF_CONFIG0 FIFO_COUNT_REC_RECORD und Little Endian
234  this->writeRegister(INTF_CONFIG0,0x60);
235  //set FIFO_CONFIG1 to Mode Snapshot and BYPASS Off
236  this->writeRegister(FIFO_CONFIG1,0x00);
237  //set TMST_CONFIG1_MREG1 TMST_CONFIIG1_TMST_EN
239  //set FiFO config 5 GYRO_EN,TMST_FSYNC, ACCEL_EN, WM_GT_TH_EN
241  //set FOF_CONFIG2 0x1 (INT triggerd each packaged)
242  this->writeRegister(FIFO_CONFIG2,0x0A);
243 };
244 
246  int16_t fifocount = 0;
247  int8_t fifohigh = this->readRegister(FIFO_COUNTH);
248  int8_t fifolow = this->readRegister(FIFO_COUNTL);
249  fifocount = (fifohigh<<8)|fifolow;
250  //fifocount |= this->readRegister(FIFO_COUNTL);
251  //fifocount = (this->readRegister(FIFO_COUNTH)<<8);
252  Serial.println(fifolow);
253  Serial.println(fifohigh);
254  Serial.println(fifocount);
255  handler->beginTransaction(SPISettings(frequency,SPI_MSBFIRST,SPI_MODE0));
256  digitalWrite(34,LOW);
257  handler->transfer(cmdRead(FIFO_DATA));
258  handler->transfer(buf,16*fifocount);
259  digitalWrite(34,HIGH);
260  handler->endTransaction();
261 
262  writeRegister(0x02,0x04);
263  delayMicroseconds(10);
264 
265  for(int i = 0; i<fifocount;i++){
266  buffer[i].header = buf[0x00+16*i];
267  buffer[i].accel.x = (buf[0x02+16*i]<<8)|buf[0x01+16*i];
268  buffer[i].accel.y = (buf[0x04+16*i]<<8)|buf[0x03+16*i];
269  buffer[i].accel.z = (buf[0x06+16*i]<<8)|buf[0x05+16*i];
270  buffer[i].gyro.x = (buf[0x08+16*i]<<8)|buf[0x07+16*i];
271  buffer[i].gyro.y = (buf[0x0A+16*i]<<8)|buf[0x09+16*i];
272  buffer[i].gyro.z = (buf[0x0C+16*i]<<8)|buf[0x0B+16*i];
273  buffer[i].temperature = buf[0x0D+16*i];
274  buffer[i].timestamp = (buf[0x0F+16*i]<<8)|buf[0x0E +16*i];
275  }
276  return fifocount;
277 };
278 
279 void MotionDetection::writeRegister(uint8_t reg, uint8_t value){
280  handler->beginTransaction(SPISettings(frequency,SPI_MSBFIRST,SPI_MODE0));
281  digitalWrite(34,LOW);
282  handler->transfer(reg);
283  handler->transfer(value);
284  digitalWrite(34,HIGH);
285  delayMicroseconds(10);
286  handler->endTransaction();
287 };
MADDR_W
#define MADDR_W
Definition: IMU_CMDs.h:35
MotionDetection.h
This component controls the IMU (Accelerometer & Gyroscope) ICM-42670-P.
WHO_AM_I
#define WHO_AM_I
Definition: IMU_CMDs.h:29
ACCEL_DATA_Z_HIGH
#define ACCEL_DATA_Z_HIGH
Definition: IMU_CMDs.h:18
Right
@ Right
Definition: MotionDetection.h:35
BLK_SEL_W
#define BLK_SEL_W
Definition: IMU_CMDs.h:33
Error
@ Error
Definition: MotionDetection.h:39
IMUResult::y
int16_t y
Definition: MotionDetection.h:18
FIFO_Package
Definition: MotionDetection.h:42
Left
@ Left
Definition: MotionDetection.h:34
CMD_WRITE
#define CMD_WRITE
Definition: IMU_CMDs.h:5
CMD_READ
#define CMD_READ
Definition: IMU_CMDs.h:4
MotionDetection::calibrateZAxis
void calibrateZAxis(uint gforceValue)
Definition: MotionDetection.cpp:74
REG_TEMP_HIGH
#define REG_TEMP_HIGH
Definition: IMU_CMDs.h:12
MotionDetection::cmdRead
uint16_t cmdRead(uint8_t regHigh, uint8_t regLow)
MCLK_RDY
#define MCLK_RDY
Definition: IMU_CMDs.h:9
IMUResult
Definition: MotionDetection.h:16
Back
@ Back
Definition: MotionDetection.h:36
MotionDetection::frequency
static const uint frequency
Definition: MotionDetection.h:54
MotionDetection::getAcceleration
IMUResult getAcceleration(void)
Triggers a new Reading of the accelerationvalues and reads them from the IMU.
Definition: MotionDetection.cpp:28
GYRO_DATA_Y_HIGH
#define GYRO_DATA_Y_HIGH
Definition: IMU_CMDs.h:23
FIFO_DATA
#define FIFO_DATA
Definition: IMU_CMDs.h:42
ACCEL_DATA_X_HIGH
#define ACCEL_DATA_X_HIGH
Definition: IMU_CMDs.h:14
FIFO_COUNTH
#define FIFO_COUNTH
Definition: IMU_CMDs.h:40
MotionDetection::getRotation
IMUResult getRotation(void)
Triggers a new reading of the gyroscope and reads the values from the imu.
Definition: MotionDetection.cpp:35
MotionDetection::readFromRegisterBank
uint8_t readFromRegisterBank(registerBank bank, uint8_t reg)
Definition: MotionDetection.cpp:173
MotionDetection::end
void end(void)
stops the component Sets the IMU to Low-Power-Mode
Definition: MotionDetection.cpp:25
GYRO_DATA_Y_LOW
#define GYRO_DATA_Y_LOW
Definition: IMU_CMDs.h:24
IMUResult::z
int16_t z
Definition: MotionDetection.h:19
yAxis
@ yAxis
Definition: MotionDetection.h:23
INTF_CONFIG0
#define INTF_CONFIG0
Definition: IMU_CMDs.h:31
Orientation::yRotation
int yRotation
Definition: MotionDetection.h:29
REG_TEMP_LOW
#define REG_TEMP_LOW
Definition: IMU_CMDs.h:11
zAxis
@ zAxis
Definition: MotionDetection.h:24
MotionDetection::getDataFromFIFO
uint getDataFromFIFO(FIFO_Package *buffer)
will read all availible packages from fifo, after 40ms Fifo is full
Definition: MotionDetection.cpp:245
MotionDetection::MotionDetection
MotionDetection()
Definition: MotionDetection.cpp:4
BLK_SEL_R
#define BLK_SEL_R
Definition: IMU_CMDs.h:34
MotionDetection::getTilt
Orientation getTilt()
calculates how the robot is tilted. It is set, that when the robot is placed normally on a flat table...
Definition: MotionDetection.cpp:78
MotionDetection::MREG3
@ MREG3
Definition: MotionDetection.h:53
FIFO_Package::header
int8_t header
Definition: MotionDetection.h:43
MotionDetection::initFIFO
void initFIFO()
Definition: MotionDetection.cpp:231
GYRO_DATA_Z_LOW
#define GYRO_DATA_Z_LOW
Definition: IMU_CMDs.h:26
ACCEL_DATA_Z_LOW
#define ACCEL_DATA_Z_LOW
Definition: IMU_CMDs.h:19
MotionDetection::writeToRegisterBank
void writeToRegisterBank(registerBank bank, uint8_t reg, uint8_t value)
Definition: MotionDetection.cpp:194
MotionDetection::MREG2
@ MREG2
Definition: MotionDetection.h:53
MotionDetection::getTemperature
float getTemperature(void)
Reads the current On Chip temperature of the IMU.
Definition: MotionDetection.cpp:45
FIFO_COUNTL
#define FIFO_COUNTL
Definition: IMU_CMDs.h:41
ACCEL_DATA_X_LOW
#define ACCEL_DATA_X_LOW
Definition: IMU_CMDs.h:15
FIFO_CONFIG1
#define FIFO_CONFIG1
Definition: IMU_CMDs.h:43
MotionDetection::begin
void begin(void)
initialized the IMU Component. Wakes the IMU from Standby Set configuration
Definition: MotionDetection.cpp:8
FIFO_Package::accel
IMUResult accel
Definition: MotionDetection.h:45
Front
@ Front
Definition: MotionDetection.h:33
MotionDetection::isShaken
bool isShaken(uint32_t threshold=defaultShakeThreshold, uint8_t axis=xAxis|yAxis|zAxis)
Detects if at the time of calling is shaken. Therefore the sum over all accelerationvalues is calcula...
Definition: MotionDetection.cpp:55
FIFO_Package::temperature
int16_t temperature
Definition: MotionDetection.h:46
MotionDetection::getTiltDirection
Direction getTiltDirection(uint tolerance=10)
Checks in which direction (Front, Left, Right, Back) the robot is tilted.
Definition: MotionDetection.cpp:122
GYRO_DATA_X_LOW
#define GYRO_DATA_X_LOW
Definition: IMU_CMDs.h:22
ACCEL_DATA_Y_LOW
#define ACCEL_DATA_Y_LOW
Definition: IMU_CMDs.h:17
MotionDetection::MREG1
@ MREG1
Definition: MotionDetection.h:53
M_W
#define M_W
Definition: IMU_CMDs.h:37
ADDR_MASK
#define ADDR_MASK
Definition: IMU_CMDs.h:6
Orientation::xRotation
int xRotation
Definition: MotionDetection.h:28
FIFO_CONFIG5
#define FIFO_CONFIG5
Definition: IMU_CMDs.h:47
GYRO_DATA_X_HIGH
#define GYRO_DATA_X_HIGH
Definition: IMU_CMDs.h:21
xAxis
@ xAxis
Definition: MotionDetection.h:22
FIFO_Package::gyro
IMUResult gyro
Definition: MotionDetection.h:44
MotionDetection::writeRegister
void writeRegister(uint8_t reg, uint8_t value)
Definition: MotionDetection.cpp:279
Orientation
Definition: MotionDetection.h:27
FIFO_Package::timestamp
int16_t timestamp
Definition: MotionDetection.h:47
PWR_MGMT0
#define PWR_MGMT0
Definition: IMU_CMDs.h:28
MotionDetection::gForceCalib
uint gForceCalib
Definition: MotionDetection.h:74
MADDR_R
#define MADDR_R
Definition: IMU_CMDs.h:36
Direction
Direction
Definition: MotionDetection.h:32
TMST_CONFIG1
#define TMST_CONFIG1
Definition: IMU_CMDs.h:48
ACCEL_DATA_Y_HIGH
#define ACCEL_DATA_Y_HIGH
Definition: IMU_CMDs.h:16
Neutral
@ Neutral
Definition: MotionDetection.h:37
MotionDetection::buf
int8_t * buf
Definition: MotionDetection.h:57
MotionDetection::cmdWrite
uint16_t cmdWrite(uint8_t regHigh, uint8_t regLow)
Flipped
@ Flipped
Definition: MotionDetection.h:38
IMUResult::x
int16_t x
Definition: MotionDetection.h:17
GYRO_DATA_Z_HIGH
#define GYRO_DATA_Z_HIGH
Definition: IMU_CMDs.h:25
FIFO_CONFIG2
#define FIFO_CONFIG2
Definition: IMU_CMDs.h:44
MotionDetection::readRegister
uint8_t readRegister(uint8_t reg)
Definition: MotionDetection.cpp:162
M_R
#define M_R
Definition: IMU_CMDs.h:38
MotionDetection::handler
SPIClass * handler
Definition: MotionDetection.h:72
MotionDetection::getWhoAmI
int8_t getWhoAmI(void)
Returns the value of reading the whoAmI register When IMU working correctly, value should be 0x67.
Definition: MotionDetection.cpp:51
MotionDetection::registerBank
registerBank
Definition: MotionDetection.h:53
MotionDetection::resetRegisterBankAccess
void resetRegisterBankAccess()
Definition: MotionDetection.cpp:224