Dezibot 4
Loading...
Searching...
No Matches
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};
36 IMUResult result;
37 result.x = readRegister(GYRO_DATA_X_HIGH) <<8;
39 result.y = readRegister(GYRO_DATA_Y_HIGH)<<8;
41 result.z = readRegister(GYRO_DATA_Z_HIGH)<<8;
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
54
55bool 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
74void 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
155uint8_t MotionDetection::cmdRead(uint8_t reg){
156 return (CMD_READ | (reg & ADDR_MASK));
157};
158uint8_t MotionDetection::cmdWrite(uint8_t reg){
159 return (CMD_WRITE | (reg & ADDR_MASK));
160};
161
162uint8_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);
191 return result;
192};
193
194void 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));
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
279void 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};
#define GYRO_DATA_Z_LOW
Definition IMU_CMDs.h:26
#define PWR_MGMT0
Definition IMU_CMDs.h:28
#define FIFO_CONFIG1
Definition IMU_CMDs.h:43
#define ADDR_MASK
Definition IMU_CMDs.h:6
#define MADDR_R
Definition IMU_CMDs.h:36
#define BLK_SEL_W
Definition IMU_CMDs.h:33
#define M_W
Definition IMU_CMDs.h:37
#define TMST_CONFIG1
Definition IMU_CMDs.h:48
#define ACCEL_DATA_Z_HIGH
Definition IMU_CMDs.h:18
#define FIFO_CONFIG2
Definition IMU_CMDs.h:44
#define REG_TEMP_LOW
Definition IMU_CMDs.h:11
#define ACCEL_DATA_X_LOW
Definition IMU_CMDs.h:15
#define MADDR_W
Definition IMU_CMDs.h:35
#define CMD_WRITE
Definition IMU_CMDs.h:5
#define GYRO_DATA_X_HIGH
Definition IMU_CMDs.h:21
#define FIFO_DATA
Definition IMU_CMDs.h:42
#define MCLK_RDY
Definition IMU_CMDs.h:9
#define INTF_CONFIG0
Definition IMU_CMDs.h:31
#define FIFO_CONFIG5
Definition IMU_CMDs.h:47
#define CMD_READ
Definition IMU_CMDs.h:4
#define WHO_AM_I
Definition IMU_CMDs.h:29
#define BLK_SEL_R
Definition IMU_CMDs.h:34
#define REG_TEMP_HIGH
Definition IMU_CMDs.h:12
#define ACCEL_DATA_Y_HIGH
Definition IMU_CMDs.h:16
#define GYRO_DATA_Y_LOW
Definition IMU_CMDs.h:24
#define GYRO_DATA_X_LOW
Definition IMU_CMDs.h:22
#define ACCEL_DATA_Z_LOW
Definition IMU_CMDs.h:19
#define FIFO_COUNTH
Definition IMU_CMDs.h:40
#define FIFO_COUNTL
Definition IMU_CMDs.h:41
#define GYRO_DATA_Y_HIGH
Definition IMU_CMDs.h:23
#define ACCEL_DATA_X_HIGH
Definition IMU_CMDs.h:14
#define ACCEL_DATA_Y_LOW
Definition IMU_CMDs.h:17
#define M_R
Definition IMU_CMDs.h:38
#define GYRO_DATA_Z_HIGH
Definition IMU_CMDs.h:25
This component controls the IMU (Accelerometer & Gyroscope) ICM-42670-P.
Direction
@ Front
@ Neutral
@ Back
@ Error
@ Left
@ Flipped
@ Right
@ yAxis
@ zAxis
@ xAxis
uint getDataFromFIFO(FIFO_Package *buffer)
will read all availible packages from fifo, after 40ms Fifo is full
uint16_t cmdWrite(uint8_t regHigh, uint8_t regLow)
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...
uint8_t readFromRegisterBank(registerBank bank, uint8_t reg)
uint16_t cmdRead(uint8_t regHigh, uint8_t regLow)
uint8_t readRegister(uint8_t reg)
Orientation getTilt()
calculates how the robot is tilted. It is set, that when the robot is placed normally on a flat table...
int8_t getWhoAmI(void)
Returns the value of reading the whoAmI register When IMU working correctly, value should be 0x67.
static const uint frequency
IMUResult getRotation(void)
Triggers a new reading of the gyroscope and reads the values from the imu.
Direction getTiltDirection(uint tolerance=10)
Checks in which direction (Front, Left, Right, Back) the robot is tilted.
void calibrateZAxis(uint gforceValue)
void end(void)
stops the component Sets the IMU to Low-Power-Mode
void writeRegister(uint8_t reg, uint8_t value)
void writeToRegisterBank(registerBank bank, uint8_t reg, uint8_t value)
void begin(void)
initialized the IMU Component. Wakes the IMU from Standby Set configuration
IMUResult getAcceleration(void)
Triggers a new Reading of the accelerationvalues and reads them from the IMU.
float getTemperature(void)
Reads the current On Chip temperature of the IMU.
IMUResult accel
int16_t temperature