{"id":10861,"date":"2021-01-17T19:27:56","date_gmt":"2021-01-17T19:27:56","guid":{"rendered":"https:\/\/wolles-elektronikkiste.de\/adxl345-the-universal-accelerometer-part-1"},"modified":"2025-09-17T16:37:27","modified_gmt":"2025-09-17T16:37:27","slug":"adxl345-the-universal-accelerometer-part-1","status":"publish","type":"post","link":"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-1","title":{"rendered":"ADXL345 &#8211; The Universal Accelerometer &#8211; Part 1"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">About this Post<\/h2>\n\n<p>In my last two posts I had reported on the 6-axis sensor <a href=\"https:\/\/wolles-elektronikkiste.de\/en\/mpu6050-accelerometer-and-gyroscope\" target=\"_blank\" rel=\"noopener\">MPU6050<\/a> and the rather simple accelerometer <a href=\"https:\/\/wolles-elektronikkiste.de\/en\/mma7361-analog-accelerometer\" target=\"_blank\" rel=\"noopener\">MMA7361<\/a> with analog output. In this article, I will now focus on the ADXL345 3-axis acceleration sensor (which includes the ADXL343). With its many features, it is for me the Swiss army knife among the accelerometers.<\/p>\n\n<p>I found a lot of libraries for the ADXL345. But I felt they were all either not complete or written in such a way that you still have to go deep into the data sheet to use them. This motivated me to write a library myself, which &#8211; at least from my point of view &#8211; is convenient to use. To make it easy to use more complex functions such as FIFO, I have added 15 example sketches to the library. Due to this large scope, I had to split the article into two parts (<a href=\"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-2\" target=\"_blank\" rel=\"noopener\">click here for part 2<\/a>). <\/p>\n<p><strong>Update 04\/16\/2025:<\/strong> I have added a separate class for the ADXL343 to the library. The same applies to the \u201cdefines\u201d such as ADXL343_RANGE_8G. Since the ADXL343 and ADXL345 have identical registers, the ADXL345 sketches also work unchanged on the ADXL343.  &nbsp; <\/p>\n\n<h2 class=\"wp-block-heading\">Features \/ Technical specifications of the ADXL345 (and ADXL343)<\/h2>\n<div class=\"wp-block-image\">\n<figure class=\"alignright size-large is-resized\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/ADXL345_small.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"784\" height=\"1000\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/ADXL345_small.jpg\" alt=\"ADXL345 Module\" class=\"wp-image-10342\" style=\"width:392px;height:500px\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/ADXL345_small.jpg 784w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/ADXL345_small-235x300.jpg 235w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/ADXL345_small-768x980.jpg 768w\" sizes=\"auto, (max-width: 784px) 100vw, 784px\" \/><\/a><\/figure>\n<\/div>\n<p>I had already described the operating principle of accelerometers in detail in my post about the <a href=\"https:\/\/wolles-elektronikkiste.de\/en\/mpu6050-accelerometer-and-gyroscope\" target=\"_blank\" rel=\"noopener\">MPU6050<\/a>.<\/p>\n<p>As with other sensors, I did not use the bare ADXL345 IC for simplicity, but rather a module. These usually have:<\/p>\n<ul>\n<li>Pull-up resistors for the I2C lines.<\/li>\n<li>A capacitor for voltage stabilization.<\/li>\n<li>A voltage converter so that you can operate the module with 3-5 volts.<\/li>\n<\/ul>\n<p>The disadvantage of the module compared to the IC is that the power consumption is slightly higher. In the normal operating mode at measuring frequencies below 10 Hz, the consumption of the actual IC should be at 30 \u00b5A. I measured 100 \u00b5A at 5 V supply voltage, and at 3.3 V it was 50 \u00b5A.<\/p>\n\n<h3 class=\"wp-block-heading\">The most important data at a glance<\/h3>\n\n<ul>\n<li>Measuring ranges: +\/-2, +\/-4, +\/-8, +\/-16 g.<\/li>\n<li>Resolution: 13 bits in the maximum measuring range (typically 4 mg \/ LSB)\n<ul>\n<li>Adjustable to 10 bits for all measuring ranges.<\/li>\n<\/ul>\n<\/li>\n<li>Communication via I2C or SPI (both implemented).<\/li>\n<li>Single and double tap detection, i.e. detection of short accelerations, e.g. due to vibrations.<\/li>\n<li>FIFO (first in, first out) buffer memory for 32 readings.<\/li>\n<li>8 interrupts, including free fall, single and double tap, activity and inactivity, FIFO overflow.\n<ul>\n<li>Interrupts can be assigned to two output pins.<\/li>\n<\/ul>\n<\/li>\n<li>Power supply: 3 &#8211; 5 volts (for the module).<\/li>\n<li>Power consumption (according to my measurements):\n<ul>\n<li>from 23 \u00b5A (stand-by mode, 3.3 volts operating voltage)<\/li>\n<li>up to 220 \u00b5A (normal mode, 3200 Hz measuring frequency, 5 volts operating voltage).<\/li>\n<\/ul>\n<\/li>\n<li>Various energy-saving modes.<\/li>\n<\/ul>\n\n<p>The best way to explain the features of the ADXL345 is to go through the example sketches.<\/p>\n\n<h3 class=\"wp-block-heading\">Wiring the ADXL345 to the Arduino (I2C)<\/h3>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/ADXL345__module_wiring-1024x589.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"589\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/ADXL345__module_wiring-1024x589.png\" alt=\"Connecting the ADXL345 to an Arduino UNO\" class=\"wp-image-10347\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/ADXL345__module_wiring-1024x589.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/ADXL345__module_wiring-300x172.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/ADXL345__module_wiring-768x442.png 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/ADXL345__module_wiring.png 1221w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Connecting the ADXL345 to an Arduino UNO<\/figcaption><\/figure>\n\n<p>The wiring shown above was used for all example sketches.<\/p>\n<ul>\n<li>VCC\/GND: 3 &#8211; 5 volts.<\/li>\n<li>3V3 is a special feature of the Adafruit module: 3.3 volts are provided there.<\/li>\n<li>CS (Chip Select): when connected to GND, the module is no longer accessible via I2C; so connect it to VCC. Or to an I\/O pin, then you can operate more than two ADXL345.<\/li>\n<li>SDA\/SCL: I2C pins; pull-ups should be present on the module.&nbsp;<\/li>\n<li>SDO: Choice of I2C address. For 0x53 leave the pin unconnected or attach it to GND, for 0x1D you connect it to VCC.<\/li>\n<li>INT1\/INT2: Interrupt Pins; you can assign the interrupts to these pins. In addition, the interrupts can be set active-high or active-low.<\/li>\n<\/ul>\n<p>The underlying ADXL345 IC can only handle 2.0 &#8211; 3.6 volts. This applies to both the power supply and the data pins. Many modules only regulate the supply voltage down, but do not take care of the data pins. The Adafruit modules are one of the laudable exceptions (see <a href=\"https:\/\/learn.adafruit.com\/assets\/108759\" target=\"_blank\" rel=\"noopener\">here<\/a>). If necessary, add a level shifter. Normally, 3.3 volt components do not break so quickly even at 5 volts on the data lines, but it can affect the service life.     &nbsp;<\/p>\n\n<h3 class=\"wp-block-heading\">Using SPI<\/h3>\n\n<p>And this is what the connection via SPI looks like (here with an Arduino Nano):<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/04\/ADXL345_SPI_module_wiring-1024x504.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"504\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/04\/ADXL345_SPI_module_wiring-1024x504.png\" alt=\"ADXL345 connected to an Arduino Nano via SPI \" class=\"wp-image-20847\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/04\/ADXL345_SPI_module_wiring-1024x504.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/04\/ADXL345_SPI_module_wiring-300x148.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/04\/ADXL345_SPI_module_wiring-768x378.png 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/04\/ADXL345_SPI_module_wiring-1320x650.png 1320w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/04\/ADXL345_SPI_module_wiring.png 1417w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">ADXL345 connected to an Arduino Nano via SPI <\/figcaption><\/figure>\n\n<p>Here too, you may need to place a level shifter between the microcontroller and the ADXL345.<\/p>\n<p>SPI (4-wire) does not work out of the box with this module:<\/p>\n\n<figure class=\"wp-block-image size-medium\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/04\/ADXL345_alt_module-300x157.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"157\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/04\/ADXL345_alt_module-300x157.jpg\" alt=\"\" class=\"wp-image-20849\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/04\/ADXL345_alt_module-300x157.jpg 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/04\/ADXL345_alt_module-768x401.jpg 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/04\/ADXL345_alt_module.jpg 919w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><figcaption class=\"wp-element-caption\">Problematic for SPI (4-Wire)<\/figcaption><\/figure>\n\n<p>The problem is that SDO is pulled to GND via the 0 \u03a9 resistor R4. SPI 3-Wire would work, but I have not implemented it. Simple remedy: Remove the resistor (desolder or use &#8220;careful force&#8221;).  <\/p>\n\n<h2 class=\"wp-block-heading\">Operation with the library ADXL345_WE<\/h2>\n\n<p>You can download the library ADXL345_WE <a href=\"https:\/\/github.com\/wollewald\/ADXL345_WE\" target=\"_blank\" rel=\"noopener\">here<\/a> from Github. For installation, unzip the ZIP file in the Arduino Library folder. Alternatively, you can install it via the Arduino IDE Library Manager.&nbsp;<\/p>\n<p>As mentioned at the beginning, I tried to make the library user-friendly. Nevertheless, it has become very extensive. This is simply due to the many features of the ADXL345.<\/p>\n<p>I will now guide you through the library using the example sketches. The sketches can be grouped according to the following themes:<\/p>\n<ul>\n<li>Basics functions<\/li>\n<li>interrupts<\/li>\n<li>Activity, inactivity features<\/li>\n<li>Single and double tap detection<\/li>\n<li>FIFO Functions<\/li>\n<\/ul>\n<p>I have added lots of comments in all sketches and inserted parameter lists for the functions. But since this can also distract from the essentials, I only print the first sketch completely here. For the others, I take out many comments. If you want to try out the sketches or build on them, take the detailed versions you download with the library.&nbsp;<\/p>\n<p><strong>The post is quite long. Impatient people can also simply try the sample sketches and return here if something should be unclear.<\/strong><\/p>\n\n<h2 class=\"wp-block-heading\">Basic functions of the ADXL345<\/h2>\n\n<p>The ADXL345 stores the determined acceleration values as raw data, which are provided in the data registers for the x, y and z axes. You get the latest values there. The maximum &#8220;age&#8221; of these depends on the measurement frequency (data rate). A high frequency leads to increased noise and power consumption. So don&#8217;t overdo it unnecessarily.<\/p>\n<p>The raw values are converted into acceleration values in g by the library. As a first approximation, the conversion factor in full resolution is 3.9 mg (= milli-g, not milligrams!) per LSB (= Least Significant Bit). In other words:<\/p>\n<p class=\"ql-center-displayed-equation\" style=\"line-height: 17px;\"><span class=\"ql-right-eqno\"> &nbsp; <\/span><span class=\"ql-left-eqno\"> &nbsp; <\/span><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/ql-cache\/quicklatex.com-f3b412a4ed23e8f9561a8db7328a7348_l3.png\" height=\"17\" width=\"334\" class=\"ql-img-displayed-equation quicklatex-auto-format\" alt=\"&#92;&#091; &#92;&#116;&#101;&#120;&#116;&#123;&#97;&#99;&#99;&#101;&#108;&#101;&#114;&#97;&#116;&#105;&#111;&#110;&#86;&#97;&#108;&#117;&#101;&#32;&#105;&#110;&#32;&#109;&#103;&#125;&#32;&#61;&#32;&#92;&#116;&#101;&#120;&#116;&#123;&#114;&#97;&#119;&#86;&#97;&#108;&#117;&#101;&#125;&#92;&#99;&#100;&#111;&#116;&#51;&#46;&#57; &#92;&#093;\" title=\"Rendered by QuickLaTeX.com\"\/><\/p>\n\n<p>For result data, such as raw data, g-values or angles, I have defined the structure (struct) xyzFloat. An xyzFloat consists of three float variables. The raw data &#8220;raw&#8221; includes, for example, the axis values raw.x, raw.y and raw.z.&nbsp;<\/p>\n\n<h3 class=\"wp-block-heading\">Example sketch 1: ADXL345_basic_data.ino<\/h3>\n\n<p>Let&#8217;s get started. In the first example sketch, you will learn about the following features:<\/p>\n<ul>\n<li><code>ADXL345_WE myAcc = ADXL345_WE( )<\/code> creates the object myAcc (stands for &#8220;my Accelerometer&#8221;). You can pass the I2C address and \/ or a TwoWire object. The latter option allows you to use both I2C buses on one ESP32. &nbsp;<\/li>\n<li><code>init()<\/code> initializes the ADXL345 with some default values. The function returns true if the ADXL345 responds as expected.<\/li>\n<li><code>setDataRate(range)<\/code> sets the measuring frequency. Select from the parameter list.<\/li>\n<li><code>setRange(range)<\/code> sets the g-range. Select from the parameter list.<\/li>\n<li><code>setFullRange(true\/false)<\/code> sets the full resolution (10-13 bits) or the reduced resolution (10 bits). The full resolution is preset. I see no reason to change that.<\/li>\n<li><code>getDataRateAsString()<\/code> returns the set measuring frequency as a string.<\/li>\n<li><code>getRangeAsString()<\/code> returns the g-range as a string.<\/li>\n<li><code>setLowPower(true\/false)<\/code> sets the Low Power Mode. It provides power savings for certain data rates at the price of slightly higher noise.&nbsp;<\/li>\n<\/ul>\n<p>As an alternative to the &#8220;get as string&#8221; functions, you can also use the following functions:<\/p>\n<ul>\n<li><code>getRange()<\/code> \n\/\n <code>getDataRate()<\/code><\/li>\n<\/ul>\n<p>But then you will only get numerical values returned, which you have to &#8220;translate&#8221;. Look at the library file ADXL345_WE.h for the details of the corresponding enum definitions.<\/p>\n<\/p>\n<div class=\"scroll-paragraph\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"ADXL345_basic_data.ino\" data-enlighter-title=\"ADXL345_basic_data.ino\">#include&lt;Wire.h&gt;\n#include&lt;ADXL345_WE.h&gt;\n#define ADXL345_I2CADDR 0x53 \/\/ 0x1D if SDO = HIGH\n\n\/* There are several ways to create your ADXL345 object:\n * ADXL345_WE myAcc = ADXL345_WE()                -&gt; uses Wire \/ I2C Address = 0x53\n * ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR) -&gt; uses Wire \/ ADXL345_I2CADDR\n * ADXL345_WE myAcc = ADXL345_WE(&amp;wire2)          -&gt; uses the TwoWire object wire2 \/ ADXL345_I2CADDR\n * ADXL345_WE myAcc = ADXL345_WE(&amp;wire2, ADXL345_I2CADDR) -&gt; all together\n *\/\nADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR);\n\nvoid setup(){\n  Wire.begin();\n  Serial.begin(115200);\n  Serial.println(\"ADXL345_Sketch - Basic Data\");\n  Serial.println();\n  if(!myAcc.init()){\n    Serial.println(\"ADXL345 not connected!\");\n  }\n   \n\/* Choose the data rate         Hz\n    ADXL345_DATA_RATE_3200    3200\n    ADXL345_DATA_RATE_1600    1600\n    ADXL345_DATA_RATE_800      800\n    ADXL345_DATA_RATE_400      400\n    ADXL345_DATA_RATE_200      200\n    ADXL345_DATA_RATE_100      100\n    ADXL345_DATA_RATE_50        50\n    ADXL345_DATA_RATE_25        25\n    ADXL345_DATA_RATE_12_5      12.5  \n    ADXL345_DATA_RATE_6_25       6.25\n    ADXL345_DATA_RATE_3_13       3.13\n    ADXL345_DATA_RATE_1_56       1.56\n    ADXL345_DATA_RATE_0_78       0.78\n    ADXL345_DATA_RATE_0_39       0.39\n    ADXL345_DATA_RATE_0_20       0.20\n    ADXL345_DATA_RATE_0_10       0.10\n*\/\n  myAcc.setDataRate(ADXL345_DATA_RATE_50);\n  delay(100);\n  Serial.print(\"Data rate: \");\n  Serial.print(myAcc.getDataRateAsString());\n\n\/* In full resolution the size of the raw values depend on the range:\n    2g = 10 bit; 4g = 11 bit; 8g = 12 bit; 16g =13 bit;\n    uncomment to change to 10 bit for all ranges. \n *\/\n  \/\/ myAcc.setFullRes(false);\n\n\/* Choose the measurement range\n    ADXL345_RANGE_16G    16g     \n    ADXL345_RANGE_8G      8g     \n    ADXL345_RANGE_4G      4g   \n    ADXL345_RANGE_2G      2g\n*\/ \n  myAcc.setRange(ADXL345_RANGE_4G);\n  Serial.print(\"  \/  g-Range: \");\n  Serial.println(myAcc.getRangeAsString());\n  Serial.println();\n\n\/* Uncomment to enable Low Power Mode. It saves power but slightly\n    increases noise. LowPower only affetcs Data Rates 12.5 Hz to 400 Hz.\n*\/\n  \/\/ myAcc.setLowPower(true);\n}\n\n\/* The LSB of the Data registers is 3.9 mg (milli-g, not milligramm).\n    This value is used calculating g from raw. However, this is an ideal\n    value which you might want to calibrate. \n*\/\n\nvoid loop() {\n  xyzFloat raw;\n  xyzFloat g;\n  myAcc.getRawValues(&amp;raw);\n  myAcc.getGValues(&amp;g);\n  \n  Serial.print(\"Raw-x = \");\n  Serial.print(raw.x);\n  Serial.print(\"  |  Raw-y = \");\n  Serial.print(raw.y);\n  Serial.print(\"  |  Raw-z = \");\n  Serial.println(raw.z);\n\n  Serial.print(\"g-x   = \");\n  Serial.print(g.x);\n  Serial.print(\"  |  g-y   = \");\n  Serial.print(g.y);\n  Serial.print(\"  |  g-z   = \");\n  Serial.println(g.z);\n\n  Serial.println();\n  \n  delay(1000);\n}<\/pre>\n<p>\u00a0<\/p>\n<\/div>\n<p>\n\n<h4 class=\"wp-block-heading\">Output of ADXL345_basic_data.ino<\/h4>\n\n<p>For the following output, I tried to position the ADXL345 flat. The raw- and g-values for the x- and y-axes should therefore be zero. The g-value of the z-axis should be 1.<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/basic_data_sketch__output.png\"><img loading=\"lazy\" decoding=\"async\" width=\"716\" height=\"376\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/basic_data_sketch__output.png\" alt=\"ADXL345 Sketch: Output of ADXL345_basic_data.ino\" class=\"wp-image-10354\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/basic_data_sketch__output.png 716w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/basic_data_sketch__output-300x158.png 300w\" sizes=\"auto, (max-width: 716px) 100vw, 716px\" \/><\/a><figcaption class=\"wp-element-caption\">Output of ADXL345_basic_data.ino<\/figcaption><\/figure>\n\n<p>You can see small deviations for the x- and y-values and a not insignificant deviation for the z-value. The deviations vary from module to module. The accelerometer is a micromechanical component with certain tolerances.<\/p>\n<p>You may have noticed that the first set of values differs more. It is advisable to discard these first values at program startup, when returning from stand-by mode and some other states. In this specific case, you could simply insert a small delay at the end of the setup.<\/p>\n\n<h3 class=\"wp-block-heading\">Example sketch 2: ADXL345_calibration.ino<\/h3>\n\n<p>This sketch is a guide to calibrating the ADXL345. Start the sketch and do not change the resolution. Rotat the ADXL345 slowly and try to find the maximum and minimum raw values for the axes. Support your arms because trembling distorts the values. It does not matter one or two units. Write down the values and then use them in the further sketches. How you do this, you will learn see in the example sketch 3.<\/p>\n<p>The maximum and minimum values are +1 g and -1 g respectively (if you perform calibration on our home planet!). For the zero points, according to this method, the following applies:<\/p>\n<p class=\"ql-center-displayed-equation\" style=\"line-height: 39px;\"><span class=\"ql-right-eqno\"> &nbsp; <\/span><span class=\"ql-left-eqno\"> &nbsp; <\/span><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/ql-cache\/quicklatex.com-8cfc65b6504ae96254ab3dde31a110bb_l3.png\" height=\"39\" width=\"339\" class=\"ql-img-displayed-equation quicklatex-auto-format\" alt=\"&#92;&#091; &#92;&#116;&#101;&#120;&#116;&#123;&#114;&#97;&#119;&#86;&#97;&#108;&#117;&#101;&#125;&#95;&#48;&#32;&#61;&#32;&#92;&#102;&#114;&#97;&#99;&#123;&#92;&#116;&#101;&#120;&#116;&#123;&#114;&#97;&#119;&#86;&#97;&#108;&#117;&#101;&#125;&#95;&#123;&#92;&#116;&#101;&#120;&#116;&#123;&#109;&#105;&#110;&#125;&#125;&#43;&#92;&#116;&#101;&#120;&#116;&#123;&#114;&#97;&#119;&#86;&#97;&#108;&#117;&#101;&#125;&#95;&#123;&#92;&#116;&#101;&#120;&#116;&#123;&#109;&#97;&#120;&#125;&#125;&#125;&#123;&#50;&#125; &#92;&#093;\" title=\"Rendered by QuickLaTeX.com\"\/><\/p>\n\n<p>Accordingly, an offset is calculated from it. The following applies to the slope:<\/p>\n<p class=\"ql-center-displayed-equation\" style=\"line-height: 40px;\"><span class=\"ql-right-eqno\"> &nbsp; <\/span><span class=\"ql-left-eqno\"> &nbsp; <\/span><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/ql-cache\/quicklatex.com-506069c96f4541c0178587f1b110ce4c_l3.png\" height=\"40\" width=\"464\" class=\"ql-img-displayed-equation quicklatex-auto-format\" alt=\"&#92;&#091; &#92;&#116;&#101;&#120;&#116;&#123;&#115;&#108;&#111;&#112;&#101;&#125;&#92;&#59;&#091;&#92;&#116;&#101;&#120;&#116;&#123;&#103;&#86;&#97;&#108;&#117;&#101;&#47;&#114;&#97;&#119;&#86;&#97;&#108;&#117;&#101;&#125;&#093;&#32;&#61;&#32;&#92;&#102;&#114;&#97;&#99;&#123;&#124;&#92;&#116;&#101;&#120;&#116;&#123;&#114;&#97;&#119;&#86;&#97;&#108;&#117;&#101;&#125;&#95;&#123;&#92;&#116;&#101;&#120;&#116;&#123;&#109;&#105;&#110;&#125;&#125;&#124;&#43;&#92;&#116;&#101;&#120;&#116;&#123;&#114;&#97;&#119;&#86;&#97;&#108;&#117;&#101;&#125;&#95;&#123;&#92;&#116;&#101;&#120;&#116;&#123;&#109;&#97;&#120;&#125;&#125;&#125;&#123;&#50;&#125; &#92;&#093;\" title=\"Rendered by QuickLaTeX.com\"\/><\/p>\n<\/p>\n<div class=\"scroll-paragraph\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"ADXL345_calibration.ino\" data-enlighter-title=\"ADXL345_calibration.ino\">#include&lt;Wire.h&gt;\n#include&lt;ADXL345_WE.h&gt;\n#define ADXL345_I2CADDR 0x53  \/\/ 0x1D if SDO = HIGH\n\n\/* There are several ways to create your ADXL345 object:\n * ADXL345_WE myAcc = ADXL345_WE()                -&gt; uses Wire \/ I2C Address = 0x53\n * ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR) -&gt; uses Wire \/ ADXL345_I2CADDR\n * ADXL345_WE myAcc = ADXL345_WE(&amp;wire2)          -&gt; uses the TwoWire object wire2 \/ ADXL345_I2CADDR\n * ADXL345_WE myAcc = ADXL345_WE(&amp;wire2, ADXL345_I2CADDR) -&gt; all together\n *\/\nADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR);\n\nvoid setup(){\n  Wire.begin();\n  Serial.begin(115200);\n  Serial.println(F(\"ADXL345_Sketch - Calibration\"));\n  Serial.println();\n  if(!myAcc.init()){\n    Serial.println(F(\"ADXL345 not connected!\"));\n  }\n  Serial.println(F(\"Calibration procedure:\"));\n  Serial.println(F(\" - stay in full resolution\"));\n  Serial.println(F(\" - supply voltage has influence (at least for the modules)\"));\n  Serial.println(F(\"        -&gt; choose the same voltage you will use in your project!\")); \n  Serial.println(F(\" - turn your ADXL slowly (!) to find the min and max raw x,y and z values\"));\n  Serial.println(F(\" - deviations of one or two units don't matter much\"));\n  Serial.println(F(\" - the calibration changes the slope of g vs raw and assumes zero is (min+max)\/2 \"));\n  Serial.println(F(\" - write down the six values \"));\n  Serial.println(F(\" - you can try the calibration values in ADXL345_angles_tilt_orientation.ino example sketch\"));\n  Serial.println(F(\" - ready to go? Then type in any key and send. \"));\n  while(!Serial.available());\n  Serial.read();\n  Serial.println(); Serial.println(); Serial.println();  \n}\n\nvoid loop() {\n  xyzFloat raw;\n  myAcc.getRawValues(&amp;raw);\n  Serial.print(F(\"Raw-x = \"));\n  Serial.print(raw.x);\n  Serial.print(F(\"  |  Raw-y = \"));\n  Serial.print(raw.y);\n  Serial.print(F(\"  |  Raw-z = \"));\n  Serial.println(raw.z);\n  \n  delay(1000); \n}\n<\/pre>\n<p>\u00a0<\/p>\n<\/div>\n<p>\n\n<p>The values I determined were: x<sub>min<\/sub> = -266.0, x<sub>max<\/sub> = 285.0, y<sub>min<\/sub> = &nbsp; -268.0, y<sub>max<\/sub> = 278.0, z<sub>min<\/sub> = -291.0, z<sub>max<\/sub> = 214.0.<\/p>\n<p>Despite the calibration, you will see some deviations because the zero point is not necessarily really in the middle between the min and max values.<\/p>\n<p>Others suggest attaching the ADXL345 to a cube- or square-shaped body to better align it for calibration. However, this assumes that the ADXL345 has been soldered truly flat to the module and that the module is mounted equally flat to the auxiliary body.<\/p>\n\n<h3 class=\"wp-block-heading\">Sample sketch 3: ADXL345_angles_orientation.ino<\/h3>\n\n<p>Here you can now apply the calibration by entering the values just obtained in the following function:<\/p>\n<ul>\n<li><code>setCorrFactors(xmin, xmax, ymin, ymax, zmin, zmax)<\/code><\/li>\n<\/ul>\n<p>The function <code>getRawValues()<\/code> still provides the uncorrected raw data. <code>getGValues()<\/code>, on the other hand, uses the corrected values. This also applies to all other sketches.<\/p>\n<p>The sketch also calculates the angles of the axes to the horizontal from the g values. Up to angles of 60\u00b0 this works well for x and y. In the next section, you&#8217;ll learn about another function that covers higher angles. Here, however, the following simple function is used:<\/p>\n<p class=\"ql-center-displayed-equation\" style=\"line-height: 19px;\"><span class=\"ql-right-eqno\"> &nbsp; <\/span><span class=\"ql-left-eqno\"> &nbsp; <\/span><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/ql-cache\/quicklatex.com-a76b62d93d8b9efaa5aeaa0f0346d9c0_l3.png\" height=\"19\" width=\"188\" class=\"ql-img-displayed-equation quicklatex-auto-format\" alt=\"&#92;&#091; &#97;&#110;&#103;&#108;&#101;&#32;&#61;&#32;&#92;&#97;&#114;&#99;&#115;&#105;&#110;&#40;&#92;&#116;&#101;&#120;&#116;&#123;&#103;&#86;&#97;&#108;&#117;&#101;&#125;&#41; &#92;&#093;\" title=\"Rendered by QuickLaTeX.com\"\/><\/p>\n\n<p>I explained why this is so and why values close to 90\u00b0 are particularly erroneous in <a href=\"https:\/\/wolles-elektronikkiste.de\/en\/mma7361-analog-accelerometer\" target=\"_blank\" rel=\"noopener\">my last post<\/a>. You get the angles via the function <code>getAngles()<\/code>. Since the arcsin function is not defined for values greater than 1, I simply cut g-values greater than 1.<\/p>\n<p>If you want to measure angles up to 60\u00b0 quite accurately and want to start at 0\u00b0, you can eliminate the offset that still exists despite calibration. For this purpose, you position the ADXL345 as flat and steady as possible and execute the function <code>measureAngleOffsets()<\/code>. After that, you will receive the additionally corrected values via <code>getCorrAngles()<\/code>.<\/p>\n<p>The last function I want to introduce for this sketch is <code>getOrientationAsString()<\/code>. This determines which axis is most upwards. Depending on the orientation, it returns: x up, x down, y up, y down, z up or z down as a string.<\/p>\n<\/p>\n<div class=\"scroll-paragraph\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"ADXL345_angles_orientation.ino\" data-enlighter-title=\"ADXL345_angles_orientation.ino\">#include&lt;Wire.h&gt;\n#include&lt;ADXL345_WE.h&gt;\n#define ADXL345_I2CADDR 0x53 \/\/ 0x1D if SDO = HIGH\n\n\/* There are several ways to create your ADXL345 object:\n * ADXL345_WE myAcc = ADXL345_WE()                -&gt; uses Wire \/ I2C Address = 0x53\n * ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR) -&gt; uses Wire \/ ADXL345_I2CADDR\n * ADXL345_WE myAcc = ADXL345_WE(&amp;wire2)          -&gt; uses the TwoWire object wire2 \/ ADXL345_I2CADDR\n * ADXL345_WE myAcc = ADXL345_WE(&amp;wire2, ADXL345_I2CADDR) -&gt; all together\n *\/\nADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR);\n\nvoid setup(){\n  Wire.begin();\n  Serial.begin(115200);\n  Serial.println(\"ADXL345_Sketch\");\n  Serial.println();\n  if(!myAcc.init()){\n    Serial.println(\"ADXL345 not connected!\");\n  }\n  \n\/* Add your min and max raw values you found with ADXL345_calibration.ino.  \n *  The order is: setCorrFactors(min x, max x, min y, max y, min z, max z).\n *  setCorrFactors calibrates the slope and assumes the zero point \n *  is (min+max)\/2. You have to add the setCorrFactors function to all sketches \n *  in which you want to use it.\n*\/\n\/\/  myAcc.setCorrFactors(-266.0, 285.0, -268.0, 278.0, -291.0, 214.0);\n\n\/* In this next step the offset for angles is corrected to get quite precise corrected \n *  angles for x and y up to ~60\u00b0. The additional offsetCorrection is only used for \n *  corrected angles measurements. The procedure just ensures to start at 0\u00b0.\n*\/\n  Serial.println(\"Position your ADXL345 flat and don't move it\");\n  delay(2000);\n  myAcc.measureAngleOffsets();\n  Serial.println(\"....done\");\n   \n\/* Choose the data rate         Hz\n    ADXL345_DATA_RATE_3200    3200\n    ADXL345_DATA_RATE_1600    1600\n    ADXL345_DATA_RATE_800      800\n    ADXL345_DATA_RATE_400      400\n    ADXL345_DATA_RATE_200      200\n    ADXL345_DATA_RATE_100      100\n    ADXL345_DATA_RATE_50        50\n    ADXL345_DATA_RATE_25        25\n    ADXL345_DATA_RATE_12_5      12.5  \n    ADXL345_DATA_RATE_6_25       6.25\n    ADXL345_DATA_RATE_3_13       3.13\n    ADXL345_DATA_RATE_1_56       1.56\n    ADXL345_DATA_RATE_0_78       0.78\n    ADXL345_DATA_RATE_0_39       0.39\n    ADXL345_DATA_RATE_0_20       0.20\n    ADXL345_DATA_RATE_0_10       0.10\n*\/\n  myAcc.setDataRate(ADXL345_DATA_RATE_50);\n  Serial.print(\"Data rate: \");\n  Serial.print(myAcc.getDataRateAsString());\n\n\/* Choose the measurement range\n    ADXL345_RANGE_16G    16g     \n    ADXL345_RANGE_8G      8g     \n    ADXL345_RANGE_4G      4g   \n    ADXL345_RANGE_2G      2g\n*\/\n  myAcc.setRange(ADXL345_RANGE_2G);\n  Serial.print(\"  \/  g-Range: \");\n  Serial.println(myAcc.getRangeAsString());\n  Serial.println();  \n}\n\nvoid loop() {\n  xyzFloat raw, g, angle, corrAngle;\n  myAcc.getRawValues(&amp;raw);\n  myAcc.getGValues(&amp;g);\n  myAcc.getAngles(&amp;angle);\n  myAcc.getCorrAngles(&amp;corrAngle);\n  \n\/* Still the uncorrected raw values!! *\/  \n  Serial.print(\"Raw-x    = \");\n  Serial.print(raw.x);\n  Serial.print(\"  |  Raw-y    = \");\n  Serial.print(raw.y);\n  Serial.print(\"  |  Raw-z    = \");\n  Serial.println(raw.z);\n\n\/* g values use the corrected raws *\/\n  Serial.print(\"g-x     = \");\n  Serial.print(g.x);\n  Serial.print(\"  |  g-y     = \");\n  Serial.print(g.y);\n  Serial.print(\"  |  g-z     = \");\n  Serial.println(g.z);\n\n\/* Angles use the corrected raws. Angles are simply calculated by\n    angle = arcsin(g Value) *\/\n  Serial.print(\"Angle x  = \");\n  Serial.print(angle.x);\n  Serial.print(\"  |  Angle y  = \");\n  Serial.print(angle.y);\n  Serial.print(\"  |  Angle z  = \");\n  Serial.println(angle.z);\n\n\/* Corrected angles use corrected raws and an extra angle \n    offsets to ensure they start at 0\u00b0 \n*\/\n  Serial.print(\"cAngle x = \");\n  Serial.print(corrAngle.x);\n  Serial.print(\"  |  cAngle y   = \");\n  Serial.print(corrAngle.y);\n  Serial.print(\"  |  cAngle z   = \");\n  Serial.println(corrAngle.z);\n\n  Serial.print(\"Orientation of the module: \");\n  Serial.println(myAcc.getOrientationAsString());\n\n  Serial.println();\n  \n  delay(1000);\n}\n<\/pre>\n<p>\u00a0<\/p>\n<\/div>\n<p>\n\n<h4 class=\"wp-block-heading\">Output of ADXL_angles_orientation <\/h4>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/angles_orientation__output.png\"><img loading=\"lazy\" decoding=\"async\" width=\"716\" height=\"535\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/angles_orientation__output.png\" alt=\"ADXL345 Sketch: Output of ADXL_angles_orientation.ino\" class=\"wp-image-10364\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/angles_orientation__output.png 716w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/angles_orientation__output-300x224.png 300w\" sizes=\"auto, (max-width: 716px) 100vw, 716px\" \/><\/a><figcaption class=\"wp-element-caption\">Output of ADXL_angles_orientation.ino<\/figcaption><\/figure>\n\n<p>You can see that the corrected g-values for the z-axis now look much better. The angles have a certain deviation due to the remaining offset. The corrected angles, on the other hand, fluctuate close to zero.&nbsp;<\/p>\n\n<h3 class=\"wp-block-heading\">Example sketch 4: ADXL345_pitch_roll_corrected_angles.ino<\/h3>\n\n<p>I have taken the method of angular calculation described here from other libraries, such as <a href=\"https:\/\/github.com\/rfetick\/MPU6050_light\" target=\"_blank\" rel=\"noopener\">MPU6050 light<\/a> or <a href=\"https:\/\/github.com\/jarzebski\/Arduino-ADXL345\" target=\"_blank\" rel=\"noopener\">Arduino-ADXL345<\/a>. The advantage of this method is that it includes several axes and thus compensates for errors. To delineate the method, I have adopted the nomenclature of others and referred to the tilt angle of the x-axis as &#8220;pitch&#8221; and that of the y-axis as &#8220;roll&#8221;. You can find a definition for the &#8220;pitch&#8221; and &#8220;roll&#8221; angles <a href=\"https:\/\/wiki.dfrobot.com\/How_to_Use_a_Three-Axis_Accelerometer_for_Tilt_Sensing\" target=\"_blank\" rel=\"noopener\">here<\/a>, for example.<\/p>\n<p class=\"ql-center-displayed-equation\" style=\"line-height: 71px;\"><span class=\"ql-right-eqno\"> &nbsp; <\/span><span class=\"ql-left-eqno\"> &nbsp; <\/span><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/ql-cache\/quicklatex.com-be8f8dd16b2c7d25cdc636ad3bc340ed_l3.png\" height=\"71\" width=\"283\" class=\"ql-img-displayed-equation quicklatex-auto-format\" alt=\"&#92;&#091; &#112;&#105;&#116;&#99;&#104;&#92;&#59;&#32;&#97;&#110;&#103;&#108;&#101;&#61;&#32;&#92;&#97;&#114;&#99;&#116;&#97;&#110;&#32;&#92;&#108;&#101;&#102;&#116;&#40;&#92;&#102;&#114;&#97;&#99;&#123;&#45;&#103;&#95;&#120;&#125;&#123;&#92;&#115;&#113;&#114;&#116;&#123;&#103;&#95;&#121;&#94;&#50;&#32;&#43;&#103;&#95;&#122;&#94;&#50;&#125;&#125;&#92;&#114;&#105;&#103;&#104;&#116;&#41; &#92;&#093;\" title=\"Rendered by QuickLaTeX.com\"\/><\/p>\n<p class=\"ql-center-displayed-equation\" style=\"line-height: 45px;\"><span class=\"ql-right-eqno\"> &nbsp; <\/span><span class=\"ql-left-eqno\"> &nbsp; <\/span><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/ql-cache\/quicklatex.com-985ee479406f587fe4196dc2994b0edc_l3.png\" height=\"45\" width=\"207\" class=\"ql-img-displayed-equation quicklatex-auto-format\" alt=\"&#92;&#091; &#114;&#111;&#108;&#108;&#92;&#59;&#97;&#110;&#103;&#108;&#101;&#32;&#61;&#32;&#92;&#97;&#114;&#99;&#116;&#97;&#110;&#92;&#108;&#101;&#102;&#116;&#40;&#32;&#92;&#102;&#114;&#97;&#99;&#123;&#103;&#95;&#121;&#125;&#123;&#103;&#95;&#122;&#125;&#32;&#92;&#114;&#105;&#103;&#104;&#116;&#41; &#92;&#093;\" title=\"Rendered by QuickLaTeX.com\"\/><\/p>\n\n<p>Again, of course, the angle determination is only valid in the static state. Additional accelerations distort the result.<\/p>\n<p>Here is the example sketch, or more precisely its main components. As a reminder: the original sample sketches are provided with many more comments.<\/p>\n<p>For comparison, the method from the previous sketch is also used.<\/p>\n<\/p>\n<div class=\"scroll-paragraph\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"ADXL345_pitch_roll_corrected_angles.ino\" data-enlighter-title=\"ADXL345_pitch_roll_corrected_angles.ino\">#include&lt;Wire.h&gt;\n#include&lt;ADXL345_WE.h&gt;\n#define ADXL345_I2CADDR 0x53 \/\/ 0x1D if SDO = HIGH\n\n\/* There are several ways to create your ADXL345 object:\n * ADXL345_WE myAcc = ADXL345_WE()                -&gt; uses Wire \/ I2C Address = 0x53\n * ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR) -&gt; uses Wire \/ ADXL345_I2CADDR\n * ADXL345_WE myAcc = ADXL345_WE(&amp;wire2)          -&gt; uses the TwoWire object wire2 \/ ADXL345_I2CADDR\n * ADXL345_WE myAcc = ADXL345_WE(&amp;wire2, ADXL345_I2CADDR) -&gt; all together\n *\/\nADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR);\n\nvoid setup(){\n  Wire.begin();\n  Serial.begin(115200);\n  Serial.println(\"ADXL345 Sketch - Pitch and Roll vs. Corrected Angles\");\n  Serial.println();\n  if(!myAcc.init()){\n    Serial.println(\"ADXL345 not connected!\");\n  }\n  \n\/* Add your min and max raw values you found with ADXL345_calibration.ino.  \n    The order is: setCorrFactors(min x, max x, min y, max y, min z, max z).\n    setCorrFactors calibrates the slope and assumes the zero point \n    is (min+max)\/2. You have to add the setCorrFactors function to all sketches \n    in which you want to use it.\n*\/\n  myAcc.setCorrFactors(-266.0, 285.0, -268.0, 278.0, -291.0, 214.0);\n\n\/* In this next step the offset for angles is corrected to get quite precise corrected \n    angles x and y up to ~60\u00b0. The additional offsetCorrection is only for corrected \n    angle measurements, not for pitch and roll. The procedure just ensures to start at 0\u00b0.\n*\/\n  Serial.println(\"Position your ADXL345 flat and don't move it\");\n  delay(2000);\n  myAcc.measureAngleOffsets();\n  Serial.println(\"....done\");\n   \n\/* Choose the data rate         Hz\n    ADXL345_DATA_RATE_3200    3200\n    ADXL345_DATA_RATE_1600    1600\n    ADXL345_DATA_RATE_800      800\n    ADXL345_DATA_RATE_400      400\n    ADXL345_DATA_RATE_200      200\n    ADXL345_DATA_RATE_100      100\n    ADXL345_DATA_RATE_50        50\n    ADXL345_DATA_RATE_25        25\n    ADXL345_DATA_RATE_12_5      12.5  \n    ADXL345_DATA_RATE_6_25       6.25\n    ADXL345_DATA_RATE_3_13       3.13\n    ADXL345_DATA_RATE_1_56       1.56\n    ADXL345_DATA_RATE_0_78       0.78\n    ADXL345_DATA_RATE_0_39       0.39\n    ADXL345_DATA_RATE_0_20       0.20\n    ADXL345_DATA_RATE_0_10       0.10\n*\/\n  myAcc.setDataRate(ADXL345_DATA_RATE_50);\n  Serial.print(\"Data rate: \");\n  Serial.print(myAcc.getDataRateAsString());\n\n\/* Choose the measurement range\n    ADXL345_RANGE_16G    16g     \n    ADXL345_RANGE_8G      8g     \n    ADXL345_RANGE_4G      4g   \n    ADXL345_RANGE_2G      2g\n*\/\n  myAcc.setRange(ADXL345_RANGE_2G);\n  Serial.print(\"  \/  g-Range: \");\n  Serial.println(myAcc.getRangeAsString());\n  Serial.println();  \n}\n\nvoid loop() {\n  \/\/xyzFloat g;\n  \/\/myAcc.getGValues(&amp;g);\n  xyzFloat corrAngles;\n  myAcc.getCorrAngles(&amp;corrAngles);\n  \n\/* Corrected angles use corrected raws and an extra angle\n    offset. The method provides quite precise values for x\/y \n    angles up 60\u00b0.\n*\/\n  Serial.print(\"Angle x = \");\n  Serial.print(corrAngles.x);\n  Serial.print(\"  |  Angle y = \");\n  Serial.print(corrAngles.y);\n  Serial.print(\"  |  Angle z = \");\n  Serial.println(corrAngles.z);\n\n\/* Pitch and roll use corrected slope, but no additional offset. \n    All axes are considered for calculation. \n*\/\n  float pitch = myAcc.getPitch();\n  float roll  = myAcc.getRoll();\n  \n  Serial.print(\"Pitch   = \"); \n  Serial.print(pitch); \n  Serial.print(\"  |  Roll    = \"); \n  Serial.println(roll); \n  \n  Serial.println();\n  \n  delay(1000);\n}<\/pre>\n<p>\u00a0<\/p>\n<\/div>\n<p>\n\n<h4 class=\"wp-block-heading\">Output of ADXL345_pitch_roll_corrected_angles.ino<\/h4>\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/07\/pitch_roll_corrected_angles_output_II.png\"><img loading=\"lazy\" decoding=\"async\" width=\"767\" height=\"419\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/07\/pitch_roll_corrected_angles_output_II.png\" alt=\"Output of ADXL345_pitch_roll_corrected_angles.ino\" class=\"wp-image-15369\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/07\/pitch_roll_corrected_angles_output_II.png 767w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/07\/pitch_roll_corrected_angles_output_II-300x164.png 300w\" sizes=\"auto, (max-width: 767px) 100vw, 767px\" \/><\/a><figcaption class=\"wp-element-caption\">Output of ADXL345_pitch_roll_corrected_angles.ino<\/figcaption><\/figure>\n\n<p>For the above output, I slowly rotated the ADXL345. I measured the values using simple tools (a protractor).  For small to medium angles, the values called &#8220;Angle&#8221; are closer to reality, at large angles the pitch\/roll method is better.<\/p>\n\n<h3 class=\"wp-block-heading\">Example sketch 5: ADXL345_sleep.ino<\/h3>\n\n<p>To save power, you can send the ADXL345 to sleep. The function to do this (and to wake it up) is:<\/p>\n<ul>\n<li><code>setSleep(true\/false)<\/code><\/li>\n<\/ul>\n<p>Sleep is interrupted by short waking phases. That cannot be stopped. But you can set the wake-up frequency to 1, 2, 4 or 8 Hz. To control the sleep mode together of the wake-up frequency, you can alternatively call the function with two parameters:<\/p>\n<ul>\n<li><code>setSleep(true\/false, frequency)<\/code><\/li>\n<\/ul>\n<p>If you don&#8217;t retrieve new data too often, you won&#8217;t notice any difference to the permanent wake mode. Only when the frequency of your readings is greater than the wake-up frequency will you see the effect.<\/p>\n<p>In the example sketch, 10 readings are retrieved in wake and sleep mode. I have set the wake-up frequency to one second, and the readings are sampled at 300 millisecond intervals. Here is the (shortened) sketch:<\/p>\n<\/p>\n<div class=\"scroll-paragraph\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"ADXL345_sleep.ino\" data-enlighter-title=\"ADXL345_sleep.ino\">#include&lt;Wire.h&gt;\n#include&lt;ADXL345_WE.h&gt;\n#define ADXL345_I2CADDR 0x53  \/\/ 0x1D if SDO = HIGH\n\n\/* There are several ways to create your ADXL345 object:\n * ADXL345_WE myAcc = ADXL345_WE()                -&gt; uses Wire \/ I2C Address = 0x53\n * ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR) -&gt; uses Wire \/ ADXL345_I2CADDR\n * ADXL345_WE myAcc = ADXL345_WE(&amp;wire2)          -&gt; uses the TwoWire object wire2 \/ ADXL345_I2CADDR\n * ADXL345_WE myAcc = ADXL345_WE(&amp;wire2, ADXL345_I2CADDR) -&gt; all together\n *\/\nADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR);\n\nvoid setup(){\n  Wire.begin();\n  Serial.begin(115200);\n  Serial.println(\"ADXL345_Sketch - Sleep\");\n  Serial.println();\n  if(!myAcc.init()){\n    Serial.println(\"ADXL345 not connected!\");\n  }\n\n\/* Insert your data from ADXL345_calibration.ino and uncomment for more precise results *\/\n \/\/ myAcc.setCorrFactors(-266.0, 285.0, -268.0, 278.0, -291.0, 214.0);\n   \n\/* Choose the data rate         Hz\n    ADXL345_DATA_RATE_3200    3200\n    ADXL345_DATA_RATE_1600    1600\n    ADXL345_DATA_RATE_800      800\n    ADXL345_DATA_RATE_400      400\n    ADXL345_DATA_RATE_200      200\n    ADXL345_DATA_RATE_100      100\n    ADXL345_DATA_RATE_50        50\n    ADXL345_DATA_RATE_25        25\n    ADXL345_DATA_RATE_12_5      12.5  \n    ADXL345_DATA_RATE_6_25       6.25\n    ADXL345_DATA_RATE_3_13       3.13\n    ADXL345_DATA_RATE_1_56       1.56\n    ADXL345_DATA_RATE_0_78       0.78\n    ADXL345_DATA_RATE_0_39       0.39\n    ADXL345_DATA_RATE_0_20       0.20\n    ADXL345_DATA_RATE_0_10       0.10\n*\/ \n  myAcc.setDataRate(ADXL345_DATA_RATE_50);\n  Serial.print(\"Data rate: \");\n  Serial.print(myAcc.getDataRateAsString());\n\n\/* Choose the measurement range\n    ADXL345_RANGE_16G    16g     \n    ADXL345_RANGE_8G      8g     \n    ADXL345_RANGE_4G      4g   \n    ADXL345_RANGE_2G      2g\n*\/\n  myAcc.setRange(ADXL345_RANGE_2G);\n  Serial.print(\"  \/  g-Range: \");\n  Serial.println(myAcc.getRangeAsString());\n  Serial.println();\n}\n\nvoid loop(){\n\/* Switch on (true) or switch off (false) sleep mode. Choose the wake up \n    frequency:\n    ADXL345_WUP_FQ_1  =  1 Hz\n    ADXL345_WUP_FQ_2  =  2 Hz\n    ADXL345_WUP_FQ_4  =  4 Hz \n    ADXL345_WUP_FQ_8  =  8 Hz\n\n    In this specific example you will see (provided you move the ADXL345) that\n    in sleep mode the values are updated every third to fourth request. In awake\n    mode the values are updated steadily. Sleep Mode saves significant power.  \n*\/\n  myAcc.setSleep(true, ADXL345_WUP_FQ_1);\n  Serial.println(\"Measure in Sleep Mode:\");\n  doMeasurements();\n  \n  myAcc.setSleep(false);\n  Serial.println(\"Measure in Normal Mode:\");\n  doMeasurements();\n}\n  \n\nvoid doMeasurements(){\n  for(int i=0; i&lt;10; i++){\n    xyzFloat g;\n    myAcc.getGValues(&amp;g);\n    \n    Serial.print(\"g-x   = \");\n    Serial.print(g.x);\n    Serial.print(\"  |  g-y   = \");\n    Serial.print(g.y);\n    Serial.print(\"  |  g-z   = \");\n    Serial.println(g.z);\n    \n    delay(300);\n  }\n}<\/pre>\n<p>\u00a0<\/p>\n<\/div>\n<p>\n\n<h4 class=\"wp-block-heading\">Output of ADXL345_sleep.ino<\/h4>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/sleep_output.png\"><img loading=\"lazy\" decoding=\"async\" width=\"716\" height=\"494\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/sleep_output.png\" alt=\"Output of ADXL345_sleep.ino\" class=\"wp-image-10375\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/sleep_output.png 716w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/sleep_output-300x207.png 300w\" sizes=\"auto, (max-width: 716px) 100vw, 716px\" \/><\/a><figcaption class=\"wp-element-caption\">Output of ADXL345_sleep.ino<\/figcaption><\/figure>\n\n<p>For the above output I moved the ADXL345 permanently. You can see that the values in normal mode are different for each query. In Sleep Mode, as expected, 3 to 4 values are identical.<\/p>\n\n<p>Actually, it would be a good time to introduce the Auto Sleep mode next. But for the Auto Sleep mode we need interrupts and therefore we treat this topic first. I&#8217;ll come back to the Auto Sleep mode a little later.<\/p>\n\n<h2 class=\"wp-block-heading\">Interrupt Features of the ADXL345<\/h2>\n\n<h3 class=\"wp-block-heading\">General information about the interrupt features<\/h3>\n\n<p>The ADXL345 distinguishes eight interrupts:<\/p>\n<ul>\n<li><strong>Overrun:<\/strong> is triggered when unread data is overwritten, i.e. when the data rate is greater than the frequency of the data retrieval.<\/li>\n<li><strong>Watermark<\/strong>: if the number of measured values in the FIFO buffer corresponds to the value defined in the FIFO control register (this will become clearer later).<\/li>\n<li><strong>Free Fall<\/strong>: this is triggered when the acceleration values on all axes fall below a certain value for a certain time.<\/li>\n<li><strong>Inactivity<\/strong>: when a limit of acceleration is exceeded on specified axes for a specified time.<\/li>\n<li><strong>Activity<\/strong>: when a limit of acceleration is exceeded on specified axes.<\/li>\n<li><strong>Single tap:<\/strong> an acceleration of a maximum duration that is above a certain limit.<\/li>\n<li><strong>Double Tap:<\/strong> two peaks, both of which satisfy the single-tap conditions and also have a certain time interval between them.<\/li>\n<li><strong>Data Ready<\/strong>: there is unread data.<\/li>\n<\/ul>\n<p>You activate interrupts with the function <code>setInterrupt(type, pin1\/pin2)<\/code>. The first parameter is the interrupt type, with the second parameter you determine at which pin the interrupt is output. See the example sketches that use interrupts for a list of allowed parameters.<\/p>\n<p><strong>It is important to note that the interrupts for Overrun, Watermark and Data Ready are always enabled.<\/strong> So, you can&#8217;t disable them, just change the output pin. Default is INT1. You have to activate all other interrupts first. You deactivate them with <code>deleteInterrupt(type)<\/code>.<\/p>\n\n<p>In the interrupt register, in the case of an interrupt, the interrupt type is stored. Reading this register deletes the interrupt so that a new interrupt can be triggered. The function for this is <code>readAndClearInterrupts()<\/code>. It returns the interrupt type as a byte. How to &#8220;translate&#8221; this can be found in the library file ADXL345_WE.h. Alternatively, you check with <code>checkInterrupt(source, type)<\/code> for a specific type.<\/p>\n<p>There is another general function, namely <code>setInterruptPolarity(polarity)<\/code>. This sets whether the interrupt pins are active-low or active-high (default). <\/p>\n\n<h3 class=\"wp-block-heading\">Example sketch 6: ADXL345_free_fall_interrupt.ino<\/h3>\n\n<p>First, let&#8217;s take a look at the Free Fall interrupt. In the example sketch, it is activated with <code>setInterrupt(ADXL345_FREEFALL, INT_PIN_2)<\/code> and assigned to INT2.<\/p>\n<p><code>setFreeFallThresholds (0.4, 100)<\/code> sets the acceleration limit to 0.4 g and the minimum duration for which it must be lower to 100 milliseconds. Limits for parameters and recommended values can be found in the example sketch. It is best to play around a little with the parameters to get to know this function better.<\/p>\n<\/p>\n<div class=\"scroll-paragraph\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"ADXL345_free_fall_interrupt.ino\" data-enlighter-title=\"ADXL345_free_fall_interrupt.ino\">#include&lt;Wire.h&gt;\n#include&lt;ADXL345_WE.h&gt;\n#define ADXL345_I2CADDR 0x53  \/\/ 0x1D if SDO = HIGH\nconst int int2Pin = 2;\nvolatile bool freeFall = false;\n\n\/* There are several ways to create your ADXL345 object:\n * ADXL345_WE myAcc = ADXL345_WE()                -&gt; uses Wire \/ I2C Address = 0x53\n * ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR) -&gt; uses Wire \/ ADXL345_I2CADDR\n * ADXL345_WE myAcc = ADXL345_WE(&amp;wire2)          -&gt; uses the TwoWire object wire2 \/ ADXL345_I2CADDR\n * ADXL345_WE myAcc = ADXL345_WE(&amp;wire2, ADXL345_I2CADDR) -&gt; all together\n *\/\nADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR);\n\nvoid setup(){\n  Wire.begin();\n  Serial.begin(115200);\n  pinMode(int2Pin, INPUT);\n  Serial.println(\"ADXL345_Sketch - Free Fall Interrupt\");\n  Serial.println();\n  if(!myAcc.init()){\n    Serial.println(\"ADXL345 not connected!\");\n  }\n\n\/* Insert your data from ADXL345_calibration.ino and uncomment for more precise results *\/\n  \/\/ myAcc.setCorrFactors(-266.0, 285.0, -268.0, 278.0, -291.0, 214.0);\n\n\/* Choose the data rate         Hz\n    ADXL345_DATA_RATE_3200    3200\n    ADXL345_DATA_RATE_1600    1600\n    ADXL345_DATA_RATE_800      800\n    ADXL345_DATA_RATE_400      400\n    ADXL345_DATA_RATE_200      200\n    ADXL345_DATA_RATE_100      100\n    ADXL345_DATA_RATE_50        50\n    ADXL345_DATA_RATE_25        25\n    ADXL345_DATA_RATE_12_5      12.5  \n    ADXL345_DATA_RATE_6_25       6.25\n    ADXL345_DATA_RATE_3_13       3.13\n    ADXL345_DATA_RATE_1_56       1.56\n    ADXL345_DATA_RATE_0_78       0.78\n    ADXL345_DATA_RATE_0_39       0.39\n    ADXL345_DATA_RATE_0_20       0.20\n    ADXL345_DATA_RATE_0_10       0.10\n*\/\n  myAcc.setDataRate(ADXL345_DATA_RATE_25);\n  Serial.print(\"Data rate: \");\n  Serial.print(myAcc.getDataRateAsString());\n \n\/* Choose the measurement range\n    ADXL345_RANGE_16G    16g     \n    ADXL345_RANGE_8G      8g     \n    ADXL345_RANGE_4G      4g   \n    ADXL345_RANGE_2G      2g\n*\/  \n  myAcc.setRange(ADXL345_RANGE_2G);\n  Serial.print(\"  \/  g-Range: \");\n  Serial.println(myAcc.getRangeAsString());\n  Serial.println();\n\n\/* The parameters of the setFreeFallThresholds function are:  \n     - g threshold - do not choose a parameter which is too low. 0.3 - 0.6 g is fine.\n     - time threshold in ms, maximum is 1275. Recommended is 100 - 350;\n    If time threshold is too low, vibrations can be detected as free fall. \n *\/\n  myAcc.setFreeFallThresholds(0.4, 100);\n  \n\/* You can choose the following interrupts:\n     Variable name:             Triggered, if:\n    ADXL345_OVERRUN      -   new data replaces unread data\n    ADXL345_WATERMARK    -   the number of samples in FIFO equals the number defined in FIFO_CTL\n    ADXL345_FREEFALL     -   acceleration values of all axes are below the threshold defined in THRESH_FF \n    ADXL345_INACTIVITY   -   acc. value of all included axes are &lt; THRESH_INACT for period &gt; TIME_INACT\n    ADXL345_ACTIVITY     -   acc. value of included axes are &gt; THRESH_ACT\n    ADXL345_DOUBLE_TAP   -   double tap detected on one incl. axis and various defined conditions are met\n    ADXL345_SINGLE_TAP   -   single tap detected on one incl. axis and various defined conditions are met\n    ADXL345_DATA_READY   -   new data available\n\n    Assign the interrupts to INT1 (INT_PIN_1) or INT2 (INT_PIN_2). Data ready, watermark and overrun are \n    always enabled. You can only change the assignment of these which is INT1 by default.\n\n    You can delete interrupts with deleteInterrupt(type);\n*\/\n  myAcc.setInterrupt(ADXL345_FREEFALL, INT_PIN_2);\n  \n  attachInterrupt(digitalPinToInterrupt(int2Pin), freeFallISR, RISING); \n  myAcc.readAndClearInterrupts();\n}\n\nvoid loop() {\n  xyzFloat raw, g;\n  myAcc.getRawValues(&amp;raw);\n  myAcc.getGValues(&amp;g);\n     \n  Serial.print(\"Raw-x = \");\n  Serial.print(raw.x);\n  Serial.print(\"  |  Raw-y = \");\n  Serial.print(raw.y);\n  Serial.print(\"  |  Raw-z = \");\n  Serial.println(raw.z);\n\n  Serial.print(\"g-x   = \");\n  Serial.print(g.x);\n  Serial.print(\"  |  g-y   = \");\n  Serial.print(g.y);\n  Serial.print(\"  |  g-z   = \");\n  Serial.println(g.z);\n\n  Serial.println();\n \n  if(freeFall==true){\n    Serial.println(\"Aaaaaaaaah!!!!! - I'm faaaaallllling!\");\n    delay(1000);\n    freeFall = false;\n    \/* by reading the interrupt register the interrupt is cleared *\/\n    myAcc.readAndClearInterrupts();\n    \n    \/* if you expect also other interrupts you can check the type. For this comment the previous line, \n    and replace by the following four lines: *\/\n    \/\/byte intType = myAcc.readAndClearInterrupts();\n    \/\/if(myAcc.checkInterrupt(intType, ADXL345_FREEFALL)){\n    \/\/  Serial.println(\"FREEFALL confirmed\");\n    \/\/}\n  }\n\n  delay(500);\n}\n\nvoid freeFallISR(){\n  freeFall = true;\n}\n<\/pre>\n<p>\u00a0<\/p>\n<\/div>\n<p>\n\n<h3 class=\"wp-block-heading\">Example sketch 7: ADXL345_data_ready_interrupt.ino <\/h3>\n\n<p>I still have one example sketch for this part 1, then it&#8217;s half-time. Here we use the Data Ready interrupt to control the data output. First, I set the measuring frequency with <code>setDataRate(ADXL345_DATA_RATE_0_20)<\/code> to a slow 0.2 Hz.<\/p>\n<p>The Data Ready Interrupt is always active. But to not interfere with the other &#8220;always-enabled&#8221; interrupts, I assigned it to INT2 with <code>setInterrupt(ADXL345_DATA_READY, INT_PIN_2)<\/code>.<\/p>\n<p>The rest is simple. The Data Ready interrupt triggers an interrupt on Arduino Pin 2. This is the signal for reading the measured values. After that, the interrupt is deleted and the next interrupt is expected.<\/p>\n<\/p>\n<div class=\"scroll-paragraph\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"ADXL345_data_ready_interrupt.ino\" data-enlighter-title=\"ADXL345_data_ready_interrupt.ino\">#include&lt;Wire.h&gt;\n#include&lt;ADXL345_WE.h&gt;\n#define ADXL345_I2CADDR 0x53 \/\/ 0x1D if SDO = HIGH\nconst int int2Pin = 2;  \/\/ interrupt pin\nvolatile bool dataReady = false;\n\n\/* There are several ways to create your ADXL345 object:\n * ADXL345_WE myAcc = ADXL345_WE()                -&gt; uses Wire \/ I2C Address = 0x53\n * ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR) -&gt; uses Wire \/ ADXL345_I2CADDR\n * ADXL345_WE myAcc = ADXL345_WE(&amp;wire2)          -&gt; uses the TwoWire object wire2 \/ ADXL345_I2CADDR\n * ADXL345_WE myAcc = ADXL345_WE(&amp;wire2, ADXL345_I2CADDR) -&gt; all together\n *\/\nADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR);\n\nvoid setup(){\n  Wire.begin();\n  Serial.begin(115200);\n  pinMode(int2Pin, INPUT);\n  Serial.println(\"ADXL345_Sketch - Data Ready Interrupt\");\n  Serial.println();\n  if(!myAcc.init()){\n    Serial.println(\"ADXL345 not connected!\");\n  }\n\n\/* Insert your data from ADXL345_calibration.ino and uncomment for more precise results *\/\n  \/\/ myAcc.setCorrFactors(-266.0, 285.0, -268.0, 278.0, -291.0, 214.0);\n\n\/* Choose the data rate         Hz\n    ADXL345_DATA_RATE_3200    3200\n    ADXL345_DATA_RATE_1600    1600\n    ADXL345_DATA_RATE_800      800\n    ADXL345_DATA_RATE_400      400\n    ADXL345_DATA_RATE_200      200\n    ADXL345_DATA_RATE_100      100\n    ADXL345_DATA_RATE_50        50\n    ADXL345_DATA_RATE_25        25\n    ADXL345_DATA_RATE_12_5      12.5  \n    ADXL345_DATA_RATE_6_25       6.25\n    ADXL345_DATA_RATE_3_13       3.13\n    ADXL345_DATA_RATE_1_56       1.56\n    ADXL345_DATA_RATE_0_78       0.78\n    ADXL345_DATA_RATE_0_39       0.39\n    ADXL345_DATA_RATE_0_20       0.20\n    ADXL345_DATA_RATE_0_10       0.10\n*\/\n\/\/ Choose a low frequency to showcase the data rate controlled output\n  myAcc.setDataRate(ADXL345_DATA_RATE_0_20);\n  Serial.print(\"Data rate: \");\n  Serial.print(myAcc.getDataRateAsString());\n\n\/* Choose the measurement range\n    ADXL345_RANGE_16G    16g     \n    ADXL345_RANGE_8G      8g     \n    ADXL345_RANGE_4G      4g   \n    ADXL345_RANGE_2G      2g\n*\/\n  myAcc.setRange(ADXL345_RANGE_2G);\n  Serial.print(\"  \/  g-Range: \");\n  Serial.println(myAcc.getRangeAsString());\n  Serial.println();\n  \n  attachInterrupt(digitalPinToInterrupt(int2Pin), dataReadyISR, RISING);\n\n\/* Default Interrupt Pin Polarity is active high. Change if you like *\/  \n  \/\/ myAcc.setInterruptPolarity(ADXL345_ACT_LOW);\n\n\/* You can choose the following interrupts:\n     Variable name:             Triggered, if:\n    ADXL345_OVERRUN      -   new data replaces unread data\n    ADXL345_WATERMARK    -   the number of samples in FIFO equals the number defined in FIFO_CTL\n    ADXL345_FREEFALL     -   acceleration values of all axes are below the threshold defined in THRESH_FF \n    ADXL345_INACTIVITY   -   acc. value of all included axes are &lt; THRESH_INACT for period &gt; TIME_INACT\n    ADXL345_ACTIVITY     -   acc. value of included axes are &gt; THRESH_ACT\n    ADXL345_DOUBLE_TAP   -   double tap detected on one incl. axis and various defined conditions are met\n    ADXL345_SINGLE_TAP   -   single tap detected on one incl. axis and various defined conditions are met\n    ADXL345_DATA_READY   -   new data available\n\n    Assign the interrupts to INT1 (INT_PIN_1) or INT2 (INT_PIN_2). Data ready, watermark and overrun are \n    always enabled. You can only change the assignment of these which is INT1 by default.\n\n    You can delete interrupts with deleteInterrupt(type);\n*\/\n  myAcc.setInterrupt(ADXL345_DATA_READY, INT_PIN_2); \n  myAcc.readAndClearInterrupts();\n}\n\n\/* In the following loop there is only one interrupt type that can occur on INT2.\n    In cases where you expect more candidates, you can check as follows:\n        uint8_t intType = myAcc.readAndClearInterrupts();\n        if(myAcc.checkInterrupt(intType, ADXL345_DATA_READY)){\n          Serial.println(\"DATA READY confirmed\");\n        }\n*\/\nvoid loop() {\n  \/\/ you see here is no delay to control the output rate\n  if(dataReady==true){\n    xyzFloat g;\n    myAcc.getGValues(&amp;g);\n    \/\/ dataReady = false; \/\/ uncomment, if you want capture next interrupts\n      \n    Serial.print(\"g-x   = \");\n    Serial.print(g.x);\n    Serial.print(\"  |  g-y   = \");\n    Serial.print(g.y);\n    Serial.print(\"  |  g-z   = \");\n    Serial.println(g.z);\n  \n    dataReady = false; \/\/ comment, if you have set dataReady to false before\n  }  \n}\n\nvoid dataReadyISR(){\n  dataReady = true;\n}<\/pre>\n<p>\u00a0<\/p>\n<\/div>\n<p>\n\n<h2 class=\"wp-block-heading\">Outlook<\/h2>\n\n<p><a href=\"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-2\" target=\"_blank\" rel=\"noopener\">In the next article<\/a>, we will come to the example sketches for<\/p>\n<ul>\n<li>Activity \/ Inactivity<\/li>\n<li>Auto Sleep Mode<\/li>\n<li>Single \/ Double Tap<\/li>\n<li>Various FIFO modes<\/li>\n<\/ul>\n\n<h2 class=\"wp-block-heading\">Acknowledgement<\/h2>\n\n<p>The utensils I attached to the ADXL345 module in the post image are from the image of a Swiss Army Knife by <a href=\"https:\/\/pixabay.com\/de\/users\/clker-free-vector-images-3736\/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=33076\" target=\"_blank\" rel=\"noopener\">Clker-Free-Vector-Images<\/a> on <a href=\"https:\/\/pixabay.com\/de\/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=33076\" target=\"_blank\" rel=\"noopener\">Pixabay<\/a>.<\/p>\n<p>I would like to thank <a href=\"https:\/\/www.adafruit.com\/\" target=\"_blank\" rel=\"noopener\">Adafruit<\/a> for publishing the Fritzing scheme of their ADXL345 module.<\/p>\n<p> <\/p>\n<p> <\/p>\n","protected":false},"excerpt":{"rendered":"<p>The ADXL345 is a 3-axis accelerometer with many features. I explain how to use it with my associated library.<\/p>\n","protected":false},"author":1,"featured_media":10340,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[572],"tags":[2442,2443,1337,2692,1349,1357,1117,1354,1351,1355,666,558,2444,1352,1503],"class_list":["post-10861","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-sensors","tag-3-wire-en","tag-4-wire-en","tag-accelerometer-en-2","tag-adxl343-en","tag-adxl345-en","tag-angle","tag-calibration","tag-double-tap-en-2","tag-fifo-en","tag-free-fall-en-3","tag-i2c-en","tag-library-en-2","tag-sdo-en","tag-single-tap-en","tag-spi-en"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>ADXL345 - The Universal Accelerometer - Part 1 &#8226; Wolles Elektronikkiste<\/title>\n<meta name=\"description\" content=\"The ADXL345 is a 3-axis accelerometer with many features. I explain how to use it with my associated library.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-1\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"ADXL345 - The Universal Accelerometer - Part 1 &#8226; Wolles Elektronikkiste\" \/>\n<meta property=\"og:description\" content=\"The ADXL345 is a 3-axis accelerometer with many features. I explain how to use it with my associated library.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-1\" \/>\n<meta property=\"og:site_name\" content=\"Wolles Elektronikkiste\" \/>\n<meta property=\"article:published_time\" content=\"2021-01-17T19:27:56+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-09-17T16:37:27+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/Beitragsbild.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1087\" \/>\n\t<meta property=\"og:image:height\" content=\"1087\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Wolfgang Ewald\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Wolfgang Ewald\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"31 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/adxl345-the-universal-accelerometer-part-1#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/adxl345-the-universal-accelerometer-part-1\"},\"author\":{\"name\":\"Wolfgang Ewald\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\"},\"headline\":\"ADXL345 &#8211; The Universal Accelerometer &#8211; Part 1\",\"datePublished\":\"2021-01-17T19:27:56+00:00\",\"dateModified\":\"2025-09-17T16:37:27+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/adxl345-the-universal-accelerometer-part-1\"},\"wordCount\":2953,\"commentCount\":84,\"publisher\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\"},\"image\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/adxl345-the-universal-accelerometer-part-1#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/Beitragsbild.jpg\",\"keywords\":[\"3-Wire\",\"4-Wire\",\"accelerometer\",\"ADXL343\",\"ADXL345\",\"angle\",\"Calibration\",\"double tap\",\"FIFO\",\"free fall\",\"I2C\",\"Library\",\"SDO\",\"single tap\",\"SPI\"],\"articleSection\":[\"Sensors\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/adxl345-the-universal-accelerometer-part-1#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/adxl345-the-universal-accelerometer-part-1\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/adxl345-the-universal-accelerometer-part-1\",\"name\":\"ADXL345 - The Universal Accelerometer - Part 1 &#8226; Wolles Elektronikkiste\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/adxl345-the-universal-accelerometer-part-1#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/adxl345-the-universal-accelerometer-part-1#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/Beitragsbild.jpg\",\"datePublished\":\"2021-01-17T19:27:56+00:00\",\"dateModified\":\"2025-09-17T16:37:27+00:00\",\"description\":\"The ADXL345 is a 3-axis accelerometer with many features. I explain how to use it with my associated library.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/adxl345-the-universal-accelerometer-part-1#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/adxl345-the-universal-accelerometer-part-1\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/adxl345-the-universal-accelerometer-part-1#primaryimage\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/Beitragsbild.jpg\",\"contentUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/Beitragsbild.jpg\",\"width\":1087,\"height\":1087},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/adxl345-the-universal-accelerometer-part-1#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Startseite\",\"item\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"ADXL345 &#8211; The Universal Accelerometer &#8211; Part 1\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#website\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\",\"name\":\"Wolles Elektronikkiste\",\"description\":\"Die wunderbare Welt der Elektronik\",\"publisher\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\",\"name\":\"Wolfgang Ewald\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\",\"contentUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\",\"width\":512,\"height\":512,\"caption\":\"Wolfgang Ewald\"},\"logo\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"ADXL345 - The Universal Accelerometer - Part 1 &#8226; Wolles Elektronikkiste","description":"The ADXL345 is a 3-axis accelerometer with many features. I explain how to use it with my associated library.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-1","og_locale":"en_US","og_type":"article","og_title":"ADXL345 - The Universal Accelerometer - Part 1 &#8226; Wolles Elektronikkiste","og_description":"The ADXL345 is a 3-axis accelerometer with many features. I explain how to use it with my associated library.","og_url":"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-1","og_site_name":"Wolles Elektronikkiste","article_published_time":"2021-01-17T19:27:56+00:00","article_modified_time":"2025-09-17T16:37:27+00:00","og_image":[{"width":1087,"height":1087,"url":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/Beitragsbild.jpg","type":"image\/jpeg"}],"author":"Wolfgang Ewald","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Wolfgang Ewald","Est. reading time":"31 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-1#article","isPartOf":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-1"},"author":{"name":"Wolfgang Ewald","@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46"},"headline":"ADXL345 &#8211; The Universal Accelerometer &#8211; Part 1","datePublished":"2021-01-17T19:27:56+00:00","dateModified":"2025-09-17T16:37:27+00:00","mainEntityOfPage":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-1"},"wordCount":2953,"commentCount":84,"publisher":{"@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46"},"image":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-1#primaryimage"},"thumbnailUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/Beitragsbild.jpg","keywords":["3-Wire","4-Wire","accelerometer","ADXL343","ADXL345","angle","Calibration","double tap","FIFO","free fall","I2C","Library","SDO","single tap","SPI"],"articleSection":["Sensors"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-1#respond"]}]},{"@type":"WebPage","@id":"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-1","url":"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-1","name":"ADXL345 - The Universal Accelerometer - Part 1 &#8226; Wolles Elektronikkiste","isPartOf":{"@id":"https:\/\/wolles-elektronikkiste.de\/en#website"},"primaryImageOfPage":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-1#primaryimage"},"image":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-1#primaryimage"},"thumbnailUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/Beitragsbild.jpg","datePublished":"2021-01-17T19:27:56+00:00","dateModified":"2025-09-17T16:37:27+00:00","description":"The ADXL345 is a 3-axis accelerometer with many features. I explain how to use it with my associated library.","breadcrumb":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-1#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-1"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-1#primaryimage","url":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/Beitragsbild.jpg","contentUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/Beitragsbild.jpg","width":1087,"height":1087},{"@type":"BreadcrumbList","@id":"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-1#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Startseite","item":"https:\/\/wolles-elektronikkiste.de\/en"},{"@type":"ListItem","position":2,"name":"ADXL345 &#8211; The Universal Accelerometer &#8211; Part 1"}]},{"@type":"WebSite","@id":"https:\/\/wolles-elektronikkiste.de\/en#website","url":"https:\/\/wolles-elektronikkiste.de\/en","name":"Wolles Elektronikkiste","description":"Die wunderbare Welt der Elektronik","publisher":{"@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/wolles-elektronikkiste.de\/en?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46","name":"Wolfgang Ewald","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png","url":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png","contentUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png","width":512,"height":512,"caption":"Wolfgang Ewald"},"logo":{"@id":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png"}}]}},"_links":{"self":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts\/10861","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/comments?post=10861"}],"version-history":[{"count":8,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts\/10861\/revisions"}],"predecessor-version":[{"id":24881,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts\/10861\/revisions\/24881"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/media\/10340"}],"wp:attachment":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/media?parent=10861"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/categories?post=10861"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/tags?post=10861"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}