{"id":10883,"date":"2021-01-20T22:41:07","date_gmt":"2021-01-20T22:41:07","guid":{"rendered":"https:\/\/wolles-elektronikkiste.de\/adxl345-the-universal-accelerometer-part-2"},"modified":"2025-09-17T17:02:17","modified_gmt":"2025-09-17T17:02:17","slug":"adxl345-the-universal-accelerometer-part-2","status":"publish","type":"post","link":"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-2","title":{"rendered":"ADXL345 &#8211; The Universal Accelerometer &#8211; Part 2"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">About this Post<\/h2>\n\n<p>This is now the second part of my article about the ADXL345 accelerometer and my <a href=\"https:\/\/github.com\/wollewald\/ADXL345_WE\" target=\"_blank\" rel=\"noopener\">associated library<\/a>. It builds on the <a href=\"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-1\" target=\"_blank\" rel=\"noopener\">first part<\/a>, in which I discussed the general features and the first seven sketches. <strong>All sketches run just as well on the ADXL343.<\/strong><\/p>\n<p>This part focuses on:<\/p>\n<ul>\n<li>Activity \/ Inactivity\n<ul>\n<li>here I catch up the Auto Sleep function<\/li>\n<\/ul>\n<\/li>\n<li>Single and Double Tap<\/li>\n<li>FIFO Functions<\/li>\n<\/ul>\n<p>Further notes:<\/p>\n<ul>\n<li>The circuit used for the example sketches is the same as that of the first part.<\/li>\n<li>Again, you&#8217;ll only find the shortened sample sketches. You get the original sketches with the library. They contain considerably more comments, especially the options for the function parameters.<\/li>\n<li>I found a few bugs after I posted the first part. So install the updates via the Arduino IDE or keep an eye out for the latest version on GitHub!<\/li>\n<\/ul>\n\n<h2 class=\"wp-block-heading\">Activity &#8211; Inactivity &#8211; Auto Sleep<\/h2>\n\n<p>The Activity interrupt is triggered when a certain acceleration value is exceeded on the specified axes. The Inactivity interrupt is triggered when the values for the axes involved fall below a certain acceleration value for a certain time.<\/p>\n<p>Both interrupts can be set up independently of each other. Because of their relationship, I treat both in one example sketch. In addition, the effect of the link bit can be best shown this way.&nbsp;<\/p>\n<p>In the last post I covered the interrupts of the ADXL345 in general.<\/p>\n\n<h3 class=\"wp-block-heading\">Example sketch 8: ADXL345_activity_inactivity_interrupt.ino<\/h3>\n\n<p>Here I use the following new functions:<\/p>\n<ul>\n<li><code>setActivityParameters(mode, axes, g-threshold)<\/code>\n<ul>\n<li>mode: is DC or AC\n<ul>\n<li>DC: the limit (threshold) applies absolutely.<\/li>\n<li>AC: the limit is the delta to the starting value.<\/li>\n<\/ul>\n<\/li>\n<li>axes: the participating axes.<\/li>\n<li>g-threshold: the limit in g.<\/li>\n<\/ul>\n<\/li>\n<li><code>setInactivityParameters(mode, axes, g-threshold, time-threshold)<\/code>\n<ul>\n<li>mode, axes, g-threshold: as above.<\/li>\n<li>time-threshold: the time limit in seconds (max. 255).<\/li>\n<\/ul>\n<\/li>\n<li><code>setLinkBit(true\/false)<\/code>\n<ul>\n<li>I&#8217;ll explain that below.<\/li>\n<\/ul>\n<\/li>\n<li><code>getActTapStatusAsString()<\/code>\n<ul>\n<li>Returns as a string which axis\/axes was\/were responsible for the Activity interrupt. Also used for the Tap functions.<\/li>\n<\/ul>\n<\/li>\n<li><code>getActTapStatus()<\/code>\n<ul>\n<li>Returns the content of the Act Tap Status register as byte. The meaning of the returned value can be understood from the data sheet and the library files. For advanced users.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>In the sketch you will find the permissible parameters. In addition, you need to activate the interrupts with <code>setInterrupt()<\/code>.<\/p>\n<p>For the activity and inactivity interrupt, I set the DC mode, select the x and y axes, set 0.5 g as the g limit, and take 10 seconds as the time limit for inactivity. <\/p>\n<p>As an interrupt can be both an activity and an inactivity interrupt, the content of the interrupt register is queried with <code>intSource = readAndClearInterrupt()<\/code> and then checked with <code> checkInterrupt(intSource, interruptType)<\/code> to see whether interruptType was the trigger.<\/p>\n<\/p>\n<div class=\"scroll-paragraph\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"ADXL345_activity_inactivity.ino\" data-enlighter-title=\"ADXL345_activity_inactivity.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 in_activity = false; \/\/ in_activity: either activity or inactivity interrupt occured\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 - Activity and Inactivity Interrupts\");\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_4G);\n  Serial.print(\"  \/  g-Range: \");\n  Serial.println(myAcc.getRangeAsString());\n  Serial.println();\n\n  attachInterrupt(digitalPinToInterrupt(int2Pin), in_activityISR, RISING);\n\n\/* Three parameters have to be set for activity:\n    1. DC \/ AC Mode:\n        ADXL345_DC_MODE - Threshold is the defined one (parameter 3)\n        ADXL345_AC_MODE - Threshold = starting acceleration + defined threshold\n    2. Axes, that are considered:\n        ADXL345_000  -  no axis (which makes no sense)\n        ADXL345_00Z  -  z \n        ADXL345_0Y0  -  y\n        ADXL345_0YZ  -  y,z\n        ADXL345_X00  -  x\n        ADXL345_X0Z  -  x,z\n        ADXL345_XY0  -  x,y\n        ADXL345_XYZ  -  all axes\n    3. Threshold in g\n*\/\n  myAcc.setActivityParameters(ADXL345_DC_MODE, ADXL345_XY0, 0.5);\n  \n\/* Four parameters have to be set for in activity:\n    1. DC \/ AC Mode:\n        see activity parameters\n    2. Axes, that are considered:\n        see activity parameters\n    3. Threshold in g\n    4. Inactivity period threshold in seconds (max 255)\n*\/  \n  myAcc.setInactivityParameters(ADXL345_DC_MODE, ADXL345_XY0, 0.5, 10.0);\n  \n\/* Setting the link bit only makes sense if both activity and inactivity are used\n *  If link bit is not set:  \n *   - activity interrupt can be triggered any time and multiple times\n *   - inactivity can be triggered if inactivity param. are met, independent from activity param. (if used) \n *  If link bit is set:\n *   - activity interrupt can only be triggered after inactivity interrupt \n *   - only one activity interrupt can be triggered until the next inactivity interrupt occurs\n *\/\n   \/\/ myAcc.setLinkBit(true);\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_ACTIVITY, INT_PIN_2);\n  myAcc.setInterrupt(ADXL345_INACTIVITY, INT_PIN_2);\n  myAcc.readAndClearInterrupts();  \n}\n\n\/* In the main loop some checks are done:\n    getActTapStatus() returns which axes are responsible for activity interrupt as byte (code in library)\n    getActTapStatusAsString() returns the axes that caused the interrupt as string\n    readAndClearInterrupts(); returns the interrupt type as byte (code in library) \n    checkInterrupt(intSource, type) returns if intSource is type as bool  \n*\/\n\nvoid loop() {\n  if ((millis() % 1000) == 1) {\n    xyzFloat g;\n    myAcc.getGValues(&amp;g);\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\n  if(in_activity == true) {\n      \/\/byte actTapSource = myAcc.getActTapStatus();\n      \/\/Serial.println(actTapSource, BIN);\n      String axes = myAcc.getActTapStatusAsString();\n      byte intSource = myAcc.readAndClearInterrupts();\n      if(myAcc.checkInterrupt(intSource, ADXL345_ACTIVITY)){\n        Serial.print(\"Activity at: \");\n        Serial.println(axes);\n      }\n     \n     if(myAcc.checkInterrupt(intSource, ADXL345_INACTIVITY)){\n        Serial.println(\"Inactivity!\");\n      }\n      \n    delay(1000);\n    myAcc.readAndClearInterrupts();\n    in_activity = false;\n  }\n}\n\nvoid in_activityISR() {\n  in_activity = true;\n}<\/pre>\n<p>\u00a0<\/p>\n<\/div>\n<p>\n\n<h4 class=\"wp-block-heading\">Output of the Activity \/ Inactivity Sketch<\/h4>\n\n<p>If the criterion for an activity interrupt is met, it is triggered. Since I have set the limits for activity and inactivity equal, an activity interrupt sets the timer for the inactivity interrupt back to zero.<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/01\/activity_inactivity_output.png\"><img loading=\"lazy\" decoding=\"async\" width=\"716\" height=\"494\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/01\/activity_inactivity_output.png\" alt=\"ADXL345 example sketch:&#10;Output of ADXL345_activity_inactivity.ino \" class=\"wp-image-10571\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/01\/activity_inactivity_output.png 716w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/01\/activity_inactivity_output-300x207.png 300w\" sizes=\"auto, (max-width: 716px) 100vw, 716px\" \/><\/a><figcaption class=\"wp-element-caption\">Output of ADXL345 activity_inactivity.ino <\/figcaption><\/figure>\n\n<h4 class=\"wp-block-heading\">The Link Bit<\/h4>\n\n<p>And now uncomment line 63 (<code>setLinkBit(true)<\/code>) and restart the sketch. Activity and Inactivity are now coupled. An Activity Interrupt &#8211; one at a time &#8211; can only be triggered if an Inactivity interrupt has been triggered before. Try it best.<\/p>\n\n<h3 class=\"wp-block-heading\">Example sketch 9: ADXL345_auto_sleep.ino<\/h3>\n\n<p>Here we now catch up with auto sleep mode. When enabled, the ADXL345 goes into sleep mode when an Inactivity interrupt has been triggered. An Activity interrupt, on the other hand, wakes up the ADXL345. As in normal sleep mode, the ADXL345 periodically wakes up briefly at a selectable frequency of 1 to 8 Hz even without an Activity interrupt.<\/p>\n<p>For Auto Sleep mode, the link bit must be set. This is done automatically by the library in the background. Accordingly, Activity and Inactivity interrupt are interdependent.<\/p>\n<p>The following features are new:<\/p>\n<ul>\n<li><code>setAutoSleep(true\/false, frequency)<\/code>\n<ul>\n<li>true\/false is the on\/off switch.<\/li>\n<li>frequency sets the wake-up frequency.<\/li>\n<\/ul>\n<\/li>\n<li><code>setAutoSleep(true\/false)<\/code>\n<ul>\n<li>Turn the Auto Sleep function on\/off without changing the wake-up frequency.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/p>\n<div class=\"scroll-paragraph\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"ADXL345_auto_sleep.ino\" data-enlighter-title=\"ADXL345_auto_sleep.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 in_activity = 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 - Auto Sleep\");\n  Serial.println();\n  if (!myAcc.init()) {\n    Serial.println(\"ADXL345 not connected!\");\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_4G);\n  Serial.print(\"  \/  g-Range: \");\n  Serial.println(myAcc.getRangeAsString());\n  Serial.println();\n \n  attachInterrupt(digitalPinToInterrupt(int2Pin), in_activityISR, RISING);\n\n\/* The following settings are similar to the settings in ADXL345_activity_inactivity_interrupt.ino *\/\n\n\/* Three parameters have to be set for activity:\n    1. DC \/ AC Mode:\n        ADXL345_DC_MODE - Threshold is the defined one (parameter 3)\n        ADXL345_AC_MODE - Threshold = starting acceleration + defined threshold \n    2. Axes, that are considered:\n        ADXL345_000  -  no axis (which makes no sense)\n        ADXL345_00Z  -  z \n        ADXL345_0Y0  -  y\n        ADXL345_0YZ  -  y,z\n        ADXL345_X00  -  x\n        ADXL345_X0Z  -  x,z\n        ADXL345_XY0  -  x,y\n        ADXL345_XYZ  -  all axes\n    3. Threshold in g\n*\/  \n  myAcc.setActivityParameters(ADXL345_DC_MODE, ADXL345_XY0, 0.8);\n\n\/* Four parameters have to be set for in activity:\n    1. DC \/ AC Mode:\n        see activity parameters\n    2. Axes, that are considered:\n        see activity parameters\n    3. Threshold in g\n    4. Inactivity period threshold in seconds (max 255)\n*\/    \n  myAcc.setInactivityParameters(ADXL345_DC_MODE, ADXL345_XY0, 0.8, 10);\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_ACTIVITY, INT_PIN_2);\n  myAcc.setInterrupt(ADXL345_INACTIVITY, INT_PIN_2);\n \n\/* Auto sleep is connected with activity and inactivity. The device goes in sleep when inactivity is \n    detected. The link bit must be set, if you want to use auto sleep. The library sets the link bit \n    automatically. When the ADXL345 goes into sleep mode it wakes up periodically (default is 8 Hz).\n    \n    Choose the wake up 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*\/\n  myAcc.setAutoSleep(true, ADXL345_WUP_FQ_1);\n  \/\/ alternative: myAcc.setAutoSleep(true\/false) without changing the wake up frequency.\n  myAcc.readAndClearInterrupts();\n\n}\n\nvoid loop() {\n  if ((millis() % 300) == 1) {\n    xyzFloat g;\n    myAcc.getGValues(&amp;g);\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\n  if(in_activity == true) {\n    byte intSource = myAcc.readAndClearInterrupts();\n    if(myAcc.checkInterrupt(intSource, ADXL345_ACTIVITY)){\n      Serial.println(\"Activity!\");\n      if(!myAcc.isAsleep()){        \/\/check the asleep bit\n        Serial.println(\"I am awake!\");\n      }\n    }\n     \n    if(myAcc.checkInterrupt(intSource, ADXL345_INACTIVITY)){\n      Serial.println(\"Inactivity!\");\n      if(myAcc.isAsleep()){\n        Serial.println(\"I am sleeping...\");\n      }\n    }\n      \n    myAcc.readAndClearInterrupts();\n    in_activity = false;\n  }\n}\n\nvoid in_activityISR() {\n  in_activity = true;\n}\n<\/pre>\n<p>\u00a0<\/p>\n<\/div>\n<p>\n\n<h4 class=\"wp-block-heading\">Output of the Auto Sleep sketch<\/h4>\n\n<p>Below you can see the excerpt of an output. I moved the ADXL345 below the activity limit. You can see that the ADXL345 is really asleep by the fact that the measured values are only updated once per second in sleep mode (as with the Sleep example sketch). Since the values are retrieved every 300 ms, 3-4 consecutive values are identical.<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/01\/auto_sleep_output.png\"><img loading=\"lazy\" decoding=\"async\" width=\"716\" height=\"494\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/01\/auto_sleep_output.png\" alt=\"ADXL345 example sketch:&#10;Output of ADXL345_auto_sleep.ino\" class=\"wp-image-10577\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/01\/auto_sleep_output.png 716w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/01\/auto_sleep_output-300x207.png 300w\" sizes=\"auto, (max-width: 716px) 100vw, 716px\" \/><\/a><figcaption class=\"wp-element-caption\">Output of ADXL345 auto_sleep.ino<\/figcaption><\/figure>\n\n<h2 class=\"wp-block-heading\">Single and Double Tap<\/h2>\n\n<p>A single tap event is basically an activity event, but with a defined maximum duration (DUR). If the event is longer than DUR, it is not considered a single tap. For example, vibrations can be distinguished from a longer acceleration. The next tap can only be detected after a latency period (latent) has elapsed. The latency begins after the value has fallen below the threshold.<\/p>\n<p>A Double Tap consists of two Single Taps with same parameters. The additional condition is that the second tap must take place in a time window that starts after the latency of the first tap has expired. Sounds complicated, but it&#8217;s not when you look at it graphically:<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/01\/tap_scheme-1024x473.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"473\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/01\/tap_scheme-1024x473.png\" alt=\"ADXL345 Single and Double Tap Detection\" class=\"wp-image-10580\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/01\/tap_scheme-1024x473.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/01\/tap_scheme-300x138.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/01\/tap_scheme-768x355.png 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/01\/tap_scheme-1320x609.png 1320w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/01\/tap_scheme.png 1510w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">ADXL345 Single and Double Tap Detection<\/figcaption><\/figure>\n\n<p>For single and double tap detection you need relatively high measuring frequencies. For example, it would make no sense to specify a value for DUR in the millisecond range, but record measured values in the seconds range. That has to fit together.<\/p>\n\n<h3 class=\"wp-block-heading\">Example sketch 10: ADXL345_single_tap.ino<\/h3>\n\n<p>You can set various parameters for the Single and Double Tap. The parameters that apply to both the single and the double tap are defined by the following function:<\/p>\n<ul>\n<li><code>setGeneralTapParameters(axes, g-threshold, duration, latent)<\/code>\n<ul>\n<li>Axes are again the axes involved.<\/li>\n<li>g-threshold is the limit in g (this time without DC\/AC mode).\n<ul>\n<li>Vibrations usually cause high acceleration values and produce &#8220;echoes&#8221;, so the data sheet recommends 3 g as a starting value.<\/li>\n<\/ul>\n<\/li>\n<li>duration is the maximum duration of the tap in milliseconds. The datasheet recommends values greater than 10 ms. The maximum is 159 ms.<\/li>\n<li>latent is the latency in milliseconds. It should be larger than 20 ms. The maximum is 318 ms.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>You already know the function <code>getActTapStatusAsString()<\/code> from ADXL345_activity_inactivity.ino. Here it now returns the axis responsible for the tap interrupt or, if necessary, several.<\/p>\n<\/p>\n<div class=\"scroll-paragraph\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"ADXL345_single_tap.ino\" data-enlighter-title=\"ADXL345_single_tap.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 tap = 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 - Single Tap 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_200);\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_8G);\n  Serial.print(\"  \/  g-Range: \");\n  Serial.println(myAcc.getRangeAsString());\n  Serial.println();\n\n  attachInterrupt(digitalPinToInterrupt(int2Pin), tapISR, RISING);\n  \n\/* The following four parameters have to be set for tap application (single and double):\n    1. Axes, that are considered:\n        ADXL345_000  -  no axis (which makes no sense)\n        ADXL345_00Z  -  z \n        ADXL345_0Y0  -  y\n        ADXL345_0YZ  -  y,z\n        ADXL345_X00  -  x\n        ADXL345_X0Z  -  x,z\n        ADXL345_XY0  -  x,y\n        ADXL345_XYZ  -  all axes\n    2. Threshold in g\n        It is recommended to not choose the value to low. 3g is a good starting point. \n    3. Duration in milliseconds (max 159 ms): \n        maximum time that the acceleration must be over g threshold to be regarded as a single tap. If \n        the acceleration drops below the g threshold before the duration is exceeded an interrupt will be \n        triggered. If also double tap is active an interrupt will only be triggered after the double tap \n        conditions have been checked. Duration should be greater than 10. \n    4. Latency time in milliseconds (maximum: 318 ms): minimum time before the next tap can be detected.\n        Starts at the end of duration or when the interrupt was triggered. Should be greater than 20 ms.  \n*\/\n  myAcc.setGeneralTapParameters(ADXL345_XY0, 3.0, 30, 100.0);\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_SINGLE_TAP, INT_PIN_2); \n  myAcc.readAndClearInterrupts();\n}\n\n\/* In the main loop some checks are done:\n    getActTapStatus() returns which axes are resposible activity interrupt as byte (code in library)\n    getActTapStatusAsString() returns the axes that caused the interrupt as string\n    readAndClearInterrupts(); return the interrupt type as byte (code in library) \n    checkInterrupt(intSource, type) returns if intSource is type as bool  \n*\/\nvoid loop() {\n  if ((millis() % 1000) == 1) {\n    xyzFloat g;\n    myAcc.getGValues(&amp;g);\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\n  if(tap == true) {\n      \/\/byte actTapSource = myAcc.getActTapStatus();\n      \/\/Serial.println(actTapSource, BIN);\n      String axes = myAcc.getActTapStatusAsString();\n      byte intSource = myAcc.readAndClearInterrupts();\n      if(myAcc.checkInterrupt(intSource, ADXL345_SINGLE_TAP)){\n        Serial.print(\"TAP at: \");\n        Serial.println(axes);\n      }\n    \n    delay(1000);\n    myAcc.readAndClearInterrupts();\n    tap = false;\n  }\n}\n\nvoid tapISR() {\n  tap = true;\n}<\/pre>\n<p>\u00a0<\/p>\n<\/div>\n<p>\n\n<h4 class=\"wp-block-heading\">Output of the Single Tap sketch<\/h4>\n\n<p>For the output below, I first tapped the module several times in the direction of the x-axis and then in the direction of the y-axis. By the way, the measurement output has no deeper meaning. That&#8217;s just so it doesn&#8217;t get boring in between.<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/01\/single_tap_output.png\"><img loading=\"lazy\" decoding=\"async\" width=\"716\" height=\"452\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/01\/single_tap_output.png\" alt=\"ADXL345 example sketch:&#10;Output of ADXL345_single_tap.ino\" class=\"wp-image-10587\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/01\/single_tap_output.png 716w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/01\/single_tap_output-300x189.png 300w\" sizes=\"auto, (max-width: 716px) 100vw, 716px\" \/><\/a><figcaption class=\"wp-element-caption\">Edition of ADXL345 single_tap.ino<\/figcaption><\/figure>\n\n<h3 class=\"wp-block-heading\">Example sketch 11: ADXL345_double_tap.ino<\/h3>\n\n<p>For Double Tap detection, you first define the general parameters as for the Singles Taps. Then you set two more parameters for the Double Taps:<\/p>\n<ul>\n<li><code>setAdditionalDoubleTapParameters(suppress, window)<\/code>\n<ul>\n<li>suppress is true or false and determines whether the suppress bit is set. If the suppress bit is set, then a second tap within the latency of the first tap invalidates the Double Tap condition. All right? If not, then go to the <a href=\"https:\/\/www.analog.com\/media\/en\/technical-documentation\/data-sheets\/ADXL345.pdf\" target=\"_blank\" rel=\"noopener\">data sheet<\/a>. There is a graphic on page 29 that should make things clearer.&nbsp;<\/li>\n<li>window sets the time window in which the second tap must take place in order to be counted as a double tap. The maximum is 318 ms.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>In the example sketch I activated both the Single and the Double Tap Interrupt. Since there can be two different interrupts, it is necessary to check which interrupt was triggered.<\/p>\n<p>The purpose of single and double tap detection is to look for characteristic shocks or vibrations. However, this requires a lot of trying out. Just play with the parameters.<\/p>\n\n<h4 class=\"wp-block-heading\">Output of the Double Tap sketch <\/h4>\n\n<p>This is what an output might look like:<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/01\/double_tap_output.png\"><img loading=\"lazy\" decoding=\"async\" width=\"716\" height=\"452\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/01\/double_tap_output.png\" alt=\"ADXL345 example sketch:&#10;Output of ADXL345_double_tap.ino\" class=\"wp-image-10591\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/01\/double_tap_output.png 716w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/01\/double_tap_output-300x189.png 300w\" sizes=\"auto, (max-width: 716px) 100vw, 716px\" \/><\/a><figcaption class=\"wp-element-caption\">Output of ADXL345 double_tap.ino<\/figcaption><\/figure>\n\n<p>In this example, I tapped the ADXL345 twice in quick succession in the direction of the x-axis.<\/p>\n\n<h2 class=\"wp-block-heading\">FIFO Functions<\/h2>\n\n<p>The FIFO buffer is a kind of recording device for measured values. This allows you to track very fast events at a measurement frequency of 3200 Hz, for example. Or you can analyze what happens before, around or after a particular event (activity or tap).<\/p>\n<p>The FIFO has space for up to 32 measured values, namely full x,y,z data sets. You can select the number. FIFO stands for &#8220;first in, first out&#8221;, i.e. the measured values that are stored first are read first. Reading of the FIFO works like normal reading of measured values. However, the data registers are not supplied with fresh readings, but from the FIFO.<\/p>\n<p>There are four modes of operation:<\/p>\n<ul>\n<li><strong>Bypass:<\/strong>FIFO is <strong>disabled<\/strong>, which is the default. The measured values are written to the data registers, and new measured values overwrite the old ones.<\/li>\n<li><strong>FIFO<\/strong>: you give the <strong>go-ahead<\/strong> to record the values. When the buffer contains the number of measured values you have defined, recording ends.  The ADXL345 triggers the Watermark interrupt. It is a bit confusing that one of the FIFO modes is also called FIFO.<\/li>\n<li><strong>Stream<\/strong>: as the name suggests, values are permanently written to the buffer. When the FIFO is full, values continue to be pushed in, and the oldest ones are pushed out. You define the <strong>end<\/strong> of the measured value recording.<\/li>\n<li><strong>Trigger<\/strong>: Measurements are permanently recorded as in Stream mode. If you choose an event (= trigger, interrupt), only the number of values you have defined remains in the FIFO. Then, however, the FIFO is filled up with new readings up to 32. Then the process ends. So, you can set the <strong>middle<\/strong> of a measured value recording in the Trigger mode.<\/li>\n<\/ul>\n\n<h3 class=\"wp-block-heading\">Example sketch 12: ADXL345_fifo_fifo.ino<\/h3>\n\n<p>The following new functions are used:<\/p>\n<ul>\n<li><code>setFifoParameters(TriggerIntPin, number)<\/code>\n<ul>\n<li>The TriggerIntPin only comes into play for the trigger mode. In this example, it doesn&#8217;t matter which parameter you choose.<\/li>\n<li>number sets the maximum number of measured values in the FIFO.<\/li>\n<\/ul>\n<\/li>\n<li><code>setFifoModes(mode)<\/code> <br><ul>\n<li>With mode, you set &#8211; guess what &#8211; the FIFO mode.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>The setting of FIFO mode is therefore simple. The other settings to make sure the whole thing works are a bit more complex. In particular, interrupts offer many possibilities for errors. It is important to follow the correct sequence.<\/p>\n<p>A few notes for example:<\/p>\n<ul>\n<li>I set the measuring frequency at 6.25 Hz quite low. With 32 measured values it takes about 5 seconds until the FIFO is full. Enough time to tilt the ADXL345 slowly, for example.<\/li>\n<li>I deactivated all measurements until the beginning of the FIFO recording.<\/li>\n<li>The measurements are started with a countdown. Of course, you can also take something other than such a starting shot, for example an interrupt.<\/li>\n<li>The Watermark interrupt is assigned to INT2. It signals the end of the measurement.<\/li>\n<li>At the end of the measurement, I output 34 x,y,z value triples. This is more than the FIFO buffer contains. I just want to show that nothing happens after the 32nd value triplet.<\/li>\n<\/ul>\n<\/p>\n<div class=\"scroll-paragraph\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"ADXL345_fifo_fifo.ino\" data-enlighter-title=\"ADXL345_fifo_fifo.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 event = 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 - FIFO - Fifo Mode\");\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_3_13);\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_4G);\n  Serial.print(\"  \/  g-Range: \");\n  Serial.println(myAcc.getRangeAsString());\n  Serial.println();\n\n\/* Stop the measure mode - no new data will be obtained *\/\n  myAcc.setMeasureMode(false);\n  attachInterrupt(digitalPinToInterrupt(int2Pin), eventISR, RISING);\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_WATERMARK, INT_PIN_2); \/\/ Interrupt when FIFO is full\n  \n\/* The following two FIFO parameters need to be set:\n    1. Trigger Bit: not relevant for this FIFO mode.\n    2. FIFO samples (max 32). Defines the size of the FIFO. One sample is an x,y,z triple.\n*\/\n  myAcc.setFifoParameters(ADXL345_TRIGGER_INT_1, 32);\n\n\/* You can choose the following FIFO modes:\n    ADXL345_FIFO     -  you choose the start, ends when FIFO is full (at defined limit)\n    ADXL345_STREAM   -  FIFO always filled with new data, old data replaced if FIFO is full; you choose the stop\n    ADXL345_TRIGGER  -  FIFO always filled up to 32 samples; when the trigger event occurs only defined number of samples\n                        is kept in the FIFO and further samples are taken after the event until FIFO is full again. \n    ADXL345_BYPASS   -  no FIFO\n*\/   \n  myAcc.setFifoMode(ADXL345_FIFO); \n  myAcc.readAndClearInterrupts();\n}\n\nvoid loop() {\n  event = false; \n  \n  countDown(); \/\/ as an alternative you could define any other event to start to fill the FIFO\n  myAcc.readAndClearInterrupts();\n  myAcc.setMeasureMode(true); \/\/ this is the actual start\n  while(!event){}  \/\/ event = true means WATERMARK interrupt triggered -&gt; means FIFO is full\n  myAcc.setMeasureMode(false);\n  Serial.println(\"FiFo full\");\n  \n  for(int i=0; i&lt;34; i++){ \/\/ this is &gt; 32 samples, but I want to show that the values do not change when FIFO is full\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  Serial.println(\"For another series of measurements, enter any key and send\");\n  \n  while(!(Serial.available())){}\n  Serial.read();\n  Serial.println();\n}\n\nvoid eventISR() {\n  event = true;\n}\n\nvoid countDown(){\n  Serial.println(\"Move your ADXL345 to obtain interesting data\");\n  Serial.println();\n  delay(1000);\n  Serial.print(\"Fifo collection begins in 3, \"); \n  delay(1000);\n  Serial.print(\"2, \"); \n  delay(1000);\n  Serial.print(\"1, \"); \n  delay(1000);\n  Serial.println(\"Now!\");\n}\n<\/pre>\n<p>\u00a0<\/p>\n<\/div>\n<p>\n\n<h4 class=\"wp-block-heading\">Output of the FIFO FIFO Sketch<\/h4>\n\n<p>For the output shown below, I slowly rotated the ADXL345 around the y-axis (i.e. the x and z values vary).<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/02\/fifo_fifo_output_32.png\"><img loading=\"lazy\" decoding=\"async\" width=\"889\" height=\"768\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/02\/fifo_fifo_output_32.png\" alt=\"Output of ADXL345 fifo_fifo.ino\" class=\"wp-image-11039\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/02\/fifo_fifo_output_32.png 889w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/02\/fifo_fifo_output_32-300x259.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/02\/fifo_fifo_output_32-768x663.png 768w\" sizes=\"auto, (max-width: 889px) 100vw, 889px\" \/><\/a><figcaption class=\"wp-element-caption\">Output of ADXL345 fifo_fifo.ino<\/figcaption><\/figure>\n\n<h3 class=\"wp-block-heading\">Example sketch 13: ADXL345_fifo_stream.ino<\/h3>\n\n<p>The example sketch does not use any new functions. A few comments:<\/p>\n<ul>\n<li><code>setFifoMode(ADXL345_STREAM)<\/code> sets the stream mode.<\/li>\n<li>As the event that ends the measurement recording, I have selected an Activity interrupt: 0.6 g on the x- or y-axis.<\/li>\n<li>The 32 measured values before the event occurs are stored in the FIFO.<\/li>\n<\/ul>\n<\/p>\n<div class=\"scroll-paragraph\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"ADXL345_fifo_stream.ino\" data-enlighter-title=\"ADXL345_fifo_stream.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 event = 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 - FIFO - Stream Mode\");\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_12_5);\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_4G);\n  Serial.print(\"  \/  g-Range: \");\n  Serial.println(myAcc.getRangeAsString());\n  Serial.println();\n\n  attachInterrupt(digitalPinToInterrupt(int2Pin), eventISR, RISING);\n\n \/* Three parameters have to be set for activity:\n    1. DC \/ AC Mode:\n        ADXL345_DC_MODE - Threshold is the defined one (parameter 3)\n        ADXL345_AC_MODE - Threshold = starting acceleration + defined threshold\n    2. Axes, that are considered:\n        ADXL345_000  -  no axis (which makes no sense)\n        ADXL345_00Z  -  z \n        ADXL345_0Y0  -  y\n        ADXL345_0YZ  -  y,z\n        ADXL345_X00  -  x\n        ADXL345_X0Z  -  x,z\n        ADXL345_XY0  -  x,y\n        ADXL345_XYZ  -  all axes\n    3. Threshold in g\n*\/\n  myAcc.setActivityParameters(ADXL345_DC_MODE, ADXL345_XY0, 0.6);\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_ACTIVITY, INT_PIN_2);\n\n\/* The following two FIFO parameters need to be set:\n    1. Trigger Bit: not relevant for this FIFO mode.\n    2. FIFO samples (max 32). Defines the size of the FIFO. One sample is an x,y,z triple.\n*\/\n  myAcc.setFifoParameters(ADXL345_TRIGGER_INT_1, 32);\n \n \/* You can choose the following FIFO modes:\n    ADXL345_FIFO     -  you choose the start, ends when FIFO is full (at defined limit)\n    ADXL345_STREAM   -  FIFO always filled with new data, old data replaced if FIFO is full; you choose the stop\n    ADXL345_TRIGGER  -  FIFO always filled up to 32 samples; when the trigger event occurs only defined number of samples\n                        is kept in the FIFO and further samples are taken after the event until FIFO is full again. \n    ADXL345_BYPASS   -  no FIFO\n*\/     \n  myAcc.setFifoMode(ADXL345_STREAM);\n  \n  myAcc.readAndClearInterrupts();\n\n  Serial.println(\"Waiting for Activity Event - I propose to slowly turn the ADXL345\");\n}\n\n\/* In the main loop some checks are done:\n    getActTapStatus() returns which axes are responsible for activity interrupt as byte (code in library)\n    getActTapStatusAsString() returns the axes that caused the interrupt as string\n    readAndClearInterrupts(); returns the interrupt type as byte (code in library) \n    checkInterrupt(intSource, type) returns if intSource is type as bool  \n*\/\n\nvoid loop() {\n  if(event){\n    myAcc.setMeasureMode(false);\n    \/\/byte actTapSource = myAcc.getActTapStatus();\n    \/\/Serial.println(actTapSource, BIN);\n    String axes = myAcc.getActTapStatusAsString();\n    byte intSource = myAcc.readAndClearInterrupts();\n    if(myAcc.checkInterrupt(intSource, ADXL345_ACTIVITY)){\n        Serial.print(\"ACT at: \");\n        Serial.println(axes);\n    }\n    printFifo();\n    Serial.println(\"For another series of measurements, enter any key and send\");\n    while(!(Serial.available())){}\n    Serial.read();\n    Serial.println();\n    Serial.println(\"Waiting for Activity Event\");\n  \n    event = false;\n    myAcc.readAndClearInterrupts();\n    myAcc.setMeasureMode(true);\n  }\n}\n\nvoid eventISR() {\n  event = true;\n}\n\nvoid printFifo(){\n  for(int i=0; i&lt;32; 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}\n<\/pre>\n<p>\u00a0<\/p>\n<\/div>\n<p>\n\n<h4 class=\"wp-block-heading\">Output of THE FIFO Stream Sketch<\/h4>\n\n<p>Again, I slowly turned the ADXL345 around the y-axis.<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/02\/fifo_stream_output_32.png\"><img loading=\"lazy\" decoding=\"async\" width=\"889\" height=\"739\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/02\/fifo_stream_output_32.png\" alt=\"Issue of ADXL345 fifo_stream.ino\" class=\"wp-image-11041\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/02\/fifo_stream_output_32.png 889w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/02\/fifo_stream_output_32-300x249.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/02\/fifo_stream_output_32-768x638.png 768w\" sizes=\"auto, (max-width: 889px) 100vw, 889px\" \/><\/a><figcaption class=\"wp-element-caption\">Issue of ADXL345 fifo_stream.ino<\/figcaption><\/figure>\n\n<h3 class=\"wp-block-heading\">Example sketch 14: ADXL345_fifo_trigger.ino<\/h3>\n\n<p>And now to the last example sketch. Here, the recording of FIFO data is controlled by a trigger. For this, I come back to the following function:<\/p>\n<ul>\n<li><code>setFifoParameters(TriggerIntPin, number)<\/code>\n<ul>\n<li>TriggerIntPin is set to INT1 or INT2. An interrupt on the selected pin is the trigger for the FIFO recording. You have to select an interrupt that you assign to this pin. Again, I have selected the Activity interrupt.<\/li>\n<li>number should be somewhere between 1 and 32. If you choose 32, that would be similar to Stream mode. If you choose 1, you might as well choose the fifo FIFO mode. For the example, I chose 15.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>The question arises as to how to detect the completion of the measurements. Basically, this would work with the Watermark interrupt. However, if we assign this to INT2, we may get confused with the Activity interrupt. And if we assign it to INT1, then there may be problems with the Data Ready interrupt, which, stupidly, cannot be turned off. A pragmatic solution would be a simple delay which length would have to be adapted to the measuring frequency. Fortunately, the number of values present in the FIFO can be queried. The getFifoStatus() function returns the content of the FIFO status register. Its bits 0 to 5 contain the number of values in the FIFO. If bit 5 is set, there are 2<sup>5<\/sup> = 32 measured values in the FIFO. This results in <sup><br><\/sup><\/p>\n<p>FIFO is full when <code>(getFifoStatus() &amp; 32) == true<\/code>.<\/p>\n<\/p>\n<div class=\"scroll-paragraph\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"ADXL345_fifo_trigger.ino\" data-enlighter-title=\"ADXL345_fifo_trigger.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 event = 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 - FIFO - Trigger Mode\");\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_12_5);\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_4G);\n  Serial.print(\"  \/  g-Range: \");\n  Serial.println(myAcc.getRangeAsString());\n  Serial.println();\n\n  attachInterrupt(digitalPinToInterrupt(int2Pin), eventISR, RISING);\n  \n\/* Three parameters have to be set for activity:\n    1. DC \/ AC Mode:\n        ADXL345_DC_MODE - Threshold is the defined one (parameter 3)\n        ADXL345_AC_MODE - Threshold = starting acceleration + defined threshold\n    2. Axes, that are considered:\n        ADXL345_000  -  no axis (which makes no sense)\n        ADXL345_00Z  -  z \n        ADXL345_0Y0  -  y\n        ADXL345_0YZ  -  y,z\n        ADXL345_X00  -  x\n        ADXL345_X0Z  -  x,z\n        ADXL345_XY0  -  x,y\n        ADXL345_XYZ  -  all axes\n    3. Threshold in g\n*\/\n  myAcc.setActivityParameters(ADXL345_DC_MODE, ADXL345_XY0, 0.6);\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_ACTIVITY, INT_PIN_2);\n\n\/* The following two FIFO parameters need to be set:\n    1. Trigger Bit: the trigger is an interrupt at INT1 or INT2\n        ADXL345_TRIGGER_INT_1 - Trigger is an interrupt at INT1\n        ADXL345_TRIGGER_INT_2 - Trigger is an interrupt at INT2\n    2. FIFO samples (max 32). Defines the size of the FIFO. One sample is an x,y,z triple.\n*\/\n  myAcc.setFifoParameters(ADXL345_TRIGGER_INT_2, 15);\n  \n\/* You can choose the following FIFO modes:\n    ADXL345_FIFO     -  you choose the start, ends when FIFO is full (at defined limit)\n    ADXL345_STREAM   -  FIFO always filled with new data, old data replaced if FIFO is full; you choose the stop\n    ADXL345_TRIGGER  -  FIFO always filled up to 32 samples; when the trigger event occurs only defined number of samples\n                        is kept in the FIFO and further samples are taken after the event until FIFO is full again. \n    ADXL345_BYPASS   -  no FIFO\n*\/       \n  myAcc.setFifoMode(ADXL345_TRIGGER);\n\n  myAcc.readAndClearInterrupts();\n\n  Serial.println(\"Waiting for Activity Event\");\n}\n\n\/* In the main loop some checks are done:\n    getActTapStatus() returns which axes are responsible for activity interrupt as byte (code in library)\n    getActTapStatusAsString() returns the axes that caused the interrupt as string\n    readAndClearInterrupts(); returns the interrupt type as byte (code in library) \n    checkInterrupt(intSource, type) returns if intSource is type as bool  \n*\/\nvoid loop() {\n  \n  if(event){\n    String axes = myAcc.getActTapStatusAsString();\n    byte intSource = myAcc.readAndClearInterrupts();\n    if(myAcc.checkInterrupt(intSource, ADXL345_ACTIVITY)){\n        Serial.print(\"Activity at: \");\n        Serial.println(axes);\n    }\n    while(!(myAcc.getFifoStatus() &amp; 32)){}\n    printFifo();\n    \n    Serial.println(\"For another series of measurements, enter any key and send\");\n    while(!(Serial.available())){}\n    Serial.read();\n    Serial.println();\n    myAcc.readAndClearInterrupts();\n    myAcc.resetTrigger();\n    Serial.println(\"Waiting for Activity Event\");\n    event = false;\n  }\n}\n\nvoid eventISR() {\n  event = true;\n}\n\nvoid printFifo(){\n  for(int i=0; i&lt;32; 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}\n<\/pre>\n<p>\u00a0<\/p>\n<\/div>\n<p>\n\n<h4 class=\"wp-block-heading\">Output of THE FIFO Trigger Sketch<\/h4>\n\n<p>For the output below, I rotated the ADXL345 around the y-axis until the activity interrupt was triggered and then turned it back. You can see that the measured value responsible for the Activity interrupt is in the middle of the FIFO values.<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/02\/fifo_trigger_output_32.png\"><img loading=\"lazy\" decoding=\"async\" width=\"889\" height=\"739\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/02\/fifo_trigger_output_32.png\" alt=\"Output of ADXL345 fifo_trigger.ino\" class=\"wp-image-11043\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/02\/fifo_trigger_output_32.png 889w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/02\/fifo_trigger_output_32-300x249.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2021\/02\/fifo_trigger_output_32-768x638.png 768w\" sizes=\"auto, (max-width: 889px) 100vw, 889px\" \/><\/a><figcaption class=\"wp-element-caption\">Output of ADXL345 fifo_trigger.ino<\/figcaption><\/figure>\n\n<p>At this measurement frequency, this is just a gimmick. It becomes interesting if you change to high measuring frequencies and analyze a tap event in more detail, for example. &nbsp;<\/p>\n\n<h2 class=\"wp-block-heading\">Closing words<\/h2>\n\n<p>Creating the library and example sketches was a pretty tough job due to the versatility of this component. I hope it was worth it and some people use the library. Bugs are not only not excluded in such a project, but almost inevitable. If you discover something or if you miss features, please get in touch. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the second part of my article about the ADXL345 and my library I go into Activity\/Inactivity, Single and Double Taps and FIFO. <\/p>\n","protected":false},"author":1,"featured_media":10340,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[919,572],"tags":[1337,1340,2692,1358,1354,1351,1352,1360,1224],"class_list":["post-10883","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-acceleration","category-sensors","tag-accelerometer-en-2","tag-accelerometer-en-3","tag-adxl343-en","tag-arduino-library","tag-double-tap-en-2","tag-fifo-en","tag-single-tap-en","tag-stream-en","tag-triggered-en"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>ADXL345 - The Universal Accelerometer - Part 2 &#8226; Wolles Elektronikkiste<\/title>\n<meta name=\"description\" content=\"In the second part of my article about the ADXL345 and my library I go into Activity\/Inactivity, Single and Double Taps and FIFO.\" \/>\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-2\" \/>\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 2 &#8226; Wolles Elektronikkiste\" \/>\n<meta property=\"og:description\" content=\"In the second part of my article about the ADXL345 and my library I go into Activity\/Inactivity, Single and Double Taps and FIFO.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-2\" \/>\n<meta property=\"og:site_name\" content=\"Wolles Elektronikkiste\" \/>\n<meta property=\"article:published_time\" content=\"2021-01-20T22:41:07+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-09-17T17:02:17+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=\"35 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-2#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/adxl345-the-universal-accelerometer-part-2\"},\"author\":{\"name\":\"Wolfgang Ewald\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\"},\"headline\":\"ADXL345 &#8211; The Universal Accelerometer &#8211; Part 2\",\"datePublished\":\"2021-01-20T22:41:07+00:00\",\"dateModified\":\"2025-09-17T17:02:17+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/adxl345-the-universal-accelerometer-part-2\"},\"wordCount\":2286,\"commentCount\":54,\"publisher\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\"},\"image\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/adxl345-the-universal-accelerometer-part-2#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/Beitragsbild.jpg\",\"keywords\":[\"accelerometer\",\"accelerometer\",\"ADXL343\",\"Arduino library\",\"double tap\",\"FIFO\",\"single tap\",\"stream\",\"triggered\"],\"articleSection\":[\"Acceleration\",\"Sensors\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/adxl345-the-universal-accelerometer-part-2#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/adxl345-the-universal-accelerometer-part-2\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/adxl345-the-universal-accelerometer-part-2\",\"name\":\"ADXL345 - The Universal Accelerometer - Part 2 &#8226; Wolles Elektronikkiste\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/adxl345-the-universal-accelerometer-part-2#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/adxl345-the-universal-accelerometer-part-2#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/Beitragsbild.jpg\",\"datePublished\":\"2021-01-20T22:41:07+00:00\",\"dateModified\":\"2025-09-17T17:02:17+00:00\",\"description\":\"In the second part of my article about the ADXL345 and my library I go into Activity\\\/Inactivity, Single and Double Taps and FIFO.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/adxl345-the-universal-accelerometer-part-2#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/adxl345-the-universal-accelerometer-part-2\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/adxl345-the-universal-accelerometer-part-2#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-2#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 2\"}]},{\"@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 2 &#8226; Wolles Elektronikkiste","description":"In the second part of my article about the ADXL345 and my library I go into Activity\/Inactivity, Single and Double Taps and FIFO.","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-2","og_locale":"en_US","og_type":"article","og_title":"ADXL345 - The Universal Accelerometer - Part 2 &#8226; Wolles Elektronikkiste","og_description":"In the second part of my article about the ADXL345 and my library I go into Activity\/Inactivity, Single and Double Taps and FIFO.","og_url":"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-2","og_site_name":"Wolles Elektronikkiste","article_published_time":"2021-01-20T22:41:07+00:00","article_modified_time":"2025-09-17T17:02:17+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":"35 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-2#article","isPartOf":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-2"},"author":{"name":"Wolfgang Ewald","@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46"},"headline":"ADXL345 &#8211; The Universal Accelerometer &#8211; Part 2","datePublished":"2021-01-20T22:41:07+00:00","dateModified":"2025-09-17T17:02:17+00:00","mainEntityOfPage":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-2"},"wordCount":2286,"commentCount":54,"publisher":{"@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46"},"image":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-2#primaryimage"},"thumbnailUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/Beitragsbild.jpg","keywords":["accelerometer","accelerometer","ADXL343","Arduino library","double tap","FIFO","single tap","stream","triggered"],"articleSection":["Acceleration","Sensors"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-2#respond"]}]},{"@type":"WebPage","@id":"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-2","url":"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-2","name":"ADXL345 - The Universal Accelerometer - Part 2 &#8226; Wolles Elektronikkiste","isPartOf":{"@id":"https:\/\/wolles-elektronikkiste.de\/en#website"},"primaryImageOfPage":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-2#primaryimage"},"image":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-2#primaryimage"},"thumbnailUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2020\/12\/Beitragsbild.jpg","datePublished":"2021-01-20T22:41:07+00:00","dateModified":"2025-09-17T17:02:17+00:00","description":"In the second part of my article about the ADXL345 and my library I go into Activity\/Inactivity, Single and Double Taps and FIFO.","breadcrumb":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-2#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-2"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/wolles-elektronikkiste.de\/en\/adxl345-the-universal-accelerometer-part-2#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-2#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 2"}]},{"@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\/10883","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=10883"}],"version-history":[{"count":6,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts\/10883\/revisions"}],"predecessor-version":[{"id":24885,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts\/10883\/revisions\/24885"}],"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=10883"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/categories?post=10883"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/tags?post=10883"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}