diff --git a/Libraries/Arduino/.gitattributes b/Libraries/Arduino/.gitattributes new file mode 100644 index 0000000..412eeda --- /dev/null +++ b/Libraries/Arduino/.gitattributes @@ -0,0 +1,22 @@ +# Auto detect text files and perform LF normalization +* text=auto + +# Custom for Visual Studio +*.cs diff=csharp +*.sln merge=union +*.csproj merge=union +*.vbproj merge=union +*.fsproj merge=union +*.dbproj merge=union + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain diff --git a/Libraries/Arduino/.gitignore b/Libraries/Arduino/.gitignore new file mode 100644 index 0000000..2778edb --- /dev/null +++ b/Libraries/Arduino/.gitignore @@ -0,0 +1,192 @@ +################# +## SparkFun Useful stuff +################# + +## AVR Development +*.eep +*.elf +*.lst +*.lss +*.sym +*.d +*.o +*.srec +*.map + +## Notepad++ backup files +*.bak + +## BOM files +*bom* + +################# +## Eclipse +################# + +*.pydevproject +.project +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.classpath +.settings/ +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# CDT-specific +.cproject + +# PDT-specific +.buildpath + + +############# +## Eagle +############# + +# Ignore the board and schematic backup files +*.b#? +*.s#? + + +################# +## Visual Studio +################# + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results +[Dd]ebug/ +[Rr]elease/ +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.vspscc +.builds +*.dotCover + +## TODO: If you have NuGet Package Restore enabled, uncomment this +#packages/ + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf + +# Visual Studio profiler +*.psess +*.vsp + +# ReSharper is a .NET coding add-in +_ReSharper* + +# Installshield output folder +[Ee]xpress + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish + +# Others +[Bb]in +[Oo]bj +sql +TestResults +*.Cache +ClientBin +stylecop.* +~$* +*.dbmdl +Generated_Code #added for RIA/Silverlight projects + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML + + +############ +## Windows +############ + +# Windows image file caches +Thumbs.db + +# Folder config file +Desktop.ini + + +############# +## Python +############# + +*.py[co] + +# Packages +*.egg +*.egg-info +dist +build +eggs +parts +bin +var +sdist +develop-eggs +.installed.cfg + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox + +#Translations +*.mo + +#Mr Developer +.mr.developer.cfg + +# Mac crap +.DS_Store diff --git a/Libraries/Arduino/LICENSE.md b/Libraries/Arduino/LICENSE.md new file mode 100644 index 0000000..e0f971f --- /dev/null +++ b/Libraries/Arduino/LICENSE.md @@ -0,0 +1,57 @@ +SparkFun License Information +============================ + +SparkFun uses two different licenses for our files - one for hardware and one for code. + +Hardware +--------- + +**SparkFun hardware is released under [Creative Commons Share-alike 4.0 International](http://creativecommons.org/licenses/by-sa/4.0/).** + +Note: This is a human-readable summary of (and not a substitute for) the [license](http://creativecommons.org/licenses/by-sa/4.0/legalcode). + +You are free to: + +Share — copy and redistribute the material in any medium or format +Adapt — remix, transform, and build upon the material +for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. +ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original. +No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. +Notices: + +You do not have to comply with the license for elements of the material in the public domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary for your intended use. For example, other rights such as publicity, privacy, or moral rights may limit how you use the material. + + +Code +-------- + +**SparkFun code, firmware, and software is released under the [MIT License](http://opensource.org/licenses/MIT).** + +The MIT License (MIT) + +Copyright (c) 2015 SparkFun Electronics + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + diff --git a/Libraries/Arduino/README.md b/Libraries/Arduino/README.md new file mode 100644 index 0000000..58f2078 --- /dev/null +++ b/Libraries/Arduino/README.md @@ -0,0 +1,62 @@ +SparkFun LIS3DH Arduino Library +======================================== + + ![LIS3DH Breakout](https://cdn.sparkfun.com//assets/parts/1/1/6/8/0/13963-02.jpg) + + [*LIS3DH Breakout (SEN-13963)*](https://www.sparkfun.com/products/13963) + +This is an arduino IDE library to control the LIS3DH. It can be configured to use I2C or SPI with 2 instances per I2C channel or any number of SPI instances. The top-level driver, class LIS3DH, contains an inner driver LIS3DHCore, a settings struct, and float-based math functions for conversion from raw to meaningful numbers. + +This has been tested with Arduino Uno. TODO:(*and Teensy 3.1 architectures*). + +Repository Contents +------------------- + +* **/examples** - Example sketches for the library (.ino). Run these from the Arduino IDE. +* **/extras** - Contains class diagrams for the driver. Ignored by IDE. +* **/src** - Source files for the library (.cpp, .h). +* **keywords.txt** - Keywords from this library that will be highlighted in the Arduino IDE. +* **library.properties** - General library properties for the Arduino package manager. + +Example Briefs +-------------- + +* ADCUsage - Demonstrates analog in reads and has notes about temperature collection +* FifoExample - Demonstrates using the built-in buffer to burst-collect data - **Good demonstration of settings** +* FullSettingExample - Shows all settings, with non-used options commented out +* IntUsage - shows configuration of interrupt bits +* LowLevelExample - Demonstrates using only the core driver without math and settings overhead +* MinimalistExample - The **easiest** configuration +* MultiI2C - Using two LIS3DHs over I2C +* MultiSPI - Using two LIS3DHs over SPI + +Documentation +-------------- + +* **[Installing an Arduino Library Guide](https://learn.sparkfun.com/tutorials/installing-an-arduino-library)** - Basic information on how to install an Arduino library. +* **[Product Repository](https://github.com/sparkfun/LIS3DH_Breakout)** - Main repository (including hardware files) for the LIS3DH Breakout. +* **[Hookup Guide](https://learn.sparkfun.com/tutorials/lis3dh-hookup-guide)** - Basic hookup guide for the LIS3DH Breakout. + +Products that use this Library +--------------------------------- + +* [SEN-13963](https://www.sparkfun.com/)- LIS3DH Breakout board + +Version History +--------------- + +* [V 1.0.0](https://github.com/sparkfun/SparkFun_LIS3DH_Arduino_Library/releases/tag/V_1.0.0) -- Initial commit of Arduino 1.6-compatible library. + +License Information +------------------- + +This product is _**open source**_! + +Please review the LICENSE.md file for license information. + +If you have any questions or concerns on licensing, please contact techsupport@sparkfun.com. + +Distributed as-is; no warranty is given. + +- Your friends at SparkFun. + diff --git a/Libraries/Arduino/examples/ADCUsage/ADCUsage.ino b/Libraries/Arduino/examples/ADCUsage/ADCUsage.ino new file mode 100644 index 0000000..07ec5ab --- /dev/null +++ b/Libraries/Arduino/examples/ADCUsage/ADCUsage.ino @@ -0,0 +1,83 @@ +/****************************************************************************** +ADCUsage.ino + +Marshall Taylor @ SparkFun Electronics +Nov 16, 2016 +https://github.com/sparkfun/LIS3DH_Breakout +https://github.com/sparkfun/SparkFun_LIS3DH_Arduino_Library + +Description: +ADC pin reading. + +This returns 10 bit values for the 3 analog in pins. The ADC works a little different +than the arduino, in that the detectable range is centered around half-rail voltage and +is not rail to rail. Connect a potentiometer between 3.3v and ground, and with the +wiper connected to a pin. + +Also shown in this sketch is how the temperature is handled in the LIS3DH. +When temperature is enabled, ADC3 can be read to determine the temperature change +only, with a LSb worth 1 degree celsius. + +Resources: +Uses Wire.h for i2c operation +Uses SPI.h for SPI operation +Either can be omitted if not used + +Development environment specifics: +Arduino IDE 1.6.4 +Teensy loader 1.23 + +Hardware connections: +Connect I2C SDA line to A4 +Connect I2C SCL line to A5 +Connect GND and 3.3v power to the IMU + +This code is released under the [MIT License](http://opensource.org/licenses/MIT). + +Please review the LICENSE.md file included with this example. If you have any questions +or concerns with licensing, please contact techsupport@sparkfun.com. + +Distributed as-is; no warranty is given. +******************************************************************************/ + +#include "SparkFunLIS3DH.h" +#include "Wire.h" +#include "SPI.h" + +LIS3DH myIMU; //Default constructor is I2C, addr 0x19. + +void setup() { + // put your setup code here, to run once: + Serial.begin(9600); + delay(1000); //relax... + Serial.println("Processor came out of reset.\n"); + + myIMU.settings.adcEnabled = 1; + //Note: By also setting tempEnabled = 1, temperature data is available + //on ADC3. Temperature *differences* can be read at a rate of + //1 degree C per unit of ADC3 + myIMU.settings.tempEnabled = 0; + myIMU.settings.accelSampleRate = 50; //Hz. Can be: 0,1,10,25,50,100,200,400,1600,5000 Hz + myIMU.settings.accelRange = 2; //Max G force readable. Can be: 2, 4, 8, 16 + myIMU.settings.xAccelEnabled = 0; + myIMU.settings.yAccelEnabled = 0; + myIMU.settings.zAccelEnabled = 0; + + //Call .begin() to configure the IMU + myIMU.begin(); + +} + +void loop() +{ + //Get all parameters + Serial.print("\nADC:\n"); + Serial.print(" 1 = "); + Serial.println(myIMU.read10bitADC1()); + Serial.print(" 2 = "); + Serial.println(myIMU.read10bitADC2()); + Serial.print(" 3 = "); + Serial.println(myIMU.read10bitADC3()); + + delay(300); +} diff --git a/Libraries/Arduino/examples/FifoExample/FifoExample.ino b/Libraries/Arduino/examples/FifoExample/FifoExample.ino new file mode 100644 index 0000000..b3ce030 --- /dev/null +++ b/Libraries/Arduino/examples/FifoExample/FifoExample.ino @@ -0,0 +1,114 @@ +/****************************************************************************** +FifoExample.ino + +Marshall Taylor @ SparkFun Electronics +Nov 16, 2016 +https://github.com/sparkfun/LIS3DH_Breakout +https://github.com/sparkfun/SparkFun_LIS3DH_Arduino_Library + +Description: +This sketch configures the FIFO, then only collects data when the watermark +is passed. + +The data output to the serial monitor is in CSV (comma separated variables) format, and +can be copy-pasted into a spreadsheet to make graphs. + +When doing math on profiles of acceleration, this is a good way to make sure the data +samples occur regularly. + +Resources: +Uses Wire.h for i2c operation +Uses SPI.h for SPI operation +Either can be omitted if not used + +Development environment specifics: +Arduino IDE 1.6.4 +Teensy loader 1.23 + +Hardware connections: +Connect I2C SDA line to A4 +Connect I2C SCL line to A5 +Connect GND and 3.3v power to the IMU + +This code is released under the [MIT License](http://opensource.org/licenses/MIT). + +Please review the LICENSE.md file included with this example. If you have any questions +or concerns with licensing, please contact techsupport@sparkfun.com. + +Distributed as-is; no warranty is given. +******************************************************************************/ + +#include "SparkFunLIS3DH.h" +#include "Wire.h" +#include "SPI.h" + +LIS3DH myIMU; //Default constructor is I2C, addr 0x19. + +uint32_t sampleNumber = 0; //Used to make CSV output row numbers + +void setup() { + // put your setup code here, to run once: + Serial.begin(9600); + delay(1000); //relax... + Serial.println("Processor came out of reset.\n"); + + myIMU.settings.adcEnabled = 0; + //Note: By also setting tempEnabled = 1, temperature data is available + //instead of ADC3 in. Temperature *differences* can be read at a rate of + //1 degree C per unit of ADC3 data. + myIMU.settings.tempEnabled = 0; + myIMU.settings.accelSampleRate = 10; //Hz. Can be: 0,1,10,25,50,100,200,400,1600,5000 Hz + myIMU.settings.accelRange = 2; //Max G force readable. Can be: 2, 4, 8, 16 + myIMU.settings.xAccelEnabled = 1; + myIMU.settings.yAccelEnabled = 1; + myIMU.settings.zAccelEnabled = 1; + + //FIFO control settings + myIMU.settings.fifoEnabled = 1; + myIMU.settings.fifoThreshold = 20; //Can be 0 to 32 + myIMU.settings.fifoMode = 1; //FIFO mode. + //fifoMode can be: + // 0 (Bypass mode, FIFO off) + // 1 (FIFO mode) + // 3 (FIFO until full) + // 4 (FIFO when trigger) + + //Call .begin() to configure the IMU (except for the fifo) + myIMU.begin(); + + Serial.print("Configuring FIFO with no error checking..."); + myIMU.fifoBegin(); //Configure fifo + Serial.print("Done!\n"); + + Serial.print("Clearing out the FIFO..."); + myIMU.fifoClear(); + Serial.print("Done!\n"); + myIMU.fifoStartRec(); //cause fifo to start taking data (re-applies mode bits) + +} + +void loop() +{ + //float temp; //This is to hold read data + //uint16_t tempUnsigned; + // + while(( myIMU.fifoGetStatus() & 0x80 ) == 0) {}; //Wait for watermark + + //Now loop until FIFO is empty. + //If having problems with the fifo not restarting after reading data, use the watermark + //bits (b5 to b0) instead. + //while(( myIMU.fifoGetStatus() & 0x1F ) > 2) //This checks that there is only a couple entries left + while(( myIMU.fifoGetStatus() & 0x20 ) == 0) //This checks for the 'empty' flag + { + Serial.print(sampleNumber); + Serial.print(","); + Serial.print(myIMU.readFloatAccelX()); + Serial.print(","); + Serial.print(myIMU.readFloatAccelY()); + Serial.print(","); + Serial.print(myIMU.readFloatAccelZ()); + Serial.println(); + sampleNumber++; + } + +} \ No newline at end of file diff --git a/Libraries/Arduino/examples/FullSettingExample/FullSettingExample.ino b/Libraries/Arduino/examples/FullSettingExample/FullSettingExample.ino new file mode 100644 index 0000000..50c09b9 --- /dev/null +++ b/Libraries/Arduino/examples/FullSettingExample/FullSettingExample.ino @@ -0,0 +1,76 @@ +/****************************************************************************** +FullSettingExample.ino + +Marshall Taylor @ SparkFun Electronics +Nov 16, 2016 +https://github.com/sparkfun/LIS3DH_Breakout +https://github.com/sparkfun/SparkFun_LIS3DH_Arduino_Library + +Description: +Most basic example of use. + +Example using the LSM6DS3 with settings applied within the begin() section. +This sketch collects accelerometer data every second, then presents +it on the serial monitor. + +Resources: +Uses Wire.h for i2c operation +Uses SPI.h for SPI operation +Either can be omitted if not used + +Development environment specifics: +Arduino IDE 1.6.4 +Teensy loader 1.23 + +Hardware connections: +Connect I2C SDA line to A4 +Connect I2C SCL line to A5 +Connect GND and 3.3v power to the IMU + +This code is released under the [MIT License](http://opensource.org/licenses/MIT). + +Please review the LICENSE.md file included with this example. If you have any questions +or concerns with licensing, please contact techsupport@sparkfun.com. + +Distributed as-is; no warranty is given. +******************************************************************************/ + +#include "SparkFunLIS3DH.h" +#include "Wire.h" +#include "SPI.h" + +LIS3DH myIMU(I2C_MODE, 0x19); //Default constructor is I2C, addr 0x19. + +void setup() { + // put your setup code here, to run once: + Serial.begin(9600); + delay(1000); //relax... + Serial.println("Processor came out of reset.\n"); + + myIMU.settings.adcEnabled = 1; + myIMU.settings.tempEnabled = 1; + myIMU.settings.accelSampleRate = 50; //Hz. Can be: 0,1,10,25,50,100,200,400,1600,5000 Hz + myIMU.settings.accelRange = 16; //Max G force readable. Can be: 2, 4, 8, 16 + myIMU.settings.xAccelEnabled = 1; + myIMU.settings.yAccelEnabled = 1; + myIMU.settings.zAccelEnabled = 1; + + //Call .begin() to configure the IMU + myIMU.begin(); + +} + + +void loop() +{ + //Get all parameters + Serial.print("\nAccelerometer:\n"); + Serial.print(" X = "); + Serial.println(myIMU.readFloatAccelX(), 4); + Serial.print(" Y = "); + Serial.println(myIMU.readFloatAccelY(), 4); + Serial.print(" Z = "); + Serial.println(myIMU.readFloatAccelZ(), 4); + + delay(1000); +} diff --git a/Libraries/Arduino/examples/IntUsage/IntUsage.ino b/Libraries/Arduino/examples/IntUsage/IntUsage.ino new file mode 100644 index 0000000..46920a1 --- /dev/null +++ b/Libraries/Arduino/examples/IntUsage/IntUsage.ino @@ -0,0 +1,221 @@ +/****************************************************************************** +IntUsage.ino + +Marshall Taylor @ SparkFun Electronics +Nov 16, 2016 +https://github.com/sparkfun/LIS3DH_Breakout +https://github.com/sparkfun/SparkFun_LIS3DH_Arduino_Library + +Description: +Interrupt support for the LIS3DH is extremely flexible, so configuration must be left +to the user. This sketch demonstrates how to make a interrupt configuration function. + +Use configIntterupts() as a template, then comment/uncomment desired options. +See ST docs for information + Doc ID 18198 (AN3308): LIS3DHpplication information + Doc ID 17530: LIS3DH datasheet + +Resources: +Uses Wire.h for i2c operation +Uses SPI.h for SPI operation +Either can be omitted if not used + +Development environment specifics: +Arduino IDE 1.6.4 +Teensy loader 1.23 + +Hardware connections: +Connect I2C SDA line to A4 +Connect I2C SCL line to A5 +Connect GND and 3.3v power to the IMU + +This code is released under the [MIT License](http://opensource.org/licenses/MIT). + +Please review the LICENSE.md file included with this example. If you have any questions +or concerns with licensing, please contact techsupport@sparkfun.com. + +Distributed as-is; no warranty is given. +******************************************************************************/ + +#include "SparkFunLIS3DH.h" +#include "Wire.h" +#include "SPI.h" + +LIS3DH myIMU(I2C_MODE, 0x19); //Default constructor is I2C, addr 0x19. + +void setup() { + // put your setup code here, to run once: + Serial.begin(9600); + delay(1000); //relax... + Serial.println("Processor came out of reset.\n"); + + //Accel sample rate and range effect interrupt time and threshold values!!! + myIMU.settings.accelSampleRate = 50; //Hz. Can be: 0,1,10,25,50,100,200,400,1600,5000 Hz + myIMU.settings.accelRange = 2; //Max G force readable. Can be: 2, 4, 8, 16 + + myIMU.settings.adcEnabled = 0; + myIMU.settings.tempEnabled = 0; + myIMU.settings.xAccelEnabled = 1; + myIMU.settings.yAccelEnabled = 1; + myIMU.settings.zAccelEnabled = 1; + + //Call .begin() to configure the IMU + myIMU.begin(); + + configIntterupts(); + +} + + +void loop() +{ + //Get all parameters + //Serial.print("\nAccelerometer:\n"); + //Serial.print(" X = "); + //Serial.println(myIMU.readFloatAccelX(), 4); + //Serial.print(" Y = "); + //Serial.println(myIMU.readFloatAccelY(), 4); + //Serial.print(" Z = "); + //Serial.println(myIMU.readFloatAccelZ(), 4); + + uint8_t dataRead; + + Serial.print("LIS3DH_INT1_SRC: 0x"); + myIMU.readRegister(&dataRead, LIS3DH_INT1_SRC);//cleared by reading + Serial.println(dataRead, HEX); + Serial.println("Decoded events:"); + if(dataRead & 0x40) Serial.println("Interrupt Active"); + if(dataRead & 0x20) Serial.println("Z high"); + if(dataRead & 0x10) Serial.println("Z low"); + if(dataRead & 0x08) Serial.println("Y high"); + if(dataRead & 0x04) Serial.println("Y low"); + if(dataRead & 0x02) Serial.println("X high"); + if(dataRead & 0x01) Serial.println("X low"); + Serial.println(); + + delay(1000); + + // Use this section to read back blocks of data from the LIS3DH for troubleshooting. +// //Dump regs: +// for( int i = LIS3DH_INT_COUNTER_REG; i <= LIS3DH_INT1_DURATION; i++) +// { +// Serial.print("0x"); +// Serial.print(i,HEX); +// Serial.print(": 0x"); +// myIMU.readRegister(&dataRead, i); +// Serial.println(dataRead, HEX); +// } + +} + +void configIntterupts() +{ + uint8_t dataToWrite = 0; + + //LIS3DH_INT1_CFG + //dataToWrite |= 0x80;//AOI, 0 = OR 1 = AND + //dataToWrite |= 0x40;//6D, 0 = interrupt source, 1 = 6 direction source + //Set these to enable individual axes of generation source (or direction) + // -- high and low are used generically + //dataToWrite |= 0x20;//Z high + //dataToWrite |= 0x10;//Z low + dataToWrite |= 0x08;//Y high + //dataToWrite |= 0x04;//Y low + //dataToWrite |= 0x02;//X high + //dataToWrite |= 0x01;//X low + myIMU.writeRegister(LIS3DH_INT1_CFG, dataToWrite); + + //LIS3DH_INT1_THS + dataToWrite = 0; + //Provide 7 bit value, 0x7F always equals max range by accelRange setting + dataToWrite |= 0x10; // 1/8 range + myIMU.writeRegister(LIS3DH_INT1_THS, dataToWrite); + + //LIS3DH_INT1_DURATION + dataToWrite = 0; + //minimum duration of the interrupt + //LSB equals 1/(sample rate) + dataToWrite |= 0x01; // 1 * 1/50 s = 20ms + myIMU.writeRegister(LIS3DH_INT1_DURATION, dataToWrite); + + //LIS3DH_CLICK_CFG + dataToWrite = 0; + //Set these to enable individual axes of generation source (or direction) + // -- set = 1 to enable + //dataToWrite |= 0x20;//Z double-click + dataToWrite |= 0x10;//Z click + //dataToWrite |= 0x08;//Y double-click + dataToWrite |= 0x04;//Y click + //dataToWrite |= 0x02;//X double-click + dataToWrite |= 0x01;//X click + myIMU.writeRegister(LIS3DH_CLICK_CFG, dataToWrite); + + //LIS3DH_CLICK_SRC + dataToWrite = 0; + //Set these to enable click behaviors (also read to check status) + // -- set = 1 to enable + //dataToWrite |= 0x20;//Enable double clicks + dataToWrite |= 0x04;//Enable single clicks + //dataToWrite |= 0x08;//sine (0 is positive, 1 is negative) + dataToWrite |= 0x04;//Z click detect enabled + dataToWrite |= 0x02;//Y click detect enabled + dataToWrite |= 0x01;//X click detect enabled + myIMU.writeRegister(LIS3DH_CLICK_SRC, dataToWrite); + + //LIS3DH_CLICK_THS + dataToWrite = 0; + //This sets the threshold where the click detection process is activated. + //Provide 7 bit value, 0x7F always equals max range by accelRange setting + dataToWrite |= 0x0A; // ~1/16 range + myIMU.writeRegister(LIS3DH_CLICK_THS, dataToWrite); + + //LIS3DH_TIME_LIMIT + dataToWrite = 0; + //Time acceleration has to fall below threshold for a valid click. + //LSB equals 1/(sample rate) + dataToWrite |= 0x08; // 8 * 1/50 s = 160ms + myIMU.writeRegister(LIS3DH_TIME_LIMIT, dataToWrite); + + //LIS3DH_TIME_LATENCY + dataToWrite = 0; + //hold-off time before allowing detection after click event + //LSB equals 1/(sample rate) + dataToWrite |= 0x08; // 4 * 1/50 s = 160ms + myIMU.writeRegister(LIS3DH_TIME_LATENCY, dataToWrite); + + //LIS3DH_TIME_WINDOW + dataToWrite = 0; + //hold-off time before allowing detection after click event + //LSB equals 1/(sample rate) + dataToWrite |= 0x10; // 16 * 1/50 s = 320ms + myIMU.writeRegister(LIS3DH_TIME_WINDOW, dataToWrite); + + //LIS3DH_CTRL_REG5 + //Int1 latch interrupt and 4D on int1 (preserve fifo en) + myIMU.readRegister(&dataToWrite, LIS3DH_CTRL_REG5); + dataToWrite &= 0xF3; //Clear bits of interest + dataToWrite |= 0x08; //Latch interrupt (Cleared by reading int1_src) + //dataToWrite |= 0x04; //Pipe 4D detection from 6D recognition to int1? + myIMU.writeRegister(LIS3DH_CTRL_REG5, dataToWrite); + + //LIS3DH_CTRL_REG3 + //Choose source for pin 1 + dataToWrite = 0; + //dataToWrite |= 0x80; //Click detect on pin 1 + dataToWrite |= 0x40; //AOI1 event (Generator 1 interrupt on pin 1) + dataToWrite |= 0x20; //AOI2 event () + //dataToWrite |= 0x10; //Data ready + //dataToWrite |= 0x04; //FIFO watermark + //dataToWrite |= 0x02; //FIFO overrun + myIMU.writeRegister(LIS3DH_CTRL_REG3, dataToWrite); + + //LIS3DH_CTRL_REG6 + //Choose source for pin 2 and both pin output inversion state + dataToWrite = 0; + dataToWrite |= 0x80; //Click int on pin 2 + //dataToWrite |= 0x40; //Generator 1 interrupt on pin 2 + //dataToWrite |= 0x10; //boot status on pin 2 + //dataToWrite |= 0x02; //invert both outputs + myIMU.writeRegister(LIS3DH_CTRL_REG6, dataToWrite); + +} \ No newline at end of file diff --git a/Libraries/Arduino/examples/LowLevelExample/LowLevelExample.ino b/Libraries/Arduino/examples/LowLevelExample/LowLevelExample.ino new file mode 100644 index 0000000..9aa905c --- /dev/null +++ b/Libraries/Arduino/examples/LowLevelExample/LowLevelExample.ino @@ -0,0 +1,226 @@ +/****************************************************************************** +LowLevelExample.ino + +Marshall Taylor @ SparkFun Electronics +Nov 16, 2016 +https://github.com/sparkfun/LIS3DH_Breakout +https://github.com/sparkfun/SparkFun_LIS3DH_Arduino_Library + +Description: +Example using the LIS3DH with ONLY read and write methods. It's up to you to +read the datasheets and get the sensor to behave as you will. + +This sketch saves a significant amount of memory because the settings and complex +math (such as floating point variables) doesn't exist. The cost of saved memory is +that the values are in 'counts', or raw data from the register. The user is +responsible for converting these raw values into something meaningful. + +Use the register words from SparkFunLIS3DH.h to manually configure the IC. + +Resources: +Uses Wire.h for i2c operation +Uses SPI.h for SPI operation + +Development environment specifics: +Arduino IDE 1.6.4 +Teensy loader 1.23 + +Hardware connections: +Connect I2C SDA line to A4 +Connect I2C SCL line to A5 +Connect GND and 3.3v power to the IMU + +This code is released under the [MIT License](http://opensource.org/licenses/MIT). + +Please review the LICENSE.md file included with this example. If you have any questions +or concerns with licensing, please contact techsupport@sparkfun.com. + +Distributed as-is; no warranty is given. +******************************************************************************/ + +#include "SparkFunLIS3DH.h" +#include "Wire.h" +#include "SPI.h" + +uint16_t errorsAndWarnings = 0; + +LIS3DHCore myIMU( I2C_MODE, 0x19 ); +//LIS3DHCore myIMU( SPI_MODE, 10 ); + +void setup() { + // put your setup code here, to run once: + Serial.begin(9600); + delay(1000); //relax... + Serial.println("Processor came out of reset.\n"); + + //Call .beginCore() to configure the IMU + if( myIMU.beginCore() != 0 ) + { + Serial.print("Error at beginCore().\n"); + } + else + { + Serial.print("\nbeginCore() passed.\n"); + } + + uint8_t dataToWrite = 0; //Temporary variable + + + //Setup the accelerometer****************************** + dataToWrite = 0; //Start Fresh! + dataToWrite |= 0x4 << 4; //ODR of 50Hz + dataToWrite |= 0x7; //Enable all axes + + //Now, write the patched together data + errorsAndWarnings += myIMU.writeRegister(LIS3DH_CTRL_REG1, dataToWrite); + + dataToWrite = 0x80; + errorsAndWarnings += myIMU.writeRegister(LIS3DH_CTRL_REG4, dataToWrite); + + dataToWrite = 0x80; //ADC enable + errorsAndWarnings += myIMU.writeRegister(LIS3DH_TEMP_CFG_REG, dataToWrite); + + + +// //Test interrupt configuration profile on int1 +// { +// dataToWrite = 0x40; //INT1 src +// errorsAndWarnings += myIMU.writeRegister(LIS3DH_CTRL_REG3, dataToWrite); +// dataToWrite = 0x08; //latch output int +// errorsAndWarnings += myIMU.writeRegister(LIS3DH_CTRL_REG5, dataToWrite); +// dataToWrite = 0x40; // +// //errorsAndWarnings += myIMU.writeRegister(LIS3DH_REFERENCE, dataToWrite); +// dataToWrite = 0x0A; //High X and high Y only +// errorsAndWarnings += myIMU.writeRegister(LIS3DH_INT1_CFG, dataToWrite); +// dataToWrite = 0x3F; // half amplitude? +// errorsAndWarnings += myIMU.writeRegister(LIS3DH_INT1_THS, dataToWrite); +// dataToWrite = 0x01; //duration? +// errorsAndWarnings += myIMU.writeRegister(LIS3DH_INT1_DURATION, dataToWrite); +// } + + + //Test interrupt configuration profile on int2 + { + dataToWrite = 0x40; //INT2 src + errorsAndWarnings += myIMU.writeRegister(LIS3DH_CTRL_REG6, dataToWrite); + dataToWrite = 0x08; //latch output int + errorsAndWarnings += myIMU.writeRegister(LIS3DH_CTRL_REG5, dataToWrite); + dataToWrite = 0x40; // + //errorsAndWarnings += myIMU.writeRegister(LIS3DH_REFERENCE, dataToWrite); + dataToWrite = 0x0A; //High X and high Y only + errorsAndWarnings += myIMU.writeRegister(LIS3DH_INT1_CFG, dataToWrite); + dataToWrite = 0x3F; // half amplitude? + errorsAndWarnings += myIMU.writeRegister(LIS3DH_INT1_THS, dataToWrite); + dataToWrite = 0x01; //duration? + errorsAndWarnings += myIMU.writeRegister(LIS3DH_INT1_DURATION, dataToWrite); + } + + //Get the ID: + uint8_t readData = 0; + Serial.print("\nReading LIS3DH_WHO_AM_I: 0x"); + myIMU.readRegister(&readData, LIS3DH_WHO_AM_I); + Serial.println(readData, HEX); + +} + + +void loop() +{ + int16_t temp; + uint8_t temp2; + + uint8_t readData = 0; + Serial.print("\nReading LIS3DH_WHO_AM_I: 0x"); + myIMU.readRegister(&readData, LIS3DH_WHO_AM_I); + Serial.println(readData, HEX); + + Serial.print("\nReading LIS3DH_STATUS_REG_AUX: 0x"); + myIMU.readRegister(&readData, LIS3DH_STATUS_REG_AUX); + Serial.println(readData, HEX); + + Serial.print("\nReading LIS3DH_INT1_SOURCE: 0x"); + myIMU.readRegister(&readData, LIS3DH_INT1_SOURCE); + Serial.println(readData, HEX); + + //Clear interrupts + //errorsAndWarnings += myIMU.writeRegister(LIS3DH_INT1_SOURCE, 0x00); + + //Dump regs: + for( int i = LIS3DH_STATUS_REG_AUX; i <= LIS3DH_INT1_DURATION; i++) + { + Serial.print("0x"); + Serial.print(i,HEX); + Serial.print(": 0x"); + myIMU.readRegister(&readData, i); + Serial.println(readData, HEX); + } + + //Read a register into the temp variable. +// if( myIMU.readRegister(&temp2, LIS3DH_OUT_Z_H) != 0 ) +// { +// errorsAndWarnings++; +// } +// Serial.println(temp2); + + //Get all parameters + Serial.print("\nAccelerometer Counts:\n"); + + Serial.print(" X = "); + //Read a register into the temp variable. + if( myIMU.readRegisterInt16(&temp, LIS3DH_OUT_X_L) != 0 ) + { + errorsAndWarnings++; + } + Serial.println(temp); + + Serial.print(" Y = "); + //Read a register into the temp variable. + if( myIMU.readRegisterInt16(&temp, LIS3DH_OUT_Y_L) != 0 ) + { + errorsAndWarnings++; + } + Serial.println(temp); + + Serial.print(" Z = "); + //Read a register into the temp variable. + if( myIMU.readRegisterInt16(&temp, LIS3DH_OUT_Z_L) != 0 ) + { + errorsAndWarnings++; + } + Serial.println(temp); + + + Serial.print("\nADC Counts:\n"); + + Serial.print(" ADC1 = "); + //Read a register into the temp variable. + if( myIMU.readRegisterInt16(&temp, LIS3DH_OUT_ADC1_L) != 0 ) + { + errorsAndWarnings++; + } + Serial.println(temp); + + Serial.print(" ADC2 = "); + //Read a register into the temp variable. + if( myIMU.readRegisterInt16(&temp, LIS3DH_OUT_ADC2_L) != 0 ) + { + errorsAndWarnings++; + } + Serial.println(temp); + + Serial.print(" ADC3 = "); + //Read a register into the temp variable. + if( myIMU.readRegisterInt16(&temp, LIS3DH_OUT_ADC3_L) != 0 ) + { + errorsAndWarnings++; + } + Serial.println(temp); + + + Serial.println(); + Serial.print("Total reported Errors and Warnings: "); + Serial.println(errorsAndWarnings); + + + delay(3000); +} \ No newline at end of file diff --git a/Libraries/Arduino/examples/MinimalistExample/MinimalistExample.ino b/Libraries/Arduino/examples/MinimalistExample/MinimalistExample.ino new file mode 100644 index 0000000..e9aa628 --- /dev/null +++ b/Libraries/Arduino/examples/MinimalistExample/MinimalistExample.ino @@ -0,0 +1,67 @@ +/****************************************************************************** +MinimalistExample.ino + +Marshall Taylor @ SparkFun Electronics +Nov 16, 2016 +https://github.com/sparkfun/LIS3DH_Breakout +https://github.com/sparkfun/SparkFun_LIS3DH_Arduino_Library + +Description: +Most basic example of use. + +Example using the LIS3DH with basic settings. This sketch collects +Accelerometer data every second, then presents it on the serial monitor. + +Resources: +Uses Wire.h for i2c operation +Uses SPI.h for SPI operation +Either can be omitted if not used + +Development environment specifics: +Arduino IDE 1.6.4 +Teensy loader 1.23 + +Hardware connections: +Connect I2C SDA line to A4 +Connect I2C SCL line to A5 +Connect GND and 3.3v power to the IMU + +This code is released under the [MIT License](http://opensource.org/licenses/MIT). + +Please review the LICENSE.md file included with this example. If you have any questions +or concerns with licensing, please contact techsupport@sparkfun.com. + +Distributed as-is; no warranty is given. +******************************************************************************/ + +#include "SparkFunLIS3DH.h" +#include "Wire.h" +#include "SPI.h" + +LIS3DH myIMU; //Default constructor is I2C, addr 0x19. + +void setup() { + // put your setup code here, to run once: + Serial.begin(9600); + delay(1000); //relax... + Serial.println("Processor came out of reset.\n"); + + //Call .begin() to configure the IMU + myIMU.begin(); + +} + + +void loop() +{ + //Get all parameters + Serial.print("\nAccelerometer:\n"); + Serial.print(" X = "); + Serial.println(myIMU.readFloatAccelX(), 4); + Serial.print(" Y = "); + Serial.println(myIMU.readFloatAccelY(), 4); + Serial.print(" Z = "); + Serial.println(myIMU.readFloatAccelZ(), 4); + + delay(1000); +} diff --git a/Libraries/Arduino/examples/MultiI2C/MultiI2C.ino b/Libraries/Arduino/examples/MultiI2C/MultiI2C.ino new file mode 100644 index 0000000..4e0ecbb --- /dev/null +++ b/Libraries/Arduino/examples/MultiI2C/MultiI2C.ino @@ -0,0 +1,102 @@ +/****************************************************************************** +MultiI2C.ino + +Marshall Taylor @ SparkFun Electronics +Nov 16, 2016 +https://github.com/sparkfun/LIS3DH_Breakout +https://github.com/sparkfun/SparkFun_LIS3DH_Arduino_Library + +Description: +Example using up to two LIS3DHs on the same I2C channel. If only one sensor +is attached, this sketch reports failure on that channel and runs with the +single sensor instead. + +Resources: +Uses Wire.h for i2c operation +Uses SPI.h for SPI operation +Either can be omitted if not used + +Development environment specifics: +Arduino IDE 1.6.4 +Teensy loader 1.23 + +Hardware connections +Connect I2C SDA line to A4 +Connect I2C SCL line to A5 +Connect GND and ***3.3v*** power to the IMU. The sensors are not 5v tolerant. + +(Multiple I2C devices use the same pins. Up to two LIS3DHs are allowed. Use +the solder jumper to select address 0x19 (default) or 0x18) + +This code is released under the [MIT License](http://opensource.org/licenses/MIT). + +Please review the LICENSE.md file included with this example. If you have any questions +or concerns with licensing, please contact techsupport@sparkfun.com. + +Distributed as-is; no warranty is given. +******************************************************************************/ + +#include "SparkFunLIS3DH.h" +#include "Wire.h" +#include "SPI.h" + +//Create two instances of the driver class +LIS3DH SensorOne( I2C_MODE, 0x19 ); +LIS3DH SensorTwo( I2C_MODE, 0x18 ); + +void setup() { + // put your setup code here, to run once: + Serial.begin(9600); + delay(1000); //relax... + Serial.println("Processor came out of reset.\n"); + + //Call .begin() to configure the IMUs + if( SensorOne.begin() != 0 ) + { + Serial.println("Problem starting the sensor at 0x19."); + } + else + { + Serial.println("Sensor at 0x19 started."); + } + if( SensorTwo.begin() != 0 ) + { + Serial.println("Problem starting the sensor at 0x18."); + } + else + { + Serial.println("Sensor at 0x18 started."); + } + +} + + +void loop() +{ + //Get all parameters + Serial.print("\nAccelerometer:\n"); + Serial.print(" X1 = "); + Serial.println(SensorOne.readFloatAccelX(), 4); + Serial.print(" Y1 = "); + Serial.println(SensorOne.readFloatAccelY(), 4); + Serial.print(" Z1 = "); + Serial.println(SensorOne.readFloatAccelZ(), 4); + Serial.print(" X2 = "); + Serial.println(SensorTwo.readFloatAccelX(), 4); + Serial.print(" Y2 = "); + Serial.println(SensorTwo.readFloatAccelY(), 4); + Serial.print(" Z2 = "); + Serial.println(SensorTwo.readFloatAccelZ(), 4); + + Serial.print("\nSensorOne Bus Errors Reported:\n"); + Serial.print(" All '1's = "); + Serial.println(SensorOne.allOnesCounter); + Serial.print(" Non-success = "); + Serial.println(SensorOne.nonSuccessCounter); + Serial.print("SensorTwo Bus Errors Reported:\n"); + Serial.print(" All '1's = "); + Serial.println(SensorTwo.allOnesCounter); + Serial.print(" Non-success = "); + Serial.println(SensorTwo.nonSuccessCounter); + delay(1000); +} diff --git a/Libraries/Arduino/examples/MultiSPI/MultiSPI.ino b/Libraries/Arduino/examples/MultiSPI/MultiSPI.ino new file mode 100644 index 0000000..f1e7953 --- /dev/null +++ b/Libraries/Arduino/examples/MultiSPI/MultiSPI.ino @@ -0,0 +1,110 @@ +/****************************************************************************** +MultiSPI.ino + +Marshall Taylor @ SparkFun Electronics +Nov 16, 2016 +https://github.com/sparkfun/LIS3DH_Breakout +https://github.com/sparkfun/SparkFun_LIS3DH_Arduino_Library + +Description: +Example using up to two LIS3DHs on the same SPI channel, with different CS pins. +If only one sensor is attached, this sketch reports failure on that channel and +runs with the single sensor instead. + +Resources: +Uses Wire.h for i2c operation +Uses SPI.h for SPI operation +Either can be omitted if not used + +Development environment specifics: +Arduino IDE 1.6.4 +Teensy loader 1.23 + +Hardware connections +***CAUTION -- SPI pins can not be connected directly to 5v IO*** + +Connect SDA/SDI lines to pin 11 through level shifters (MOSI) +Connect SCL pin lines to pin 13 through level shifters (SCLK) +Connect SDO/SA0 lines to pin 12 through level shifters (MISO) +Connect CS to free pins through level shifters. This example uses 9 and 10. +Connect GND and ***3.3v*** power to the IMU. The sensors are not 5v tolerant. + +(Multiple SPI devices share pins except for the Chip Select lines which +are unique for each device on the bus.) + +This code is released under the [MIT License](http://opensource.org/licenses/MIT). + +Please review the LICENSE.md file included with this example. If you have any questions +or concerns with licensing, please contact techsupport@sparkfun.com. + +Distributed as-is; no warranty is given. +******************************************************************************/ + +#include "SparkFunLIS3DH.h" +#include "Wire.h" +#include "SPI.h" + +//Create two instances of the driver class +LIS3DH SensorOne( SPI_MODE, 10 ); +LIS3DH SensorTwo( SPI_MODE, 9 ); + + +void setup() { + // put your setup code here, to run once: + Serial.begin(9600); + delay(1000); //relax... + Serial.println("Processor came out of reset.\n"); + + //Call .begin() to configure the IMUs + uint8_t returnData = 0; + returnData = SensorOne.begin(); + if(( returnData != 0x00 )&&( returnData != 0xFF )) + { + Serial.println("Problem starting the sensor with CS @ Pin 10."); + } + else + { + Serial.println("Sensor with CS @ Pin 10 started."); + } + returnData = SensorTwo.begin(); + if(( returnData != 0x00 )&&( returnData != 0xFF )) + { + Serial.println("Problem starting the sensor with CS @ Pin 9."); + } + else + { + Serial.println("Sensor with CS @ Pin 9 started."); + } + +} + + +void loop() +{ + //Get all parameters + Serial.print("\nAccelerometer:\n"); + Serial.print(" X1 = "); + Serial.println(SensorOne.readFloatAccelX(), 4); + Serial.print(" Y1 = "); + Serial.println(SensorOne.readFloatAccelY(), 4); + Serial.print(" Z1 = "); + Serial.println(SensorOne.readFloatAccelZ(), 4); + Serial.print(" X2 = "); + Serial.println(SensorTwo.readFloatAccelX(), 4); + Serial.print(" Y2 = "); + Serial.println(SensorTwo.readFloatAccelY(), 4); + Serial.print(" Z2 = "); + Serial.println(SensorTwo.readFloatAccelZ(), 4); + + Serial.print("\nSensorOne Bus Errors Reported:\n"); + Serial.print(" All '1's = "); + Serial.println(SensorOne.allOnesCounter); + Serial.print(" Non-success = "); + Serial.println(SensorOne.nonSuccessCounter); + Serial.print("SensorTwo Bus Errors Reported:\n"); + Serial.print(" All '1's = "); + Serial.println(SensorTwo.allOnesCounter); + Serial.print(" Non-success = "); + Serial.println(SensorTwo.nonSuccessCounter); + delay(1000); +} diff --git a/Libraries/Arduino/examples/README.md b/Libraries/Arduino/examples/README.md new file mode 100644 index 0000000..61aa7a2 --- /dev/null +++ b/Libraries/Arduino/examples/README.md @@ -0,0 +1,15 @@ +SparkFun Arduino Examples +========================== + +Example Briefs +-------------- + +* FifoExample - Demonstrates using the built-in buffer to burst-collect data - **Good demonstration of settings** +* InterruptFreeFall - Embedded function demonstrating free-fall detection +* InterruptHWTapConfig - Embedded function demonstrating tap and double-tap detection +* LowLevelExample - Demonstrates using only the core driver without math and settings overhead +* MemoryPagingExample - Demonstrates switching between memory pages +* MinimalistExample - The **easiest** configuration +* MultiI2C - Using two LSM6DS3s over I2C +* MultiSPI - Using two LSM6DS3s over SPI +* Pedometer - Embedded function demonstrating step-counting feature diff --git a/Libraries/Arduino/extras/class diagrams.pdf b/Libraries/Arduino/extras/class diagrams.pdf new file mode 100644 index 0000000..b9f0958 Binary files /dev/null and b/Libraries/Arduino/extras/class diagrams.pdf differ diff --git a/Libraries/Arduino/keywords.txt b/Libraries/Arduino/keywords.txt new file mode 100644 index 0000000..ba968df --- /dev/null +++ b/Libraries/Arduino/keywords.txt @@ -0,0 +1,85 @@ +######################################################## +# Syntax Coloring Map for SparkFun LSM6DS3 IMU Library # +######################################################## +# Class +################################################################### + +LIS3DHCore KEYWORD1 +LIS3DH KEYWORD1 + +################################################################### +# Methods and Functions +################################################################### + +beginCore KEYWORD2 +readRegisterRegion KEYWORD2 +readRegister KEYWORD2 +readRegisterInt16 KEYWORD2 +writeRegister KEYWORD2 +settings KEYWORD2 +allOnesCounter KEYWORD2 +begin KEYWORD2 +readRawAccelX KEYWORD2 +readRawAccelY KEYWORD2 +readRawAccelZ KEYWORD2 +readFloatAccelX KEYWORD2 +readFloatAccelY KEYWORD2 +readFloatAccelZ KEYWORD2 +read10bitADC1 KEYWORD2 +read10bitADC2 KEYWORD2 +read10bitADC3 KEYWORD2 +fifoBegin KEYWORD2 +fifoClear KEYWORD2 +fifoGetStatus KEYWORD2 +fifoStartRec KEYWORD2 +fifoEnd KEYWORD2 +calcAccel KEYWORD2 + +################################################################### +# Constants +################################################################### + +I2C_MODE LITERAL1 +SPI_MODE LITERAL1 +IMU_SUCCESS LITERAL1 +IMU_HW_ERROR LITERAL1 +IMU_NOT_SUPPORTED LITERAL1 +IMU_GENERIC_ERROR LITERAL1 +IMU_OUT_OF_BOUNDS LITERAL1 +IMU_ALL_ONES_WARNING LITERAL1 +LIS3DH_STATUS_REG_AUX LITERAL1 +LIS3DH_OUT_ADC1_L LITERAL1 +LIS3DH_OUT_ADC1_H LITERAL1 +LIS3DH_OUT_ADC2_L LITERAL1 +LIS3DH_OUT_ADC2_H LITERAL1 +LIS3DH_OUT_ADC3_L LITERAL1 +LIS3DH_OUT_ADC3_H LITERAL1 +LIS3DH_WHO_AM_I LITERAL1 +LIS3DH_TEMP_CFG_REG LITERAL1 +LIS3DH_CTRL_REG1 LITERAL1 +LIS3DH_CTRL_REG2 LITERAL1 +LIS3DH_CTRL_REG3 LITERAL1 +LIS3DH_CTRL_REG4 LITERAL1 +LIS3DH_CTRL_REG5 LITERAL1 +LIS3DH_CTRL_REG6 LITERAL1 +LIS3DH_REFERENCE LITERAL1 +LIS3DH_STATUS_REG2 LITERAL1 +LIS3DH_OUT_X_L LITERAL1 +LIS3DH_OUT_X_H LITERAL1 +LIS3DH_OUT_Y_L LITERAL1 +LIS3DH_OUT_Y_H LITERAL1 +LIS3DH_OUT_Z_L LITERAL1 +LIS3DH_OUT_Z_H LITERAL1 +LIS3DH_FIFO_CTRL_REG LITERAL1 +LIS3DH_FIFO_SRC_REG LITERAL1 +LIS3DH_INT1_CFG LITERAL1 +LIS3DH_INT1_SRC LITERAL1 +LIS3DH_INT1_THS LITERAL1 +LIS3DH_INT1_DURATION LITERAL1 +LIS3DH_CLICK_CFG LITERAL1 +LIS3DH_CLICK_SRC LITERAL1 +LIS3DH_CLICK_THS LITERAL1 +LIS3DH_TIME_LIMIT LITERAL1 +LIS3DH_TIME_LATENCY LITERAL1 +LIS3DH_TIME_WINDOW LITERAL1 + diff --git a/Libraries/Arduino/library.properties b/Libraries/Arduino/library.properties new file mode 100644 index 0000000..dfe0721 --- /dev/null +++ b/Libraries/Arduino/library.properties @@ -0,0 +1,9 @@ +name=SparkFun LIS3DH Breakout +version=1.0.0 +author=SparkFun Electronics +maintainer=SparkFun Electronics +sentence=A library to drive the STmicro LIS3DH by SPI or I2C. +paragraph=Uno examples to drive by I2C or SPI, collect extra sensor inputs, and operate FIFO +category=Sensors +url=https://github.com/sparkfun/SparkFun_LIS3DH_Arduino_Library +architectures=* \ No newline at end of file diff --git a/Libraries/Arduino/src/SparkFunLIS3DH.cpp b/Libraries/Arduino/src/SparkFunLIS3DH.cpp new file mode 100644 index 0000000..f76b1c5 --- /dev/null +++ b/Libraries/Arduino/src/SparkFunLIS3DH.cpp @@ -0,0 +1,705 @@ +/****************************************************************************** +SparkFunLIS3DH.cpp +LIS3DH Arduino and Teensy Driver + +Marshall Taylor @ SparkFun Electronics +Nov 16, 2016 +https://github.com/sparkfun/LIS3DH_Breakout +https://github.com/sparkfun/SparkFun_LIS3DH_Arduino_Library + +Resources: +Uses Wire.h for i2c operation +Uses SPI.h for SPI operation +Either can be omitted if not used + +Development environment specifics: +Arduino IDE 1.6.4 +Teensy loader 1.23 + +This code is released under the [MIT License](http://opensource.org/licenses/MIT). + +Please review the LICENSE.md file included with this example. If you have any questions +or concerns with licensing, please contact techsupport@sparkfun.com. + +Distributed as-is; no warranty is given. +******************************************************************************/ +//Use VERBOSE_SERIAL to add debug serial to an existing Serial object. +//Note: Use of VERBOSE_SERIAL adds delays surround RW ops, and should not be used +//for functional testing. +//#define VERBOSE_SERIAL + +//See SparkFunLIS3DH.h for additional topology notes. + +#include "SparkFunLIS3DH.h" +#include "stdint.h" + +#include "Wire.h" +#include "SPI.h" + +//****************************************************************************// +// +// LIS3DHCore functions. +// +// Construction arguments: +// ( uint8_t busType, uint8_t inputArg ), +// +// where inputArg is address for I2C_MODE and chip select pin +// number for SPI_MODE +// +// For SPI, construct LIS3DHCore myIMU(SPI_MODE, 10); +// For I2C, construct LIS3DHCore myIMU(I2C_MODE, 0x6B); +// +// Default construction is I2C mode, address 0x6B. +// +//****************************************************************************// +LIS3DHCore::LIS3DHCore( uint8_t busType, uint8_t inputArg ) : commInterface(I2C_MODE), I2CAddress(0x19), chipSelectPin(10) +{ + commInterface = busType; + if( commInterface == I2C_MODE ) + { + I2CAddress = inputArg; + } + if( commInterface == SPI_MODE ) + { + chipSelectPin = inputArg; + } + +} + +status_t LIS3DHCore::beginCore(void) +{ + status_t returnError = IMU_SUCCESS; + + switch (commInterface) { + + case I2C_MODE: + Wire.begin(); + break; + + case SPI_MODE: + // initalize the chip select pins: + pinMode(chipSelectPin, OUTPUT); + digitalWrite(chipSelectPin, HIGH); + // start the SPI library: + SPI.begin(); + // Maximum SPI frequency is 10MHz, could divide by 2 here: + SPI.setClockDivider(SPI_CLOCK_DIV4); + // Data is read and written MSb first. + SPI.setBitOrder(MSBFIRST); + // Data is captured on rising edge of clock (CPHA = 0) + // Base value of the clock is HIGH (CPOL = 1) + + // MODE3 for 328p operation +#ifdef __AVR__ + SPI.setDataMode(SPI_MODE3); +#else +#endif + + // MODE0 for Teensy 3.1 operation +#ifdef __MK20DX256__ + SPI.setDataMode(SPI_MODE0); +#else +#endif + break; + default: + break; + } + + //Spin for a few ms + volatile uint8_t temp = 0; + for( uint16_t i = 0; i < 10000; i++ ) + { + temp++; + } + + //Check the ID register to determine if the operation was a success. + uint8_t readCheck; + readRegister(&readCheck, LIS3DH_WHO_AM_I); + if( readCheck != 0x33 ) + { + returnError = IMU_HW_ERROR; + } + + return returnError; + +} + +//****************************************************************************// +// +// ReadRegisterRegion +// +// Parameters: +// *outputPointer -- Pass &variable (base address of) to save read data to +// offset -- register to read +// length -- number of bytes to read +// +// Note: Does not know if the target memory space is an array or not, or +// if there is the array is big enough. if the variable passed is only +// two bytes long and 3 bytes are requested, this will over-write some +// other memory! +// +//****************************************************************************// +status_t LIS3DHCore::readRegisterRegion(uint8_t *outputPointer , uint8_t offset, uint8_t length) +{ + status_t returnError = IMU_SUCCESS; + + //define pointer that will point to the external space + uint8_t i = 0; + uint8_t c = 0; + uint8_t tempFFCounter = 0; + + switch (commInterface) { + + case I2C_MODE: + Wire.beginTransmission(I2CAddress); + offset |= 0x80; //turn auto-increment bit on, bit 7 for I2C + Wire.write(offset); + if( Wire.endTransmission() != 0 ) + { + returnError = IMU_HW_ERROR; + } + else //OK, all worked, keep going + { + // request 6 bytes from slave device + Wire.requestFrom(I2CAddress, length); + while ( (Wire.available()) && (i < length)) // slave may send less than requested + { + c = Wire.read(); // receive a byte as character + *outputPointer = c; + outputPointer++; + i++; + } + } + break; + + case SPI_MODE: + // take the chip select low to select the device: + digitalWrite(chipSelectPin, LOW); + // send the device the register you want to read: + SPI.transfer(offset | 0x80 | 0x40); //Ored with "read request" bit and "auto increment" bit + while ( i < length ) // slave may send less than requested + { + c = SPI.transfer(0x00); // receive a byte as character + if( c == 0xFF ) + { + //May have problem + tempFFCounter++; + } + *outputPointer = c; + outputPointer++; + i++; + } + if( tempFFCounter == i ) + { + //Ok, we've recieved all ones, report + returnError = IMU_ALL_ONES_WARNING; + } + // take the chip select high to de-select: + digitalWrite(chipSelectPin, HIGH); + break; + + default: + break; + } + + return returnError; +} + +//****************************************************************************// +// +// ReadRegister +// +// Parameters: +// *outputPointer -- Pass &variable (address of) to save read data to +// offset -- register to read +// +//****************************************************************************// +status_t LIS3DHCore::readRegister(uint8_t* outputPointer, uint8_t offset) { + //Return value + uint8_t result; + uint8_t numBytes = 1; + status_t returnError = IMU_SUCCESS; + + switch (commInterface) { + + case I2C_MODE: + Wire.beginTransmission(I2CAddress); + Wire.write(offset); + if( Wire.endTransmission() != 0 ) + { + returnError = IMU_HW_ERROR; + } + Wire.requestFrom(I2CAddress, numBytes); + while ( Wire.available() ) // slave may send less than requested + { + result = Wire.read(); // receive a byte as a proper uint8_t + } + break; + + case SPI_MODE: + // take the chip select low to select the device: + digitalWrite(chipSelectPin, LOW); + // send the device the register you want to read: + SPI.transfer(offset | 0x80); //Ored with "read request" bit + // send a value of 0 to read the first byte returned: + result = SPI.transfer(0x00); + // take the chip select high to de-select: + digitalWrite(chipSelectPin, HIGH); + + if( result == 0xFF ) + { + //we've recieved all ones, report + returnError = IMU_ALL_ONES_WARNING; + } + break; + + default: + break; + } + + *outputPointer = result; + return returnError; +} + +//****************************************************************************// +// +// readRegisterInt16 +// +// Parameters: +// *outputPointer -- Pass &variable (base address of) to save read data to +// offset -- register to read +// +//****************************************************************************// +status_t LIS3DHCore::readRegisterInt16( int16_t* outputPointer, uint8_t offset ) +{ + { + //offset |= 0x80; //turn auto-increment bit on + uint8_t myBuffer[2]; + status_t returnError = readRegisterRegion(myBuffer, offset, 2); //Does memory transfer + int16_t output = (int16_t)myBuffer[0] | int16_t(myBuffer[1] << 8); + *outputPointer = output; + return returnError; + } + +} + +//****************************************************************************// +// +// writeRegister +// +// Parameters: +// offset -- register to write +// dataToWrite -- 8 bit data to write to register +// +//****************************************************************************// +status_t LIS3DHCore::writeRegister(uint8_t offset, uint8_t dataToWrite) { + status_t returnError = IMU_SUCCESS; + switch (commInterface) { + case I2C_MODE: + //Write the byte + Wire.beginTransmission(I2CAddress); + Wire.write(offset); + Wire.write(dataToWrite); + if( Wire.endTransmission() != 0 ) + { + returnError = IMU_HW_ERROR; + } + break; + + case SPI_MODE: + // take the chip select low to select the device: + digitalWrite(chipSelectPin, LOW); + // send the device the register you want to read: + SPI.transfer(offset); + // send a value of 0 to read the first byte returned: + SPI.transfer(dataToWrite); + // decrement the number of bytes left to read: + // take the chip select high to de-select: + digitalWrite(chipSelectPin, HIGH); + break; + + //No way to check error on this write (Except to read back but that's not reliable) + + default: + break; + } + + return returnError; +} + +//****************************************************************************// +// +// Main user class -- wrapper for the core class + maths +// +// Construct with same rules as the core ( uint8_t busType, uint8_t inputArg ) +// +//****************************************************************************// +LIS3DH::LIS3DH( uint8_t busType, uint8_t inputArg ) : LIS3DHCore( busType, inputArg ) +{ + //Construct with these default settings + //ADC stuff + settings.adcEnabled = 1; + + //Temperature settings + settings.tempEnabled = 1; + + //Accelerometer settings + settings.accelSampleRate = 50; //Hz. Can be: 0,1,10,25,50,100,200,400,1600,5000 Hz + settings.accelRange = 2; //Max G force readable. Can be: 2, 4, 8, 16 + + settings.xAccelEnabled = 1; + settings.yAccelEnabled = 1; + settings.zAccelEnabled = 1; + + //FIFO control settings + settings.fifoEnabled = 0; + settings.fifoThreshold = 20; //Can be 0 to 32 + settings.fifoMode = 0; //FIFO mode. + + allOnesCounter = 0; + nonSuccessCounter = 0; + +} + +//****************************************************************************// +// +// Begin +// +// This starts the lower level begin, then applies settings +// +//****************************************************************************// +status_t LIS3DH::begin( void ) +{ + //Begin the inherited core. This gets the physical wires connected + status_t returnError = beginCore(); + + applySettings(); + + return returnError; +} + +//****************************************************************************// +// +// Configuration section +// +// This uses the stored SensorSettings to start the IMU +// Use statements such as "myIMU.settings.commInterface = SPI_MODE;" or +// "myIMU.settings.accelEnabled = 1;" to configure before calling .begin(); +// +//****************************************************************************// +void LIS3DH::applySettings( void ) +{ + uint8_t dataToWrite = 0; //Temporary variable + + //Build TEMP_CFG_REG + dataToWrite = 0; //Start Fresh! + dataToWrite = ((settings.tempEnabled & 0x01) << 6) | ((settings.adcEnabled & 0x01) << 7); + //Now, write the patched together data +#ifdef VERBOSE_SERIAL + Serial.print("LIS3DH_TEMP_CFG_REG: 0x"); + Serial.println(dataToWrite, HEX); +#endif + writeRegister(LIS3DH_TEMP_CFG_REG, dataToWrite); + + //Build CTRL_REG1 + dataToWrite = 0; //Start Fresh! + // Convert ODR + switch(settings.accelSampleRate) + { + case 1: + dataToWrite |= (0x01 << 4); + break; + case 10: + dataToWrite |= (0x02 << 4); + break; + case 25: + dataToWrite |= (0x03 << 4); + break; + case 50: + dataToWrite |= (0x04 << 4); + break; + case 100: + dataToWrite |= (0x05 << 4); + break; + case 200: + dataToWrite |= (0x06 << 4); + break; + default: + case 400: + dataToWrite |= (0x07 << 4); + break; + case 1600: + dataToWrite |= (0x08 << 4); + break; + case 5000: + dataToWrite |= (0x09 << 4); + break; + } + + dataToWrite |= (settings.zAccelEnabled & 0x01) << 2; + dataToWrite |= (settings.yAccelEnabled & 0x01) << 1; + dataToWrite |= (settings.xAccelEnabled & 0x01); + //Now, write the patched together data +#ifdef VERBOSE_SERIAL + Serial.print("LIS3DH_CTRL_REG1: 0x"); + Serial.println(dataToWrite, HEX); +#endif + writeRegister(LIS3DH_CTRL_REG1, dataToWrite); + + //Build CTRL_REG4 + dataToWrite = 0; //Start Fresh! + // Convert scaling + switch(settings.accelRange) + { + case 2: + dataToWrite |= (0x00 << 4); + break; + case 4: + dataToWrite |= (0x01 << 4); + break; + case 8: + dataToWrite |= (0x02 << 4); + break; + default: + case 16: + dataToWrite |= (0x03 << 4); + break; + } + dataToWrite |= 0x80; //set block update + dataToWrite |= 0x08; //set high resolution +#ifdef VERBOSE_SERIAL + Serial.print("LIS3DH_CTRL_REG4: 0x"); + Serial.println(dataToWrite, HEX); +#endif + //Now, write the patched together data + writeRegister(LIS3DH_CTRL_REG4, dataToWrite); + +} +//****************************************************************************// +// +// Accelerometer section +// +//****************************************************************************// +int16_t LIS3DH::readRawAccelX( void ) +{ + int16_t output; + status_t errorLevel = readRegisterInt16( &output, LIS3DH_OUT_X_L ); + if( errorLevel != IMU_SUCCESS ) + { + if( errorLevel == IMU_ALL_ONES_WARNING ) + { + allOnesCounter++; + } + else + { + nonSuccessCounter++; + } + } + return output; +} +float LIS3DH::readFloatAccelX( void ) +{ + float output = calcAccel(readRawAccelX()); + return output; +} + +int16_t LIS3DH::readRawAccelY( void ) +{ + int16_t output; + status_t errorLevel = readRegisterInt16( &output, LIS3DH_OUT_Y_L ); + if( errorLevel != IMU_SUCCESS ) + { + if( errorLevel == IMU_ALL_ONES_WARNING ) + { + allOnesCounter++; + } + else + { + nonSuccessCounter++; + } + } + return output; +} + +float LIS3DH::readFloatAccelY( void ) +{ + float output = calcAccel(readRawAccelY()); + return output; +} + +int16_t LIS3DH::readRawAccelZ( void ) +{ + int16_t output; + status_t errorLevel = readRegisterInt16( &output, LIS3DH_OUT_Z_L ); + if( errorLevel != IMU_SUCCESS ) + { + if( errorLevel == IMU_ALL_ONES_WARNING ) + { + allOnesCounter++; + } + else + { + nonSuccessCounter++; + } + } + return output; + +} + +float LIS3DH::readFloatAccelZ( void ) +{ + float output = calcAccel(readRawAccelZ()); + return output; +} + +float LIS3DH::calcAccel( int16_t input ) +{ + float output; + switch(settings.accelRange) + { + case 2: + output = (float)input / 15987; + break; + case 4: + output = (float)input / 7840; + break; + case 8: + output = (float)input / 3883; + break; + case 16: + output = (float)input / 1280; + break; + default: + output = 0; + break; + } + return output; +} + +//****************************************************************************// +// +// Accelerometer section +// +//****************************************************************************// +uint16_t LIS3DH::read10bitADC1( void ) +{ + int16_t intTemp; + uint16_t uintTemp; + readRegisterInt16( &intTemp, LIS3DH_OUT_ADC1_L ); + intTemp = 0 - intTemp; + uintTemp = intTemp + 32768; + return uintTemp >> 6; +} + +uint16_t LIS3DH::read10bitADC2( void ) +{ + int16_t intTemp; + uint16_t uintTemp; + readRegisterInt16( &intTemp, LIS3DH_OUT_ADC2_L ); + intTemp = 0 - intTemp; + uintTemp = intTemp + 32768; + return uintTemp >> 6; +} + +uint16_t LIS3DH::read10bitADC3( void ) +{ + int16_t intTemp; + uint16_t uintTemp; + readRegisterInt16( &intTemp, LIS3DH_OUT_ADC3_L ); + intTemp = 0 - intTemp; + uintTemp = intTemp + 32768; + return uintTemp >> 6; +} + +//****************************************************************************// +// +// FIFO section +// +//****************************************************************************// +void LIS3DH::fifoBegin( void ) +{ + uint8_t dataToWrite = 0; //Temporary variable + + //Build LIS3DH_FIFO_CTRL_REG + readRegister( &dataToWrite, LIS3DH_FIFO_CTRL_REG ); //Start with existing data + dataToWrite &= 0x20;//clear all but bit 5 + dataToWrite |= (settings.fifoMode & 0x03) << 6; //apply mode + dataToWrite |= (settings.fifoThreshold & 0x1F); //apply threshold + //Now, write the patched together data +#ifdef VERBOSE_SERIAL + Serial.print("LIS3DH_FIFO_CTRL_REG: 0x"); + Serial.println(dataToWrite, HEX); +#endif + writeRegister(LIS3DH_FIFO_CTRL_REG, dataToWrite); + + //Build CTRL_REG5 + readRegister( &dataToWrite, LIS3DH_CTRL_REG5 ); //Start with existing data + dataToWrite &= 0xBF;//clear bit 6 + dataToWrite |= (settings.fifoEnabled & 0x01) << 6; + //Now, write the patched together data +#ifdef VERBOSE_SERIAL + Serial.print("LIS3DH_CTRL_REG5: 0x"); + Serial.println(dataToWrite, HEX); +#endif + writeRegister(LIS3DH_CTRL_REG5, dataToWrite); +} + +void LIS3DH::fifoClear( void ) { + //Drain the fifo data and dump it + while( (fifoGetStatus() & 0x20 ) == 0 ) { + readRawAccelX(); + readRawAccelY(); + readRawAccelZ(); + } +} + +void LIS3DH::fifoStartRec( void ) +{ + uint8_t dataToWrite = 0; //Temporary variable + + //Turn off... + readRegister( &dataToWrite, LIS3DH_FIFO_CTRL_REG ); //Start with existing data + dataToWrite &= 0x3F;//clear mode +#ifdef VERBOSE_SERIAL + Serial.print("LIS3DH_FIFO_CTRL_REG: 0x"); + Serial.println(dataToWrite, HEX); +#endif + writeRegister(LIS3DH_FIFO_CTRL_REG, dataToWrite); + // ... then back on again + readRegister( &dataToWrite, LIS3DH_FIFO_CTRL_REG ); //Start with existing data + dataToWrite &= 0x3F;//clear mode + dataToWrite |= (settings.fifoMode & 0x03) << 6; //apply mode + //Now, write the patched together data +#ifdef VERBOSE_SERIAL + Serial.print("LIS3DH_FIFO_CTRL_REG: 0x"); + Serial.println(dataToWrite, HEX); +#endif + writeRegister(LIS3DH_FIFO_CTRL_REG, dataToWrite); +} + +uint8_t LIS3DH::fifoGetStatus( void ) +{ + //Return some data on the state of the fifo + uint8_t tempReadByte = 0; + readRegister(&tempReadByte, LIS3DH_FIFO_SRC_REG); +#ifdef VERBOSE_SERIAL + Serial.print("LIS3DH_FIFO_SRC_REG: 0x"); + Serial.println(tempReadByte, HEX); +#endif + return tempReadByte; +} + +void LIS3DH::fifoEnd( void ) +{ + uint8_t dataToWrite = 0; //Temporary variable + + //Turn off... + readRegister( &dataToWrite, LIS3DH_FIFO_CTRL_REG ); //Start with existing data + dataToWrite &= 0x3F;//clear mode +#ifdef VERBOSE_SERIAL + Serial.print("LIS3DH_FIFO_CTRL_REG: 0x"); + Serial.println(dataToWrite, HEX); +#endif + writeRegister(LIS3DH_FIFO_CTRL_REG, dataToWrite); +} + diff --git a/Libraries/Arduino/src/SparkFunLIS3DH.h b/Libraries/Arduino/src/SparkFunLIS3DH.h new file mode 100644 index 0000000..d8a6cdf --- /dev/null +++ b/Libraries/Arduino/src/SparkFunLIS3DH.h @@ -0,0 +1,201 @@ +/****************************************************************************** +SparkFunLIS3DH.h +LIS3DH Arduino and Teensy Driver + +Marshall Taylor @ SparkFun Electronics +Nov 16, 2016 +https://github.com/sparkfun/LIS3DH_Breakout +https://github.com/sparkfun/SparkFun_LIS3DH_Arduino_Library + +Resources: +Uses Wire.h for i2c operation +Uses SPI.h for SPI operation +Either can be omitted if not used + +Development environment specifics: +Arduino IDE 1.6.4 +Teensy loader 1.23 + +This code is released under the [MIT License](http://opensource.org/licenses/MIT). + +Please review the LICENSE.md file included with this example. If you have any questions +or concerns with licensing, please contact techsupport@sparkfun.com. + +Distributed as-is; no warranty is given. +******************************************************************************/ + +#ifndef __LIS3DH_IMU_H__ +#define __LIS3DH_IMU_H__ + +#include "stdint.h" + +//values for commInterface +#define I2C_MODE 0 +#define SPI_MODE 1 + +// Return values +typedef enum +{ + IMU_SUCCESS, + IMU_HW_ERROR, + IMU_NOT_SUPPORTED, + IMU_GENERIC_ERROR, + IMU_OUT_OF_BOUNDS, + IMU_ALL_ONES_WARNING, + //... +} status_t; + +//This is the core operational class of the driver. +// LIS3DHCore contains only read and write operations towards the IMU. +// To use the higher level functions, use the class LIS3DH which inherits +// this class. + +class LIS3DHCore +{ +public: + LIS3DHCore( uint8_t ); + LIS3DHCore( uint8_t, uint8_t ); + ~LIS3DHCore() = default; + + status_t beginCore( void ); + + //The following utilities read and write to the IMU + + //ReadRegisterRegion takes a uint8 array address as input and reads + // a chunk of memory into that array. + status_t readRegisterRegion(uint8_t*, uint8_t, uint8_t ); + + //readRegister reads one 8-bit register + status_t readRegister(uint8_t*, uint8_t); + + //Reads two 8-bit regs, LSByte then MSByte order, and concatenates them. + // Acts as a 16-bit read operation + status_t readRegisterInt16(int16_t*, uint8_t offset ); + + //Writes an 8-bit byte; + status_t writeRegister(uint8_t, uint8_t); + +private: + //Communication stuff + uint8_t commInterface; + uint8_t I2CAddress; + uint8_t chipSelectPin; +}; + +//This struct holds the settings the driver uses to do calculations +struct SensorSettings +{ +public: + //ADC and Temperature settings + uint8_t adcEnabled; + uint8_t tempEnabled; + + //Accelerometer settings + uint16_t accelSampleRate; //Hz. Can be: 0,1,10,25,50,100,200,400,1600,5000 Hz + uint8_t accelRange; //Max G force readable. Can be: 2, 4, 8, 16 + + uint8_t xAccelEnabled; + uint8_t yAccelEnabled; + uint8_t zAccelEnabled; + + //Fifo settings + uint8_t fifoEnabled; + uint8_t fifoMode; //can be 0x0,0x1,0x2,0x3 + uint8_t fifoThreshold; +}; + + +//This is the highest level class of the driver. +// +// class LIS3DH inherits the core and makes use of the beginCore() +//method through it's own begin() method. It also contains the +//settings struct to hold user settings. + +class LIS3DH : public LIS3DHCore +{ +public: + //IMU settings + SensorSettings settings; + + //Error checking + uint16_t allOnesCounter; + uint16_t nonSuccessCounter; + + //Constructor generates default SensorSettings. + //(over-ride after construction if desired) + LIS3DH( uint8_t busType = I2C_MODE, uint8_t inputArg = 0x19 ); + //~LIS3DH() = default; + + //Call to apply SensorSettings + status_t begin( void ); + void applySettings( void ); + + //Returns the raw bits from the sensor cast as 16-bit signed integers + int16_t readRawAccelX( void ); + int16_t readRawAccelY( void ); + int16_t readRawAccelZ( void ); + + //Returns the values as floats. Inside, this calls readRaw___(); + float readFloatAccelX( void ); + float readFloatAccelY( void ); + float readFloatAccelZ( void ); + + //ADC related calls + uint16_t read10bitADC1( void ); + uint16_t read10bitADC2( void ); + uint16_t read10bitADC3( void ); + + //FIFO stuff + void fifoBegin( void ); + void fifoClear( void ); + uint8_t fifoGetStatus( void ); + void fifoStartRec(); + void fifoEnd( void ); + + float calcAccel( int16_t ); + +private: + +}; + +//Device Registers +#define LIS3DH_STATUS_REG_AUX 0x07 +#define LIS3DH_OUT_ADC1_L 0x08 +#define LIS3DH_OUT_ADC1_H 0x09 +#define LIS3DH_OUT_ADC2_L 0x0A +#define LIS3DH_OUT_ADC2_H 0x0B +#define LIS3DH_OUT_ADC3_L 0x0C +#define LIS3DH_OUT_ADC3_H 0x0D +#define LIS3DH_INT_COUNTER_REG 0x0E +#define LIS3DH_WHO_AM_I 0x0F + +#define LIS3DH_TEMP_CFG_REG 0x1F +#define LIS3DH_CTRL_REG1 0x20 +#define LIS3DH_CTRL_REG2 0x21 +#define LIS3DH_CTRL_REG3 0x22 +#define LIS3DH_CTRL_REG4 0x23 +#define LIS3DH_CTRL_REG5 0x24 +#define LIS3DH_CTRL_REG6 0x25 +#define LIS3DH_REFERENCE 0x26 +#define LIS3DH_STATUS_REG2 0x27 +#define LIS3DH_OUT_X_L 0x28 +#define LIS3DH_OUT_X_H 0x29 +#define LIS3DH_OUT_Y_L 0x2A +#define LIS3DH_OUT_Y_H 0x2B +#define LIS3DH_OUT_Z_L 0x2C +#define LIS3DH_OUT_Z_H 0x2D +#define LIS3DH_FIFO_CTRL_REG 0x2E +#define LIS3DH_FIFO_SRC_REG 0x2F +#define LIS3DH_INT1_CFG 0x30 +#define LIS3DH_INT1_SRC 0x31 +#define LIS3DH_INT1_THS 0x32 +#define LIS3DH_INT1_DURATION 0x33 + +#define LIS3DH_CLICK_CFG 0x38 +#define LIS3DH_CLICK_SRC 0x39 +#define LIS3DH_CLICK_THS 0x3A +#define LIS3DH_TIME_LIMIT 0x3B +#define LIS3DH_TIME_LATENCY 0x3C +#define LIS3DH_TIME_WINDOW 0x3D + +#endif // End of __LIS3DH_IMU_H__ definition check