├── List of public functions.pdf ├── ADXL345_I2C_module_wiring.png ├── ADXL345_SPI_module_wiring.png ├── library.properties ├── src ├── xyzFloat.h ├── ADXL343_WE.h ├── xyzFloat.cpp ├── ADXL345_WE.h └── ADXL345_WE.cpp ├── LICENSE ├── examples ├── ADXL345_calibration │ └── ADXL345_calibration.ino ├── ADXL345_basic_data │ └── ADXL345_basic_data.ino ├── ADXL343_basic_data │ └── ADXL343_basic_data.ino ├── ADXL345_sleep │ └── ADXL345_sleep.ino ├── ADXL345_SPI_two_devices_two_interfaces │ └── ADXL345_SPI_two_devices_two_interfaces.ino ├── ADXL345_SPI_two_devices_one_interface │ └── ADXL345_SPI_two_devices_one_interface.ino ├── ADXL345_pitch_roll_corrected_angles │ └── ADXL345_pitch_roll_corrected_angles.ino ├── ADXL345_basic_data_with_connection_check │ └── ADXL345_basic_data_with_connection_check.ino ├── ADXL345_SPI_basic_data │ └── ADXL345_SPI_basic_data.ino ├── ADXL345_angles_orientation │ └── ADXL345_angles_orientation.ino ├── ADXL345_data_ready_interrupt │ └── ADXL345_data_ready_interrupt.ino ├── ADXL345_free_fall_interrupt │ └── ADXL345_free_fall_interrupt.ino ├── ADXL345_fifo_fifo │ └── ADXL345_fifo_fifo.ino ├── ADXL345_single_tap │ └── ADXL345_single_tap.ino ├── ADXL345_auto_sleep │ └── ADXL345_auto_sleep.ino ├── ADXL345_fifo_stream │ └── ADXL345_fifo_stream.ino ├── ADXL345_activity_inactivity_interrupt │ └── ADXL345_activity_inactivity_interrupt.ino ├── ADXL345_fifo_trigger │ └── ADXL345_fifo_trigger.ino └── ADXL345_double_tap │ └── ADXL345_double_tap.ino ├── README.md └── keywords.txt /List of public functions.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wollewald/ADXL345_WE/HEAD/List of public functions.pdf -------------------------------------------------------------------------------- /ADXL345_I2C_module_wiring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wollewald/ADXL345_WE/HEAD/ADXL345_I2C_module_wiring.png -------------------------------------------------------------------------------- /ADXL345_SPI_module_wiring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wollewald/ADXL345_WE/HEAD/ADXL345_SPI_module_wiring.png -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=ADXL345_WE 2 | version=3.1.0 3 | author=Wolfgang Ewald 4 | maintainer=Wolfgang Ewald 5 | sentence=A library for the ADXL345 and ADXL343 accelerometer 6 | paragraph=An easy-to-use library with lots of example sketches. It allows to use most of the features of the ADXL345 including all interrupts and FIFO modes. 7 | category=Sensors 8 | url=https://github.com/wollewald/ADXL345_WE 9 | architectures=* 10 | includes=ADXL345_WE.h 11 | 12 | -------------------------------------------------------------------------------- /src/xyzFloat.h: -------------------------------------------------------------------------------- 1 | /* defines the structure xyzFloat which is used for gyroscopes, accelerometers and 2 | magnetometers such as ICM209468, MPU9250, ADXL345, etc. */ 3 | 4 | #ifndef XYZ_FLOAT_H_ 5 | #define XYZ_FLOAT_H_ 6 | #include 7 | struct xyzFloat { 8 | float x; 9 | float y; 10 | float z; 11 | 12 | xyzFloat(); 13 | xyzFloat(float const x, float const y, float const z); 14 | 15 | xyzFloat operator+() const; 16 | xyzFloat operator-() const; 17 | xyzFloat operator+(xyzFloat const & summand) const; 18 | xyzFloat operator-(xyzFloat const & subtrahend) const; 19 | xyzFloat operator*(float const operand) const; 20 | xyzFloat operator*(xyzFloat const & operand) const; 21 | xyzFloat operator/(float const divisor) const; 22 | xyzFloat & operator+=(xyzFloat const & summand); 23 | xyzFloat & operator-=(xyzFloat const & subtrahend); 24 | xyzFloat & operator*=(xyzFloat const & operand); 25 | xyzFloat & operator*=(float const operand); 26 | xyzFloat & operator/=(float const divisor); 27 | }; 28 | #endif -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Wolfgang (Wolle) Ewald 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/ADXL343_WE.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * This is a library for the ADXL345 / ADXL343 accelerometer. 4 | * 5 | * You'll find several example sketches which should enable you to use the library. 6 | * 7 | * You are free to use it, change it or build on it. In case you like it, it would 8 | * be cool if you give it a star. 9 | * 10 | * If you find bugs, please inform me! 11 | * 12 | * Written by Wolfgang (Wolle) Ewald 13 | * https://wolles-elektronikkiste.de/adxl345-teil-1 (German) 14 | * https://wolles-elektronikkiste.de/en/adxl345-the-universal-accelerometer-part-1 (English) 15 | * 16 | * 17 | ******************************************************************************/ 18 | 19 | #ifndef ADXL343_WE_H_ 20 | #define ADXL343_WE_H_ 21 | 22 | #if (ARDUINO >= 100) 23 | #include "Arduino.h" 24 | #else 25 | #include "WProgram.h" 26 | #endif 27 | 28 | #include "ADXL345_WE.h" 29 | #include 30 | #include 31 | #include "xyzFloat.h" 32 | 33 | class ADXL343_WE : public ADXL345_WE { 34 | public: 35 | using ADXL345_WE::ADXL345_WE; 36 | }; 37 | 38 | 39 | 40 | #endif 41 | 42 | 43 | -------------------------------------------------------------------------------- /examples/ADXL345_calibration/ADXL345_calibration.ino: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Example sketch for the ADXL345_WE / ADXL343_WE library 3 | * 4 | * This sketch shows how to calibrate the ADXL345 5 | * It does not use the internal offset registers. 6 | * 7 | * Further information can be found on: 8 | * https://wolles-elektronikkiste.de/adxl345-teil-1 (German) 9 | * https://wolles-elektronikkiste.de/en/adxl345-the-universal-accelerometer-part-1 (English) 10 | * 11 | ***************************************************************************/ 12 | #include 13 | #include 14 | #define ADXL345_I2CADDR 0x53 // 0x1D if SDO = HIGH 15 | 16 | /* There are several ways to create your ADXL345 object: 17 | * ADXL345_WE myAcc = ADXL345_WE() -> uses Wire / I2C Address = 0x53 18 | * ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR) -> uses Wire / ADXL345_I2CADDR 19 | * ADXL345_WE myAcc = ADXL345_WE(&wire2) -> uses the TwoWire object wire2 / ADXL345_I2CADDR 20 | * ADXL345_WE myAcc = ADXL345_WE(&wire2, ADXL345_I2CADDR) -> all together 21 | */ 22 | ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR); 23 | 24 | void setup(){ 25 | Wire.begin(); 26 | Serial.begin(115200); 27 | Serial.println(F("ADXL345_Sketch - Calibration")); 28 | Serial.println(); 29 | if(!myAcc.init()){ 30 | Serial.println(F("ADXL345 not connected!")); 31 | } 32 | Serial.println(F("Calibration procedure:")); 33 | Serial.println(F(" - stay in full resolution")); 34 | Serial.println(F(" - supply voltage has influence (at least for the modules)")); 35 | Serial.println(F(" -> choose the same voltage you will use in your project!")); 36 | Serial.println(F(" - turn your ADXL slowly (!) to find the min and max raw x,y and z values")); 37 | Serial.println(F(" - deviations of one or two units don't matter much")); 38 | Serial.println(F(" - the calibration changes the slope of g vs raw and assumes zero is (min+max)/2 ")); 39 | Serial.println(F(" - write down the six values ")); 40 | Serial.println(F(" - you can try the calibration values in ADXL345_angles_tilt_orientation.ino example sketch")); 41 | Serial.println(F(" - ready to go? Then type in any key and send. ")); 42 | while(!Serial.available()); 43 | Serial.read(); 44 | Serial.println(); Serial.println(); Serial.println(); 45 | } 46 | 47 | void loop() { 48 | xyzFloat raw; 49 | myAcc.getRawValues(&raw); 50 | Serial.print(F("Raw-x = ")); 51 | Serial.print(raw.x); 52 | Serial.print(F(" | Raw-y = ")); 53 | Serial.print(raw.y); 54 | Serial.print(F(" | Raw-z = ")); 55 | Serial.println(raw.z); 56 | 57 | delay(1000); 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/xyzFloat.cpp: -------------------------------------------------------------------------------- 1 | /* defines the structure xyzFloat which is used for gyroscopes, accelerometers and 2 | magnetometers such as ICM20948, MPU9250, ADXL345, etc. */ 3 | 4 | #include "xyzFloat.h" 5 | 6 | xyzFloat::xyzFloat() 7 | : xyzFloat(0.f, 0.f, 0.f) 8 | { 9 | // intentionally empty 10 | } 11 | 12 | xyzFloat::xyzFloat(float const x, float const y, float const z) 13 | : x(x) 14 | , y(y) 15 | , z(z) 16 | { 17 | // intentionally empty 18 | } 19 | 20 | xyzFloat xyzFloat::operator+() const 21 | { 22 | return *this; 23 | } 24 | 25 | xyzFloat xyzFloat::operator-() const 26 | { 27 | return xyzFloat{-x, 28 | -y, 29 | -z}; 30 | } 31 | 32 | xyzFloat xyzFloat::operator+(xyzFloat const & summand) const 33 | { 34 | return xyzFloat{x + summand.x, 35 | y + summand.y, 36 | z + summand.z}; 37 | } 38 | 39 | xyzFloat xyzFloat::operator-(xyzFloat const & subtrahend) const 40 | { 41 | return xyzFloat{x - subtrahend.x, 42 | y - subtrahend.y, 43 | z - subtrahend.z}; 44 | } 45 | 46 | xyzFloat xyzFloat::operator*(float const operand) const 47 | { 48 | return xyzFloat{x * operand, 49 | y * operand, 50 | z * operand}; 51 | } 52 | 53 | xyzFloat xyzFloat::operator*(xyzFloat const & operand) const 54 | { 55 | return xyzFloat{x * operand.x, 56 | y * operand.y, 57 | z * operand.z}; 58 | } 59 | 60 | xyzFloat xyzFloat::operator/(float const divisor) const 61 | { 62 | return xyzFloat{x / divisor, 63 | y / divisor, 64 | z / divisor}; 65 | } 66 | 67 | xyzFloat & xyzFloat::operator+=(xyzFloat const & summand) 68 | { 69 | x += summand.x; 70 | y += summand.y; 71 | z += summand.z; 72 | return *this; 73 | } 74 | 75 | xyzFloat & xyzFloat::operator-=(xyzFloat const & subtrahend) 76 | { 77 | x -= subtrahend.x; 78 | y -= subtrahend.y; 79 | z -= subtrahend.z; 80 | return *this; 81 | } 82 | 83 | xyzFloat & xyzFloat::operator*=(xyzFloat const & operand) 84 | { 85 | x *= operand.x; 86 | y *= operand.y; 87 | z *= operand.z; 88 | return *this; 89 | } 90 | 91 | xyzFloat & xyzFloat::operator*=(float const operand) 92 | { 93 | x *= operand; 94 | y *= operand; 95 | z *= operand; 96 | return *this; 97 | } 98 | 99 | xyzFloat & xyzFloat::operator/=(float const divisor) 100 | { 101 | x /= divisor; 102 | y /= divisor; 103 | z /= divisor; 104 | return *this; 105 | } 106 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ADXL345_WE 2 | Arduino Library for the ADXL345 and the ADXL343 accelerometer. 3 | 4 | I have tried to create a library for the ADXL345 which is easy to use for people who don't want to deal with all the registers. Therefore I have added lots example sketches which will enable you to deal even with the more complex features such as the FIFO modes. Howerever I still recommend to have a look into the data sheet to get a deeper understanding. 5 | 6 | You can use both I2C and SPI. If you want to find out how to use SPI, look at the ADXL345_SPI_basic_data.ino. 7 | 8 |

ADXL343 vs. ADXL345

9 | The ADXL343 has the same registers and settings like the ADXL345. The data sheets of both devices differ only marginally, e.g. the sensitivity of the ADXL345 has defined min./max. values, whereas the ADXL343 has only typical values. All example sketches run on both devices without any changes. However, with version 3.0.2 I have introduced a new ADXL343_WE class and defines like "ADXL343_RANGE_8G" because users might feel better using the correct name. 10 | 11 | 12 | The ADXL343 modules that I have seen so far have two QWIIC connectors, which are convenient to use if your MCU board also has a QWIIC connector (e.g. Arduino UNO R4). 13 | 14 |

General Information

15 | 16 | A detailed tutorial is available: 17 | 18 | https://wolles-elektronikkiste.de/adxl345-teil-1 (German) 19 | 20 | https://wolles-elektronikkiste.de/en/adxl345-the-universal-accelerometer-part-1 (English) 21 | 22 | If you are not so much experienced with the ADXL345, I recommend to work through the examples in the following order: 23 | 24 | 1) ADXL345_basic_data 25 | 2) ADXL345_SPI_basic_data 26 | 3) ADXL345_basic_data_with_connection_check 27 | 4) ADXL345_calibration 28 | 5) ADXL345_angles_orientation 29 | 6) ADXL345_pitch_roll_corrected_angles 30 | 7) ADXL345_sleep 31 | 8) ADXL345_free_fall_interrupt 32 | 9) ADXL345_data_ready_interrupt 33 | 10) ADXL345_activity_inactivity_interrupt 34 | 11) ADXL345_auto_sleep.ino 35 | 12) ADXL345_single_tap 36 | 13) ADXL345_double_tap 37 | 14) ADXL345_fifo_fifo 38 | 15) ADXL345_fifo_stream 39 | 16) ADXL345_fifo_trigger 40 | 17) ADXL345_SPI_two_devices_one_interface 41 | 18) ADXL345_SPI_two_devices_two_interfaces 42 | 43 | To develop this library I have worked with a ADXL345 module. It should also work with the bare ADXL345 IC. For the module I have noticed that the power consumption is much higher than mentioned in the data sheet. I think the issue is the voltage converter on the module. You can reduce the power consumption by choosing 3.3 volts instead of 5 volts. At least this worked with my module. 44 | 45 | If you like my library please give it a star. If you don't like it I would be happy to get feedback. And if you find bugs I will try to eliminate them as quickly as possible. 46 | 47 |

If SPI does not work

