-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathRAK1905-9dof.cpp
235 lines (205 loc) · 7.22 KB
/
RAK1905-9dof.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
/**
* @file RAK1905-9dof.cpp
* @author Bernd Giesecke ([email protected])
* @brief Initialize and read values from the MPU9250 sensor
* @version 0.1
* @date 2022-04-11
*
* @copyright Copyright (c) 2022
*
*/
#include "main.h"
#include <MPU9250_WE.h>
// Forward declarations
void int_callback_rak1905(void);
/** Sensor instance using Wire */
MPU9250_WE mpu_sensor = MPU9250_WE();
/** Interrupt pin, depends on slot */
uint8_t mpu_int_pin = WB_IO5;
/**
* @brief Initialize MPU9250 9-axis
* acceleration sensor
*
* @return true If sensor was found and is initialized
* @return false If sensor initialization failed
*/
bool init_rak1905(void)
{
// Setup interrupt pin
pinMode(mpu_int_pin, INPUT);
Wire.begin();
if (!mpu_sensor.init())
{
MYLOG("9DOF", "Chip ID %02x %02x", mpu_sensor.whoAmI(), mpu_sensor.whoAmIMag());
MYLOG("9DOF", "9DOF sensor initialization failed (motion sensor)");
return false;
}
if (!mpu_sensor.initMagnetometer())
{
MYLOG("9DOF", "Chip ID %02x %02x", mpu_sensor.whoAmI(), mpu_sensor.whoAmIMag());
MYLOG("9DOF", "9DOF sensor initialization failed (magneto sensor)");
return false;
}
MYLOG("9DOF", "Chip ID %02x %02x", mpu_sensor.whoAmI(), mpu_sensor.whoAmIMag());
// Auto offsets
mpu_sensor.autoOffsets();
/* Sample rate divider divides the output rate of the gyroscope and accelerometer.
* Sample rate = Internal sample rate / (1 + divider)
* It can only be applied if the corresponding DLPF is enabled and 0<DLPF<7!
* Divider is a number 0...255
*/
mpu_sensor.setSampleRateDivider(5);
/* MPU9250_ACC_RANGE_2G 2 g (default)
* MPU9250_ACC_RANGE_4G 4 g
* MPU9250_ACC_RANGE_8G 8 g
* MPU9250_ACC_RANGE_16G 16 g
*/
mpu_sensor.setAccRange(MPU9250_ACC_RANGE_2G);
/* Enable/disable the digital low pass filter for the accelerometer
* If disabled the bandwidth is 1.13 kHz, delay is 0.75 ms, output rate is 4 kHz
*/
mpu_sensor.enableAccDLPF(true);
/* Digital low pass filter (DLPF) for the accelerometer, if enabled
* MPU9250_DPLF_0, MPU9250_DPLF_2, ...... MPU9250_DPLF_7
* DLPF Bandwidth [Hz] Delay [ms] Output rate [kHz]
* 0 460 1.94 1
* 1 184 5.80 1
* 2 92 7.80 1
* 3 41 11.80 1
* 4 20 19.80 1
* 5 10 35.70 1
* 6 5 66.96 1
* 7 460 1.94 1
*/
mpu_sensor.setAccDLPF(MPU9250_DLPF_6);
/* Set accelerometer output data rate in low power mode (cycle enabled)
* MPU9250_LP_ACC_ODR_0_24 0.24 Hz
* MPU9250_LP_ACC_ODR_0_49 0.49 Hz
* MPU9250_LP_ACC_ODR_0_98 0.98 Hz
* MPU9250_LP_ACC_ODR_1_95 1.95 Hz
* MPU9250_LP_ACC_ODR_3_91 3.91 Hz
* MPU9250_LP_ACC_ODR_7_81 7.81 Hz
* MPU9250_LP_ACC_ODR_15_63 15.63 Hz
* MPU9250_LP_ACC_ODR_31_25 31.25 Hz
* MPU9250_LP_ACC_ODR_62_5 62.5 Hz
* MPU9250_LP_ACC_ODR_125 125 Hz
* MPU9250_LP_ACC_ODR_250 250 Hz
* MPU9250_LP_ACC_ODR_500 500 Hz
*/
// mpu_sensor.setLowPowerAccDataRate(MPU9250_LP_ACC_ODR_125);
/* Set the interrupt pin:
* MPU9250_ACT_LOW = active-low
* MPU9250_ACT_HIGH = active-high (default)
*/
mpu_sensor.setIntPinPolarity(MPU9250_ACT_HIGH);
/* If latch is enabled the Interrupt Pin Level is held until the Interrupt Status
* is cleared. If latch is disabled the Interrupt Puls is ~50µs (default).
*/
mpu_sensor.enableIntLatch(true);
/* The Interrupt can be cleared by any read. Otherwise the Interrupt will only be
* cleared if the Interrupt Status register is read (default).
*/
mpu_sensor.enableClearIntByAnyRead(false);
/* Enable/disable interrupts:
* MPU9250_DATA_READY
* MPU9250_FIFO_OVF
* MPU9250_WOM_INT
*
* You can enable all interrupts.
*/
// mpu_sensor.enableInterrupt(MPU9250_DATA_READY);
mpu_sensor.enableInterrupt(MPU9250_WOM_INT);
// myMPU9250.disableInterrupt(MPU9250_FIFO_OVF);
/* Set the Wake On Motion Threshold
* Choose 1 (= 4 mg) ..... 255 (= 1020 mg);
*/
mpu_sensor.setWakeOnMotionThreshold(128); // 128 = ~0.5 g
/* Enable/disable wake on motion (WOM) and WOM mode:
* MPU9250_WOM_DISABLE
* MPU9250_WOM_ENABLE
* ***
* MPU9250_WOM_COMP_DISABLE // reference is the starting value
* MPU9250_WOM_COMP_ENABLE // reference is the last value
*/
mpu_sensor.enableWakeOnMotion(MPU9250_WOM_ENABLE, MPU9250_WOM_COMP_DISABLE);
/* If cycle is set, and standby or sleep are not set, the module will cycle between
* sleep and taking a sample at a rate determined by setLowPowerAccDataRate().
*/
// mpu_sensor.enableCycle(true);
/* You can enable or disable the axes for gyroscope and/or accelerometer measurements.
* By default all axes are enabled. Parameters are:
* MPU9250_ENABLE_XYZ //all axes are enabled (default)
* MPU9250_ENABLE_XY0 // X, Y enabled, Z disabled
* MPU9250_ENABLE_X0Z
* MPU9250_ENABLE_X00
* MPU9250_ENABLE_0YZ
* MPU9250_ENABLE_0Y0
* MPU9250_ENABLE_00Z
* MPU9250_ENABLE_000 // all axes disabled
*/
// myMPU9250.enableAccAxes(MPU9250_ENABLE_XYZ);
// Set the interrupt callback function
attachInterrupt(mpu_int_pin, int_callback_rak1905, RISING);
return true;
}
/**
* @brief Reads the values from the MPU9250
*
*/
void read_rak1905(void)
{
xyzFloat gValue = mpu_sensor.getGValues();
xyzFloat gyr = mpu_sensor.getGyrValues();
xyzFloat magValue = mpu_sensor.getMagValues();
float temp = mpu_sensor.getTemperature();
float resultantG = mpu_sensor.getResultantG(gValue);
MYLOG("9DOF", "Acceleration in g (x,y,z): %f %f %f", gValue.x, gValue.y, gValue.z);
MYLOG("9DOF", "Resultant g: %f", resultantG);
MYLOG("9DOF", "Gyroscope data in degrees/s: %f %f %f", gyr.x, gyr.y, gyr.z);
MYLOG("9DOF", "Magnetometer Data in μTesla: %f %f %f", magValue.x, magValue.y, magValue.z);
MYLOG("9DOF", "Temperature in °C: %f", temp);
}
/**
* @brief Assign/reassing interrupt pin
*
* @param new_irq_pin new GPIO to assign to interrupt
*/
void int_assign_rak1905(uint8_t new_irq_pin)
{
detachInterrupt(mpu_int_pin);
mpu_int_pin = new_irq_pin;
attachInterrupt(mpu_int_pin, int_callback_rak1905, RISING);
}
/**
* @brief ACC interrupt handler
* @note gives semaphore to wake up main loop
*
*/
void int_callback_rak1905(void)
{
if ((millis() - last_trigger) > 15000)
{
MYLOG("9DOF", "Interrupt triggered");
last_trigger = millis();
// Read the sensors and trigger a packet
sensor_handler(NULL);
// Stop a timer.
api.system.timer.stop(RAK_TIMER_0);
// Start a timer.
api.system.timer.start(RAK_TIMER_0, 30000, NULL);
}
motion_detected = true;
clear_int_rak1905();
}
/**
* @brief Clear ACC interrupt register to enable next wakeup
*
*/
void clear_int_rak1905(void)
{
byte source = mpu_sensor.readAndClearInterrupts();
if (mpu_sensor.checkInterrupt(source, MPU9250_WOM_INT))
{
MYLOG("9DOF", "Interrupt Type: Motion");
}
}