From 7723f39b6befd194d3c41377f8515d7b31175dbc Mon Sep 17 00:00:00 2001 From: Bernd Porr Date: Sun, 13 Feb 2022 12:03:22 +0000 Subject: [PATCH] Moved the initisalisers --- CMakeLists.txt | 4 +- LSM9DS1.cpp | 255 +++++++++++++++++++++++------------------------- LSM9DS1.h | 117 ++++++++++++++++++---- LSM9DS1_Types.h | 75 -------------- README.md | 4 +- 5 files changed, 228 insertions(+), 227 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b23586f..557f475 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,12 @@ cmake_minimum_required(VERSION 3.1.0) +set(CMAKE_CXX_STANDARD 11) + if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) set(CMAKE_BUILD_TYPE "RelWithDebInfo") endif() -project(LSM9DS1_RaspberryPi_Library LANGUAGES CXX) +project(LSM9DS1_RaspberryPi_Library VERSION 2.0.0 LANGUAGES CXX) include(GNUInstallDirs) add_subdirectory(example) diff --git a/LSM9DS1.cpp b/LSM9DS1.cpp index af04c72..dbc93e1 100644 --- a/LSM9DS1.cpp +++ b/LSM9DS1.cpp @@ -34,88 +34,77 @@ float magSensitivity[4] = {0.00014, 0.00029, 0.00043, 0.00058}; #define DEBUG #endif -LSM9DS1::LSM9DS1(uint8_t i2cBUS, uint8_t xgAddr, uint8_t mAddr, uint8_t drdy_gpio) { - settings.device.i2c_bus = i2cBUS; - settings.device.agAddress = xgAddr; - settings.device.mAddress = mAddr; - settings.device.drdy_gpio = drdy_gpio; +LSM9DS1::LSM9DS1(DeviceSettings deviceSettings) { + device = deviceSettings; #ifdef DEBUG - fprintf(stderr,"LSM9DS1: bus=%02x, agAddr=%02x, mAddr=%02x\n",settings.device.i2c_bus,settings.device.agAddress,settings.device.mAddress); + fprintf(stderr,"LSM9DS1: bus=%02x, agAddr=%02x, mAddr=%02x\n", + device.i2c_bus,device.agAddress,device.mAddress); #endif - settings.gyro.enabled = true; - settings.gyro.enableX = true; - settings.gyro.enableY = true; - settings.gyro.enableZ = true; // gyro scale can be 245, 500, or 2000 - settings.gyro.scale = 245; + gyro.scale = 245; // gyro sample rate: value between 1-6 // 1 = 14.9 4 = 238 // 2 = 59.5 5 = 476 // 3 = 119 6 = 952 - settings.gyro.sampleRate = 3; + gyro.sampleRate = 3; // gyro cutoff frequency: value between 0-3 // Actual value of cutoff frequency depends // on sample rate. - settings.gyro.bandwidth = 0; - settings.gyro.lowPowerEnable = false; - settings.gyro.HPFEnable = false; + gyro.bandwidth = 0; + gyro.lowPowerEnable = false; + gyro.HPFEnable = false; // Gyro HPF cutoff frequency: value between 0-9 // Actual value depends on sample rate. Only applies // if gyroHPFEnable is true. - settings.gyro.HPFCutoff = 0; - settings.gyro.flipX = false; - settings.gyro.flipY = false; - settings.gyro.flipZ = false; - settings.gyro.orientation = 0; - settings.gyro.latchInterrupt = true; - - settings.accel.enabled = true; - settings.accel.enableX = true; - settings.accel.enableY = true; - settings.accel.enableZ = true; + gyro.HPFCutoff = 0; + gyro.flipX = false; + gyro.flipY = false; + gyro.flipZ = false; + gyro.orientation = 0; + gyro.latchInterrupt = true; + + accel.enabled = true; + accel.enableX = true; + accel.enableY = true; + accel.enableZ = true; // accel scale can be 2, 4, 8, or 16 - settings.accel.scale = 16; + accel.scale = 16; // accel sample rate can be 1-6 // 1 = 10 Hz 4 = 238 Hz // 2 = 50 Hz 5 = 476 Hz // 3 = 119 Hz 6 = 952 Hz - settings.accel.sampleRate = 3; + accel.sampleRate = 3; // Accel cutoff freqeuncy can be any value between -1 - 3. // -1 = bandwidth determined by sample rate // 0 = 408 Hz 2 = 105 Hz // 1 = 211 Hz 3 = 50 Hz - settings.accel.bandwidth = -1; - settings.accel.highResEnable = false; + accel.bandwidth = -1; + accel.highResEnable = false; // accelHighResBandwidth can be any value between 0-3 // LP cutoff is set to a factor of sample rate // 0 = ODR/50 2 = ODR/9 // 1 = ODR/100 3 = ODR/400 - settings.accel.highResBandwidth = 0; + accel.highResBandwidth = 0; - settings.mag.enabled = true; + mag.enabled = true; // mag scale can be 4, 8, 12, or 16 - settings.mag.scale = 4; + mag.scale = 4; // mag data rate can be 0-7 // 0 = 0.625 Hz 4 = 10 Hz // 1 = 1.25 Hz 5 = 20 Hz // 2 = 2.5 Hz 6 = 40 Hz // 3 = 5 Hz 7 = 80 Hz - settings.mag.sampleRate = 7; - settings.mag.tempCompensationEnable = false; + mag.sampleRate = 7; + mag.tempCompensationEnable = false; // magPerformance can be any value between 0-3 // 0 = Low power mode 2 = high performance // 1 = medium performance 3 = ultra-high performance - settings.mag.XYPerformance = 3; - settings.mag.ZPerformance = 3; - settings.mag.lowPowerEnable = false; - // magOperatingMode can be 0-2 - // 0 = continuous conversion - // 1 = single-conversion - // 2 = power down - settings.mag.operatingMode = 0; - - settings.temp.enabled = true; + mag.XYPerformance = 3; + mag.ZPerformance = 3; + mag.lowPowerEnable = false; + + temp.enabled = true; for (int i=0; i<3; i++) { gBias[i] = 0; @@ -130,20 +119,18 @@ LSM9DS1::LSM9DS1(uint8_t i2cBUS, uint8_t xgAddr, uint8_t mAddr, uint8_t drdy_gpi uint16_t LSM9DS1::begin() { - //! Todo: don't use _xgAddress or _mAddress, duplicating memory - _xgAddress = settings.device.agAddress; - _mAddress = settings.device.mAddress; - - int cfg = gpioCfgGetInternals(); - cfg |= PI_CFG_NOSIGHANDLER; - gpioCfgSetInternals(cfg); - int r = gpioInitialise(); - if (r < 0) { - char msg[] = "Cannot init pigpio."; + if (device.initPIGPIO) { + int cfg = gpioCfgGetInternals(); + cfg |= PI_CFG_NOSIGHANDLER; + gpioCfgSetInternals(cfg); + int r = gpioInitialise(); + if (r < 0) { + char msg[] = "Cannot init pigpio."; #ifdef DEBUG - fprintf(stderr,"%s\n",msg); + fprintf(stderr,"%s\n",msg); #endif - throw msg; + throw msg; + } } constrainScales(); @@ -174,8 +161,8 @@ uint16_t LSM9DS1::begin() calibrate(); - gpioSetMode(settings.device.drdy_gpio,PI_INPUT); - gpioSetISRFuncEx(settings.device.drdy_gpio,RISING_EDGE,ISR_TIMEOUT,gpioISR,(void*)this); + gpioSetMode(device.drdy_gpio,PI_INPUT); + gpioSetISRFuncEx(device.drdy_gpio,RISING_EDGE,ISR_TIMEOUT,gpioISR,(void*)this); return whoAmICombined; } @@ -199,7 +186,7 @@ void LSM9DS1::timerEvent() { } void LSM9DS1::end() { - gpioSetISRFuncEx(settings.device.drdy_gpio,RISING_EDGE,-1,NULL,(void*)this); + gpioSetISRFuncEx(device.drdy_gpio,RISING_EDGE,-1,NULL,(void*)this); gpioTerminate(); } @@ -215,10 +202,10 @@ void LSM9DS1::initGyro() // To disable gyro, set sample rate bits to 0. We'll only set sample // rate if the gyro is enabled. - if (settings.gyro.enabled) { - tempRegValue = (settings.gyro.sampleRate & 0x07) << 5; + if (gyro.enabled) { + tempRegValue = (gyro.sampleRate & 0x07) << 5; } - switch (settings.gyro.scale) { + switch (gyro.scale) { case 500: tempRegValue |= (0x1 << 3); break; @@ -227,7 +214,7 @@ void LSM9DS1::initGyro() break; // Otherwise we'll set it to 245 dps (0x0 << 4) } - tempRegValue |= (settings.gyro.bandwidth & 0x3); + tempRegValue |= (gyro.bandwidth & 0x3); xgWriteByte(CTRL_REG1_G, tempRegValue); // CTRL_REG2_G (Default value: 0x00) @@ -241,9 +228,9 @@ void LSM9DS1::initGyro() // LP_mode - Low-power mode enable (0: disabled, 1: enabled) // HP_EN - HPF enable (0:disabled, 1: enabled) // HPCF_G[3:0] - HPF cutoff frequency - tempRegValue = settings.gyro.lowPowerEnable ? (1<<7) : 0; - if (settings.gyro.HPFEnable) { - tempRegValue |= (1<<6) | (settings.gyro.HPFCutoff & 0x0F); + tempRegValue = gyro.lowPowerEnable ? (1<<7) : 0; + if (gyro.HPFEnable) { + tempRegValue |= (1<<6) | (gyro.HPFCutoff & 0x0F); } xgWriteByte(CTRL_REG3_G, tempRegValue); @@ -255,10 +242,10 @@ void LSM9DS1::initGyro() // LIR_XL1 - Latched interrupt (0:not latched, 1:latched) // 4D_XL1 - 4D option on interrupt (0:6D used, 1:4D used) tempRegValue = 0; - if (settings.gyro.enableZ) tempRegValue |= (1<<5); - if (settings.gyro.enableY) tempRegValue |= (1<<4); - if (settings.gyro.enableX) tempRegValue |= (1<<3); - if (settings.gyro.latchInterrupt) tempRegValue |= (1<<1); + if (gyro.enableZ) tempRegValue |= (1<<5); + if (gyro.enableY) tempRegValue |= (1<<4); + if (gyro.enableX) tempRegValue |= (1<<3); + if (gyro.latchInterrupt) tempRegValue |= (1<<1); xgWriteByte(CTRL_REG4, tempRegValue); // ORIENT_CFG_G (Default value: 0x00) @@ -266,9 +253,9 @@ void LSM9DS1::initGyro() // SignX_G - Pitch axis (X) angular rate sign (0: positive, 1: negative) // Orient [2:0] - Directional user orientation selection tempRegValue = 0; - if (settings.gyro.flipX) tempRegValue |= (1<<5); - if (settings.gyro.flipY) tempRegValue |= (1<<4); - if (settings.gyro.flipZ) tempRegValue |= (1<<3); + if (gyro.flipX) tempRegValue |= (1<<5); + if (gyro.flipY) tempRegValue |= (1<<4); + if (gyro.flipZ) tempRegValue |= (1<<3); xgWriteByte(ORIENT_CFG_G, tempRegValue); } @@ -283,9 +270,9 @@ void LSM9DS1::initAccel() // Zen_XL - Z-axis output enabled // Yen_XL - Y-axis output enabled // Xen_XL - X-axis output enabled - if (settings.accel.enableZ) tempRegValue |= (1<<5); - if (settings.accel.enableY) tempRegValue |= (1<<4); - if (settings.accel.enableX) tempRegValue |= (1<<3); + if (accel.enableZ) tempRegValue |= (1<<5); + if (accel.enableY) tempRegValue |= (1<<4); + if (accel.enableX) tempRegValue |= (1<<3); xgWriteByte(CTRL_REG5_XL, tempRegValue); @@ -297,11 +284,11 @@ void LSM9DS1::initAccel() // BW_XL[1:0] - Anti-aliasing filter bandwidth selection tempRegValue = 0; // To disable the accel, set the sampleRate bits to 0. - if (settings.accel.enabled) + if (accel.enabled) { - tempRegValue |= (settings.accel.sampleRate & 0x07) << 5; + tempRegValue |= (accel.sampleRate & 0x07) << 5; } - switch (settings.accel.scale) + switch (accel.scale) { case 4: tempRegValue |= (0x2 << 3); @@ -314,10 +301,10 @@ void LSM9DS1::initAccel() break; // Otherwise it'll be set to 2g (0x0 << 3) } - if (settings.accel.bandwidth >= 0) + if (accel.bandwidth >= 0) { tempRegValue |= (1<<2); // Set BW_SCAL_ODR - tempRegValue |= (settings.accel.bandwidth & 0x03); + tempRegValue |= (accel.bandwidth & 0x03); } xgWriteByte(CTRL_REG6_XL, tempRegValue); @@ -328,12 +315,17 @@ void LSM9DS1::initAccel() // FDS - Filtered data selection // HPIS1 - HPF enabled for interrupt function tempRegValue = 0; - if (settings.accel.highResEnable) + if (accel.highResEnable) { tempRegValue |= (1<<7); // Set HR bit - tempRegValue |= (settings.accel.highResBandwidth & 0x3) << 5; + tempRegValue |= (accel.highResBandwidth & 0x3) << 5; } xgWriteByte(CTRL_REG7_XL, tempRegValue); + + // INT2_CTRL (0Dd) + // Enable data ready on the INT2 pin: INT2_DRDY_XL = 1 + xgWriteByte(INT2_CTRL, 1); + } // This is a function that uses the FIFO to accumulate sample of accelerometer and gyro data, average @@ -436,9 +428,9 @@ void LSM9DS1::initMag() // 10: high performance, 11:ultra-high performance // DO[2:0] - Output data rate selection // ST - Self-test enable - if (settings.mag.tempCompensationEnable) tempRegValue |= (1<<7); - tempRegValue |= (settings.mag.XYPerformance & 0x3) << 5; - tempRegValue |= (settings.mag.sampleRate & 0x7) << 2; + if (mag.tempCompensationEnable) tempRegValue |= (1<<7); + tempRegValue |= (mag.XYPerformance & 0x3) << 5; + tempRegValue |= (mag.sampleRate & 0x7) << 2; mWriteByte(CTRL_REG1_M, tempRegValue); // CTRL_REG2_M (Default value 0x00) @@ -447,7 +439,7 @@ void LSM9DS1::initMag() // REBOOT - Reboot memory content (0:normal, 1:reboot) // SOFT_RST - Reset config and user registers (0:default, 1:reset) tempRegValue = 0; - switch (settings.mag.scale) + switch (mag.scale) { case 8: tempRegValue |= (0x1 << 5); @@ -471,8 +463,9 @@ void LSM9DS1::initMag() // 00:continuous conversion, 01:single-conversion, // 10,11: Power-down tempRegValue = 0; - if (settings.mag.lowPowerEnable) tempRegValue |= (1<<5); - tempRegValue |= (settings.mag.operatingMode & 0x3); + if (mag.lowPowerEnable) tempRegValue |= (1<<5); + const int operatingMode = 0; + tempRegValue |= (operatingMode & 0x3); mWriteByte(CTRL_REG3_M, tempRegValue); // Continuous conversion mode // CTRL_REG4_M (Default value: 0x00) @@ -482,7 +475,7 @@ void LSM9DS1::initMag() // 10:high performance, 10:ultra-high performance // BLE - Big/little endian data tempRegValue = 0; - tempRegValue = (settings.mag.ZPerformance & 0x3) << 2; + tempRegValue = (mag.ZPerformance & 0x3) << 2; mWriteByte(CTRL_REG4_M, tempRegValue); // CTRL_REG5_M (Default value: 0x00) @@ -642,14 +635,14 @@ void LSM9DS1::setGyroScale(uint16_t gScl) { case 500: ctrl1RegValue |= (0x1 << 3); - settings.gyro.scale = 500; + gyro.scale = 500; break; case 2000: ctrl1RegValue |= (0x3 << 3); - settings.gyro.scale = 2000; + gyro.scale = 2000; break; default: // Otherwise we'll set it to 245 dps (0x0 << 4) - settings.gyro.scale = 245; + gyro.scale = 245; break; } xgWriteByte(CTRL_REG1_G, ctrl1RegValue); @@ -668,18 +661,18 @@ void LSM9DS1::setAccelScale(uint8_t aScl) { case 4: tempRegValue |= (0x2 << 3); - settings.accel.scale = 4; + accel.scale = 4; break; case 8: tempRegValue |= (0x3 << 3); - settings.accel.scale = 8; + accel.scale = 8; break; case 16: tempRegValue |= (0x1 << 3); - settings.accel.scale = 16; + accel.scale = 16; break; default: // Otherwise it'll be set to 2g (0x0 << 3) - settings.accel.scale = 2; + accel.scale = 2; break; } xgWriteByte(CTRL_REG6_XL, tempRegValue); @@ -699,18 +692,18 @@ void LSM9DS1::setMagScale(uint8_t mScl) { case 8: temp |= (0x1 << 5); - settings.mag.scale = 8; + mag.scale = 8; break; case 12: temp |= (0x2 << 5); - settings.mag.scale = 12; + mag.scale = 12; break; case 16: temp |= (0x3 << 5); - settings.mag.scale = 16; + mag.scale = 16; break; default: // Otherwise we'll default to 4 gauss (00) - settings.mag.scale = 4; + mag.scale = 4; break; } @@ -735,7 +728,7 @@ void LSM9DS1::setGyroODR(uint8_t gRate) temp &= 0xFF^(0x7 << 5); temp |= (gRate & 0x07) << 5; // Update our settings struct - settings.gyro.sampleRate = gRate & 0x07; + gyro.sampleRate = gRate & 0x07; // And write the new register value back into CTRL_REG1_G: xgWriteByte(CTRL_REG1_G, temp); } @@ -752,7 +745,7 @@ void LSM9DS1::setAccelODR(uint8_t aRate) temp &= 0x1F; // Then shift in our new ODR bits: temp |= ((aRate & 0x07) << 5); - settings.accel.sampleRate = aRate & 0x07; + accel.sampleRate = aRate & 0x07; // And write the new register value back into CTRL_REG1_XM: xgWriteByte(CTRL_REG6_XL, temp); } @@ -766,25 +759,25 @@ void LSM9DS1::setMagODR(uint8_t mRate) temp &= 0xFF^(0x7 << 2); // Then shift in our new ODR bits: temp |= ((mRate & 0x07) << 2); - settings.mag.sampleRate = mRate & 0x07; + mag.sampleRate = mRate & 0x07; // And write the new register value back into CTRL_REG5_XM: mWriteByte(CTRL_REG1_M, temp); } void LSM9DS1::calcgRes() { - gRes = ((float) settings.gyro.scale) / 32768.0; + gRes = ((float) gyro.scale) / 32768.0; } void LSM9DS1::calcaRes() { - aRes = ((float) settings.accel.scale) / 32768.0; + aRes = ((float) accel.scale) / 32768.0; } void LSM9DS1::calcmRes() { - //mRes = ((float) settings.mag.scale) / 32768.0; - switch (settings.mag.scale) + //mRes = ((float) mag.scale) / 32768.0; + switch (mag.scale) { case 4: mRes = magSensitivity[0]; @@ -979,60 +972,60 @@ uint8_t LSM9DS1::getFIFOSamples() void LSM9DS1::constrainScales() { - if ((settings.gyro.scale != 245) && (settings.gyro.scale != 500) && - (settings.gyro.scale != 2000)) { - settings.gyro.scale = 245; + if ((gyro.scale != 245) && (gyro.scale != 500) && + (gyro.scale != 2000)) { + gyro.scale = 245; } - if ((settings.accel.scale != 2) && (settings.accel.scale != 4) && - (settings.accel.scale != 8) && (settings.accel.scale != 16)) { - settings.accel.scale = 2; + if ((accel.scale != 2) && (accel.scale != 4) && + (accel.scale != 8) && (accel.scale != 16)) { + accel.scale = 2; } - if ((settings.mag.scale != 4) && (settings.mag.scale != 8) && - (settings.mag.scale != 12) && (settings.mag.scale != 16)) { - settings.mag.scale = 4; + if ((mag.scale != 4) && (mag.scale != 8) && + (mag.scale != 12) && (mag.scale != 16)) { + mag.scale = 4; } } void LSM9DS1::xgWriteByte(uint8_t subAddress, uint8_t data) { - I2CwriteByte(_xgAddress, subAddress, data); + I2CwriteByte(device.agAddress, subAddress, data); return ; } void LSM9DS1::mWriteByte(uint8_t subAddress, uint8_t data) { - return I2CwriteByte(_mAddress, subAddress, data); + return I2CwriteByte(device.mAddress, subAddress, data); } uint8_t LSM9DS1::xgReadByte(uint8_t subAddress) { - return I2CreadByte(_xgAddress, subAddress); + return I2CreadByte(device.agAddress, subAddress); } void LSM9DS1::xgReadBytes(uint8_t subAddress, uint8_t *dest, uint8_t count) { - I2CreadBytes(_xgAddress, subAddress, dest, count); + I2CreadBytes(device.agAddress, subAddress, dest, count); } uint8_t LSM9DS1::mReadByte(uint8_t subAddress) { - return I2CreadByte(_mAddress, subAddress); + return I2CreadByte(device.mAddress, subAddress); } void LSM9DS1::mReadBytes(uint8_t subAddress, uint8_t *dest, uint8_t count) { - I2CreadBytes(_mAddress, subAddress, dest, count); + I2CreadBytes(device.mAddress, subAddress, dest, count); } // pigpio read and write protocols void LSM9DS1::I2CwriteByte(uint8_t address, uint8_t subAddress, uint8_t data) { - int fd = i2cOpen(settings.device.i2c_bus, address, 0); + int fd = i2cOpen(device.i2c_bus, address, 0); if (fd < 0) { #ifdef DEBUG - fprintf(stderr,"Could not write %02x to %02x,%02x,%02x\n",data,settings.device.i2c_bus,address,subAddress); + fprintf(stderr,"Could not write %02x to %02x,%02x,%02x\n",data,device.i2c_bus,address,subAddress); #endif throw could_not_open_i2c; } @@ -1042,10 +1035,10 @@ void LSM9DS1::I2CwriteByte(uint8_t address, uint8_t subAddress, uint8_t data) uint8_t LSM9DS1::I2CreadByte(uint8_t address, uint8_t subAddress) { - int fd = i2cOpen(settings.device.i2c_bus, address, 0); + int fd = i2cOpen(device.i2c_bus, address, 0); if (fd < 0) { #ifdef DEBUG - fprintf(stderr,"Could not read byte from %02x,%02x,%02x\n",settings.device.i2c_bus,address,subAddress); + fprintf(stderr,"Could not read byte from %02x,%02x,%02x\n",device.i2c_bus,address,subAddress); #endif throw could_not_open_i2c; } @@ -1053,7 +1046,7 @@ uint8_t LSM9DS1::I2CreadByte(uint8_t address, uint8_t subAddress) data = i2cReadByteData(fd, subAddress); if (data < 0) { #ifdef DEBUG - fprintf(stderr,"Could not read byte from %02x,%02x,%02x. ret=%d.\n",settings.device.i2c_bus,address,subAddress,data); + fprintf(stderr,"Could not read byte from %02x,%02x,%02x. ret=%d.\n",device.i2c_bus,address,subAddress,data); #endif throw "Could not read from i2c."; } @@ -1063,10 +1056,10 @@ uint8_t LSM9DS1::I2CreadByte(uint8_t address, uint8_t subAddress) uint8_t LSM9DS1::I2CreadBytes(uint8_t address, uint8_t subAddress, uint8_t * dest, uint8_t count) { - int fd = i2cOpen(settings.device.i2c_bus, address, 0); + int fd = i2cOpen(device.i2c_bus, address, 0); if (fd < 0) { #ifdef DEBUG - fprintf(stderr,"Could not read %n byte(s) from %02x,%02x,%02x\n",count,settings.device.i2c_bus,address,subAddress); + fprintf(stderr,"Could not read %n byte(s) from %02x,%02x,%02x\n",count,device.i2c_bus,address,subAddress); #endif throw could_not_open_i2c; } diff --git a/LSM9DS1.h b/LSM9DS1.h index 30c938a..9121c12 100644 --- a/LSM9DS1.h +++ b/LSM9DS1.h @@ -31,13 +31,103 @@ Distributed as-is; no warranty is given. #include "LSM9DS1_Types.h" #include +static const char could_not_open_i2c[] = "Could not open I2C.\n"; + +#define ISR_TIMEOUT 1000 + +// Gyroscope settings: +struct GyroSettings +{ + uint8_t enabled = true; + + // gyro scale can be 245, 500, or 2000 + uint16_t scale = 245; + + // gyro sample rate (Hz): value between 1-6 + // 1 = 14.9 4 = 238 + // 2 = 59.5 5 = 476 + // 3 = 119 6 = 952 + uint8_t sampleRate; + + uint8_t bandwidth = 0; + uint8_t lowPowerEnable = false; + uint8_t HPFEnable = false; + uint8_t HPFCutoff = 0; + uint8_t flipX = false; + uint8_t flipY = false; + uint8_t flipZ = false; + uint8_t orientation = 0; + uint8_t enableX = true; + uint8_t enableY = true; + uint8_t enableZ = true; + uint8_t latchInterrupt = true; +}; + #define LSM9DS1_AG_ADDR 0x6B #define LSM9DS1_M_ADDR 0x1E +#define LSM9DS1_DEFAULT_I2C_BUS 1 #define LSM9DS1_DRDY_GPIO 22 -static const char could_not_open_i2c[] = "Could not open I2C.\n"; +struct DeviceSettings +{ + uint8_t agAddress = LSM9DS1_AG_ADDR; // I2C acc address + uint8_t mAddress = LSM9DS1_M_ADDR; // I2C mag address + unsigned i2c_bus = LSM9DS1_DEFAULT_I2C_BUS; // I2C bus + unsigned drdy_gpio = LSM9DS1_DRDY_GPIO; // data ready pin (int2) + bool initPIGPIO = true; // inits pigpio +}; -#define ISR_TIMEOUT 1000 +// Accelerometer settings: +struct AccelSettings +{ + uint8_t enabled = true; + // accel scale (in g) can be 2, 4, 8, or 16 + uint8_t scale = 16; + // accel sample rate (Hz) can be 1-6 + // 1 = 10 Hz 4 = 238 Hz + // 2 = 50 Hz 5 = 476 Hz + // 3 = 119 Hz 6 = 952 Hz + uint8_t sampleRate = 2; + // New accel stuff: + uint8_t enableX = true; + uint8_t enableY = true; + uint8_t enableZ = true; + // Accel cutoff freqeuncy can be any value between -1 - 3. + // -1 = bandwidth determined by sample rate + // 0 = 408 Hz 2 = 105 Hz + // 1 = 211 Hz 3 = 50 Hz + int8_t bandwidth = -1; + uint8_t highResEnable = false; + uint8_t highResBandwidth = 0; +}; + +// Magnetometer settings: +struct MagSettings +{ + uint8_t enabled = true; + uint8_t scale = 4; + // mag data rate can be 0-7 + // 0 = 0.625 Hz 4 = 10 Hz + // 1 = 1.25 Hz 5 = 20 Hz + // 2 = 2.5 Hz 6 = 40 Hz + // 3 = 5 Hz 7 = 80 Hz + uint8_t sampleRate = 7; + + // New mag stuff: + uint8_t tempCompensationEnable = false; + // magPerformance can be any value between 0-3 + // 0 = Low power mode 2 = high performance + // 1 = medium performance 3 = ultra-high performance + uint8_t XYPerformance = 3; + uint8_t ZPerformance = 3; + uint8_t lowPowerEnable = false; +}; + +struct TemperatureSettings +{ + // Temperature settings + uint8_t enabled = true; +}; enum lsm9ds1_axis { X_AXIS, @@ -65,7 +155,11 @@ class LSM9DS1callback { class LSM9DS1 { public: - IMUSettings settings; + DeviceSettings device; + MagSettings mag; + GyroSettings gyro; + AccelSettings accel; + TemperatureSettings temp; // We'll store the gyro, accel, and magnetometer readings in a series of // public class variables. Each sensor gets three variables -- one for each @@ -80,17 +174,8 @@ class LSM9DS1 int16_t gBiasRaw[3], aBiasRaw[3], mBiasRaw[3]; // LSM9DS1 -- LSM9DS1 class constructor - // The constructor will set up a handful of private variables, and set the - // communication mode as well. - // Input: - // - xgAddr = I2C address of the accel/gyroscope. - // - mAddr = I2C address of the magnetometer. - // - i2cBUS = i2c bus (0 or 1) - LSM9DS1(uint8_t i2cBUS = 1, uint8_t xgAddr = LSM9DS1_AG_ADDR, uint8_t mAddr = LSM9DS1_M_ADDR, uint8_t drdy_gpio = LSM9DS1_DRDY_GPIO); - - ~LSM9DS1() { - gpioTerminate(); - } + // Input: DeviceSettings + LSM9DS1(DeviceSettings deviceSettings = DeviceSettings()); // begin() -- Initialize the gyro, accelerometer, and magnetometer. // This will set up the scale and output rate of each sensor. The values set @@ -358,10 +443,6 @@ class LSM9DS1 protected: - // x_mAddress and gAddress store the I2C address or SPI chip select pin - // for each sensor. - uint8_t _mAddress, _xgAddress; - // gRes, aRes, and mRes store the current resolution for each sensor. // Units of these values would be DPS (or g's or Gs's) per ADC tick. // This value is calculated as (sensor scale) / (2^15). diff --git a/LSM9DS1_Types.h b/LSM9DS1_Types.h index 9f0d97f..961e4f7 100644 --- a/LSM9DS1_Types.h +++ b/LSM9DS1_Types.h @@ -165,79 +165,4 @@ enum fifoMode_type FIFO_CONT = 5 }; -struct gyroSettings -{ - // Gyroscope settings: - uint8_t enabled; - uint16_t scale; // Changed this to 16-bit - uint8_t sampleRate; - // New gyro stuff: - uint8_t bandwidth; - uint8_t lowPowerEnable; - uint8_t HPFEnable; - uint8_t HPFCutoff; - uint8_t flipX; - uint8_t flipY; - uint8_t flipZ; - uint8_t orientation; - uint8_t enableX; - uint8_t enableY; - uint8_t enableZ; - uint8_t latchInterrupt; -}; - -struct deviceSettings -{ - uint8_t agAddress; // I2C address - uint8_t mAddress; // I2C address - unsigned i2c_bus; - unsigned drdy_gpio; -}; - -struct accelSettings -{ - // Accelerometer settings: - uint8_t enabled; - uint8_t scale; - uint8_t sampleRate; - // New accel stuff: - uint8_t enableX; - uint8_t enableY; - uint8_t enableZ; - int8_t bandwidth; - uint8_t highResEnable; - uint8_t highResBandwidth; -}; - -struct magSettings -{ - // Magnetometer settings: - uint8_t enabled; - uint8_t scale; - uint8_t sampleRate; - // New mag stuff: - uint8_t tempCompensationEnable; - uint8_t XYPerformance; - uint8_t ZPerformance; - uint8_t lowPowerEnable; - uint8_t operatingMode; -}; - -struct temperatureSettings -{ - // Temperature settings - uint8_t enabled; -}; - -struct IMUSettings -{ - deviceSettings device; - - gyroSettings gyro; - accelSettings accel; - magSettings mag; - - temperatureSettings temp; -}; - #endif diff --git a/README.md b/README.md index 54d1efa..fbd9efb 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LSM9DS1 RaspberryPI C++ Library -With C++ callback handler which is called at the 80Hz sampling rate of the LSM9DS1. +With C++ callback handler which is called at the sampling rate of the accelerometer of the LSM9DS1. Based on the [SparkFun_LSM9DS1_Arduino_Library](https://github.com/sparkfun/SparkFun_LSM9DS1_Arduino_Library) @@ -14,7 +14,7 @@ Use an LSM9DS1 breakout board from Sparkfun or make your own (see at the bottom - Connect the 3.3V power (pin 1) and GND (pin 9) to the LSM9DS1. - Connect the I2C SDA (pin 3) & I2C SCL (pin 5) to the LSM9DS1. - - Connect the GPIO22 (pin 15) to the DRDY output of the LSM9DS1. + - Connect the GPIO22 (pin 15) to the INT2 output of the LSM9DS1. ## Software requirement