48 | 49 | My library has implemented SPI 4-Wire. Some modules have SDO connected GND via an 0 ohm resistor. With this resistor only SPI 3-Wire would work. Your options are: 50 | 51 | 1) Remove the 0 ohm resistor connected to SDO (R4 on my module) 52 | 2) Replace the 0 ohm resistor connected to SDO by an internal or external pull-down resistor of 4.7 kohm or 10 kohm 53 | 3) Find another library which supports SPI 3-Wire 54 | 55 | ![ADXL345_hack](https://github.com/wollewald/ADXL345_WE/assets/41305162/2fc39482-70f7-4de1-ac0b-2e27f28ac15e) 56 | 57 | Another SPI issue might occur when using ESP8266 boards like the WEMOS D1 mini or NodeMCU. The standard CS Pin (e.g. D8/GPIO15 on a WEMOS D1 mini or NodeMCU) might not work since the CS Pin on most ADXL345 modules has a pull-up resistor. And if D8 is high at reset, the ESP8266 will not boot. In that case choose a different ESP8266 pin as CS! 58 | 59 | -------------------------------------------------------------------------------- /examples/ADXL345_basic_data/ADXL345_basic_data.ino: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Example sketch for the ADXL345_WE / ADXL343_WE library 3 | * 4 | * This sketch shows how to get the basic raw and g values 5 | * 6 | * Further information can be found on: 7 | * https://wolles-elektronikkiste.de/adxl345-teil-1 (German) 8 | * https://wolles-elektronikkiste.de/en/adxl345-the-universal-accelerometer-part-1 (English) 9 | * 10 | ***************************************************************************/ 11 | 12 | #include 13 | #include 14 | #define ADXL345_I2CADDR 0x53 // 0x1D if SDO = HIGH 15 | 16 | /* There are several ways to create your ADXL345 object: 17 | * ADXL345_WE myAcc = ADXL345_WE() -> uses Wire / I2C Address = 0x53 18 | * ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR) -> uses Wire / ADXL345_I2CADDR 19 | * ADXL345_WE myAcc = ADXL345_WE(&wire2) -> uses the TwoWire object wire2 / ADXL345_I2CADDR 20 | * ADXL345_WE myAcc = ADXL345_WE(&wire2, ADXL345_I2CADDR) -> all together 21 | */ 22 | ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR); 23 | 24 | void setup(){ 25 | Wire.begin(); 26 | Serial.begin(115200); 27 | Serial.println("ADXL345_Sketch - Basic Data"); 28 | Serial.println(); 29 | if(!myAcc.init()){ 30 | Serial.println("ADXL345 not connected!"); 31 | } 32 | 33 | /* Choose the data rate Hz 34 | ADXL345_DATA_RATE_3200 3200 35 | ADXL345_DATA_RATE_1600 1600 36 | ADXL345_DATA_RATE_800 800 37 | ADXL345_DATA_RATE_400 400 38 | ADXL345_DATA_RATE_200 200 39 | ADXL345_DATA_RATE_100 100 40 | ADXL345_DATA_RATE_50 50 41 | ADXL345_DATA_RATE_25 25 42 | ADXL345_DATA_RATE_12_5 12.5 43 | ADXL345_DATA_RATE_6_25 6.25 44 | ADXL345_DATA_RATE_3_13 3.13 45 | ADXL345_DATA_RATE_1_56 1.56 46 | ADXL345_DATA_RATE_0_78 0.78 47 | ADXL345_DATA_RATE_0_39 0.39 48 | ADXL345_DATA_RATE_0_20 0.20 49 | ADXL345_DATA_RATE_0_10 0.10 50 | */ 51 | myAcc.setDataRate(ADXL345_DATA_RATE_50); 52 | delay(100); 53 | Serial.print("Data rate: "); 54 | Serial.print(myAcc.getDataRateAsString()); 55 | 56 | /* In full resolution the size of the raw values depend on the range: 57 | 2g = 10 bit; 4g = 11 bit; 8g = 12 bit; 16g =13 bit; 58 | uncomment to change to 10 bit for all ranges. 59 | */ 60 | // myAcc.setFullRes(false); 61 | 62 | /* Choose the measurement range 63 | ADXL345_RANGE_16G 16g 64 | ADXL345_RANGE_8G 8g 65 | ADXL345_RANGE_4G 4g 66 | ADXL345_RANGE_2G 2g 67 | */ 68 | myAcc.setRange(ADXL345_RANGE_4G); 69 | Serial.print(" / g-Range: "); 70 | Serial.println(myAcc.getRangeAsString()); 71 | Serial.println(); 72 | 73 | /* Uncomment to enable Low Power Mode. It saves power but slightly 74 | increases noise. LowPower only affetcs Data Rates 12.5 Hz to 400 Hz. 75 | */ 76 | // myAcc.setLowPower(true); 77 | } 78 | 79 | /* The LSB of the Data registers is 3.9 mg (milli-g, not milligramm). 80 | This value is used calculating g from raw. However, this is an ideal 81 | value which you might want to calibrate. 82 | */ 83 | 84 | void loop() { 85 | xyzFloat raw; 86 | xyzFloat g; 87 | myAcc.getRawValues(&raw); 88 | myAcc.getGValues(&g); 89 | 90 | Serial.print("Raw-x = "); 91 | Serial.print(raw.x); 92 | Serial.print(" | Raw-y = "); 93 | Serial.print(raw.y); 94 | Serial.print(" | Raw-z = "); 95 | Serial.println(raw.z); 96 | 97 | Serial.print("g-x = "); 98 | Serial.print(g.x); 99 | Serial.print(" | g-y = "); 100 | Serial.print(g.y); 101 | Serial.print(" | g-z = "); 102 | Serial.println(g.z); 103 | 104 | Serial.println(); 105 | 106 | delay(1000); 107 | 108 | } 109 | -------------------------------------------------------------------------------- /examples/ADXL343_basic_data/ADXL343_basic_data.ino: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Example sketch for the ADXL345_WE / ADXL343 library 3 | * 4 | * This sketch shows how to get the basic raw and g values from the ADXL343. 5 | * 6 | * Further information can be found on: 7 | * https://wolles-elektronikkiste.de/adxl345-teil-1 (German) 8 | * https://wolles-elektronikkiste.de/en/adxl345-the-universal-accelerometer-part-1 (English) 9 | * 10 | ***************************************************************************/ 11 | 12 | #include 13 | #include 14 | #define ADXL343_I2CADDR 0x53 // 0x1D if SDO = HIGH 15 | 16 | /* There are several ways to create your ADXL343 object: 17 | * ADXL343_WE myAcc = ADXL343_WE() -> uses Wire / I2C Address = 0x53 18 | * ADXL343_WE myAcc = ADXL343_WE(ADXL343_I2CADDR) -> uses Wire / ADXL343_I2CADDR 19 | * ADXL343_WE myAcc = ADXL343_WE(&wire2) -> uses the TwoWire object wire2 / ADXL343_I2CADDR 20 | * ADXL343_WE myAcc = ADXL343_WE(&wire2, ADXL343_I2CADDR) -> all together 21 | */ 22 | ADXL343_WE myAcc = ADXL343_WE(ADXL343_I2CADDR); 23 | 24 | void setup(){ 25 | Wire.begin(); 26 | Serial.begin(115200); 27 | Serial.println("ADXL343_Sketch - Basic Data"); 28 | Serial.println(); 29 | if(!myAcc.init()){ 30 | Serial.println("ADXL343 not connected!"); 31 | } 32 | 33 | /* Choose the data rate Hz 34 | ADXL343_DATA_RATE_3200 3200 35 | ADXL343_DATA_RATE_1600 1600 36 | ADXL343_DATA_RATE_800 800 37 | ADXL343_DATA_RATE_400 400 38 | ADXL343_DATA_RATE_200 200 39 | ADXL343_DATA_RATE_100 100 40 | ADXL343_DATA_RATE_50 50 41 | ADXL343_DATA_RATE_25 25 42 | ADXL343_DATA_RATE_12_5 12.5 43 | ADXL343_DATA_RATE_6_25 6.25 44 | ADXL343_DATA_RATE_3_13 3.13 45 | ADXL343_DATA_RATE_1_56 1.56 46 | ADXL343_DATA_RATE_0_78 0.78 47 | ADXL343_DATA_RATE_0_39 0.39 48 | ADXL343_DATA_RATE_0_20 0.20 49 | ADXL343_DATA_RATE_0_10 0.10 50 | */ 51 | myAcc.setDataRate(ADXL343_DATA_RATE_50); 52 | delay(100); 53 | Serial.print("Data rate: "); 54 | Serial.print(myAcc.getDataRateAsString()); 55 | 56 | /* In full resolution the size of the raw values depend on the range: 57 | 2g = 10 bit; 4g = 11 bit; 8g = 12 bit; 16g =13 bit; 58 | uncomment to change to 10 bit for all ranges. 59 | */ 60 | // myAcc.setFullRes(false); 61 | 62 | /* Choose the measurement range 63 | ADXL343_RANGE_16G 16g 64 | ADXL343_RANGE_8G 8g 65 | ADXL343_RANGE_4G 4g 66 | ADXL343_RANGE_2G 2g 67 | */ 68 | myAcc.setRange(ADXL343_RANGE_4G); 69 | Serial.print(" / g-Range: "); 70 | Serial.println(myAcc.getRangeAsString()); 71 | Serial.println(); 72 | 73 | /* Uncomment to enable Low Power Mode. It saves power but slightly 74 | increases noise. LowPower only affetcs Data Rates 12.5 Hz to 400 Hz. 75 | */ 76 | // myAcc.setLowPower(true); 77 | } 78 | 79 | /* The LSB of the Data registers is 3.9 mg (milli-g, not milligramm). 80 | This value is used calculating g from raw. However, this is an ideal 81 | value which you might want to calibrate. 82 | */ 83 | 84 | void loop() { 85 | xyzFloat raw; 86 | xyzFloat g; 87 | myAcc.getRawValues(&raw); 88 | myAcc.getGValues(&g); 89 | 90 | Serial.print("Raw-x = "); 91 | Serial.print(raw.x); 92 | Serial.print(" | Raw-y = "); 93 | Serial.print(raw.y); 94 | Serial.print(" | Raw-z = "); 95 | Serial.println(raw.z); 96 | 97 | Serial.print("g-x = "); 98 | Serial.print(g.x); 99 | Serial.print(" | g-y = "); 100 | Serial.print(g.y); 101 | Serial.print(" | g-z = "); 102 | Serial.println(g.z); 103 | 104 | Serial.println(); 105 | 106 | delay(1000); 107 | 108 | } 109 | -------------------------------------------------------------------------------- /examples/ADXL345_sleep/ADXL345_sleep.ino: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Example sketch for the ADXL345_WE / ADXL343_WE library 3 | * 4 | * This sketch shows how to use sleep mode of the ADXL345 and its effect 5 | * 6 | * Further information can be found on: 7 | * https://wolles-elektronikkiste.de/adxl345-teil-1 (German) 8 | * https://wolles-elektronikkiste.de/en/adxl345-the-universal-accelerometer-part-1 (English) 9 | * 10 | ***************************************************************************/ 11 | 12 | #include 13 | #include 14 | #define ADXL345_I2CADDR 0x53 // 0x1D if SDO = HIGH 15 | 16 | /* There are several ways to create your ADXL345 object: 17 | * ADXL345_WE myAcc = ADXL345_WE() -> uses Wire / I2C Address = 0x53 18 | * ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR) -> uses Wire / ADXL345_I2CADDR 19 | * ADXL345_WE myAcc = ADXL345_WE(&wire2) -> uses the TwoWire object wire2 / ADXL345_I2CADDR 20 | * ADXL345_WE myAcc = ADXL345_WE(&wire2, ADXL345_I2CADDR) -> all together 21 | */ 22 | ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR); 23 | 24 | void setup(){ 25 | Wire.begin(); 26 | Serial.begin(115200); 27 | Serial.println("ADXL345_Sketch - Sleep"); 28 | Serial.println(); 29 | if(!myAcc.init()){ 30 | Serial.println("ADXL345 not connected!"); 31 | } 32 | 33 | /* Insert your data from ADXL345_calibration.ino and uncomment for more precise results */ 34 | // myAcc.setCorrFactors(-266.0, 285.0, -268.0, 278.0, -291.0, 214.0); 35 | 36 | /* Choose the data rate Hz 37 | ADXL345_DATA_RATE_3200 3200 38 | ADXL345_DATA_RATE_1600 1600 39 | ADXL345_DATA_RATE_800 800 40 | ADXL345_DATA_RATE_400 400 41 | ADXL345_DATA_RATE_200 200 42 | ADXL345_DATA_RATE_100 100 43 | ADXL345_DATA_RATE_50 50 44 | ADXL345_DATA_RATE_25 25 45 | ADXL345_DATA_RATE_12_5 12.5 46 | ADXL345_DATA_RATE_6_25 6.25 47 | ADXL345_DATA_RATE_3_13 3.13 48 | ADXL345_DATA_RATE_1_56 1.56 49 | ADXL345_DATA_RATE_0_78 0.78 50 | ADXL345_DATA_RATE_0_39 0.39 51 | ADXL345_DATA_RATE_0_20 0.20 52 | ADXL345_DATA_RATE_0_10 0.10 53 | */ 54 | myAcc.setDataRate(ADXL345_DATA_RATE_50); 55 | Serial.print("Data rate: "); 56 | Serial.print(myAcc.getDataRateAsString()); 57 | 58 | /* Choose the measurement range 59 | ADXL345_RANGE_16G 16g 60 | ADXL345_RANGE_8G 8g 61 | ADXL345_RANGE_4G 4g 62 | ADXL345_RANGE_2G 2g 63 | */ 64 | myAcc.setRange(ADXL345_RANGE_2G); 65 | Serial.print(" / g-Range: "); 66 | Serial.println(myAcc.getRangeAsString()); 67 | Serial.println(); 68 | } 69 | 70 | void loop(){ 71 | /* Switch on (true) or switch off (false) sleep mode. Choose the wake up 72 | frequency: 73 | ADXL345_WUP_FQ_1 = 1 Hz 74 | ADXL345_WUP_FQ_2 = 2 Hz 75 | ADXL345_WUP_FQ_4 = 4 Hz 76 | ADXL345_WUP_FQ_8 = 8 Hz 77 | 78 | In this specific example you will see (provided you move the ADXL345) that 79 | in sleep mode the values are updated every third to fourth request. In awake 80 | mode the values are updated steadily. Sleep Mode saves significant power. 81 | */ 82 | myAcc.setSleep(true, ADXL345_WUP_FQ_1); 83 | Serial.println("Measure in Sleep Mode:"); 84 | doMeasurements(); 85 | 86 | myAcc.setSleep(false); 87 | Serial.println("Measure in Normal Mode:"); 88 | doMeasurements(); 89 | } 90 | 91 | 92 | void doMeasurements(){ 93 | for(int i=0; i<10; i++){ 94 | xyzFloat g; 95 | myAcc.getGValues(&g); 96 | 97 | Serial.print("g-x = "); 98 | Serial.print(g.x); 99 | Serial.print(" | g-y = "); 100 | Serial.print(g.y); 101 | Serial.print(" | g-z = "); 102 | Serial.println(g.z); 103 | 104 | delay(300); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /examples/ADXL345_SPI_two_devices_two_interfaces/ADXL345_SPI_two_devices_two_interfaces.ino: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Example sketch for the ADXL345_WE / ADXL343_WE library 3 | * 4 | * This sketch shows how use two devices with two SPI interfaces (e.g. ESP32). 5 | * 6 | * Further information can be found on: 7 | * https://wolles-elektronikkiste.de/adxl345-teil-1 (German) 8 | * https://wolles-elektronikkiste.de/en/adxl345-the-universal-accelerometer-part-1 (English) 9 | * 10 | ***************************************************************************/ 11 | 12 | #include 13 | #include 14 | #define CS_PIN_1 5 15 | #define CS_PIN_2 15 16 | bool spi = true; // flag indicating that SPI shall be used 17 | 18 | SPIClass SPI_2(HSPI); // create SPI_2 object 19 | 20 | ADXL345_WE myAcc_1 = ADXL345_WE(&SPI, CS_PIN_1, spi); 21 | ADXL345_WE myAcc_2 = ADXL345_WE(&SPI_2, CS_PIN_2, spi); 22 | 23 | void setup(){ 24 | Serial.begin(115200); 25 | /* You can set the SPI clock speed. Default is 5 MHz. */ 26 | // myAcc_1.setSPIClockSpeed(5000000); 27 | // myAcc_2.setSPIClockSpeed(5000000); 28 | 29 | Serial.println("ADXL345_Sketch - Basic Data"); 30 | if(!myAcc_1.init()){ 31 | Serial.println("ADXL345 1 not connected!"); 32 | } 33 | else{ 34 | Serial.println("ADXL345 1: success!!"); 35 | } 36 | delay(100); 37 | 38 | if(!myAcc_2.init()){ 39 | Serial.println("ADXL345 2 not connected!"); 40 | } 41 | else{ 42 | Serial.println("ADXL345 2: success!!"); 43 | } 44 | delay(100); 45 | 46 | 47 | 48 | /* Choose the data rate Hz 49 | ADXL345_DATA_RATE_3200 3200 50 | ADXL345_DATA_RATE_1600 1600 51 | ADXL345_DATA_RATE_800 800 52 | ADXL345_DATA_RATE_400 400 53 | ADXL345_DATA_RATE_200 200 54 | ADXL345_DATA_RATE_100 100 55 | ADXL345_DATA_RATE_50 50 56 | ADXL345_DATA_RATE_25 25 57 | ADXL345_DATA_RATE_12_5 12.5 58 | ADXL345_DATA_RATE_6_25 6.25 59 | ADXL345_DATA_RATE_3_13 3.13 60 | ADXL345_DATA_RATE_1_56 1.56 61 | ADXL345_DATA_RATE_0_78 0.78 62 | ADXL345_DATA_RATE_0_39 0.39 63 | ADXL345_DATA_RATE_0_20 0.20 64 | ADXL345_DATA_RATE_0_10 0.10 65 | */ 66 | /*myAcc_1.setDataRate(ADXL345_DATA_RATE_12_5); 67 | delay(100); 68 | Serial.print("Data rate: "); 69 | Serial.print(myAcc_1.getDataRateAsString());*/ 70 | 71 | /* In full resolution the size of the raw values depend on the 72 | range: 2g = 10 bit; 4g = 11 bit; 8g = 12 bit; 16g =13 bit; 73 | uncomment to change to 10 bit for all ranges. 74 | */ 75 | // myAcc.setFullRes(false); 76 | 77 | /* Choose the measurement range 78 | ADXL345_RANGE_16G 16g 79 | ADXL345_RANGE_8G 8g 80 | ADXL345_RANGE_4G 4g 81 | ADXL345_RANGE_2G 2g 82 | */ 83 | /*myAcc_1.setRange(ADXL345_RANGE_4G); 84 | Serial.print(" / g-Range: "); 85 | Serial.println(myAcc_1.getRangeAsString()); 86 | Serial.println();*/ 87 | 88 | /* Uncomment to enable Low Power Mode. It saves power but slightly 89 | increases noise. LowPower only affetcs Data Rates 12.5 Hz to 400 Hz. 90 | */ 91 | // myAcc.setLowPower(true); 92 | } 93 | 94 | /* The LSB of the Data registers is 3.9 mg (milli-g, not milligramm). 95 | This value is used calculating g from raw. However, this is an ideal 96 | value which you might want to calibrate. 97 | */ 98 | 99 | void loop() { 100 | xyzFloat g; 101 | myAcc_1.getGValues(&g); 102 | 103 | Serial.print("g-x = "); 104 | Serial.print(g.x); 105 | Serial.print(" | g-y = "); 106 | Serial.print(g.y); 107 | Serial.print(" | g-z = "); 108 | Serial.println(g.z); 109 | 110 | myAcc_2.getGValues(&g); 111 | 112 | Serial.print("g-x = "); 113 | Serial.print(g.x); 114 | Serial.print(" | g-y = "); 115 | Serial.print(g.y); 116 | Serial.print(" | g-z = "); 117 | Serial.println(g.z); 118 | 119 | Serial.println("*********************"); 120 | 121 | delay(1000); 122 | 123 | } 124 | -------------------------------------------------------------------------------- /examples/ADXL345_SPI_two_devices_one_interface/ADXL345_SPI_two_devices_one_interface.ino: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Example sketch for the ADXL345_WE / ADXL343_WE library 3 | * 4 | * This sketch shows how use two devices with one SPI interface. 5 | * 6 | * Further information can be found on: 7 | * https://wolles-elektronikkiste.de/adxl345-teil-1 (German) 8 | * https://wolles-elektronikkiste.de/en/adxl345-the-universal-accelerometer-part-1 (English) 9 | * 10 | ***************************************************************************/ 11 | 12 | #include 13 | #include 14 | #define CS_PIN_1 7 15 | #define CS_PIN_2 6 16 | // const int sensorID_1 = 42; // needed for Arduino UNO R4 Minima or WIFI 17 | // const int sensorID_2 = 4242; // needed for Arduino UNO R4 Minima or WIFI 18 | bool spi = true; // flag indicating that SPI shall be used 19 | 20 | ADXL345_WE myAcc_1 = ADXL345_WE(&SPI, CS_PIN_1, spi); 21 | ADXL345_WE myAcc_2 = ADXL345_WE(&SPI, CS_PIN_2, spi); 22 | 23 | /* For Arduino UNO R4 boards choose these constructors */ 24 | // ADXL345_WE myAcc_1 = ADXL345_WE(&SPI, CS_PIN_1, spi, sensorID_1); 25 | // ADXL345_WE myAcc_2 = ADXL345_WE(&SPI, CS_PIN_2, spi, sensorID_2); 26 | 27 | void setup(){ 28 | Serial.begin(115200); 29 | /* You can set the SPI clock speed. Default is 5 MHz. */ 30 | // myAcc_1.setSPIClockSpeed(5000000); 31 | // myAcc_2.setSPIClockSpeed(5000000); 32 | 33 | pinMode(CS_PIN_1, OUTPUT); 34 | digitalWrite(CS_PIN_1, HIGH); 35 | pinMode(CS_PIN_2, OUTPUT); 36 | digitalWrite(CS_PIN_2, HIGH); 37 | Serial.println("ADXL345_Sketch - Basic Data"); 38 | if(!myAcc_1.init()){ 39 | Serial.println("ADXL345 1 not connected!"); 40 | } 41 | else{ 42 | Serial.println("ADXL345 1: success!!"); 43 | } 44 | delay(100); 45 | 46 | if(!myAcc_2.init()){ 47 | Serial.println("ADXL345 2 not connected!"); 48 | } 49 | else{ 50 | Serial.println("ADXL345 2: success!!"); 51 | } 52 | delay(100); 53 | 54 | 55 | 56 | /* Choose the data rate Hz 57 | ADXL345_DATA_RATE_3200 3200 58 | ADXL345_DATA_RATE_1600 1600 59 | ADXL345_DATA_RATE_800 800 60 | ADXL345_DATA_RATE_400 400 61 | ADXL345_DATA_RATE_200 200 62 | ADXL345_DATA_RATE_100 100 63 | ADXL345_DATA_RATE_50 50 64 | ADXL345_DATA_RATE_25 25 65 | ADXL345_DATA_RATE_12_5 12.5 66 | ADXL345_DATA_RATE_6_25 6.25 67 | ADXL345_DATA_RATE_3_13 3.13 68 | ADXL345_DATA_RATE_1_56 1.56 69 | ADXL345_DATA_RATE_0_78 0.78 70 | ADXL345_DATA_RATE_0_39 0.39 71 | ADXL345_DATA_RATE_0_20 0.20 72 | ADXL345_DATA_RATE_0_10 0.10 73 | */ 74 | /*myAcc_1.setDataRate(ADXL345_DATA_RATE_12_5); 75 | delay(100); 76 | Serial.print("Data rate: "); 77 | Serial.print(myAcc_1.getDataRateAsString());*/ 78 | 79 | /* In full resolution the size of the raw values depend on the 80 | range: 2g = 10 bit; 4g = 11 bit; 8g = 12 bit; 16g =13 bit; 81 | uncomment to change to 10 bit for all ranges. 82 | */ 83 | // myAcc.setFullRes(false); 84 | 85 | /* Choose the measurement range 86 | ADXL345_RANGE_16G 16g 87 | ADXL345_RANGE_8G 8g 88 | ADXL345_RANGE_4G 4g 89 | ADXL345_RANGE_2G 2g 90 | */ 91 | /*myAcc_1.setRange(ADXL345_RANGE_4G); 92 | Serial.print(" / g-Range: "); 93 | Serial.println(myAcc_1.getRangeAsString()); 94 | Serial.println();*/ 95 | 96 | /* Uncomment to enable Low Power Mode. It saves power but slightly 97 | increases noise. LowPower only affetcs Data Rates 12.5 Hz to 400 Hz. 98 | */ 99 | // myAcc.setLowPower(true); 100 | } 101 | 102 | /* The LSB of the Data registers is 3.9 mg (milli-g, not milligramm). 103 | This value is used calculating g from raw. However, this is an ideal 104 | value which you might want to calibrate. 105 | */ 106 | 107 | void loop() { 108 | xyzFloat g; 109 | myAcc_1.getGValues(&g); 110 | 111 | Serial.print("g-x = "); 112 | Serial.print(g.x); 113 | Serial.print(" | g-y = "); 114 | Serial.print(g.y); 115 | Serial.print(" | g-z = "); 116 | Serial.println(g.z); 117 | 118 | myAcc_2.getGValues(&g); 119 | 120 | Serial.print("g-x = "); 121 | Serial.print(g.x); 122 | Serial.print(" | g-y = "); 123 | Serial.print(g.y); 124 | Serial.print(" | g-z = "); 125 | Serial.println(g.z); 126 | 127 | Serial.println("*********************"); 128 | 129 | delay(1000); 130 | 131 | } 132 | -------------------------------------------------------------------------------- /examples/ADXL345_pitch_roll_corrected_angles/ADXL345_pitch_roll_corrected_angles.ino: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Example sketch for the ADXL345_WE / ADXL343_WE library 3 | * 4 | * This sketch shows how to measure pitch and roll angles of the ADXL345 5 | * vs. the corrected angle method. 6 | * It does not use the internal offset registers. 7 | * Please note the ADXL345 "forgets" calibration data when reset or repowered. 8 | * You might consider to save them to the EEPROM 9 | * 10 | * Further information can be found on: 11 | * https://wolles-elektronikkiste.de/adxl345-teil-1 (German) 12 | * https://wolles-elektronikkiste.de/en/adxl345-the-universal-accelerometer-part-1 (English) 13 | * 14 | ***************************************************************************/ 15 | 16 | #include 17 | #include 18 | #define ADXL345_I2CADDR 0x53 // 0x1D if SDO = HIGH 19 | 20 | /* There are several ways to create your ADXL345 object: 21 | * ADXL345_WE myAcc = ADXL345_WE() -> uses Wire / I2C Address = 0x53 22 | * ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR) -> uses Wire / ADXL345_I2CADDR 23 | * ADXL345_WE myAcc = ADXL345_WE(&wire2) -> uses the TwoWire object wire2 / ADXL345_I2CADDR 24 | * ADXL345_WE myAcc = ADXL345_WE(&wire2, ADXL345_I2CADDR) -> all together 25 | */ 26 | ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR); 27 | 28 | void setup(){ 29 | Wire.begin(); 30 | Serial.begin(115200); 31 | Serial.println("ADXL345 Sketch - Pitch and Roll vs. Corrected Angles"); 32 | Serial.println(); 33 | if(!myAcc.init()){ 34 | Serial.println("ADXL345 not connected!"); 35 | } 36 | 37 | /* Add your min and max raw values you found with ADXL345_calibration.ino. 38 | The order is: setCorrFactors(min x, max x, min y, max y, min z, max z). 39 | setCorrFactors calibrates the slope and assumes the zero point 40 | is (min+max)/2. You have to add the setCorrFactors function to all sketches 41 | in which you want to use it. 42 | */ 43 | myAcc.setCorrFactors(-266.0, 285.0, -268.0, 278.0, -291.0, 214.0); 44 | 45 | /* In this next step the offset for angles is corrected to get quite precise corrected 46 | angles x and y up to ~60°. The additional offsetCorrection is only for corrected 47 | angle measurements, not for pitch and roll. The procedure just ensures to start at 0°. 48 | */ 49 | Serial.println("Position your ADXL345 flat and don't move it"); 50 | delay(2000); 51 | myAcc.measureAngleOffsets(); 52 | Serial.println("....done"); 53 | 54 | /* Choose the data rate Hz 55 | ADXL345_DATA_RATE_3200 3200 56 | ADXL345_DATA_RATE_1600 1600 57 | ADXL345_DATA_RATE_800 800 58 | ADXL345_DATA_RATE_400 400 59 | ADXL345_DATA_RATE_200 200 60 | ADXL345_DATA_RATE_100 100 61 | ADXL345_DATA_RATE_50 50 62 | ADXL345_DATA_RATE_25 25 63 | ADXL345_DATA_RATE_12_5 12.5 64 | ADXL345_DATA_RATE_6_25 6.25 65 | ADXL345_DATA_RATE_3_13 3.13 66 | ADXL345_DATA_RATE_1_56 1.56 67 | ADXL345_DATA_RATE_0_78 0.78 68 | ADXL345_DATA_RATE_0_39 0.39 69 | ADXL345_DATA_RATE_0_20 0.20 70 | ADXL345_DATA_RATE_0_10 0.10 71 | */ 72 | myAcc.setDataRate(ADXL345_DATA_RATE_50); 73 | Serial.print("Data rate: "); 74 | Serial.print(myAcc.getDataRateAsString()); 75 | 76 | /* Choose the measurement range 77 | ADXL345_RANGE_16G 16g 78 | ADXL345_RANGE_8G 8g 79 | ADXL345_RANGE_4G 4g 80 | ADXL345_RANGE_2G 2g 81 | */ 82 | myAcc.setRange(ADXL345_RANGE_2G); 83 | Serial.print(" / g-Range: "); 84 | Serial.println(myAcc.getRangeAsString()); 85 | Serial.println(); 86 | } 87 | 88 | void loop() { 89 | //xyzFloat g; 90 | //myAcc.getGValues(&g); 91 | xyzFloat corrAngles; 92 | myAcc.getCorrAngles(&corrAngles); 93 | 94 | /* Corrected angles use corrected raws and an extra angle 95 | offset. The method provides quite precise values for x/y 96 | angles up 60°. 97 | */ 98 | Serial.print("Angle x = "); 99 | Serial.print(corrAngles.x); 100 | Serial.print(" | Angle y = "); 101 | Serial.print(corrAngles.y); 102 | Serial.print(" | Angle z = "); 103 | Serial.println(corrAngles.z); 104 | 105 | /* Pitch and roll use corrected slope, but no additional offset. 106 | All axes are considered for calculation. 107 | */ 108 | float pitch = myAcc.getPitch(); 109 | float roll = myAcc.getRoll(); 110 | 111 | Serial.print("Pitch = "); 112 | Serial.print(pitch); 113 | Serial.print(" | Roll = "); 114 | Serial.println(roll); 115 | 116 | Serial.println(); 117 | 118 | delay(1000); 119 | 120 | } 121 | -------------------------------------------------------------------------------- /examples/ADXL345_basic_data_with_connection_check/ADXL345_basic_data_with_connection_check.ino: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Example sketch for the ADXL345_WE / ADXL343_WE library 3 | * 4 | * This sketch shows how to get the connection status. Several functions return 5 | * a bool value that indicates whether the ADXL345 is connected. But this only works 6 | * with I2C, because it is using the ACK/NACK Bit. For SPI you can use isConnected(), 7 | * which is less efficient because it triggers an extra read operation. 8 | * 9 | * Further information can be found on: 10 | * https://wolles-elektronikkiste.de/adxl345-teil-1 (German) 11 | * https://wolles-elektronikkiste.de/en/adxl345-the-universal-accelerometer-part-1 (English) 12 | * 13 | ***************************************************************************/ 14 | 15 | #include 16 | #include 17 | #define ADXL345_I2CADDR 0x53 // 0x1D if SDO = HIGH 18 | 19 | /* There are several ways to create your ADXL345 object: 20 | * ADXL345_WE myAcc = ADXL345_WE() -> uses Wire / I2C Address = 0x53 21 | * ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR) -> uses Wire / ADXL345_I2CADDR 22 | * ADXL345_WE myAcc = ADXL345_WE(&wire2) -> uses the TwoWire object wire2 / ADXL345_I2CADDR 23 | * ADXL345_WE myAcc = ADXL345_WE(&wire2, ADXL345_I2CADDR) -> all together 24 | */ 25 | ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR); 26 | 27 | void setup(){ 28 | Wire.begin(); 29 | Serial.begin(115200); 30 | Serial.println("ADXL345_Sketch - Basic Data"); 31 | Serial.println(); 32 | if(!myAcc.init()){ 33 | Serial.println("ADXL345 not connected!"); 34 | } 35 | 36 | /* Choose the data rate Hz 37 | ADXL345_DATA_RATE_3200 3200 38 | ADXL345_DATA_RATE_1600 1600 39 | ADXL345_DATA_RATE_800 800 40 | ADXL345_DATA_RATE_400 400 41 | ADXL345_DATA_RATE_200 200 42 | ADXL345_DATA_RATE_100 100 43 | ADXL345_DATA_RATE_50 50 44 | ADXL345_DATA_RATE_25 25 45 | ADXL345_DATA_RATE_12_5 12.5 46 | ADXL345_DATA_RATE_6_25 6.25 47 | ADXL345_DATA_RATE_3_13 3.13 48 | ADXL345_DATA_RATE_1_56 1.56 49 | ADXL345_DATA_RATE_0_78 0.78 50 | ADXL345_DATA_RATE_0_39 0.39 51 | ADXL345_DATA_RATE_0_20 0.20 52 | ADXL345_DATA_RATE_0_10 0.10 53 | */ 54 | myAcc.setDataRate(ADXL345_DATA_RATE_50); 55 | delay(100); 56 | Serial.print("Data rate: "); 57 | Serial.print(myAcc.getDataRateAsString()); 58 | 59 | /* In full resolution the size of the raw values depend on the range: 60 | 2g = 10 bit; 4g = 11 bit; 8g = 12 bit; 16g =13 bit; 61 | uncomment to change to 10 bit for all ranges. 62 | */ 63 | // if(!myAcc.setFullRes(false)){ 64 | // errorMessage(); 65 | //} 66 | 67 | /* Choose the measurement range 68 | ADXL345_RANGE_16G 16g 69 | ADXL345_RANGE_8G 8g 70 | ADXL345_RANGE_4G 4g 71 | ADXL345_RANGE_2G 2g 72 | */ 73 | if(!myAcc.setRange(ADXL345_RANGE_4G)){ 74 | errorMessage(); 75 | } 76 | Serial.print(" / g-Range: "); 77 | Serial.println(myAcc.getRangeAsString()); 78 | Serial.println(); 79 | 80 | /* Uncomment to enable Low Power Mode. It saves power but slightly 81 | increases noise. LowPower only affetcs Data Rates 12.5 Hz to 400 Hz. 82 | */ 83 | // myAcc.setLowPower(true); 84 | } 85 | 86 | /* The LSB of the Data registers is 3.9 mg (milli-g, not milligramm). 87 | This value is used calculating g from raw. However, this is an ideal 88 | value which you might want to calibrate. 89 | */ 90 | 91 | void loop() { 92 | /* When using SPI, you can check with isConnected() whether the ADXL345 is still connected. 93 | The function simply tries to read the Device ID. Of course, it also works for I2C but 94 | it is less efficient than the I2C-checks, because isConnected() requires an additional 95 | register read. It may impact your ability to achieve the highest data rates. 96 | */ 97 | // if (!myAcc.isConnected()) { 98 | // errorMessage(); 99 | // } 100 | 101 | xyzFloat raw; 102 | xyzFloat g; 103 | if(!myAcc.getRawValues(&raw)){ 104 | errorMessage(); 105 | } 106 | if(!myAcc.getGValues(&g)){ 107 | errorMessage(); 108 | } 109 | 110 | Serial.print("Raw-x = "); 111 | Serial.print(raw.x); 112 | Serial.print(" | Raw-y = "); 113 | Serial.print(raw.y); 114 | Serial.print(" | Raw-z = "); 115 | Serial.println(raw.z); 116 | 117 | Serial.print("g-x = "); 118 | Serial.print(g.x); 119 | Serial.print(" | g-y = "); 120 | Serial.print(g.y); 121 | Serial.print(" | g-z = "); 122 | Serial.println(g.z); 123 | 124 | Serial.println(); 125 | 126 | delay(1000); 127 | } 128 | 129 | void errorMessage() { 130 | Serial.println("Connection lost to the ADX345. Please check your circuit."); 131 | // while(1){;} // uncomment if the sketch shall be stopped in case of connection issues 132 | } 133 | -------------------------------------------------------------------------------- /examples/ADXL345_SPI_basic_data/ADXL345_SPI_basic_data.ino: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Example sketch for the ADXL345_WE / ADXL343_WE library 3 | * 4 | * This sketch shows how use SPI for the basic data sketch. Please apply the 5 | * same steps in the other sketches if you want to use SPI. 6 | * 7 | * Further information can be found on: 8 | * https://wolles-elektronikkiste.de/adxl345-teil-1 (German) 9 | * https://wolles-elektronikkiste.de/en/adxl345-the-universal-accelerometer-part-1 (English) 10 | * 11 | ***************************************************************************/ 12 | 13 | #include 14 | #include 15 | #define CS_PIN 5 // Chip Select Pin 16 | /* In case you want to change the default SPI pins (e.g. for ESP32 or STM32 boards), uncomment and adjust: */ 17 | // #define MOSI_PIN 22 18 | // #define MISO_PIN 17 19 | // #define SCK_PIN 16 20 | /* If you use an ESP8266, the standard CS Pin (e.g. D8/GPIO15 on a WEMOS D1 mini or NodeMCU) might not work since the CS pin of 21 | the ADXL345 has a pull-up resistor on most modules. If D8 is high at reset, the ESP8266 will not boot. In that case choose a 22 | different pin as CS! */ 23 | 24 | bool spi = true; // flag indicating that SPI shall be used 25 | 26 | /* There are three ways to create your ADXL345 object in SPI mode 27 | * ADXL345_WE myAcc = ADXL345_WE(CS_PIN, spi) -> uses SPI, spi is just a flag, see SPI example 28 | * ADXL345_WE myAcc = ADXL345_WE(&SPI, CS_PIN, spi) -> uses SPI / passes the SPI object, spi is just a flag, see SPI example 29 | * ADXL345_WE myAcc = ADXL345_WE(&SPI, CS_PIN, spi, MOSI_PIN, MISO_PIN, SCK_PIN) -> like the latter, but also changes the SPI pins 30 | */ 31 | 32 | ADXL345_WE myAcc = ADXL345_WE(CS_PIN, spi); 33 | 34 | /* Changing SPI pins on STM32 boards can be a bit diffcult - the following worked on a Nucleo-L432KC board: 35 | 36 | #define CS_PIN D3 37 | #define MOSI_PIN A6 38 | #define MISO_PIN D10 39 | #define SCK_PIN A1 40 | bool spi = true; 41 | ADXL345_WE myAcc = ADXL345_WE(&SPI, CS_PIN, spi, MOSI_PIN, MISO_PIN, SCK_PIN); 42 | 43 | Or, using the same pins: 44 | SPIClass mySPI(MOSI_PIN, MISO_PIN, SCK_PIN); // don't pass the CS-Pin (=SSEL) 45 | ADXL345_WE myAcc = ADXL345_WE(&mySPI, CS_PIN, spi); 46 | */ 47 | 48 | void setup(){ 49 | Serial.begin(115200); 50 | Serial.println("ADXL345_Sketch - Basic Data"); 51 | 52 | /* You can set the SPI clock speed. Default is 5 MHz. */ 53 | // myAcc.setSPIClockSpeed(4000000); 54 | 55 | if(!myAcc.init()){ 56 | Serial.println("ADXL345 not connected!"); 57 | } 58 | 59 | /* Choose the data rate Hz 60 | ADXL345_DATA_RATE_3200 3200 61 | ADXL345_DATA_RATE_1600 1600 62 | ADXL345_DATA_RATE_800 800 63 | ADXL345_DATA_RATE_400 400 64 | ADXL345_DATA_RATE_200 200 65 | ADXL345_DATA_RATE_100 100 66 | ADXL345_DATA_RATE_50 50 67 | ADXL345_DATA_RATE_25 25 68 | ADXL345_DATA_RATE_12_5 12.5 69 | ADXL345_DATA_RATE_6_25 6.25 70 | ADXL345_DATA_RATE_3_13 3.13 71 | ADXL345_DATA_RATE_1_56 1.56 72 | ADXL345_DATA_RATE_0_78 0.78 73 | ADXL345_DATA_RATE_0_39 0.39 74 | ADXL345_DATA_RATE_0_20 0.20 75 | ADXL345_DATA_RATE_0_10 0.10 76 | */ 77 | myAcc.setDataRate(ADXL345_DATA_RATE_12_5); 78 | delay(100); 79 | Serial.print("Data rate: "); 80 | Serial.print(myAcc.getDataRateAsString()); 81 | 82 | /* In full resolution the size of the raw values depend on the 83 | range: 2g = 10 bit; 4g = 11 bit; 8g = 12 bit; 16g =13 bit; 84 | uncomment to change to 10 bit for all ranges. 85 | */ 86 | // myAcc.setFullRes(false); 87 | 88 | /* Choose the measurement range 89 | ADXL345_RANGE_16G 16g 90 | ADXL345_RANGE_8G 8g 91 | ADXL345_RANGE_4G 4g 92 | ADXL345_RANGE_2G 2g 93 | */ 94 | myAcc.setRange(ADXL345_RANGE_4G); 95 | Serial.print(" / g-Range: "); 96 | Serial.println(myAcc.getRangeAsString()); 97 | Serial.println(); 98 | 99 | /* Uncomment to enable Low Power Mode. It saves power but slightly 100 | increases noise. LowPower only affetcs Data Rates 12.5 Hz to 400 Hz. 101 | */ 102 | // myAcc.setLowPower(true); 103 | } 104 | 105 | /* The LSB of the Data registers is 3.9 mg (milli-g, not milligramm). 106 | This value is used calculating g from raw. However, this is an ideal 107 | value which you might want to calibrate. 108 | */ 109 | 110 | void loop() { 111 | xyzFloat raw, g; 112 | myAcc.getRawValues(&raw); 113 | myAcc.getGValues(&g); 114 | 115 | Serial.print("Raw-x = "); 116 | Serial.print(raw.x); 117 | Serial.print(" | Raw-y = "); 118 | Serial.print(raw.y); 119 | Serial.print(" | Raw-z = "); 120 | Serial.println(raw.z); 121 | 122 | Serial.print("g-x = "); 123 | Serial.print(g.x); 124 | Serial.print(" | g-y = "); 125 | Serial.print(g.y); 126 | Serial.print(" | g-z = "); 127 | Serial.println(g.z); 128 | 129 | Serial.println(); 130 | 131 | delay(1000); 132 | 133 | } 134 | -------------------------------------------------------------------------------- /examples/ADXL345_angles_orientation/ADXL345_angles_orientation.ino: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Example sketch for the ADXL345_WE / ADXL343_WE library 3 | * 4 | * This sketch shows how to measure angles, corrected angles and orientation 5 | * of the ADXL345 6 | * It does not use the internal offset registers (OFSX, OFSY, OFSZ). 7 | * Please note the ADXL345 "forgets" calibration data when reset or repowered. 8 | * You might consider to save them to the EEPROM 9 | * 10 | * Further information can be found on: 11 | * https://wolles-elektronikkiste.de/adxl345-teil-1 (German) 12 | * https://wolles-elektronikkiste.de/en/adxl345-the-universal-accelerometer-part-1 (English) 13 | * 14 | ***************************************************************************/ 15 | 16 | #include 17 | #include 18 | #define ADXL345_I2CADDR 0x53 // 0x1D if SDO = HIGH 19 | 20 | /* There are several ways to create your ADXL345 object: 21 | * ADXL345_WE myAcc = ADXL345_WE() -> uses Wire / I2C Address = 0x53 22 | * ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR) -> uses Wire / ADXL345_I2CADDR 23 | * ADXL345_WE myAcc = ADXL345_WE(&wire2) -> uses the TwoWire object wire2 / ADXL345_I2CADDR 24 | * ADXL345_WE myAcc = ADXL345_WE(&wire2, ADXL345_I2CADDR) -> all together 25 | */ 26 | ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR); 27 | 28 | void setup(){ 29 | Wire.begin(); 30 | Serial.begin(115200); 31 | Serial.println("ADXL345_Sketch"); 32 | Serial.println(); 33 | if(!myAcc.init()){ 34 | Serial.println("ADXL345 not connected!"); 35 | } 36 | 37 | /* Add your min and max raw values you found with ADXL345_calibration.ino. 38 | * The order is: setCorrFactors(min x, max x, min y, max y, min z, max z). 39 | * setCorrFactors calibrates the slope and assumes the zero point 40 | * is (min+max)/2. You have to add the setCorrFactors function to all sketches 41 | * in which you want to use it. 42 | */ 43 | // myAcc.setCorrFactors(-266.0, 285.0, -268.0, 278.0, -291.0, 214.0); 44 | 45 | /* In this next step the offset for angles is corrected to get quite precise corrected 46 | * angles for x and y up to ~60°. The additional offsetCorrection is only used for 47 | * corrected angles measurements. The procedure just ensures to start at 0°. 48 | */ 49 | Serial.println("Position your ADXL345 flat and don't move it"); 50 | delay(2000); 51 | myAcc.measureAngleOffsets(); 52 | Serial.println("....done"); 53 | 54 | /* Choose the data rate Hz 55 | ADXL345_DATA_RATE_3200 3200 56 | ADXL345_DATA_RATE_1600 1600 57 | ADXL345_DATA_RATE_800 800 58 | ADXL345_DATA_RATE_400 400 59 | ADXL345_DATA_RATE_200 200 60 | ADXL345_DATA_RATE_100 100 61 | ADXL345_DATA_RATE_50 50 62 | ADXL345_DATA_RATE_25 25 63 | ADXL345_DATA_RATE_12_5 12.5 64 | ADXL345_DATA_RATE_6_25 6.25 65 | ADXL345_DATA_RATE_3_13 3.13 66 | ADXL345_DATA_RATE_1_56 1.56 67 | ADXL345_DATA_RATE_0_78 0.78 68 | ADXL345_DATA_RATE_0_39 0.39 69 | ADXL345_DATA_RATE_0_20 0.20 70 | ADXL345_DATA_RATE_0_10 0.10 71 | */ 72 | myAcc.setDataRate(ADXL345_DATA_RATE_50); 73 | Serial.print("Data rate: "); 74 | Serial.print(myAcc.getDataRateAsString()); 75 | 76 | /* Choose the measurement range 77 | ADXL345_RANGE_16G 16g 78 | ADXL345_RANGE_8G 8g 79 | ADXL345_RANGE_4G 4g 80 | ADXL345_RANGE_2G 2g 81 | */ 82 | myAcc.setRange(ADXL345_RANGE_2G); 83 | Serial.print(" / g-Range: "); 84 | Serial.println(myAcc.getRangeAsString()); 85 | Serial.println(); 86 | } 87 | 88 | void loop() { 89 | xyzFloat raw, g, angle, corrAngle; 90 | myAcc.getRawValues(&raw); 91 | myAcc.getGValues(&g); 92 | myAcc.getAngles(&angle); 93 | myAcc.getCorrAngles(&corrAngle); 94 | 95 | /* Still the uncorrected raw values!! */ 96 | Serial.print("Raw-x = "); 97 | Serial.print(raw.x); 98 | Serial.print(" | Raw-y = "); 99 | Serial.print(raw.y); 100 | Serial.print(" | Raw-z = "); 101 | Serial.println(raw.z); 102 | 103 | /* g values use the corrected raws */ 104 | Serial.print("g-x = "); 105 | Serial.print(g.x); 106 | Serial.print(" | g-y = "); 107 | Serial.print(g.y); 108 | Serial.print(" | g-z = "); 109 | Serial.println(g.z); 110 | 111 | /* Angles use the corrected raws. Angles are simply calculated by 112 | angle = arcsin(g Value) */ 113 | Serial.print("Angle x = "); 114 | Serial.print(angle.x); 115 | Serial.print(" | Angle y = "); 116 | Serial.print(angle.y); 117 | Serial.print(" | Angle z = "); 118 | Serial.println(angle.z); 119 | 120 | /* Corrected angles use corrected raws and an extra angle 121 | offsets to ensure they start at 0° 122 | */ 123 | Serial.print("cAngle x = "); 124 | Serial.print(corrAngle.x); 125 | Serial.print(" | cAngle y = "); 126 | Serial.print(corrAngle.y); 127 | Serial.print(" | cAngle z = "); 128 | Serial.println(corrAngle.z); 129 | 130 | Serial.print("Orientation of the module: "); 131 | Serial.println(myAcc.getOrientationAsString()); 132 | 133 | Serial.println(); 134 | 135 | delay(1000); 136 | 137 | } 138 | -------------------------------------------------------------------------------- /examples/ADXL345_data_ready_interrupt/ADXL345_data_ready_interrupt.ino: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Example sketch for the ADXL345_WE / ADXL343_WE library 3 | * 4 | * This sketch shows how to use the data ready interrupt. 5 | * 6 | * Further information can be found on: 7 | * https://wolles-elektronikkiste.de/adxl345-teil-1 (German) 8 | * https://wolles-elektronikkiste.de/en/adxl345-the-universal-accelerometer-part-1 (English) 9 | * 10 | ***************************************************************************/ 11 | 12 | #include 13 | #include 14 | #define ADXL345_I2CADDR 0x53 // 0x1D if SDO = HIGH 15 | const int int2Pin = 2; // interrupt pin 16 | volatile bool dataReady = false; 17 | 18 | /* There are several ways to create your ADXL345 object: 19 | * ADXL345_WE myAcc = ADXL345_WE() -> uses Wire / I2C Address = 0x53 20 | * ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR) -> uses Wire / ADXL345_I2CADDR 21 | * ADXL345_WE myAcc = ADXL345_WE(&wire2) -> uses the TwoWire object wire2 / ADXL345_I2CADDR 22 | * ADXL345_WE myAcc = ADXL345_WE(&wire2, ADXL345_I2CADDR) -> all together 23 | */ 24 | ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR); 25 | 26 | void setup(){ 27 | Wire.begin(); 28 | Serial.begin(115200); 29 | pinMode(int2Pin, INPUT); 30 | Serial.println("ADXL345_Sketch - Data Ready Interrupt"); 31 | Serial.println(); 32 | if(!myAcc.init()){ 33 | Serial.println("ADXL345 not connected!"); 34 | } 35 | 36 | /* Insert your data from ADXL345_calibration.ino and uncomment for more precise results */ 37 | // myAcc.setCorrFactors(-266.0, 285.0, -268.0, 278.0, -291.0, 214.0); 38 | 39 | /* Choose the data rate Hz 40 | ADXL345_DATA_RATE_3200 3200 41 | ADXL345_DATA_RATE_1600 1600 42 | ADXL345_DATA_RATE_800 800 43 | ADXL345_DATA_RATE_400 400 44 | ADXL345_DATA_RATE_200 200 45 | ADXL345_DATA_RATE_100 100 46 | ADXL345_DATA_RATE_50 50 47 | ADXL345_DATA_RATE_25 25 48 | ADXL345_DATA_RATE_12_5 12.5 49 | ADXL345_DATA_RATE_6_25 6.25 50 | ADXL345_DATA_RATE_3_13 3.13 51 | ADXL345_DATA_RATE_1_56 1.56 52 | ADXL345_DATA_RATE_0_78 0.78 53 | ADXL345_DATA_RATE_0_39 0.39 54 | ADXL345_DATA_RATE_0_20 0.20 55 | ADXL345_DATA_RATE_0_10 0.10 56 | */ 57 | // Choose a low frequency to showcase the data rate controlled output 58 | myAcc.setDataRate(ADXL345_DATA_RATE_0_20); 59 | Serial.print("Data rate: "); 60 | Serial.print(myAcc.getDataRateAsString()); 61 | 62 | /* Choose the measurement range 63 | ADXL345_RANGE_16G 16g 64 | ADXL345_RANGE_8G 8g 65 | ADXL345_RANGE_4G 4g 66 | ADXL345_RANGE_2G 2g 67 | */ 68 | myAcc.setRange(ADXL345_RANGE_2G); 69 | Serial.print(" / g-Range: "); 70 | Serial.println(myAcc.getRangeAsString()); 71 | Serial.println(); 72 | 73 | attachInterrupt(digitalPinToInterrupt(int2Pin), dataReadyISR, RISING); 74 | 75 | /* Default Interrupt Pin Polarity is active high. Change if you like */ 76 | // myAcc.setInterruptPolarity(ADXL345_ACT_LOW); 77 | 78 | /* You can choose the following interrupts: 79 | Variable name: Triggered, if: 80 | ADXL345_OVERRUN - new data replaces unread data 81 | ADXL345_WATERMARK - the number of samples in FIFO equals the number defined in FIFO_CTL 82 | ADXL345_FREEFALL - acceleration values of all axes are below the threshold defined in THRESH_FF 83 | ADXL345_INACTIVITY - acc. value of all included axes are < THRESH_INACT for period > TIME_INACT 84 | ADXL345_ACTIVITY - acc. value of included axes are > THRESH_ACT 85 | ADXL345_DOUBLE_TAP - double tap detected on one incl. axis and various defined conditions are met 86 | ADXL345_SINGLE_TAP - single tap detected on one incl. axis and various defined conditions are met 87 | ADXL345_DATA_READY - new data available 88 | 89 | Assign the interrupts to INT1 (INT_PIN_1) or INT2 (INT_PIN_2). Data ready, watermark and overrun are 90 | always enabled. You can only change the assignment of these which is INT1 by default. 91 | 92 | You can delete interrupts with deleteInterrupt(type); 93 | */ 94 | myAcc.setInterrupt(ADXL345_DATA_READY, INT_PIN_2); 95 | myAcc.readAndClearInterrupts(); 96 | } 97 | 98 | /* In the following loop there is only one interrupt type that can occur on INT2. 99 | In cases where you expect more candidates, you can check as follows: 100 | uint8_t intType = myAcc.readAndClearInterrupts(); 101 | if(myAcc.checkInterrupt(intType, ADXL345_DATA_READY)){ 102 | Serial.println("DATA READY confirmed"); 103 | } 104 | */ 105 | void loop() { 106 | // you see here is no delay to control the output rate 107 | if(dataReady==true){ 108 | xyzFloat g; 109 | myAcc.getGValues(&g); 110 | // dataReady = false; // uncomment, if you want capture next interrupts 111 | 112 | Serial.print("g-x = "); 113 | Serial.print(g.x); 114 | Serial.print(" | g-y = "); 115 | Serial.print(g.y); 116 | Serial.print(" | g-z = "); 117 | Serial.println(g.z); 118 | 119 | dataReady = false; // comment, if you have set dataReady to false before 120 | } 121 | } 122 | 123 | void dataReadyISR(){ 124 | dataReady = true; 125 | } 126 | -------------------------------------------------------------------------------- /examples/ADXL345_free_fall_interrupt/ADXL345_free_fall_interrupt.ino: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Example sketch for the ADXL345_WE / ADXL343_WE library 3 | * 4 | * This sketch shows how to use the free fall interrupt. 5 | * 6 | * Further information can be found on: 7 | * https://wolles-elektronikkiste.de/adxl345-teil-1 (German) 8 | * https://wolles-elektronikkiste.de/en/adxl345-the-universal-accelerometer-part-1 (English) 9 | * 10 | ***************************************************************************/ 11 | 12 | #include 13 | #include 14 | #define ADXL345_I2CADDR 0x53 // 0x1D if SDO = HIGH 15 | const int int2Pin = 2; 16 | volatile bool freeFall = false; 17 | 18 | /* There are several ways to create your ADXL345 object: 19 | * ADXL345_WE myAcc = ADXL345_WE() -> uses Wire / I2C Address = 0x53 20 | * ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR) -> uses Wire / ADXL345_I2CADDR 21 | * ADXL345_WE myAcc = ADXL345_WE(&wire2) -> uses the TwoWire object wire2 / ADXL345_I2CADDR 22 | * ADXL345_WE myAcc = ADXL345_WE(&wire2, ADXL345_I2CADDR) -> all together 23 | */ 24 | ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR); 25 | 26 | void setup(){ 27 | Wire.begin(); 28 | Serial.begin(115200); 29 | pinMode(int2Pin, INPUT); 30 | Serial.println("ADXL345_Sketch - Free Fall Interrupt"); 31 | Serial.println(); 32 | if(!myAcc.init()){ 33 | Serial.println("ADXL345 not connected!"); 34 | } 35 | 36 | /* Insert your data from ADXL345_calibration.ino and uncomment for more precise results */ 37 | // myAcc.setCorrFactors(-266.0, 285.0, -268.0, 278.0, -291.0, 214.0); 38 | 39 | /* Choose the data rate Hz 40 | ADXL345_DATA_RATE_3200 3200 41 | ADXL345_DATA_RATE_1600 1600 42 | ADXL345_DATA_RATE_800 800 43 | ADXL345_DATA_RATE_400 400 44 | ADXL345_DATA_RATE_200 200 45 | ADXL345_DATA_RATE_100 100 46 | ADXL345_DATA_RATE_50 50 47 | ADXL345_DATA_RATE_25 25 48 | ADXL345_DATA_RATE_12_5 12.5 49 | ADXL345_DATA_RATE_6_25 6.25 50 | ADXL345_DATA_RATE_3_13 3.13 51 | ADXL345_DATA_RATE_1_56 1.56 52 | ADXL345_DATA_RATE_0_78 0.78 53 | ADXL345_DATA_RATE_0_39 0.39 54 | ADXL345_DATA_RATE_0_20 0.20 55 | ADXL345_DATA_RATE_0_10 0.10 56 | */ 57 | myAcc.setDataRate(ADXL345_DATA_RATE_25); 58 | Serial.print("Data rate: "); 59 | Serial.print(myAcc.getDataRateAsString()); 60 | 61 | /* Choose the measurement range 62 | ADXL345_RANGE_16G 16g 63 | ADXL345_RANGE_8G 8g 64 | ADXL345_RANGE_4G 4g 65 | ADXL345_RANGE_2G 2g 66 | */ 67 | myAcc.setRange(ADXL345_RANGE_2G); 68 | Serial.print(" / g-Range: "); 69 | Serial.println(myAcc.getRangeAsString()); 70 | Serial.println(); 71 | 72 | /* The parameters of the setFreeFallThresholds function are: 73 | - g threshold - do not choose a parameter which is too low. 0.3 - 0.6 g is fine. 74 | - time threshold in ms, maximum is 1275. Recommended is 100 - 350; 75 | If time threshold is too low, vibrations can be detected as free fall. 76 | */ 77 | myAcc.setFreeFallThresholds(0.4, 100); 78 | 79 | /* You can choose the following interrupts: 80 | Variable name: Triggered, if: 81 | ADXL345_OVERRUN - new data replaces unread data 82 | ADXL345_WATERMARK - the number of samples in FIFO equals the number defined in FIFO_CTL 83 | ADXL345_FREEFALL - acceleration values of all axes are below the threshold defined in THRESH_FF 84 | ADXL345_INACTIVITY - acc. value of all included axes are < THRESH_INACT for period > TIME_INACT 85 | ADXL345_ACTIVITY - acc. value of included axes are > THRESH_ACT 86 | ADXL345_DOUBLE_TAP - double tap detected on one incl. axis and various defined conditions are met 87 | ADXL345_SINGLE_TAP - single tap detected on one incl. axis and various defined conditions are met 88 | ADXL345_DATA_READY - new data available 89 | 90 | Assign the interrupts to INT1 (INT_PIN_1) or INT2 (INT_PIN_2). Data ready, watermark and overrun are 91 | always enabled. You can only change the assignment of these which is INT1 by default. 92 | 93 | You can delete interrupts with deleteInterrupt(type); 94 | */ 95 | myAcc.setInterrupt(ADXL345_FREEFALL, INT_PIN_2); 96 | 97 | attachInterrupt(digitalPinToInterrupt(int2Pin), freeFallISR, RISING); 98 | myAcc.readAndClearInterrupts(); 99 | } 100 | 101 | void loop() { 102 | xyzFloat raw, g; 103 | myAcc.getRawValues(&raw); 104 | myAcc.getGValues(&g); 105 | 106 | Serial.print("Raw-x = "); 107 | Serial.print(raw.x); 108 | Serial.print(" | Raw-y = "); 109 | Serial.print(raw.y); 110 | Serial.print(" | Raw-z = "); 111 | Serial.println(raw.z); 112 | 113 | Serial.print("g-x = "); 114 | Serial.print(g.x); 115 | Serial.print(" | g-y = "); 116 | Serial.print(g.y); 117 | Serial.print(" | g-z = "); 118 | Serial.println(g.z); 119 | 120 | Serial.println(); 121 | 122 | if(freeFall==true){ 123 | Serial.println("Aaaaaaaaah!!!!! - I'm faaaaallllling!"); 124 | delay(1000); 125 | freeFall = false; 126 | /* by reading the interrupt register the interrupt is cleared */ 127 | myAcc.readAndClearInterrupts(); 128 | 129 | /* if you expect also other interrupts you can check the type. For this comment the previous line, 130 | and replace by the following four lines: */ 131 | //byte intType = myAcc.readAndClearInterrupts(); 132 | //if(myAcc.checkInterrupt(intType, ADXL345_FREEFALL)){ 133 | // Serial.println("FREEFALL confirmed"); 134 | //} 135 | } 136 | 137 | delay(500); 138 | } 139 | 140 | void freeFallISR(){ 141 | freeFall = true; 142 | } 143 | -------------------------------------------------------------------------------- /examples/ADXL345_fifo_fifo/ADXL345_fifo_fifo.ino: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Example sketch for the ADXL345_WE / ADXL343_WE library 3 | * 4 | * This sketch shows how to use the FIFO in fifo mode. 5 | * 6 | * Further information can be found on: 7 | * https://wolles-elektronikkiste.de/adxl345-teil-1 (German) 8 | * https://wolles-elektronikkiste.de/en/adxl345-the-universal-accelerometer-part-1 (English) 9 | * 10 | ***************************************************************************/ 11 | 12 | #include 13 | #include 14 | #define ADXL345_I2CADDR 0x53 // 0x1D if SDO = HIGH 15 | const int int2Pin = 2; 16 | volatile bool event = false; 17 | 18 | /* There are several ways to create your ADXL345 object: 19 | * ADXL345_WE myAcc = ADXL345_WE() -> uses Wire / I2C Address = 0x53 20 | * ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR) -> uses Wire / ADXL345_I2CADDR 21 | * ADXL345_WE myAcc = ADXL345_WE(&wire2) -> uses the TwoWire object wire2 / ADXL345_I2CADDR 22 | * ADXL345_WE myAcc = ADXL345_WE(&wire2, ADXL345_I2CADDR) -> all together 23 | */ 24 | ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR); 25 | 26 | void setup() { 27 | Wire.begin(); 28 | Serial.begin(115200); 29 | pinMode(int2Pin, INPUT); 30 | Serial.println("ADXL345_Sketch - FIFO - Fifo Mode"); 31 | Serial.println(); 32 | if (!myAcc.init()) { 33 | Serial.println("ADXL345 not connected!"); 34 | } 35 | 36 | /* Insert your data from ADXL345_calibration.ino and uncomment for more precise results */ 37 | // myAcc.setCorrFactors(-266.0, 285.0, -268.0, 278.0, -291.0, 214.0); 38 | 39 | /* Choose the data rate Hz 40 | ADXL345_DATA_RATE_3200 3200 41 | ADXL345_DATA_RATE_1600 1600 42 | ADXL345_DATA_RATE_800 800 43 | ADXL345_DATA_RATE_400 400 44 | ADXL345_DATA_RATE_200 200 45 | ADXL345_DATA_RATE_100 100 46 | ADXL345_DATA_RATE_50 50 47 | ADXL345_DATA_RATE_25 25 48 | ADXL345_DATA_RATE_12_5 12.5 49 | ADXL345_DATA_RATE_6_25 6.25 50 | ADXL345_DATA_RATE_3_13 3.13 51 | ADXL345_DATA_RATE_1_56 1.56 52 | ADXL345_DATA_RATE_0_78 0.78 53 | ADXL345_DATA_RATE_0_39 0.39 54 | ADXL345_DATA_RATE_0_20 0.20 55 | ADXL345_DATA_RATE_0_10 0.10 56 | */ 57 | myAcc.setDataRate(ADXL345_DATA_RATE_3_13); 58 | Serial.print("Data rate: "); 59 | Serial.print(myAcc.getDataRateAsString()); 60 | 61 | /* Choose the measurement range 62 | ADXL345_RANGE_16G 16g 63 | ADXL345_RANGE_8G 8g 64 | ADXL345_RANGE_4G 4g 65 | ADXL345_RANGE_2G 2g 66 | */ 67 | myAcc.setRange(ADXL345_RANGE_4G); 68 | Serial.print(" / g-Range: "); 69 | Serial.println(myAcc.getRangeAsString()); 70 | Serial.println(); 71 | 72 | /* Stop the measure mode - no new data will be obtained */ 73 | myAcc.setMeasureMode(false); 74 | attachInterrupt(digitalPinToInterrupt(int2Pin), eventISR, RISING); 75 | 76 | /* You can choose the following interrupts: 77 | Variable name: Triggered, if: 78 | ADXL345_OVERRUN - new data replaces unread data 79 | ADXL345_WATERMARK - the number of samples in FIFO equals the number defined in FIFO_CTL 80 | ADXL345_FREEFALL - acceleration values of all axes are below the threshold defined in THRESH_FF 81 | ADXL345_INACTIVITY - acc. value of all included axes are < THRESH_INACT for period > TIME_INACT 82 | ADXL345_ACTIVITY - acc. value of included axes are > THRESH_ACT 83 | ADXL345_DOUBLE_TAP - double tap detected on one incl. axis and various defined conditions are met 84 | ADXL345_SINGLE_TAP - single tap detected on one incl. axis and various defined conditions are met 85 | ADXL345_DATA_READY - new data available 86 | 87 | Assign the interrupts to INT1 (INT_PIN_1) or INT2 (INT_PIN_2). Data ready, watermark and overrun are 88 | always enabled. You can only change the assignment of these which is INT1 by default. 89 | 90 | You can delete interrupts with deleteInterrupt(type); 91 | */ 92 | myAcc.setInterrupt(ADXL345_WATERMARK, INT_PIN_2); // Interrupt when FIFO is full 93 | 94 | /* The following two FIFO parameters need to be set: 95 | 1. Trigger Bit: not relevant for this FIFO mode. 96 | 2. FIFO samples (max 32). Defines the size of the FIFO. One sample is an x,y,z triple. 97 | */ 98 | myAcc.setFifoParameters(ADXL345_TRIGGER_INT_1, 32); 99 | 100 | /* You can choose the following FIFO modes: 101 | ADXL345_FIFO - you choose the start, ends when FIFO is full (at defined limit) 102 | ADXL345_STREAM - FIFO always filled with new data, old data replaced if FIFO is full; you choose the stop 103 | ADXL345_TRIGGER - FIFO always filled up to 32 samples; when the trigger event occurs only defined number of samples 104 | is kept in the FIFO and further samples are taken after the event until FIFO is full again. 105 | ADXL345_BYPASS - no FIFO 106 | */ 107 | myAcc.setFifoMode(ADXL345_FIFO); 108 | myAcc.readAndClearInterrupts(); 109 | } 110 | 111 | void loop() { 112 | event = false; 113 | 114 | countDown(); // as an alternative you could define any other event to start to fill the FIFO 115 | myAcc.readAndClearInterrupts(); 116 | myAcc.setMeasureMode(true); // this is the actual start 117 | while(!event){} // event = true means WATERMARK interrupt triggered -> means FIFO is full 118 | myAcc.setMeasureMode(false); 119 | Serial.println("FiFo full"); 120 | 121 | for(int i=0; i<34; i++){ // this is > 32 samples, but I want to show that the values do not change when FIFO is full 122 | xyzFloat g; 123 | myAcc.getGValues(&g); 124 | 125 | Serial.print("g-x = "); 126 | Serial.print(g.x); 127 | Serial.print(" | g-y = "); 128 | Serial.print(g.y); 129 | Serial.print(" | g-z = "); 130 | Serial.println(g.z); 131 | } 132 | Serial.println("For another series of measurements, enter any key and send"); 133 | 134 | while(!(Serial.available())){} 135 | Serial.read(); 136 | Serial.println(); 137 | } 138 | 139 | void eventISR() { 140 | event = true; 141 | } 142 | 143 | void countDown(){ 144 | Serial.println("Move your ADXL345 to obtain interesting data"); 145 | Serial.println(); 146 | delay(1000); 147 | Serial.print("Fifo collection begins in 3, "); 148 | delay(1000); 149 | Serial.print("2, "); 150 | delay(1000); 151 | Serial.print("1, "); 152 | delay(1000); 153 | Serial.println("Now!"); 154 | } 155 | -------------------------------------------------------------------------------- /examples/ADXL345_single_tap/ADXL345_single_tap.ino: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Example sketch for the ADXL345_WE / ADXL343_WE library 3 | * 4 | * This sketch shows how to use the single tap function. 5 | * 6 | * Further information can be found on: 7 | * https://wolles-elektronikkiste.de/adxl345-teil-1 (German) 8 | * https://wolles-elektronikkiste.de/en/adxl345-the-universal-accelerometer-part-1 (English) 9 | * 10 | ***************************************************************************/ 11 | #include 12 | #include 13 | #define ADXL345_I2CADDR 0x53 // 0x1D if SDO = HIGH 14 | const int int2Pin = 2; 15 | volatile bool tap = false; 16 | 17 | /* There are several ways to create your ADXL345 object: 18 | * ADXL345_WE myAcc = ADXL345_WE() -> uses Wire / I2C Address = 0x53 19 | * ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR) -> uses Wire / ADXL345_I2CADDR 20 | * ADXL345_WE myAcc = ADXL345_WE(&wire2) -> uses the TwoWire object wire2 / ADXL345_I2CADDR 21 | * ADXL345_WE myAcc = ADXL345_WE(&wire2, ADXL345_I2CADDR) -> all together 22 | */ 23 | ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR); 24 | 25 | void setup() { 26 | Wire.begin(); 27 | Serial.begin(115200); 28 | pinMode(int2Pin, INPUT); 29 | Serial.println("ADXL345_Sketch - Single Tap Interrupt"); 30 | Serial.println(); 31 | if (!myAcc.init()) { 32 | Serial.println("ADXL345 not connected!"); 33 | } 34 | 35 | /* Insert your data from ADXL345_calibration.ino and uncomment for more precise results */ 36 | // myAcc.setCorrFactors(-266.0, 285.0, -268.0, 278.0, -291.0, 214.0); 37 | 38 | /* Choose the data rate Hz 39 | ADXL345_DATA_RATE_3200 3200 40 | ADXL345_DATA_RATE_1600 1600 41 | ADXL345_DATA_RATE_800 800 42 | ADXL345_DATA_RATE_400 400 43 | ADXL345_DATA_RATE_200 200 44 | ADXL345_DATA_RATE_100 100 45 | ADXL345_DATA_RATE_50 50 46 | ADXL345_DATA_RATE_25 25 47 | ADXL345_DATA_RATE_12_5 12.5 48 | ADXL345_DATA_RATE_6_25 6.25 49 | ADXL345_DATA_RATE_3_13 3.13 50 | ADXL345_DATA_RATE_1_56 1.56 51 | ADXL345_DATA_RATE_0_78 0.78 52 | ADXL345_DATA_RATE_0_39 0.39 53 | ADXL345_DATA_RATE_0_20 0.20 54 | ADXL345_DATA_RATE_0_10 0.10 55 | */ 56 | myAcc.setDataRate(ADXL345_DATA_RATE_200); 57 | Serial.print("Data rate: "); 58 | Serial.print(myAcc.getDataRateAsString()); 59 | 60 | /* Choose the measurement range 61 | ADXL345_RANGE_16G 16g 62 | ADXL345_RANGE_8G 8g 63 | ADXL345_RANGE_4G 4g 64 | ADXL345_RANGE_2G 2g 65 | */ 66 | myAcc.setRange(ADXL345_RANGE_8G); 67 | Serial.print(" / g-Range: "); 68 | Serial.println(myAcc.getRangeAsString()); 69 | Serial.println(); 70 | 71 | attachInterrupt(digitalPinToInterrupt(int2Pin), tapISR, RISING); 72 | 73 | /* The following four parameters have to be set for tap application (single and double): 74 | 1. Axes, that are considered: 75 | ADXL345_000 - no axis (which makes no sense) 76 | ADXL345_00Z - z 77 | ADXL345_0Y0 - y 78 | ADXL345_0YZ - y,z 79 | ADXL345_X00 - x 80 | ADXL345_X0Z - x,z 81 | ADXL345_XY0 - x,y 82 | ADXL345_XYZ - all axes 83 | 2. Threshold in g 84 | It is recommended to not choose the value to low. 3g is a good starting point. 85 | 3. Duration in milliseconds (max 159 ms): 86 | maximum time that the acceleration must be over g threshold to be regarded as a single tap. If 87 | the acceleration drops below the g threshold before the duration is exceeded an interrupt will be 88 | triggered. If also double tap is active an interrupt will only be triggered after the double tap 89 | conditions have been checked. Duration should be greater than 10. 90 | 4. Latency time in milliseconds (maximum: 318 ms): minimum time before the next tap can be detected. 91 | Starts at the end of duration or when the interrupt was triggered. Should be greater than 20 ms. 92 | */ 93 | myAcc.setGeneralTapParameters(ADXL345_XY0, 3.0, 30, 100.0); 94 | 95 | /* You can choose the following interrupts: 96 | Variable name: Triggered, if: 97 | ADXL345_OVERRUN - new data replaces unread data 98 | ADXL345_WATERMARK - the number of samples in FIFO equals the number defined in FIFO_CTL 99 | ADXL345_FREEFALL - acceleration values of all axes are below the threshold defined in THRESH_FF 100 | ADXL345_INACTIVITY - acc. value of all included axes are < THRESH_INACT for period > TIME_INACT 101 | ADXL345_ACTIVITY - acc. value of included axes are > THRESH_ACT 102 | ADXL345_DOUBLE_TAP - double tap detected on one incl. axis and various defined conditions are met 103 | ADXL345_SINGLE_TAP - single tap detected on one incl. axis and various defined conditions are met 104 | ADXL345_DATA_READY - new data available 105 | 106 | Assign the interrupts to INT1 (INT_PIN_1) or INT2 (INT_PIN_2). Data ready, watermark and overrun are 107 | always enabled. You can only change the assignment of these which is INT1 by default. 108 | 109 | You can delete interrupts with deleteInterrupt(type); 110 | */ 111 | myAcc.setInterrupt(ADXL345_SINGLE_TAP, INT_PIN_2); 112 | myAcc.readAndClearInterrupts(); 113 | } 114 | 115 | /* In the main loop some checks are done: 116 | getActTapStatus() returns which axes are resposible activity interrupt as byte (code in library) 117 | getActTapStatusAsString() returns the axes that caused the interrupt as string 118 | readAndClearInterrupts(); return the interrupt type as byte (code in library) 119 | checkInterrupt(intSource, type) returns if intSource is type as bool 120 | */ 121 | void loop() { 122 | if ((millis() % 1000) == 1) { 123 | xyzFloat g; 124 | myAcc.getGValues(&g); 125 | Serial.print("g-x = "); 126 | Serial.print(g.x); 127 | Serial.print(" | g-y = "); 128 | Serial.print(g.y); 129 | Serial.print(" | g-z = "); 130 | Serial.println(g.z); 131 | delay(1); 132 | } 133 | 134 | if(tap == true) { 135 | //byte actTapSource = myAcc.getActTapStatus(); 136 | //Serial.println(actTapSource, BIN); 137 | String axes = myAcc.getActTapStatusAsString(); 138 | byte intSource = myAcc.readAndClearInterrupts(); 139 | if(myAcc.checkInterrupt(intSource, ADXL345_SINGLE_TAP)){ 140 | Serial.print("TAP at: "); 141 | Serial.println(axes); 142 | } 143 | 144 | delay(1000); 145 | myAcc.readAndClearInterrupts(); 146 | tap = false; 147 | } 148 | } 149 | 150 | void tapISR() { 151 | tap = true; 152 | } 153 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For ADXL345_WE 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | ADXL345_WE KEYWORD1 10 | 11 | # ENUM TYPES 12 | ADXL345_WAKE_UP KEYWORD1 13 | adxl345_wakeUpFreq KEYWORD1 14 | ADXL345_PWR_CTL KEYWORD1 15 | adxl345_pwrCtl KEYWORD1 16 | ADXL345_DATA_RATE KEYWORD1 17 | adxl345_dataRate KEYWORD1 18 | ADXL345_RANGE KEYWORD1 19 | adxl345_range KEYWORD1 20 | ADXL345_ORIENTATION KEYWORD1 21 | adxl345_orientation KEYWORD1 22 | ADXL345_INT KEYWORD1 23 | adxl345_int KEYWORD1 24 | ADXL345_ACT_TAP_SET KEYWORD1 25 | adxl345_actTapSet KEYWORD1 26 | ADXL345_DC_AC KEYWORD1 27 | adxl345_dcAcMode KEYWORD1 28 | ADXL345_WAKE_UP_FREQ KEYWORD1 29 | adxl345_wUpFreq KEYWORD1 30 | ADXL345_ACT_TAP KEYWORD1 31 | adxl345_actTap KEYWORD1 32 | ADXL345_FIFO_MODE KEYWORD1 33 | adxl345_fifoMode KEYWORD1 34 | ADXL345_TRIGGER_INT KEYWORD1 35 | 36 | # STRUCT TYPES 37 | xyzFloat KEYWORD1 38 | 39 | 40 | ####################################### 41 | # Methods and Functions (KEYWORD2) 42 | ####################################### 43 | 44 | init KEYWORD2 45 | setSPIClockSpeed KEYWORD2 46 | setCorrFactors KEYWORD2 47 | setDataRate KEYWORD2 48 | getDataRate KEYWORD2 49 | getDataRateAsString KEYWORD2 50 | getPowerCtlReg KEYWORD2 51 | setRange KEYWORD2 52 | getRange KEYWORD2 53 | setFullRes KEYWORD2 54 | getRangeAsString KEYWORD2 55 | getRawValues KEYWORD2 56 | getCorrectedRawValues KEYWORD2 57 | getGValues KEYWORD2 58 | getAngles KEYWORD2 59 | getTilts KEYWORD2 60 | measureAngleOffsets KEYWORD2 61 | getAngleOffsets KEYWORD2 62 | setAngleOffsets KEYWORD2 63 | getOrientation KEYWORD2 64 | getOrientationAsString KEYWORD2 65 | getPitch KEYWORD2 66 | getRoll KEYWORD2 67 | setMeasureMode KEYWORD2 68 | setSleep KEYWORD2 69 | setAutoSleep KEYWORD2 70 | isAsleep KEYWORD2 71 | setLowPower KEYWORD2 72 | setInterrupt KEYWORD2 73 | setInterruptPolarity KEYWORD2 74 | deleteInterrupt KEYWORD2 75 | readAndClearInterrupts KEYWORD2 76 | checkInterrupt KEYWORD2 77 | setLinkBit KEYWORD2 78 | setFreeFallThresholds KEYWORD2 79 | setActivityParameters KEYWORD2 80 | setInactivityParameters KEYWORD2 81 | setGeneralTapParameters KEYWORD2 82 | setAdditionalDoubleTapParameters KEYWORD2 83 | getActTapStatus KEYWORD2 84 | getActTapStatusAsString KEYWORD2 85 | setFifoParameters KEYWORD2 86 | setFifoMode KEYWORD2 87 | getFifoStatus KEYWORD2 88 | resetTrigger KEYWORD2 89 | 90 | ####################################### 91 | # Constants (LITERAL1) 92 | ####################################### 93 | 94 | # ENUM VALUES 95 | ADXL345_WAKE_UP_0 LITERAL1 96 | ADXL345_WAKE_UP_1 LITERAL1 97 | ADXL345_SLEEP LITERAL1 98 | ADXL345_MEASURE LITERAL1 99 | ADXL345_AUTO_SLEEP LITERAL1 100 | ADXL345_LINK LITERAL1 101 | ADXL345_WAKE_UP_FREQ_8 LITERAL1 102 | ADXL345_WAKE_UP_FREQ_4 LITERAL1 103 | ADXL345_WAKE_UP_FREQ_2 LITERAL1 104 | ADXL345_WAKE_UP_FREQ_1 LITERAL1 105 | ADXL345_DATA_RATE_3200 LITERAL1 106 | ADXL345_DATA_ATE_1600 LITERAL1 107 | ADXL345_DATA_RATE_800 LITERAL1 108 | ADXL345_DATA_RATE_400 LITERAL1 109 | ADXL345_DATA_RATE_200 LITERAL1 110 | ADXL345_DATA_RATE_100 LITERAL1 111 | ADXL345_DATA_RATE_50 LITERAL1 112 | ADXL345_DATA_RATE_25 LITERAL1 113 | ADXL345_DATA_RATE_12_5 LITERAL1 114 | ADXL345_DATA_RATE_6_25 LITERAL1 115 | ADXL345_DATA_RATE_3_13 LITERAL1 116 | ADXL345_DATA_RATE_1_56 LITERAL1 117 | ADXL345_DATA_RATE_0_78 LITERAL1 118 | ADXL345_DATA_RATE_0_39 LITERAL1 119 | ADXL345_DATA_RATE_0_20 LITERAL1 120 | ADXL345_DATA_RATE_0_10 LITERAL1 121 | ADXL345_RANGE_16G LITERAL1 122 | ADXL345_RANGE_8G LITERAL1 123 | ADXL345_RANGE_4G LITERAL1 124 | ADXL345_RANGE_2G LITERAL1 125 | ADXL345_OVERRUN LITERAL1 126 | ADXL345_WATERMARK LITERAL1 127 | ADXL345_FREEFALL LITERAL1 128 | ADXL345_INACTIVITY LITERAL1 129 | ADXL345_ACTIVITY LITERAL1 130 | ADXL345_DOUBLE_TAP LITERAL1 131 | ADXL345_SINGLE_TAP LITERAL1 132 | ADXL345_DATA_READY LITERAL1 133 | ADXL345_000 LITERAL1 134 | ADXL345_00Z LITERAL1 135 | ADXL345_0Y0 LITERAL1 136 | ADXL345_0YZ LITERAL1 137 | ADXL345_X00 LITERAL1 138 | ADXL345_X0Z LITERAL1 139 | ADXL345_XY0 LITERAL1 140 | ADXL345_XYZ LITERAL1 141 | ADXL345_DC_MODE LITERAL1 142 | ADXL345_AC_MODE LITERAL1 143 | ADXL345_WUP_FQ_8 LITERAL1 144 | ADXL345_WUP_FQ_4 LITERAL1 145 | ADXL345_WUP_FQ_2 LITERAL1 146 | ADXL345_WUP_FQ_1 LITERAL1 147 | ADXL345_TAP_Z LITERAL1 148 | ADXL345_TAP_Y LITERAL1 149 | ADXL345_TAP_X LITERAL1 150 | ADXL345_ASLEEP LITERAL1 151 | ADXL345_ACT_Z LITERAL1 152 | ADXL345_ACT_Y LITERAL1 153 | ADXL345_ACT_X LITERAL1 154 | ADXL345_BYPASS LITERAL1 155 | ADXL345_FIFO LITERAL1 156 | ADXL345_STREAM LITERAL1 157 | ADXL345_TRIGGER LITERAL1 158 | ADXL345_TRIGGER_INT_1 LITERAL1 159 | ADXL345_TRIGGER_INT_2 LITERAL1 160 | ADXL343_WAKE_UP_0 LITERAL1 161 | ADXL343_WAKE_UP_1 LITERAL1 162 | ADXL343_SLEEP LITERAL1 163 | ADXL343_MEASURE LITERAL1 164 | ADXL343_AUTO_SLEEP LITERAL1 165 | ADXL343_LINK LITERAL1 166 | ADXL343_WAKE_UP_FREQ_8 LITERAL1 167 | ADXL343_WAKE_UP_FREQ_4 LITERAL1 168 | ADXL343_WAKE_UP_FREQ_2 LITERAL1 169 | ADXL343_WAKE_UP_FREQ_1 LITERAL1 170 | ADXL343_DATA_RATE_3200 LITERAL1 171 | ADXL343_DATA_ATE_1600 LITERAL1 172 | ADXL343_DATA_RATE_800 LITERAL1 173 | ADXL343_DATA_RATE_400 LITERAL1 174 | ADXL343_DATA_RATE_200 LITERAL1 175 | ADXL343_DATA_RATE_100 LITERAL1 176 | ADXL343_DATA_RATE_50 LITERAL1 177 | ADXL343_DATA_RATE_25 LITERAL1 178 | ADXL343_DATA_RATE_12_5 LITERAL1 179 | ADXL343_DATA_RATE_6_25 LITERAL1 180 | ADXL343_DATA_RATE_3_13 LITERAL1 181 | ADXL343_DATA_RATE_1_56 LITERAL1 182 | ADXL343_DATA_RATE_0_78 LITERAL1 183 | ADXL343_DATA_RATE_0_39 LITERAL1 184 | ADXL343_DATA_RATE_0_20 LITERAL1 185 | ADXL343_DATA_RATE_0_10 LITERAL1 186 | ADXL343_RANGE_16G LITERAL1 187 | ADXL343_RANGE_8G LITERAL1 188 | ADXL343_RANGE_4G LITERAL1 189 | ADXL343_RANGE_2G LITERAL1 190 | ADXL343_OVERRUN LITERAL1 191 | ADXL343_WATERMARK LITERAL1 192 | ADXL343_FREEFALL LITERAL1 193 | ADXL343_INACTIVITY LITERAL1 194 | ADXL343_ACTIVITY LITERAL1 195 | ADXL343_DOUBLE_TAP LITERAL1 196 | ADXL343_SINGLE_TAP LITERAL1 197 | ADXL343_DATA_READY LITERAL1 198 | ADXL343_000 LITERAL1 199 | ADXL343_00Z LITERAL1 200 | ADXL343_0Y0 LITERAL1 201 | ADXL343_0YZ LITERAL1 202 | ADXL343_X00 LITERAL1 203 | ADXL343_X0Z LITERAL1 204 | ADXL343_XY0 LITERAL1 205 | ADXL343_XYZ LITERAL1 206 | ADXL343_DC_MODE LITERAL1 207 | ADXL343_AC_MODE LITERAL1 208 | ADXL343_WUP_FQ_8 LITERAL1 209 | ADXL343_WUP_FQ_4 LITERAL1 210 | ADXL343_WUP_FQ_2 LITERAL1 211 | ADXL343_WUP_FQ_1 LITERAL1 212 | ADXL343_TAP_Z LITERAL1 213 | ADXL343_TAP_Y LITERAL1 214 | ADXL343_TAP_X LITERAL1 215 | ADXL343_ASLEEP LITERAL1 216 | ADXL343_ACT_Z LITERAL1 217 | ADXL343_ACT_Y LITERAL1 218 | ADXL343_ACT_X LITERAL1 219 | ADXL343_BYPASS LITERAL1 220 | ADXL343_FIFO LITERAL1 221 | ADXL343_STREAM LITERAL1 222 | ADXL343_TRIGGER LITERAL1 223 | ADXL343_TRIGGER_INT_1 LITERAL1 224 | ADXL343_TRIGGER_INT_2 LITERAL1 225 | 226 | #OTHER DEFINES 227 | INT_PIN_1 LITERAL1 228 | INT_PIN_2 LITERAL1 229 | ADXL345_ACT_LOW LITERAL1 230 | ADXL345_ACT_HIGH LITERAL1 231 | ADXL343_ACT_LOW LITERAL1 232 | ADXL343_ACT_HIGH LITERAL1 -------------------------------------------------------------------------------- /examples/ADXL345_auto_sleep/ADXL345_auto_sleep.ino: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Example sketch for the ADXL345_WE / ADXL343_WE library 3 | * 4 | * This sketch shows how to use the auto sleep function. 5 | * 6 | * Further information can be found on: 7 | * https://wolles-elektronikkiste.de/adxl345-teil-1 8 | * https://wolles-elektronikkiste.de/en/adxl345-the-universal-accelerometer-part-1 (English) 9 | * 10 | ***************************************************************************/ 11 | #include 12 | #include 13 | #define ADXL345_I2CADDR 0x53 // 0x1D if SDO = HIGH 14 | const int int2Pin = 2; 15 | volatile bool in_activity = false; 16 | 17 | /* There are several ways to create your ADXL345 object: 18 | * ADXL345_WE myAcc = ADXL345_WE() -> uses Wire / I2C Address = 0x53 19 | * ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR) -> uses Wire / ADXL345_I2CADDR 20 | * ADXL345_WE myAcc = ADXL345_WE(&wire2) -> uses the TwoWire object wire2 / ADXL345_I2CADDR 21 | * ADXL345_WE myAcc = ADXL345_WE(&wire2, ADXL345_I2CADDR) -> all together 22 | */ 23 | ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR); 24 | 25 | void setup() { 26 | Wire.begin(); 27 | Serial.begin(115200); 28 | pinMode(int2Pin, INPUT); 29 | Serial.println("ADXL345_Sketch - Auto Sleep"); 30 | Serial.println(); 31 | if (!myAcc.init()) { 32 | Serial.println("ADXL345 not connected!"); 33 | } 34 | /* Insert your data from ADXL345_calibration.ino and uncomment for more precise results */ 35 | // myAcc.setCorrFactors(-266.0, 285.0, -268.0, 278.0, -291.0, 214.0); 36 | 37 | /* Choose the data rate Hz 38 | ADXL345_DATA_RATE_3200 3200 39 | ADXL345_DATA_RATE_1600 1600 40 | ADXL345_DATA_RATE_800 800 41 | ADXL345_DATA_RATE_400 400 42 | ADXL345_DATA_RATE_200 200 43 | ADXL345_DATA_RATE_100 100 44 | ADXL345_DATA_RATE_50 50 45 | ADXL345_DATA_RATE_25 25 46 | ADXL345_DATA_RATE_12_5 12.5 47 | ADXL345_DATA_RATE_6_25 6.25 48 | ADXL345_DATA_RATE_3_13 3.13 49 | ADXL345_DATA_RATE_1_56 1.56 50 | ADXL345_DATA_RATE_0_78 0.78 51 | ADXL345_DATA_RATE_0_39 0.39 52 | ADXL345_DATA_RATE_0_20 0.20 53 | ADXL345_DATA_RATE_0_10 0.10 54 | */ 55 | myAcc.setDataRate(ADXL345_DATA_RATE_25); 56 | Serial.print("Data rate: "); 57 | Serial.print(myAcc.getDataRateAsString()); 58 | 59 | /* Choose the measurement range 60 | ADXL345_RANGE_16G 16g 61 | ADXL345_RANGE_8G 8g 62 | ADXL345_RANGE_4G 4g 63 | ADXL345_RANGE_2G 2g 64 | */ 65 | myAcc.setRange(ADXL345_RANGE_4G); 66 | Serial.print(" / g-Range: "); 67 | Serial.println(myAcc.getRangeAsString()); 68 | Serial.println(); 69 | 70 | attachInterrupt(digitalPinToInterrupt(int2Pin), in_activityISR, RISING); 71 | 72 | /* The following settings are similar to the settings in ADXL345_activity_inactivity_interrupt.ino */ 73 | 74 | /* Three parameters have to be set for activity: 75 | 1. DC / AC Mode: 76 | ADXL345_DC_MODE - Threshold is the defined one (parameter 3) 77 | ADXL345_AC_MODE - Threshold = starting acceleration + defined threshold 78 | 2. Axes, that are considered: 79 | ADXL345_000 - no axis (which makes no sense) 80 | ADXL345_00Z - z 81 | ADXL345_0Y0 - y 82 | ADXL345_0YZ - y,z 83 | ADXL345_X00 - x 84 | ADXL345_X0Z - x,z 85 | ADXL345_XY0 - x,y 86 | ADXL345_XYZ - all axes 87 | 3. Threshold in g 88 | */ 89 | myAcc.setActivityParameters(ADXL345_DC_MODE, ADXL345_XY0, 0.8); 90 | 91 | /* Four parameters have to be set for in activity: 92 | 1. DC / AC Mode: 93 | see activity parameters 94 | 2. Axes, that are considered: 95 | see activity parameters 96 | 3. Threshold in g 97 | 4. Inactivity period threshold in seconds (max 255) 98 | */ 99 | myAcc.setInactivityParameters(ADXL345_DC_MODE, ADXL345_XY0, 0.8, 10); 100 | 101 | /* You can choose the following interrupts: 102 | Variable name: Triggered, if: 103 | ADXL345_OVERRUN - new data replaces unread data 104 | ADXL345_WATERMARK - the number of samples in FIFO equals the number defined in FIFO_CTL 105 | ADXL345_FREEFALL - acceleration values of all axes are below the threshold defined in THRESH_FF 106 | ADXL345_INACTIVITY - acc. value of all included axes are < THRESH_INACT for period > TIME_INACT 107 | ADXL345_ACTIVITY - acc. value of included axes are > THRESH_ACT 108 | ADXL345_DOUBLE_TAP - double tap detected on one incl. axis and various defined conditions are met 109 | ADXL345_SINGLE_TAP - single tap detected on one incl. axis and various defined conditions are met 110 | ADXL345_DATA_READY - new data available 111 | 112 | Assign the interrupts to INT1 (INT_PIN_1) or INT2 (INT_PIN_2). Data ready, watermark and overrun are 113 | always enabled. You can only change the assignment of these which is INT1 by default. 114 | 115 | You can delete interrupts with deleteInterrupt(type); 116 | */ 117 | myAcc.setInterrupt(ADXL345_ACTIVITY, INT_PIN_2); 118 | myAcc.setInterrupt(ADXL345_INACTIVITY, INT_PIN_2); 119 | 120 | /* Auto sleep is connected with activity and inactivity. The device goes in sleep when inactivity is 121 | detected. The link bit must be set, if you want to use auto sleep. The library sets the link bit 122 | automatically. When the ADXL345 goes into sleep mode it wakes up periodically (default is 8 Hz). 123 | 124 | Choose the wake up frequency: 125 | ADXL345_WUP_FQ_1 = 1 Hz 126 | ADXL345_WUP_FQ_2 = 2 Hz 127 | ADXL345_WUP_FQ_4 = 4 Hz 128 | ADXL345_WUP_FQ_8 = 8 Hz 129 | 130 | */ 131 | myAcc.setAutoSleep(true, ADXL345_WUP_FQ_1); 132 | // alternative: myAcc.setAutoSleep(true/false) without changing the wake up frequency. 133 | myAcc.readAndClearInterrupts(); 134 | 135 | } 136 | 137 | void loop() { 138 | if ((millis() % 300) == 1) { 139 | xyzFloat g; 140 | myAcc.getGValues(&g); 141 | Serial.print("g-x = "); 142 | Serial.print(g.x); 143 | Serial.print(" | g-y = "); 144 | Serial.print(g.y); 145 | Serial.print(" | g-z = "); 146 | Serial.println(g.z); 147 | delay(4); 148 | } 149 | 150 | if(in_activity == true) { 151 | byte intSource = myAcc.readAndClearInterrupts(); 152 | if(myAcc.checkInterrupt(intSource, ADXL345_ACTIVITY)){ 153 | Serial.println("Activity!"); 154 | if(!myAcc.isAsleep()){ //check the asleep bit 155 | Serial.println("I am awake!"); 156 | } 157 | } 158 | 159 | if(myAcc.checkInterrupt(intSource, ADXL345_INACTIVITY)){ 160 | Serial.println("Inactivity!"); 161 | if(myAcc.isAsleep()){ 162 | Serial.println("I am sleeping..."); 163 | } 164 | } 165 | 166 | myAcc.readAndClearInterrupts(); 167 | in_activity = false; 168 | } 169 | } 170 | 171 | void in_activityISR() { 172 | in_activity = true; 173 | } 174 | -------------------------------------------------------------------------------- /examples/ADXL345_fifo_stream/ADXL345_fifo_stream.ino: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Example sketch for the ADXL345_WE / ADXL343_WE library 3 | * 4 | * This sketch shows how to use the FIFO in stream mode. 5 | * 6 | * Further information can be found on: 7 | * https://wolles-elektronikkiste.de/adxl345-teil-1 (German) 8 | * https://wolles-elektronikkiste.de/en/adxl345-the-universal-accelerometer-part-1 (English) 9 | * 10 | ***************************************************************************/ 11 | 12 | #include 13 | #include 14 | #define ADXL345_I2CADDR 0x53 // 0x1D if SDO = HIGH 15 | const int int2Pin = 2; 16 | volatile bool event = false; 17 | 18 | /* There are several ways to create your ADXL345 object: 19 | * ADXL345_WE myAcc = ADXL345_WE() -> uses Wire / I2C Address = 0x53 20 | * ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR) -> uses Wire / ADXL345_I2CADDR 21 | * ADXL345_WE myAcc = ADXL345_WE(&wire2) -> uses the TwoWire object wire2 / ADXL345_I2CADDR 22 | * ADXL345_WE myAcc = ADXL345_WE(&wire2, ADXL345_I2CADDR) -> all together 23 | */ 24 | ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR); 25 | 26 | void setup() { 27 | Wire.begin(); 28 | Serial.begin(115200); 29 | pinMode(int2Pin, INPUT); 30 | Serial.println("ADXL345_Sketch - FIFO - Stream Mode"); 31 | Serial.println(); 32 | if (!myAcc.init()) { 33 | Serial.println("ADXL345 not connected!"); 34 | } 35 | 36 | /* Insert your data from ADXL345_calibration.ino and uncomment for more precise results */ 37 | // myAcc.setCorrFactors(-266.0, 285.0, -268.0, 278.0, -291.0, 214.0); 38 | 39 | /* Choose the data rate Hz 40 | ADXL345_DATA_RATE_3200 3200 41 | ADXL345_DATA_RATE_1600 1600 42 | ADXL345_DATA_RATE_800 800 43 | ADXL345_DATA_RATE_400 400 44 | ADXL345_DATA_RATE_200 200 45 | ADXL345_DATA_RATE_100 100 46 | ADXL345_DATA_RATE_50 50 47 | ADXL345_DATA_RATE_25 25 48 | ADXL345_DATA_RATE_12_5 12.5 49 | ADXL345_DATA_RATE_6_25 6.25 50 | ADXL345_DATA_RATE_3_13 3.13 51 | ADXL345_DATA_RATE_1_56 1.56 52 | ADXL345_DATA_RATE_0_78 0.78 53 | ADXL345_DATA_RATE_0_39 0.39 54 | ADXL345_DATA_RATE_0_20 0.20 55 | ADXL345_DATA_RATE_0_10 0.10 56 | */ 57 | myAcc.setDataRate(ADXL345_DATA_RATE_12_5); 58 | Serial.print("Data rate: "); 59 | Serial.print(myAcc.getDataRateAsString()); 60 | 61 | /* Choose the measurement range 62 | ADXL345_RANGE_16G 16g 63 | ADXL345_RANGE_8G 8g 64 | ADXL345_RANGE_4G 4g 65 | ADXL345_RANGE_2G 2g 66 | */ 67 | myAcc.setRange(ADXL345_RANGE_4G); 68 | Serial.print(" / g-Range: "); 69 | Serial.println(myAcc.getRangeAsString()); 70 | Serial.println(); 71 | 72 | attachInterrupt(digitalPinToInterrupt(int2Pin), eventISR, RISING); 73 | 74 | /* Three parameters have to be set for activity: 75 | 1. DC / AC Mode: 76 | ADXL345_DC_MODE - Threshold is the defined one (parameter 3) 77 | ADXL345_AC_MODE - Threshold = starting acceleration + defined threshold 78 | 2. Axes, that are considered: 79 | ADXL345_000 - no axis (which makes no sense) 80 | ADXL345_00Z - z 81 | ADXL345_0Y0 - y 82 | ADXL345_0YZ - y,z 83 | ADXL345_X00 - x 84 | ADXL345_X0Z - x,z 85 | ADXL345_XY0 - x,y 86 | ADXL345_XYZ - all axes 87 | 3. Threshold in g 88 | */ 89 | myAcc.setActivityParameters(ADXL345_DC_MODE, ADXL345_XY0, 0.6); 90 | 91 | /* You can choose the following interrupts: 92 | Variable name: Triggered, if: 93 | ADXL345_OVERRUN - new data replaces unread data 94 | ADXL345_WATERMARK - the number of samples in FIFO equals the number defined in FIFO_CTL 95 | ADXL345_FREEFALL - acceleration values of all axes are below the threshold defined in THRESH_FF 96 | ADXL345_INACTIVITY - acc. value of all included axes are < THRESH_INACT for period > TIME_INACT 97 | ADXL345_ACTIVITY - acc. value of included axes are > THRESH_ACT 98 | ADXL345_DOUBLE_TAP - double tap detected on one incl. axis and various defined conditions are met 99 | ADXL345_SINGLE_TAP - single tap detected on one incl. axis and various defined conditions are met 100 | ADXL345_DATA_READY - new data available 101 | 102 | Assign the interrupts to INT1 (INT_PIN_1) or INT2 (INT_PIN_2). Data ready, watermark and overrun are 103 | always enabled. You can only change the assignment of these which is INT1 by default. 104 | 105 | You can delete interrupts with deleteInterrupt(type); 106 | */ 107 | myAcc.setInterrupt(ADXL345_ACTIVITY, INT_PIN_2); 108 | 109 | /* The following two FIFO parameters need to be set: 110 | 1. Trigger Bit: not relevant for this FIFO mode. 111 | 2. FIFO samples (max 32). Defines the size of the FIFO. One sample is an x,y,z triple. 112 | */ 113 | myAcc.setFifoParameters(ADXL345_TRIGGER_INT_1, 32); 114 | 115 | /* You can choose the following FIFO modes: 116 | ADXL345_FIFO - you choose the start, ends when FIFO is full (at defined limit) 117 | ADXL345_STREAM - FIFO always filled with new data, old data replaced if FIFO is full; you choose the stop 118 | ADXL345_TRIGGER - FIFO always filled up to 32 samples; when the trigger event occurs only defined number of samples 119 | is kept in the FIFO and further samples are taken after the event until FIFO is full again. 120 | ADXL345_BYPASS - no FIFO 121 | */ 122 | myAcc.setFifoMode(ADXL345_STREAM); 123 | 124 | myAcc.readAndClearInterrupts(); 125 | 126 | Serial.println("Waiting for Activity Event - I propose to slowly turn the ADXL345"); 127 | } 128 | 129 | /* In the main loop some checks are done: 130 | getActTapStatus() returns which axes are responsible for activity interrupt as byte (code in library) 131 | getActTapStatusAsString() returns the axes that caused the interrupt as string 132 | readAndClearInterrupts(); returns the interrupt type as byte (code in library) 133 | checkInterrupt(intSource, type) returns if intSource is type as bool 134 | */ 135 | 136 | void loop() { 137 | if(event){ 138 | myAcc.setMeasureMode(false); 139 | //byte actTapSource = myAcc.getActTapStatus(); 140 | //Serial.println(actTapSource, BIN); 141 | String axes = myAcc.getActTapStatusAsString(); 142 | byte intSource = myAcc.readAndClearInterrupts(); 143 | if(myAcc.checkInterrupt(intSource, ADXL345_ACTIVITY)){ 144 | Serial.print("ACT at: "); 145 | Serial.println(axes); 146 | } 147 | printFifo(); 148 | Serial.println("For another series of measurements, enter any key and send"); 149 | while(!(Serial.available())){} 150 | Serial.read(); 151 | Serial.println(); 152 | Serial.println("Waiting for Activity Event"); 153 | 154 | event = false; 155 | myAcc.readAndClearInterrupts(); 156 | myAcc.setMeasureMode(true); 157 | } 158 | } 159 | 160 | void eventISR() { 161 | event = true; 162 | } 163 | 164 | void printFifo(){ 165 | for(int i=0; i<32; i++){ 166 | xyzFloat g; 167 | myAcc.getGValues(&g); 168 | 169 | Serial.print("g-x = "); 170 | Serial.print(g.x); 171 | Serial.print(" | g-y = "); 172 | Serial.print(g.y); 173 | Serial.print(" | g-z = "); 174 | Serial.println(g.z); 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /examples/ADXL345_activity_inactivity_interrupt/ADXL345_activity_inactivity_interrupt.ino: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Example sketch for the ADXL345_WE / ADXL343_WE library 3 | * 4 | * This sketch shows how to use the activity / inactivity interrupts. 5 | * 6 | * Further information can be found on: 7 | * https://wolles-elektronikkiste.de/adxl345-teil-1 (German) 8 | * https://wolles-elektronikkiste.de/en/adxl345-the-universal-accelerometer-part-1 (English) 9 | * 10 | ***************************************************************************/ 11 | 12 | #include 13 | #include 14 | #define ADXL345_I2CADDR 0x53 // 0x1D if SDO = HIGH 15 | const int int2Pin = 2; 16 | volatile bool in_activity = false; // in_activity: either activity or inactivity interrupt occured 17 | 18 | /* There are several ways to create your ADXL345 object: 19 | * ADXL345_WE myAcc = ADXL345_WE() -> uses Wire / I2C Address = 0x53 20 | * ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR) -> uses Wire / ADXL345_I2CADDR 21 | * ADXL345_WE myAcc = ADXL345_WE(&wire2) -> uses the TwoWire object wire2 / ADXL345_I2CADDR 22 | * ADXL345_WE myAcc = ADXL345_WE(&wire2, ADXL345_I2CADDR) -> all together 23 | */ 24 | ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR); 25 | 26 | void setup() { 27 | Wire.begin(); 28 | Serial.begin(115200); 29 | pinMode(int2Pin, INPUT); 30 | Serial.println("ADXL345_Sketch - Activity and Inactivity Interrupts"); 31 | Serial.println(); 32 | if (!myAcc.init()) { 33 | Serial.println("ADXL345 not connected!"); 34 | } 35 | 36 | /* Insert your data from ADXL345_calibration.ino and uncomment for more precise results */ 37 | // myAcc.setCorrFactors(-266.0, 285.0, -268.0, 278.0, -291.0, 214.0); 38 | 39 | /* Choose the data rate Hz 40 | ADXL345_DATA_RATE_3200 3200 41 | ADXL345_DATA_RATE_1600 1600 42 | ADXL345_DATA_RATE_800 800 43 | ADXL345_DATA_RATE_400 400 44 | ADXL345_DATA_RATE_200 200 45 | ADXL345_DATA_RATE_100 100 46 | ADXL345_DATA_RATE_50 50 47 | ADXL345_DATA_RATE_25 25 48 | ADXL345_DATA_RATE_12_5 12.5 49 | ADXL345_DATA_RATE_6_25 6.25 50 | ADXL345_DATA_RATE_3_13 3.13 51 | ADXL345_DATA_RATE_1_56 1.56 52 | ADXL345_DATA_RATE_0_78 0.78 53 | ADXL345_DATA_RATE_0_39 0.39 54 | ADXL345_DATA_RATE_0_20 0.20 55 | ADXL345_DATA_RATE_0_10 0.10 56 | */ 57 | myAcc.setDataRate(ADXL345_DATA_RATE_25); 58 | Serial.print("Data rate: "); 59 | Serial.print(myAcc.getDataRateAsString()); 60 | 61 | /* Choose the measurement range 62 | ADXL345_RANGE_16G 16g 63 | ADXL345_RANGE_8G 8g 64 | ADXL345_RANGE_4G 4g 65 | ADXL345_RANGE_2G 2g 66 | */ 67 | myAcc.setRange(ADXL345_RANGE_4G); 68 | Serial.print(" / g-Range: "); 69 | Serial.println(myAcc.getRangeAsString()); 70 | Serial.println(); 71 | 72 | attachInterrupt(digitalPinToInterrupt(int2Pin), in_activityISR, RISING); 73 | 74 | /* Three parameters have to be set for activity: 75 | 1. DC / AC Mode: 76 | ADXL345_DC_MODE - Threshold is the defined one (parameter 3) 77 | ADXL345_AC_MODE - Threshold = starting acceleration + defined threshold 78 | 2. Axes, that are considered: 79 | ADXL345_000 - no axis (which makes no sense) 80 | ADXL345_00Z - z 81 | ADXL345_0Y0 - y 82 | ADXL345_0YZ - y,z 83 | ADXL345_X00 - x 84 | ADXL345_X0Z - x,z 85 | ADXL345_XY0 - x,y 86 | ADXL345_XYZ - all axes 87 | 3. Threshold in g 88 | */ 89 | myAcc.setActivityParameters(ADXL345_DC_MODE, ADXL345_XY0, 0.5); 90 | 91 | /* Four parameters have to be set for in activity: 92 | 1. DC / AC Mode: 93 | see activity parameters 94 | 2. Axes, that are considered: 95 | see activity parameters 96 | 3. Threshold in g 97 | 4. Inactivity period threshold in seconds (max 255) 98 | */ 99 | myAcc.setInactivityParameters(ADXL345_DC_MODE, ADXL345_XY0, 0.5, 10.0); 100 | 101 | /* Setting the link bit only makes sense if both activity and inactivity are used 102 | * If link bit is not set: 103 | * - activity interrupt can be triggered any time and multiple times 104 | * - inactivity can be triggered if inactivity param. are met, independent from activity param. (if used) 105 | * If link bit is set: 106 | * - activity interrupt can only be triggered after inactivity interrupt 107 | * - only one activity interrupt can be triggered until the next inactivity interrupt occurs 108 | */ 109 | // myAcc.setLinkBit(true); 110 | 111 | /* You can choose the following interrupts: 112 | Variable name: Triggered, if: 113 | ADXL345_OVERRUN - new data replaces unread data 114 | ADXL345_WATERMARK - the number of samples in FIFO equals the number defined in FIFO_CTL 115 | ADXL345_FREEFALL - acceleration values of all axes are below the threshold defined in THRESH_FF 116 | ADXL345_INACTIVITY - acc. value of all included axes are < THRESH_INACT for period > TIME_INACT 117 | ADXL345_ACTIVITY - acc. value of included axes are > THRESH_ACT 118 | ADXL345_DOUBLE_TAP - double tap detected on one incl. axis and various defined conditions are met 119 | ADXL345_SINGLE_TAP - single tap detected on one incl. axis and various defined conditions are met 120 | ADXL345_DATA_READY - new data available 121 | 122 | Assign the interrupts to INT1 (INT_PIN_1) or INT2 (INT_PIN_2). Data ready, watermark and overrun are 123 | always enabled. You can only change the assignment of these which is INT1 by default. 124 | 125 | You can delete interrupts with deleteInterrupt(type); 126 | */ 127 | myAcc.setInterrupt(ADXL345_ACTIVITY, INT_PIN_2); 128 | myAcc.setInterrupt(ADXL345_INACTIVITY, INT_PIN_2); 129 | myAcc.readAndClearInterrupts(); 130 | } 131 | 132 | /* In the main loop some checks are done: 133 | getActTapStatus() returns which axes are responsible for activity interrupt as byte (code in library) 134 | getActTapStatusAsString() returns the axes that caused the interrupt as string 135 | readAndClearInterrupts(); returns the interrupt type as byte (code in library) 136 | checkInterrupt(intSource, type) returns if intSource is type as bool 137 | */ 138 | 139 | void loop() { 140 | if ((millis() % 1000) == 1) { 141 | xyzFloat g; 142 | myAcc.getGValues(&g); 143 | Serial.print("g-x = "); 144 | Serial.print(g.x); 145 | Serial.print(" | g-y = "); 146 | Serial.print(g.y); 147 | Serial.print(" | g-z = "); 148 | Serial.println(g.z); 149 | delay(1); 150 | } 151 | 152 | if(in_activity == true) { 153 | //byte actTapSource = myAcc.getActTapStatus(); 154 | //Serial.println(actTapSource, BIN); 155 | String axes = myAcc.getActTapStatusAsString(); 156 | byte intSource = myAcc.readAndClearInterrupts(); 157 | if(myAcc.checkInterrupt(intSource, ADXL345_ACTIVITY)){ 158 | Serial.print("Activity at: "); 159 | Serial.println(axes); 160 | } 161 | 162 | if(myAcc.checkInterrupt(intSource, ADXL345_INACTIVITY)){ 163 | Serial.println("Inactivity!"); 164 | } 165 | 166 | delay(1000); 167 | myAcc.readAndClearInterrupts(); 168 | in_activity = false; 169 | } 170 | } 171 | 172 | void in_activityISR() { 173 | in_activity = true; 174 | } 175 | -------------------------------------------------------------------------------- /examples/ADXL345_fifo_trigger/ADXL345_fifo_trigger.ino: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Example sketch for the ADXL345_WE / ADXL343_WE library 3 | * 4 | * This sketch shows how to use the FIFO in trigger mode. 5 | * 6 | * Further information can be found on: 7 | * https://wolles-elektronikkiste.de/adxl345-teil-1 (German) 8 | * https://wolles-elektronikkiste.de/en/adxl345-the-universal-accelerometer-part-1 (English) 9 | * 10 | ***************************************************************************/ 11 | 12 | #include 13 | #include 14 | #define ADXL345_I2CADDR 0x53 // 0x1D if SDO = HIGH 15 | const int int2Pin = 2; 16 | volatile bool event = false; 17 | 18 | /* There are several ways to create your ADXL345 object: 19 | * ADXL345_WE myAcc = ADXL345_WE() -> uses Wire / I2C Address = 0x53 20 | * ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR) -> uses Wire / ADXL345_I2CADDR 21 | * ADXL345_WE myAcc = ADXL345_WE(&wire2) -> uses the TwoWire object wire2 / ADXL345_I2CADDR 22 | * ADXL345_WE myAcc = ADXL345_WE(&wire2, ADXL345_I2CADDR) -> all together 23 | */ 24 | ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR); 25 | 26 | void setup() { 27 | Wire.begin(); 28 | Serial.begin(115200); 29 | pinMode(int2Pin, INPUT); 30 | Serial.println("ADXL345_Sketch - FIFO - Trigger Mode"); 31 | Serial.println(); 32 | if (!myAcc.init()) { 33 | Serial.println("ADXL345 not connected!"); 34 | } 35 | 36 | /* Insert your data from ADXL345_calibration.ino and uncomment for more precise results */ 37 | // myAcc.setCorrFactors(-266.0, 285.0, -268.0, 278.0, -291.0, 214.0); 38 | 39 | /* Choose the data rate Hz 40 | ADXL345_DATA_RATE_3200 3200 41 | ADXL345_DATA_RATE_1600 1600 42 | ADXL345_DATA_RATE_800 800 43 | ADXL345_DATA_RATE_400 400 44 | ADXL345_DATA_RATE_200 200 45 | ADXL345_DATA_RATE_100 100 46 | ADXL345_DATA_RATE_50 50 47 | ADXL345_DATA_RATE_25 25 48 | ADXL345_DATA_RATE_12_5 12.5 49 | ADXL345_DATA_RATE_6_25 6.25 50 | ADXL345_DATA_RATE_3_13 3.13 51 | ADXL345_DATA_RATE_1_56 1.56 52 | ADXL345_DATA_RATE_0_78 0.78 53 | ADXL345_DATA_RATE_0_39 0.39 54 | ADXL345_DATA_RATE_0_20 0.20 55 | ADXL345_DATA_RATE_0_10 0.10 56 | */ 57 | myAcc.setDataRate(ADXL345_DATA_RATE_12_5); 58 | Serial.print("Data rate: "); 59 | Serial.print(myAcc.getDataRateAsString()); 60 | 61 | /* Choose the measurement range 62 | ADXL345_RANGE_16G 16g 63 | ADXL345_RANGE_8G 8g 64 | ADXL345_RANGE_4G 4g 65 | ADXL345_RANGE_2G 2g 66 | */ 67 | myAcc.setRange(ADXL345_RANGE_4G); 68 | Serial.print(" / g-Range: "); 69 | Serial.println(myAcc.getRangeAsString()); 70 | Serial.println(); 71 | 72 | attachInterrupt(digitalPinToInterrupt(int2Pin), eventISR, RISING); 73 | 74 | /* Three parameters have to be set for activity: 75 | 1. DC / AC Mode: 76 | ADXL345_DC_MODE - Threshold is the defined one (parameter 3) 77 | ADXL345_AC_MODE - Threshold = starting acceleration + defined threshold 78 | 2. Axes, that are considered: 79 | ADXL345_000 - no axis (which makes no sense) 80 | ADXL345_00Z - z 81 | ADXL345_0Y0 - y 82 | ADXL345_0YZ - y,z 83 | ADXL345_X00 - x 84 | ADXL345_X0Z - x,z 85 | ADXL345_XY0 - x,y 86 | ADXL345_XYZ - all axes 87 | 3. Threshold in g 88 | */ 89 | myAcc.setActivityParameters(ADXL345_DC_MODE, ADXL345_XY0, 0.6); 90 | 91 | /* You can choose the following interrupts: 92 | Variable name: Triggered, if: 93 | ADXL345_OVERRUN - new data replaces unread data 94 | ADXL345_WATERMARK - the number of samples in FIFO equals the number defined in FIFO_CTL 95 | ADXL345_FREEFALL - acceleration values of all axes are below the threshold defined in THRESH_FF 96 | ADXL345_INACTIVITY - acc. value of all included axes are < THRESH_INACT for period > TIME_INACT 97 | ADXL345_ACTIVITY - acc. value of included axes are > THRESH_ACT 98 | ADXL345_DOUBLE_TAP - double tap detected on one incl. axis and various defined conditions are met 99 | ADXL345_SINGLE_TAP - single tap detected on one incl. axis and various defined conditions are met 100 | ADXL345_DATA_READY - new data available 101 | 102 | Assign the interrupts to INT1 (INT_PIN_1) or INT2 (INT_PIN_2). Data ready, watermark and overrun are 103 | always enabled. You can only change the assignment of these which is INT1 by default. 104 | 105 | You can delete interrupts with deleteInterrupt(type); 106 | */ 107 | myAcc.setInterrupt(ADXL345_ACTIVITY, INT_PIN_2); 108 | 109 | /* The following two FIFO parameters need to be set: 110 | 1. Trigger Bit: the trigger is an interrupt at INT1 or INT2 111 | ADXL345_TRIGGER_INT_1 - Trigger is an interrupt at INT1 112 | ADXL345_TRIGGER_INT_2 - Trigger is an interrupt at INT2 113 | 2. FIFO samples (max 32). Defines the size of the FIFO. One sample is an x,y,z triple. 114 | */ 115 | myAcc.setFifoParameters(ADXL345_TRIGGER_INT_2, 15); 116 | 117 | /* You can choose the following FIFO modes: 118 | ADXL345_FIFO - you choose the start, ends when FIFO is full (at defined limit) 119 | ADXL345_STREAM - FIFO always filled with new data, old data replaced if FIFO is full; you choose the stop 120 | ADXL345_TRIGGER - FIFO always filled up to 32 samples; when the trigger event occurs only defined number of samples 121 | is kept in the FIFO and further samples are taken after the event until FIFO is full again. 122 | ADXL345_BYPASS - no FIFO 123 | */ 124 | myAcc.setFifoMode(ADXL345_TRIGGER); 125 | 126 | myAcc.readAndClearInterrupts(); 127 | 128 | Serial.println("Waiting for Activity Event"); 129 | } 130 | 131 | /* In the main loop some checks are done: 132 | getActTapStatus() returns which axes are responsible for activity interrupt as byte (code in library) 133 | getActTapStatusAsString() returns the axes that caused the interrupt as string 134 | readAndClearInterrupts(); returns the interrupt type as byte (code in library) 135 | checkInterrupt(intSource, type) returns if intSource is type as bool 136 | */ 137 | void loop() { 138 | 139 | if(event){ 140 | String axes = myAcc.getActTapStatusAsString(); 141 | byte intSource = myAcc.readAndClearInterrupts(); 142 | if(myAcc.checkInterrupt(intSource, ADXL345_ACTIVITY)){ 143 | Serial.print("Activity at: "); 144 | Serial.println(axes); 145 | } 146 | while(!(myAcc.getFifoStatus() & 32)){} 147 | printFifo(); 148 | 149 | Serial.println("For another series of measurements, enter any key and send"); 150 | while(!(Serial.available())){} 151 | Serial.read(); 152 | Serial.println(); 153 | myAcc.readAndClearInterrupts(); 154 | myAcc.resetTrigger(); 155 | Serial.println("Waiting for Activity Event"); 156 | event = false; 157 | } 158 | } 159 | 160 | void eventISR() { 161 | event = true; 162 | } 163 | 164 | void printFifo(){ 165 | for(int i=0; i<32; i++){ 166 | xyzFloat g; 167 | myAcc.getGValues(&g); 168 | 169 | Serial.print("g-x = "); 170 | Serial.print(g.x); 171 | Serial.print(" | g-y = "); 172 | Serial.print(g.y); 173 | Serial.print(" | g-z = "); 174 | Serial.println(g.z); 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /examples/ADXL345_double_tap/ADXL345_double_tap.ino: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Example sketch for the ADXL345_WE / ADXL343_WE library 3 | * 4 | * This sketch shows how to use the double tap function in combination with 5 | * single tap. 6 | * 7 | * Further information can be found on: 8 | * https://wolles-elektronikkiste.de/adxl345-teil-1 (German) 9 | * https://wolles-elektronikkiste.de/en/adxl345-the-universal-accelerometer-part-1 (English) 10 | * 11 | ***************************************************************************/ 12 | 13 | #include 14 | #include 15 | #define ADXL345_I2CADDR 0x53 // 0x1D if SDO = HIGH 16 | const int int1Pin = 2; 17 | volatile bool tap = false; 18 | 19 | /* There are several ways to create your ADXL345 object: 20 | * ADXL345_WE myAcc = ADXL345_WE() -> uses Wire / I2C Address = 0x53 21 | * ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR) -> uses Wire / ADXL345_I2CADDR 22 | * ADXL345_WE myAcc = ADXL345_WE(&wire2) -> uses the TwoWire object wire2 / ADXL345_I2CADDR 23 | * ADXL345_WE myAcc = ADXL345_WE(&wire2, ADXL345_I2CADDR) -> all together 24 | */ 25 | ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR); 26 | 27 | void setup() { 28 | Wire.begin(); 29 | Serial.begin(115200); 30 | pinMode(int1Pin, INPUT); 31 | Serial.println("ADXL345_Sketch - Single Tap Interrupt"); 32 | Serial.println(); 33 | if (!myAcc.init()) { 34 | Serial.println("ADXL345 not connected!"); 35 | } 36 | 37 | /* Insert your data from ADXL345_calibration.ino and uncomment for more precise results */ 38 | // myAcc.setCorrFactors(-266.0, 285.0, -268.0, 278.0, -291.0, 214.0); 39 | 40 | /* Choose the data rate Hz 41 | ADXL345_DATA_RATE_3200 3200 42 | ADXL345_DATA_RATE_1600 1600 43 | ADXL345_DATA_RATE_800 800 44 | ADXL345_DATA_RATE_400 400 45 | ADXL345_DATA_RATE_200 200 46 | ADXL345_DATA_RATE_100 100 47 | ADXL345_DATA_RATE_50 50 48 | ADXL345_DATA_RATE_25 25 49 | ADXL345_DATA_RATE_12_5 12.5 50 | ADXL345_DATA_RATE_6_25 6.25 51 | ADXL345_DATA_RATE_3_13 3.13 52 | ADXL345_DATA_RATE_1_56 1.56 53 | ADXL345_DATA_RATE_0_78 0.78 54 | ADXL345_DATA_RATE_0_39 0.39 55 | ADXL345_DATA_RATE_0_20 0.20 56 | ADXL345_DATA_RATE_0_10 0.10 57 | */ 58 | myAcc.setDataRate(ADXL345_DATA_RATE_200); 59 | Serial.print("Data rate: "); 60 | Serial.print(myAcc.getDataRateAsString()); 61 | 62 | /* Choose the measurement range 63 | ADXL345_RANGE_16G 16g 64 | ADXL345_RANGE_8G 8g 65 | ADXL345_RANGE_4G 4g 66 | ADXL345_RANGE_2G 2g 67 | */ 68 | myAcc.setRange(ADXL345_RANGE_8G); 69 | Serial.print(" / g-Range: "); 70 | Serial.println(myAcc.getRangeAsString()); 71 | Serial.println(); 72 | 73 | attachInterrupt(digitalPinToInterrupt(int1Pin), tapISR, RISING); 74 | 75 | /* The following four parameters have to be set for tap application (single and double): 76 | 1. Axes, that are considered: 77 | ADXL345_000 - no axis (which makes no sense) 78 | ADXL345_00Z - z 79 | ADXL345_0Y0 - y 80 | ADXL345_0YZ - y,z 81 | ADXL345_X00 - x 82 | ADXL345_X0Z - x,z 83 | ADXL345_XY0 - x,y 84 | ADXL345_XYZ - all axes 85 | 2. Threshold in g 86 | It is recommended to not choose the value to low. 3g is a good starting point. 87 | 3. Duration in milliseconds (max 159 ms): 88 | maximum time that the acceleration must be over g threshold to be regarded as a single tap. If 89 | the acceleration drops below the g threshold before the duration is exceeded an interrupt will be 90 | triggered. If also double tap is active an interrupt will only be triggered after the double tap 91 | conditions have been checked. Duration should be greater than 10. 92 | 4. Latency time in milliseconds (maximum: 318 ms): minimum time before the next tap can be detected. 93 | Starts at the end of duration or when the interrupt was triggered. Should be greater than 20 ms. 94 | */ 95 | myAcc.setGeneralTapParameters(ADXL345_XY0, 3.0, 30, 100.0); 96 | 97 | /* For double tap detection additional parameters have to be set: 98 | 1. Suppress bit: if the bit is set, a spike over the threshold during the latency time will invalidate 99 | the double tap. You find graphs that explain this better than words in the data sheet. If the bit is 100 | not set, the tap during latency time will be ignored. Another tap in the time window (see 2) will lead 101 | to double tap detection. 102 | 2. Time window in milliseconds: starts after latency time. The second tap must occur during the time window 103 | period, otherwise it is a single tap (if single tap is active). Maximum window is 318 ms. 104 | */ 105 | myAcc.setAdditionalDoubleTapParameters(false, 250); 106 | 107 | /* You can choose the following interrupts: 108 | Variable name: Triggered, if: 109 | ADXL345_OVERRUN - new data replaces unread data 110 | ADXL345_WATERMARK - the number of samples in FIFO equals the number defined in FIFO_CTL 111 | ADXL345_FREEFALL - acceleration values of all axes are below the threshold defined in THRESH_FF 112 | ADXL345_INACTIVITY - acc. value of all included axes are < THRESH_INACT for period > TIME_INACT 113 | ADXL345_ACTIVITY - acc. value of included axes are > THRESH_ACT 114 | ADXL345_DOUBLE_TAP - double tap detected on one incl. axis and various defined conditions are met 115 | ADXL345_SINGLE_TAP - single tap detected on one incl. axis and various defined conditions are met 116 | ADXL345_DATA_READY - new data available 117 | 118 | Assign the interrupts to INT1 (INT_PIN_1) or INT2 (INT_PIN_2). Data ready, watermark and overrun are 119 | always enabled. You can only change the assignment of these which is INT1 by default. 120 | 121 | You can delete interrupts with deleteInterrupt(type); 122 | */ 123 | myAcc.setInterrupt(ADXL345_SINGLE_TAP, INT_PIN_2); 124 | myAcc.setInterrupt(ADXL345_DOUBLE_TAP, INT_PIN_2); 125 | myAcc.readAndClearInterrupts(); 126 | } 127 | 128 | /* In the main loop some checks are done: 129 | getActTapStatus() returns which axes are responsible for activity interrupt as byte (code in library) 130 | getActTapStatusAsString() returns the axes that caused the interrupt as string 131 | readAndClearInterrupts(); returns the interrupt type as byte (code in library) 132 | checkInterrupt(intSource, type) returns if intSource is type as bool 133 | */ 134 | void loop() { 135 | if ((millis() % 1000) == 1) { 136 | xyzFloat g; 137 | myAcc.getGValues(&g); 138 | Serial.print("g-x = "); 139 | Serial.print(g.x); 140 | Serial.print(" | g-y = "); 141 | Serial.print(g.y); 142 | Serial.print(" | g-z = "); 143 | Serial.println(g.z); 144 | delay(1); 145 | } 146 | 147 | if(tap == true) { 148 | //byte actTapSource = myAcc.getActTapStatus(); 149 | //Serial.println(actTapSource, BIN); 150 | String axes = myAcc.getActTapStatusAsString(); 151 | byte intSource = myAcc.readAndClearInterrupts(); 152 | if(myAcc.checkInterrupt(intSource, ADXL345_SINGLE_TAP)){ 153 | Serial.print("TAP at: "); 154 | Serial.println(axes); 155 | } 156 | if(myAcc.checkInterrupt(intSource, ADXL345_DOUBLE_TAP)){ 157 | Serial.print("DOUBLE TAP at: "); 158 | Serial.println(axes); 159 | } 160 | 161 | delay(1000); 162 | myAcc.readAndClearInterrupts(); 163 | tap = false; 164 | } 165 | } 166 | 167 | void tapISR() { 168 | tap = true; 169 | } 170 | -------------------------------------------------------------------------------- /src/ADXL345_WE.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * This is a library for the ADXL345 / ASXL343 accelerometer. 4 | * 5 | * You'll find several example sketches which should enable you to use the library. 6 | * 7 | * You are free to use it, change it or build on it. In case you like it, it would 8 | * be cool if you give it a star. 9 | * 10 | * If you find bugs, please inform me! 11 | * 12 | * Written by Wolfgang (Wolle) Ewald 13 | * https://wolles-elektronikkiste.de/adxl345-teil-1 (German) 14 | * https://wolles-elektronikkiste.de/en/adxl345-the-universal-accelerometer-part-1 (English) 15 | * 16 | * 17 | ******************************************************************************/ 18 | 19 | #ifndef ADXL345_WE_H_ 20 | #define ADXL345_WE_H_ 21 | 22 | #if (ARDUINO >= 100) 23 | #include "Arduino.h" 24 | #else 25 | #include "WProgram.h" 26 | #endif 27 | 28 | #include 29 | #include 30 | #include "xyzFloat.h" 31 | 32 | /* Definitions */ 33 | 34 | constexpr uint8_t INT_PIN_1 {0x01}; 35 | constexpr uint8_t INT_PIN_2 {0x02}; 36 | constexpr uint8_t ADXL345_ACT_LOW {0x01}; 37 | constexpr uint8_t ADXL345_ACT_HIGH {0x00}; 38 | #define ADXL343_ACT_LOW ADXL_345_ACT_LOW 39 | #define ADXL343_ACT_HIGH ADXL345_ACT_HIGH 40 | 41 | constexpr float ADXL345_FLOAT_ERROR {999.0}; // Returned by getPitch() and getRoll() to indicate error 42 | constexpr float ADXL343_FLOAT_ERROR {ADXL345_FLOAT_ERROR}; 43 | 44 | typedef enum ADXL345_PWR_CTL { 45 | ADXL345_WAKE_UP_0, ADXL345_WAKE_UP_1, ADXL345_SLEEP, 46 | ADXL345_MEASURE, ADXL345_AUTO_SLEEP, ADXL345_LINK, 47 | ADXL343_WAKE_UP_0 = ADXL345_WAKE_UP_0, 48 | ADXL343_WAKE_UP_1 = ADXL345_WAKE_UP_1, 49 | ADXL343_SLEEP = ADXL345_SLEEP, 50 | ADXL343_MEASURE = ADXL345_MEASURE, 51 | ADXL343_AUTO_SLEEP = ADXL345_AUTO_SLEEP, 52 | ADXL343_LINK = ADXL345_LINK 53 | } adxl345_pwrCtl; 54 | 55 | typedef enum ADXL345_DATA_RATE { 56 | ADXL345_DATA_RATE_ERROR = -1, // returned on read error, cannot be set 57 | ADXL345_DATA_RATE_3200 = 0x0F, 58 | ADXL345_DATA_RATE_1600 = 0x0E, 59 | ADXL345_DATA_RATE_800 = 0x0D, 60 | ADXL345_DATA_RATE_400 = 0x0C, 61 | ADXL345_DATA_RATE_200 = 0x0B, 62 | ADXL345_DATA_RATE_100 = 0x0A, 63 | ADXL345_DATA_RATE_50 = 0x09, 64 | ADXL345_DATA_RATE_25 = 0x08, 65 | ADXL345_DATA_RATE_12_5 = 0x07, 66 | ADXL345_DATA_RATE_6_25 = 0x06, 67 | ADXL345_DATA_RATE_3_13 = 0x05, 68 | ADXL345_DATA_RATE_1_56 = 0x04, 69 | ADXL345_DATA_RATE_0_78 = 0x03, 70 | ADXL345_DATA_RATE_0_39 = 0x02, 71 | ADXL345_DATA_RATE_0_20 = 0x01, 72 | ADXL345_DATA_RATE_0_10 = 0x00, 73 | ADXL343_DATA_RATE_ERROR = ADXL345_DATA_RATE_ERROR, 74 | ADXL343_DATA_RATE_3200 = ADXL345_DATA_RATE_3200, 75 | ADXL343_DATA_RATE_1600 = ADXL345_DATA_RATE_1600, 76 | ADXL343_DATA_RATE_800 = ADXL345_DATA_RATE_800, 77 | ADXL343_DATA_RATE_400 = ADXL345_DATA_RATE_400, 78 | ADXL343_DATA_RATE_200 = ADXL345_DATA_RATE_200, 79 | ADXL343_DATA_RATE_100 = ADXL345_DATA_RATE_100, 80 | ADXL343_DATA_RATE_50 = ADXL345_DATA_RATE_50, 81 | ADXL343_DATA_RATE_25 = ADXL345_DATA_RATE_25, 82 | ADXL343_DATA_RATE_12_5 = ADXL345_DATA_RATE_12_5, 83 | ADXL343_DATA_RATE_6_25 = ADXL345_DATA_RATE_6_25, 84 | ADXL343_DATA_RATE_3_13 = ADXL345_DATA_RATE_3_13, 85 | ADXL343_DATA_RATE_1_56 = ADXL345_DATA_RATE_1_56, 86 | ADXL343_DATA_RATE_0_78 = ADXL345_DATA_RATE_0_78, 87 | ADXL343_DATA_RATE_0_39 = ADXL345_DATA_RATE_0_39, 88 | ADXL343_DATA_RATE_0_20 = ADXL345_DATA_RATE_0_20, 89 | ADXL343_DATA_RATE_0_10 = ADXL345_DATA_RATE_0_10 90 | } adxl345_dataRate; 91 | 92 | typedef enum ADXL345_RANGE { 93 | ADXL345_RANGE_ERROR = -1, // returned on read error, cannot be set 94 | ADXL345_RANGE_16G = 0b11, 95 | ADXL345_RANGE_8G = 0b10, 96 | ADXL345_RANGE_4G = 0b01, 97 | ADXL345_RANGE_2G = 0b00, 98 | ADXL343_RANGE_ERROR = ADXL345_RANGE_ERROR, 99 | ADXL343_RANGE_16G = ADXL345_RANGE_16G, 100 | ADXL343_RANGE_8G = ADXL345_RANGE_8G, 101 | ADXL343_RANGE_4G = ADXL345_RANGE_4G, 102 | ADXL343_RANGE_2G = ADXL345_RANGE_2G 103 | } adxl345_range; 104 | 105 | typedef enum ADXL345_ORIENTATION { 106 | ADXL345_ORIENTATION_ERROR = -1, // returned on read error 107 | ADXL343_ORIENTATION_ERROR = ADXL345_ORIENTATION_ERROR, 108 | FLAT = 0, FLAT_1, XY, XY_1, YX, YX_1 109 | } adxl345_orientation; 110 | 111 | typedef enum ADXL345_INT { 112 | ADXL345_OVERRUN, ADXL345_WATERMARK, ADXL345_FREEFALL, ADXL345_INACTIVITY, 113 | ADXL345_ACTIVITY, ADXL345_DOUBLE_TAP, ADXL345_SINGLE_TAP, ADXL345_DATA_READY, 114 | ADXL343_OVERRUN = ADXL345_OVERRUN, 115 | ADXL343_WATERMARK = ADXL345_WATERMARK, 116 | ADXL343_FREEFALL = ADXL345_FREEFALL, 117 | ADXL343_INACTIVITY = ADXL345_INACTIVITY, 118 | ADXL343_ACTIVITY = ADXL345_ACTIVITY, 119 | ADXL343_DOUBLE_TAP = ADXL345_DOUBLE_TAP, 120 | ADXL343_SINGLE_TAP = ADXL345_SINGLE_TAP, 121 | ADXL343_DATA_READY = ADXL345_DATA_READY 122 | } adxl345_int; 123 | 124 | typedef enum ADXL345_ACT_TAP_SET { 125 | ADXL345_000, ADXL345_00Z, ADXL345_0Y0, ADXL345_0YZ, 126 | ADXL345_X00, ADXL345_X0Z, ADXL345_XY0, ADXL345_XYZ, 127 | ADXL343_000 = ADXL345_000, 128 | ADXL343_00Z = ADXL345_00Z, 129 | ADXL343_0Y0 = ADXL345_0Y0, 130 | ADXL343_0YZ = ADXL345_0YZ, 131 | ADXL343_X00 = ADXL345_X00, 132 | ADXL343_X0Z = ADXL345_X0Z, 133 | ADXL343_XY0 = ADXL345_XY0, 134 | ADXL343_XYZ = ADXL345_XYZ 135 | } adxl345_actTapSet; 136 | 137 | typedef enum ADXL345_DC_AC { 138 | ADXL345_DC_MODE = 0, 139 | ADXL345_AC_MODE = 0x08, 140 | ADXL343_DC_MODE = ADXL345_DC_MODE, 141 | ADXL343_AC_MODE = ADXL345_AC_MODE 142 | } adxl345_dcAcMode; 143 | 144 | typedef enum ADXL345_WAKE_UP_FREQ{ 145 | ADXL345_WUP_FQ_UNSET = -1, 146 | ADXL345_WUP_FQ_8 = 0, ADXL345_WUP_FQ_4, ADXL345_WUP_FQ_2, ADXL345_WUP_FQ_1, 147 | ADXL343_WUP_FQ_UNSET = ADXL345_WUP_FQ_UNSET, 148 | ADXL343_WUP_FQ_8 = ADXL345_WUP_FQ_8, 149 | ADXL343_WUP_FQ_4 = ADXL345_WUP_FQ_4, 150 | ADXL343_WUP_FQ_2 = ADXL345_WUP_FQ_2, 151 | ADXL343_WUP_FQ_1 = ADXL345_WUP_FQ_1 152 | } adxl345_wUpFreq; 153 | 154 | typedef enum ADXL345_ACT_TAP { 155 | ADXL345_TAP_Z, ADXL345_TAP_Y, ADXL345_TAP_X, ADXL345_ASLEEP, ADXL345_ACT_Z, ADXL345_ACT_Y, ADXL345_ACT_X, 156 | ADXL343_TAP_Z = ADXL345_TAP_Z, 157 | ADXL343_TAP_Y = ADXL345_TAP_Y, 158 | ADXL343_TAP_X = ADXL345_TAP_X, 159 | ADXL343_ASLEEP = ADXL345_ASLEEP, 160 | ADXL343_ACT_Z = ADXL345_ACT_Z, 161 | ADXL343_ACT_Y = ADXL345_ACT_Y, 162 | ADXL343_ACT_X = ADXL345_ACT_X 163 | } adxl345_actTap; 164 | 165 | typedef enum ADXL345_FIFO_MODE { 166 | ADXL345_BYPASS, ADXL345_FIFO, ADXL345_STREAM, ADXL345_TRIGGER, 167 | ADXL343_BYPASS = ADXL345_BYPASS, 168 | ADXL343_FIFO = ADXL345_FIFO, 169 | ADXL343_STREAM = ADXL345_STREAM, 170 | ADXL343_TRIGGER = ADXL345_TRIGGER 171 | } adxl345_fifoMode; 172 | 173 | typedef enum ADXL345_TRIGGER_INT { 174 | ADXL345_TRIGGER_INT_1, ADXL345_TRIGGER_INT_2, 175 | ADXL343_TRIGGER_INT_1 = ADXL345_TRIGGER_INT_1, 176 | ADXL343_TRIGGER_INT_2 = ADXL345_TRIGGER_INT_2 177 | } adxl345_triggerInt; 178 | 179 | class ADXL345_WE 180 | { 181 | public: 182 | 183 | /* Constructors */ 184 | 185 | ADXL345_WE(uint8_t addr = 0x53) : _wire{&Wire}, i2cAddress{addr}, useSPI{false} {} 186 | 187 | ADXL345_WE(TwoWire *w, uint8_t addr = 0x53) : _wire{w}, i2cAddress{addr}, useSPI{false} {} 188 | 189 | ADXL345_WE(int cs, bool spi, int mosi = 999, int miso = 999, int sck = 999, int sid = -1) 190 | : _spi{&SPI}, csPin{cs}, useSPI{spi}, mosiPin{mosi}, misoPin{miso}, sckPin{sck}, sensorID{sid} {} 191 | 192 | ADXL345_WE(SPIClass *s, int cs, bool spi, int mosi = 999, int miso = 999, int sck = 999, int sid = -1) 193 | : _spi{s}, csPin{cs}, useSPI{spi}, mosiPin{mosi}, misoPin{miso}, sckPin{sck}, sensorID{sid} {} 194 | 195 | /* registers */ 196 | 197 | static constexpr uint8_t ADXL345_DEVID {0x00}; 198 | static constexpr uint8_t ADXL345_THRESH_TAP {0x1D}; 199 | static constexpr uint8_t ADXL345_OFSX {0x1E}; 200 | static constexpr uint8_t ADXL345_OFSY {0x1F}; 201 | static constexpr uint8_t ADXL345_OFSZ {0x20}; 202 | static constexpr uint8_t ADXL345_DUR {0x21}; 203 | static constexpr uint8_t ADXL345_LATENT {0x22}; 204 | static constexpr uint8_t ADXL345_WINDOW {0x23}; 205 | static constexpr uint8_t ADXL345_THRESH_ACT {0x24}; 206 | static constexpr uint8_t ADXL345_THRESH_INACT {0x25}; 207 | static constexpr uint8_t ADXL345_TIME_INACT {0x26}; 208 | static constexpr uint8_t ADXL345_ACT_INACT_CTL {0x27}; 209 | static constexpr uint8_t ADXL345_THRESH_FF {0x28}; 210 | static constexpr uint8_t ADXL345_TIME_FF {0x29}; 211 | static constexpr uint8_t ADXL345_TAP_AXES {0x2A}; 212 | static constexpr uint8_t ADXL345_ACT_TAP_STATUS {0x2B}; 213 | static constexpr uint8_t ADXL345_BW_RATE {0x2C}; 214 | static constexpr uint8_t ADXL345_POWER_CTL {0x2D}; 215 | static constexpr uint8_t ADXL345_INT_ENABLE {0x2E}; 216 | static constexpr uint8_t ADXL345_INT_MAP {0x2F}; 217 | static constexpr uint8_t ADXL345_INT_SOURCE {0x30}; 218 | static constexpr uint8_t ADXL345_DATA_FORMAT {0x31}; 219 | static constexpr uint8_t ADXL345_DATAX0 {0x32}; 220 | static constexpr uint8_t ADXL345_DATAX1 {0x33}; 221 | static constexpr uint8_t ADXL345_DATAY0 {0x34}; 222 | static constexpr uint8_t ADXL345_DATAY1 {0x35}; 223 | static constexpr uint8_t ADXL345_DATAZ0 {0x36}; 224 | static constexpr uint8_t ADXL345_DATAZ1 {0x37}; 225 | static constexpr uint8_t ADXL345_FIFO_CTL {0x38}; 226 | static constexpr uint8_t ADXL345_FIFO_STATUS {0x39}; 227 | 228 | /* Register bits */ 229 | 230 | static constexpr uint8_t ADXL345_FULL_RES {0x03}; 231 | static constexpr uint8_t ADXL345_SUPPRESS {0x03}; 232 | static constexpr uint8_t ADXL345_LOW_POWER {0x04}; 233 | static constexpr uint8_t ADXL345_DEVICE_ID_VAL {0xE5}; 234 | 235 | /* Other */ 236 | 237 | static constexpr float MILLI_G_PER_LSB {3.9}; 238 | static constexpr float UNITS_PER_G {256.41};// = 1/0.0039 239 | 240 | /* Basic settings */ 241 | 242 | bool init(); 243 | void setSPIClockSpeed(unsigned long clock); 244 | void setCorrFactors(float xMin, float xMax, float yMin, float yMax, float zMin, float zMax); 245 | bool setDataRate(adxl345_dataRate rate); 246 | adxl345_dataRate getDataRate(); 247 | String getDataRateAsString(); 248 | uint8_t getPowerCtlReg(); 249 | bool setRange(adxl345_range range); 250 | adxl345_range getRange(); 251 | bool setFullRes(bool full); 252 | String getRangeAsString(); 253 | uint8_t getDeviceID(); 254 | bool isConnected(); 255 | 256 | /* x,y,z results */ 257 | 258 | bool getRawValues(xyzFloat *rawVal); 259 | bool getCorrectedRawValues(xyzFloat *rawVal); 260 | bool getGValues(xyzFloat *gVal); 261 | 262 | /* Angles and Orientation */ 263 | 264 | bool getAngles(xyzFloat *angleVal); 265 | bool getCorrAngles(xyzFloat *corrAngleVal); 266 | bool measureAngleOffsets(); 267 | xyzFloat getAngleOffsets(); 268 | void setAngleOffsets(const xyzFloat aos); 269 | adxl345_orientation getOrientation(); 270 | String getOrientationAsString(); 271 | float getPitch(); 272 | float getRoll(); 273 | 274 | /* Power, Sleep, Standby */ 275 | 276 | bool setMeasureMode(bool measure); 277 | bool setSleep(bool sleep, adxl345_wUpFreq freq = ADXL345_WUP_FQ_UNSET); 278 | bool setAutoSleep(bool autoSleep, adxl345_wUpFreq freq = ADXL345_WUP_FQ_UNSET); 279 | bool isAsleep(); 280 | bool setLowPower(bool lowpwr); 281 | bool isLowPower(); 282 | 283 | /* Interrupts */ 284 | 285 | bool setInterrupt(adxl345_int type, uint8_t pin); 286 | bool setInterruptPolarity(uint8_t pol); 287 | bool deleteInterrupt(adxl345_int type); 288 | uint8_t readAndClearInterrupts(); 289 | bool checkInterrupt(uint8_t source, adxl345_int type); 290 | bool setLinkBit(bool link); 291 | void setFreeFallThresholds(float ffg, float fft); 292 | bool setActivityParameters(adxl345_dcAcMode mode, adxl345_actTapSet axes, float threshold); 293 | bool setInactivityParameters(adxl345_dcAcMode mode, adxl345_actTapSet axes, float threshold, uint8_t inactTime); 294 | bool setGeneralTapParameters(adxl345_actTapSet axes, float threshold, float duration, float latent); 295 | bool setAdditionalDoubleTapParameters(bool suppress, float window); 296 | uint8_t getActTapStatus(); 297 | String getActTapStatusAsString(); 298 | 299 | /* FIFO */ 300 | 301 | bool setFifoParameters(adxl345_triggerInt intNumber, uint8_t samples); 302 | bool setFifoMode(adxl345_fifoMode mode); 303 | uint8_t getFifoStatus(); 304 | bool resetTrigger(); 305 | 306 | protected: 307 | TwoWire *_wire; 308 | SPIClass *_spi; 309 | SPISettings mySPISettings = SPISettings(); 310 | unsigned long spiClock = 5000000; 311 | uint8_t i2cAddress; 312 | uint8_t regVal; // intermediate storage of register values 313 | xyzFloat offsetVal; 314 | xyzFloat angleOffsetVal; 315 | xyzFloat corrFact; 316 | int csPin; 317 | bool useSPI; 318 | int mosiPin; 319 | int misoPin; 320 | int sckPin; 321 | int sensorID; 322 | float rangeFactor; 323 | void writeRegister(uint8_t reg, uint8_t val); 324 | bool readRegister8(uint8_t reg, uint8_t *val); 325 | bool readMultipleRegisters(uint8_t reg, uint8_t count, uint8_t *buf); 326 | bool adxl345_lowRes; 327 | }; 328 | 329 | #endif 330 | 331 | 332 | -------------------------------------------------------------------------------- /src/ADXL345_WE.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************** 2 | * This is a library for the ADXL345 / ADXL343 accelerometer. 3 | * 4 | * You'll find an example which should enable you to use the library. 5 | * 6 | * You are free to use it, change it or build on it. In case you like 7 | * it, it would be cool if you give it a star. 8 | * 9 | * If you find bugs, please inform me! 10 | * 11 | * Written by Wolfgang (Wolle) Ewald 12 | * https://wolles-elektronikkiste.de/adxl345-teil-1 (German) 13 | * https://wolles-elektronikkiste.de/en/adxl345-the-universal-accelerometer-part-1 (English) 14 | * 15 | *********************************************************************/ 16 | 17 | #include "ADXL345_WE.h" 18 | 19 | /************ Basic settings ************/ 20 | 21 | bool ADXL345_WE::init(){ 22 | if(useSPI){ 23 | if(mosiPin == 999){ 24 | _spi->begin(); 25 | } 26 | #ifdef ESP32 27 | else{ 28 | _spi->begin(sckPin, misoPin, mosiPin, csPin); 29 | } 30 | #endif 31 | #ifdef ARDUINO_ARCH_STM32 32 | else { 33 | _spi->setMISO(misoPin); 34 | _spi->setMOSI(mosiPin); 35 | _spi->setSCLK(sckPin); 36 | _spi->begin(); 37 | } 38 | #endif 39 | setSPIClockSpeed(spiClock); 40 | pinMode(csPin, OUTPUT); 41 | digitalWrite(csPin, HIGH); 42 | } 43 | writeRegister(ADXL345_POWER_CTL, 0); 44 | writeRegister(ADXL345_POWER_CTL, 16); 45 | setMeasureMode(true); 46 | rangeFactor = 1.0; 47 | corrFact = {1.0, 1.0, 1.0}; 48 | offsetVal = {0.0, 0.0, 0.0}; 49 | angleOffsetVal = {0.0, 0.0, 0.0}; 50 | writeRegister(ADXL345_DATA_FORMAT,0); 51 | setFullRes(true); 52 | uint8_t ctrlVal; 53 | bool ok = readRegister8(ADXL345_DATA_FORMAT, &ctrlVal); 54 | if(!ok || ctrlVal != 0b1000){ 55 | return false; 56 | } 57 | writeRegister(ADXL345_INT_ENABLE, 0); 58 | writeRegister(ADXL345_INT_MAP,0); 59 | writeRegister(ADXL345_TIME_INACT, 0); 60 | writeRegister(ADXL345_THRESH_INACT,0); 61 | writeRegister(ADXL345_ACT_INACT_CTL, 0); 62 | writeRegister(ADXL345_DUR,0); 63 | writeRegister(ADXL345_LATENT,0); 64 | writeRegister(ADXL345_THRESH_TAP,0); 65 | writeRegister(ADXL345_TAP_AXES,0); 66 | writeRegister(ADXL345_WINDOW, 0); 67 | readAndClearInterrupts(); 68 | writeRegister(ADXL345_FIFO_CTL,0); 69 | writeRegister(ADXL345_FIFO_STATUS,0); 70 | 71 | return true; 72 | } 73 | 74 | void ADXL345_WE::setSPIClockSpeed(unsigned long clock = 5000000){ 75 | spiClock = clock; 76 | mySPISettings = SPISettings(spiClock, MSBFIRST, SPI_MODE3); 77 | } 78 | 79 | void ADXL345_WE::setCorrFactors(float xMin, float xMax, float yMin, float yMax, float zMin, float zMax){ 80 | corrFact.x = UNITS_PER_G / (0.5 * (xMax - xMin)); 81 | corrFact.y = UNITS_PER_G / (0.5 * (yMax - yMin)); 82 | corrFact.z = UNITS_PER_G / (0.5 * (zMax - zMin)); 83 | offsetVal.x = (xMax + xMin) * 0.5; 84 | offsetVal.y = (yMax + yMin) * 0.5; 85 | offsetVal.z = (zMax + zMin) * 0.5; 86 | } 87 | 88 | bool ADXL345_WE::setDataRate(adxl345_dataRate rate){ 89 | if (!readRegister8(ADXL345_BW_RATE, ®Val) || rate == ADXL345_DATA_RATE_ERROR) { 90 | return false; 91 | } 92 | regVal &= 0xF0; 93 | regVal |= rate; 94 | writeRegister(ADXL345_BW_RATE, regVal); 95 | return true; 96 | } 97 | 98 | adxl345_dataRate ADXL345_WE::getDataRate(){ 99 | if (!readRegister8(ADXL345_BW_RATE, ®Val)) { 100 | return ADXL345_DATA_RATE_ERROR; 101 | } 102 | return (adxl345_dataRate)(regVal & 0x0F); 103 | } 104 | 105 | 106 | String ADXL345_WE::getDataRateAsString(){ 107 | adxl345_dataRate dataRate = getDataRate(); 108 | switch(dataRate) { 109 | case ADXL345_DATA_RATE_ERROR: return(F("ERROR")); break; 110 | case ADXL345_DATA_RATE_3200: return(F("3200 Hz")); break; 111 | case ADXL345_DATA_RATE_1600: return(F("1600 Hz")); break; 112 | case ADXL345_DATA_RATE_800: return(F("800 Hz")); break; 113 | case ADXL345_DATA_RATE_400: return(F("400 Hz")); break; 114 | case ADXL345_DATA_RATE_200: return(F("200 Hz")); break; 115 | case ADXL345_DATA_RATE_100: return(F("100 Hz")); break; 116 | case ADXL345_DATA_RATE_50: return(F("50 Hz")); break; 117 | case ADXL345_DATA_RATE_25: return(F("25 Hz")); break; 118 | case ADXL345_DATA_RATE_12_5: return(F("12.5 Hz")); break; 119 | case ADXL345_DATA_RATE_6_25: return(F("6.25 Hz")); break; 120 | case ADXL345_DATA_RATE_3_13: return(F("3.13 Hz")); break; 121 | case ADXL345_DATA_RATE_1_56: return(F("1.56 Hz")); break; 122 | case ADXL345_DATA_RATE_0_78: return(F("0.78 Hz")); break; 123 | case ADXL345_DATA_RATE_0_39: return(F("0.39 Hz")); break; 124 | case ADXL345_DATA_RATE_0_20: return(F("0.20 Hz")); break; 125 | case ADXL345_DATA_RATE_0_10: return(F("0.10 Hz")); break; 126 | default: return(F("unknown")); 127 | } 128 | } 129 | 130 | bool ADXL345_WE::setRange(adxl345_range range){ 131 | if (!readRegister8(ADXL345_DATA_FORMAT, ®Val) || range == ADXL345_RANGE_ERROR) { 132 | return false; 133 | } 134 | if(adxl345_lowRes){ 135 | switch(range){ 136 | case ADXL345_RANGE_ERROR: return false; break; // Already handled, but avoids compiler warning 137 | case ADXL345_RANGE_2G: rangeFactor = 1.0; break; 138 | case ADXL345_RANGE_4G: rangeFactor = 2.0; break; 139 | case ADXL345_RANGE_8G: rangeFactor = 4.0; break; 140 | case ADXL345_RANGE_16G: rangeFactor = 8.0; break; 141 | } 142 | } 143 | else{ 144 | rangeFactor = 1.0; 145 | } 146 | regVal &= 0b11111100; 147 | regVal |= range; 148 | writeRegister(ADXL345_DATA_FORMAT, regVal); 149 | return true; 150 | } 151 | 152 | adxl345_range ADXL345_WE::getRange(){ 153 | if (!readRegister8(ADXL345_DATA_FORMAT, ®Val)) { 154 | return ADXL345_RANGE_ERROR; 155 | } 156 | regVal &= 0x03; 157 | return adxl345_range(regVal); 158 | } 159 | 160 | bool ADXL345_WE::setFullRes(bool full){ 161 | if (!readRegister8(ADXL345_DATA_FORMAT, ®Val)) { 162 | return false; 163 | } 164 | if(full){ 165 | adxl345_lowRes = false; 166 | rangeFactor = 1.0; 167 | regVal |= (1<x = (static_cast((rawData[1] << 8) | rawData[0])) * 1.0; 217 | rawVal->y = (static_cast((rawData[3] << 8) | rawData[2])) * 1.0; 218 | rawVal->z = (static_cast((rawData[5] << 8) | rawData[4])) * 1.0; 219 | return true; 220 | } 221 | 222 | bool ADXL345_WE::getCorrectedRawValues(xyzFloat *rawVal){ 223 | if (!getRawValues(rawVal)) { 224 | return false; 225 | } 226 | rawVal->x -= (offsetVal.x / rangeFactor); 227 | rawVal->y -= (offsetVal.y / rangeFactor); 228 | rawVal->z -= (offsetVal.z / rangeFactor); 229 | return true; 230 | } 231 | 232 | bool ADXL345_WE::getGValues(xyzFloat *gVal){ 233 | if (!getCorrectedRawValues(gVal)) { 234 | return false; 235 | } 236 | *gVal *= corrFact * MILLI_G_PER_LSB * rangeFactor / 1000.0; 237 | return true; 238 | } 239 | 240 | /************ Angles and Orientation ************/ 241 | 242 | bool ADXL345_WE::getAngles(xyzFloat *angleVal){ 243 | xyzFloat gVal; 244 | if (!getGValues(&gVal)) { 245 | return false; 246 | } 247 | if(gVal.x > 1){ 248 | gVal.x = 1; 249 | } 250 | else if(gVal.x < -1){ 251 | gVal.x = -1; 252 | } 253 | angleVal->x = (asin(gVal.x)) * 57.296; 254 | 255 | if(gVal.y > 1){ 256 | gVal.y = 1; 257 | } 258 | else if(gVal.y < -1){ 259 | gVal.y = -1; 260 | } 261 | angleVal->y = (asin(gVal.y)) * 57.296; 262 | 263 | if(gVal.z > 1){ 264 | gVal.z = 1; 265 | } 266 | else if(gVal.z < -1){ 267 | gVal.z = -1; 268 | } 269 | angleVal->z = (asin(gVal.z)) * 57.296; 270 | return true; 271 | } 272 | 273 | bool ADXL345_WE::getCorrAngles(xyzFloat *corrAngleVal){ 274 | if (!getAngles(corrAngleVal)) { 275 | return false; 276 | } 277 | *corrAngleVal -= angleOffsetVal; 278 | return true; 279 | } 280 | 281 | bool ADXL345_WE::measureAngleOffsets(){ 282 | return getAngles(&angleOffsetVal); 283 | } 284 | 285 | xyzFloat ADXL345_WE::getAngleOffsets(){ 286 | return angleOffsetVal; 287 | } 288 | 289 | void ADXL345_WE::setAngleOffsets(const xyzFloat aos){ 290 | angleOffsetVal = aos; 291 | } 292 | 293 | adxl345_orientation ADXL345_WE::getOrientation(){ 294 | adxl345_orientation orientation = FLAT; 295 | xyzFloat angleVal; 296 | if (!getAngles(&angleVal)) { 297 | return ADXL345_ORIENTATION_ERROR; 298 | } 299 | if(abs(angleVal.x) < 45){ // |x| < 45 300 | if(abs(angleVal.y) < 45){ // |y| < 45 301 | if(angleVal.z > 0){ // z > 0 302 | orientation = FLAT; 303 | } 304 | else{ // z < 0 305 | orientation = FLAT_1; 306 | } 307 | } 308 | else{ // |y| > 45 309 | if(angleVal.y > 0){ // y > 0 310 | orientation = XY; 311 | } 312 | else{ // y < 0 313 | orientation = XY_1; 314 | } 315 | } 316 | } 317 | else{ // |x| >= 45 318 | if(angleVal.x > 0){ // x > 0 319 | orientation = YX; 320 | } 321 | else{ // x < 0 322 | orientation = YX_1; 323 | } 324 | } 325 | return orientation; 326 | } 327 | 328 | String ADXL345_WE::getOrientationAsString(){ 329 | adxl345_orientation orientation = getOrientation(); 330 | String orientationAsString = ""; 331 | switch(orientation){ 332 | case ADXL345_ORIENTATION_ERROR: orientationAsString = "ERROR"; break; 333 | case FLAT: orientationAsString = "z up"; break; 334 | case FLAT_1: orientationAsString = "z down"; break; 335 | case XY: orientationAsString = "y up"; break; 336 | case XY_1: orientationAsString = "y down"; break; 337 | case YX: orientationAsString = "x up"; break; 338 | case YX_1: orientationAsString = "x down"; break; 339 | } 340 | return orientationAsString; 341 | } 342 | 343 | float ADXL345_WE::getPitch(){ 344 | xyzFloat gVal; 345 | if (!getGValues(&gVal)) { 346 | return ADXL345_FLOAT_ERROR; 347 | } 348 | float pitch = (atan2(-gVal.x, sqrt(abs((gVal.y*gVal.y + gVal.z*gVal.z))))*180.0)/M_PI; 349 | return pitch; 350 | } 351 | 352 | float ADXL345_WE::getRoll(){ 353 | xyzFloat gVal; 354 | if (!getGValues(&gVal)) { 355 | return ADXL345_FLOAT_ERROR; 356 | } 357 | float roll = (atan2(gVal.y, gVal.z)*180.0)/M_PI; 358 | return roll; 359 | } 360 | 361 | /************ Power, Sleep, Standby ************/ 362 | 363 | bool ADXL345_WE::setMeasureMode(bool measure){ 364 | if (!readRegister8(ADXL345_POWER_CTL, ®Val)) { 365 | return false; 366 | } 367 | if(measure){ 368 | regVal |= (1<(round(ffg / 0.0625)); 522 | if(regVal<1){ 523 | regVal = 1; 524 | } 525 | writeRegister(ADXL345_THRESH_FF, regVal); 526 | regVal = static_cast(round(fft / 5)); 527 | if(regVal<1){ 528 | regVal = 1; 529 | } 530 | writeRegister(ADXL345_TIME_FF, regVal); 531 | } 532 | 533 | bool ADXL345_WE::setActivityParameters(adxl345_dcAcMode mode, adxl345_actTapSet axes, float threshold){ 534 | regVal = static_cast(round(threshold / 0.0625)); 535 | if(regVal<1){ 536 | regVal = 1; 537 | } 538 | 539 | writeRegister(ADXL345_THRESH_ACT, regVal); 540 | 541 | if (!readRegister8(ADXL345_ACT_INACT_CTL, ®Val)) { 542 | return false; 543 | } 544 | regVal &= 0x0F; 545 | regVal |= (static_cast(mode) + static_cast(axes))<<4; 546 | writeRegister(ADXL345_ACT_INACT_CTL, regVal); 547 | return true; 548 | } 549 | 550 | bool ADXL345_WE::setInactivityParameters(adxl345_dcAcMode mode, adxl345_actTapSet axes, float threshold, uint8_t inactTime){ 551 | regVal = static_cast(round(threshold / 0.0625)); 552 | if(regVal<1){ 553 | regVal = 1; 554 | } 555 | writeRegister(ADXL345_THRESH_INACT, regVal); 556 | writeRegister(ADXL345_TIME_INACT, inactTime); 557 | 558 | if (!readRegister8(ADXL345_ACT_INACT_CTL, ®Val)) { 559 | return false; 560 | } 561 | regVal &= 0xF0; 562 | regVal |= static_cast(mode) + static_cast(axes); 563 | writeRegister(ADXL345_ACT_INACT_CTL, regVal); 564 | return true; 565 | } 566 | 567 | bool ADXL345_WE::setGeneralTapParameters(adxl345_actTapSet axes, float threshold, float duration, float latent){ 568 | if (!readRegister8(ADXL345_TAP_AXES, ®Val)) { 569 | return false; 570 | } 571 | regVal &= 0b11111000; 572 | regVal |= static_cast(axes); 573 | writeRegister(ADXL345_TAP_AXES, regVal); 574 | 575 | regVal = static_cast(round(threshold / 0.0625)); 576 | if(regVal<1){ 577 | regVal = 1; 578 | } 579 | writeRegister(ADXL345_THRESH_TAP,regVal); 580 | 581 | regVal = static_cast(round(duration / 0.625)); 582 | if(regVal<1){ 583 | regVal = 1; 584 | } 585 | writeRegister(ADXL345_DUR, regVal); 586 | 587 | regVal = static_cast(round(latent / 1.25)); 588 | if(regVal<1){ 589 | regVal = 1; 590 | } 591 | writeRegister(ADXL345_LATENT, regVal); 592 | return true; 593 | } 594 | 595 | bool ADXL345_WE::setAdditionalDoubleTapParameters(bool suppress, float window){ 596 | if (!readRegister8(ADXL345_TAP_AXES, ®Val)) { 597 | return false; 598 | } 599 | if(suppress){ 600 | regVal |= (1<(round(window / 1.25)); 608 | writeRegister(ADXL345_WINDOW, regVal); 609 | return true; 610 | } 611 | 612 | uint8_t ADXL345_WE::getActTapStatus(){ 613 | if (!readRegister8(ADXL345_ACT_TAP_STATUS, ®Val)) { 614 | return 0; // Not ideal 615 | } 616 | return regVal; 617 | } 618 | 619 | String ADXL345_WE::getActTapStatusAsString(){ 620 | if (!readRegister8(ADXL345_ACT_TAP_STATUS, ®Val)) { 621 | return String("ERROR"); 622 | } 623 | String returnStr = ""; 624 | if(regVal & (1<beginTransmission(i2cAddress); 678 | _wire->write(reg); 679 | _wire->write(val); 680 | _wire->endTransmission(); 681 | } 682 | else{ 683 | _spi->beginTransaction(mySPISettings); 684 | digitalWrite(csPin, LOW); 685 | delayMicroseconds(5); 686 | _spi->transfer(reg); 687 | _spi->transfer(val); 688 | digitalWrite(csPin, HIGH); 689 | _spi->endTransaction(); 690 | } 691 | } 692 | 693 | bool ADXL345_WE::readRegister8(uint8_t reg, uint8_t *val){ 694 | if(!useSPI){ 695 | bool ok = true; 696 | _wire->beginTransmission(i2cAddress); 697 | ok &= (_wire->write(reg) == 1); 698 | ok &= (_wire->endTransmission(false) == 0); 699 | _wire->requestFrom(i2cAddress, static_cast(1)); 700 | if(ok && _wire->available()){ 701 | // Success 702 | *val = _wire->read(); 703 | return true; 704 | } 705 | // No response 706 | return false; 707 | } 708 | else{ 709 | reg |= 0x80; 710 | _spi->beginTransaction(mySPISettings); 711 | digitalWrite(csPin, LOW); 712 | delayMicroseconds(5); 713 | _spi->transfer(reg); 714 | *val = _spi->transfer(0x00); 715 | digitalWrite(csPin, HIGH); 716 | _spi->endTransaction(); 717 | return true; // Error checking is not possible with SPI 718 | } 719 | } 720 | 721 | bool ADXL345_WE::readMultipleRegisters(uint8_t reg, uint8_t count, uint8_t *buf){ 722 | if(!useSPI){ 723 | bool ok = true; 724 | _wire->beginTransmission(i2cAddress); 725 | ok &= (_wire->write(reg) == 1); 726 | ok &= (_wire->endTransmission(false) == 0); 727 | _wire->requestFrom(i2cAddress, count); 728 | if (ok && _wire->available() == count) { 729 | // Success 730 | for(int i=0; iread(); 732 | } 733 | return true; 734 | } 735 | // No response, or incomplete response 736 | return false; 737 | } 738 | else{ 739 | reg = reg | 0x80; 740 | reg = reg | 0x40; 741 | _spi->beginTransaction(mySPISettings); 742 | digitalWrite(csPin, LOW); 743 | delayMicroseconds(5); 744 | _spi->transfer(reg); 745 | for(int i=0; itransfer(0x00); 747 | } 748 | digitalWrite(csPin, HIGH); 749 | _spi->endTransaction(); 750 | return true; // Error checking is not possible with SPI 751 | } 752 | } 753 | 754 | 755 | --------------------------------------------------------------------------------