ADXL345 tap detection

As I promised in my previous ADXL345 tutorial, today I am going to write about ADXL345 single and double tap functions. I already covered how to interface ADXL345 with STM32 and read the accelerations in different axes (i.e X, Y and Z), you can check that out by going to Today we will be covering the TAP functionality of this device.


In order to program the single and double taps, we need to write the following registers:-

  • POWER_CTL (0x2D) Register  for power saving features
  • TAP AXES (0x2A) Register for Axis control for tap/double tap
  • THRESH_TAP (0x1D) Register for Tap threshold
  • DUR (0x21) Register for Tap duration
  • LATENT (0x22) Register for Tap Latency
  • WINDOW (0x23) Register for Tap window in order to detect Double tap
  • INT_MAP (0x2F) Register for Interrupt mapping control
  • INT_ENABLE (0x2E) Register for Interrupt enable control
  • INT_SOURCE (0x30) Register for getting interrupt Source

After setting values to all registers, we will read the INT_SOURCE register and this will give us the source of interrupt i.e. whether it’s from single or double tap.

Some Insight into the CODE

void adxl_write (uint8_t reg, uint8_t value)
	uint8_t data[2];
	data[0] = reg;
	data[1] = value;
	HAL_I2C_Master_Transmit (&hi2c1, adxl_address, data, 2, 100);

uint8_t adxl_read(uint8_t reg)
	uint8_t data_rec;
    HAL_I2C_Mem_Read (&hi2c1, adxl_address, reg, 1, & data_rec, 1, 100);
    return data_rec;

These functions are from my previous tutorial and I am going to use these to write and read data to ADXL345.

Write the POWER_CTL register first to wake the ADXL345.

adxl_write (0x2d, 0x00);  // reset all bits

adxl_write (0x2d, 0x08);  // measure and wake up 8hz

Write the values to TAP AXES Register enabling only the tap detection in Z axis.

adxl_write (0x2A, 0x01);  // enable tap detection on Z axis

Set the TAP THRESHOLD to 2.5g. To do that we need to write 40 (2.5/.0625) to the THRESH_TAP Register. This means that you need at least 2.5g acceleration in Z AXIS in order for the tap to qualify as TAP.

adxl_write (0x1D, 40);  // set tap threshold 2.5g/.0625

Set the TAP DURATION to .02 sec and to do that we need to write 32 (.02/.000625) to the DUR Register. This value indicates maximum time that an event must be above the THRESH_TAP threshold to qualify as a tap event. 

adxl_write (0x21, 32);  // set tap duration .02 sec/.000625

Set the TAP LATENCY to .1 sec, write 80 (.1/.0125) to LATENT Register. This is the wait time from the detection of a tap event
to the start of the time window (defined by the window register) during which a possible second tap event can be detected.

adxl_write (0x22, 80);  // double tap latency .1sec/.00125

Set the TAP WINDOW to .3 sec by writing 240 (.3/.00125) to WINDOW register. This value representing the amount of time after the expiration of the latency time (determined by the latent register) during which a second valid tap can begin.

adxl_write (0x23, 240);  // double tap window .3sec/.00125

Enable the INT1 pin by writing 0 to INT_MAP Register. 

adxl_write (0x2F, 0x00);  // int map reg 0 means INT1

Next we will read the INT_SOURCE Register and analyse whether it was a single or double tap

data = adxl_read(0x30);

	  if ((data>>5)& 0x01) HAL_UART_Transmit(&huart2, display_double, sizeof (display_double),  10);  // double tap detected
	  else if ((data>>6) & 0x01) HAL_UART_Transmit(&huart2, display_single, sizeof (display_single),  10); // single tap


As you can see in the image below, on detection,  the single and double tap is being transmitted via UART.

Check out the VIDEO Below

Notify of
Inline Feedbacks
View all comments