66 : spiSlave(bus, chipSelect), odr(odr), bdu(bdu), fullScale(fullScale)
91 : spiSlave(bus, chipSelect, config), odr(odr), bdu(bdu),
106 LOG_WARN(logger,
"Already initialized");
120 uint8_t ctrlReg5Value = (fullScale << 3);
125 sensitivity = selectSensitivity();
129 uint8_t ctrlReg4Value =
130 (odr << 4) | (bdu << 3) | (7 << 0);
149 "Unable to perform selftest, sensor not initialized");
154 const uint8_t numSamples = 5;
157 float X_ST[numSamples] = {0};
158 float Y_ST[numSamples] = {0};
159 float Z_ST[numSamples] = {0};
160 float X_NO_ST[numSamples] = {0};
161 float Y_NO_ST[numSamples] = {0};
162 float Z_NO_ST[numSamples] = {0};
164 float AVG_ST[3] = {0};
165 float AVG_NO_ST[3] = {0};
187 for (uint8_t i = 0; i < numSamples; i++)
193 miosix::Thread::sleep(10);
196 ctrlReg5Value &= ~(3 << 1);
206 for (uint8_t i = 0; i < numSamples; i++)
212 miosix::Thread::sleep(10);
219 for (uint8_t i = 0; i < numSamples; i++)
221 AVG_ST[0] += X_ST[i];
222 AVG_ST[1] += Y_ST[i];
223 AVG_ST[2] += Z_ST[i];
224 AVG_NO_ST[0] += X_NO_ST[i];
225 AVG_NO_ST[1] += Y_NO_ST[i];
226 AVG_NO_ST[2] += Z_NO_ST[i];
228 for (uint8_t i = 0; i < 3; i++)
230 AVG_ST[i] /= numSamples;
231 AVG_NO_ST[i] /= numSamples;
237 ctrlReg4Value = (odr << 4) | (bdu << 3) | (7 << 0);
244 ctrlReg5Value = (fullScale << 3);
251 float delta[3] = {0};
252 for (uint8_t i = 0; i < 3; i++)
253 delta[i] = fabs(AVG_NO_ST[i] - AVG_ST[i]);
256 "Selftest: delta[x] = {}, delta[y] = {}, delta[z] = {}",
257 delta[0], delta[1], delta[2]);
262 SELF_TEST_DIFF_X_Y + SELF_TEST_DIFF_X_Y * SELF_TEST_TOLERANCE) ||
264 SELF_TEST_DIFF_X_Y + SELF_TEST_DIFF_X_Y * SELF_TEST_TOLERANCE) ||
266 SELF_TEST_DIFF_Z + SELF_TEST_DIFF_Z * SELF_TEST_TOLERANCE))
268 LOG_ERR(logger,
"Selftest failed");
328 LOG_WARN(logger,
"Unable to sample, sensor not initialized");
333 AccelerometerData accelData = readAccelData();
334 TemperatureData tempData = readTemperature();
339 return LIS3DSHData(accelData, tempData);
347 AccelerometerData readAccelData()
349 AccelerometerData accelData;
351 SPITransaction spi(spiSlave);
354 uint8_t status = spi.readRegister(STATUS);
361 accelData.accelerationTimestamp =
365 int8_t accel_L = spi.readRegister(OUT_X_L);
366 int8_t accel_H = spi.readRegister(OUT_X_H);
367 accelData.accelerationX =
368 static_cast<float>(combine(accel_H, accel_L)) * sensitivity;
371 accel_L = spi.readRegister(OUT_Y_L);
372 accel_H = spi.readRegister(OUT_Y_H);
373 accelData.accelerationY =
374 static_cast<float>(combine(accel_H, accel_L)) * sensitivity;
377 accel_L = spi.readRegister(OUT_Z_L);
378 accel_H = spi.readRegister(OUT_Z_H);
379 accelData.accelerationZ =
380 static_cast<float>(combine(accel_H, accel_L)) * sensitivity;
398 TemperatureData readTemperature()
400 SPITransaction spi(spiSlave);
403 int8_t t = spi.readRegister(OUT_T);
405 return TemperatureData{
407 t + TEMPERATURE_REF};
419 SPITransaction spi(spiSlave);
422 uint8_t whoAmIValue = spi.readRegister(WHO_AM_I_REG);
423 if (whoAmIValue == WHO_AM_I_DEFAULT_VALUE)
425 LOG_DEBUG(logger,
"Correct WHO_AM_I value");
430 LOG_ERR(logger,
"Wrong WHO_AM_I value, got {} instead of {}",
431 whoAmIValue, WHO_AM_I_DEFAULT_VALUE);
445 int16_t combine(uint8_t msb, uint8_t lsb) {
return (msb << 8) | lsb; }
454 float selectSensitivity()
475 LOG_ERR(logger,
"Invalid full scale range given, using +/-2g");
522 bool initialized =
false;
532 const float sensitivityValues[5] = {0.06, 0.12, 0.18, 0.24, 0.73};
538 const uint8_t WHO_AM_I_DEFAULT_VALUE = 63;
540 const float TEMPERATURE_REF = 25.0f;
544 const float SELF_TEST_DIFF_X_Y = 140.0f;
545 const float SELF_TEST_DIFF_Z = 590.0f;
546 const float SELF_TEST_TOLERANCE = 0.3f;
LIS3DSH(SPIBusInterface &bus, miosix::GpioPin chipSelect, uint8_t odr=OutputDataRate::ODR_100_HZ, uint8_t bdu=BlockDataUpdate::UPDATE_AFTER_READ_MODE, uint8_t fullScale=FullScale::FULL_SCALE_2G)
Constructor.
LIS3DSH(SPIBusInterface &bus, miosix::GpioPin chipSelect, SPIBusConfig config, uint8_t odr=OutputDataRate::ODR_100_HZ, uint8_t bdu=BlockDataUpdate::UPDATE_AFTER_READ_MODE, uint8_t fullScale=FullScale::FULL_SCALE_2G)
Constructor.