# Motion sensor

The motion sensor extension board is based on the **LIS3DHTR** by STMicroelectronics. The sensor uses I2C to communicate with the Picoclick (SDA = GPIO2, SCL = GPIO8). It has an ultra low power voltage regulator on board and can be used to activate the Picoclick by firing an interrupt. The interrupt can be configured via software.

## Hardware

### Overview

<figure><img src="https://3814073947-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8e8Y0oYz6ujS2c1GD1Qy%2Fuploads%2FupuvUUcCf5VAzIkKCfFW%2Fpc3_ext_motion.png?alt=media&#x26;token=ca6a8b1a-bdde-4a49-84ac-868ef529faa9" alt=""><figcaption></figcaption></figure>

### Technical drawing

<figure><img src="https://3814073947-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8e8Y0oYz6ujS2c1GD1Qy%2Fuploads%2FjoGSvzo3DKFk7YGtCek7%2Fpc3_ext_motion_techdraw.png?alt=media&#x26;token=26636b27-53f6-4a3d-9a40-82f8f52f0884" alt=""><figcaption><p>Measurements in mm, grid is 0.5mm</p></figcaption></figure>

* PCB: 18mm x 10mm
* Thickness: 1mm
* Mounting holes: 3.2mm
* Corner radius: 2mm

### Schematics

<figure><img src="https://3814073947-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8e8Y0oYz6ujS2c1GD1Qy%2Fuploads%2FdXZsjStOZwXqf8i1fNIV%2Fpc3_ext_lis3dh_schematics.png?alt=media&#x26;token=2608411e-01eb-4284-b2af-51e0abdd38c5" alt=""><figcaption></figcaption></figure>

## Software

Hardwaretest can be found on [GitHub](https://github.com/makermoekoe/Picoclick-C3/tree/main/code/Picoclick_C3/PC3_Hardwaretest_Motion).

```
#include <Arduino.h>
#include <WiFi.h>
#include <FastLED.h>
#include <SparkFunLIS3DH.h>
#include <Wire.h>
#include "config.h"

LIS3DH lis(I2C_MODE, 0x19); //Default constructor is I2C, addr 0x19.

void configIntterupts();

void setup(){
  pinMode(BUTTON_PIN, INPUT);
  pinMode(ADC_ENABLE_PIN, OUTPUT);
  pinMode(ADC_PIN, INPUT);
  analogReadResolution(12);
  digitalWrite(ADC_ENABLE_PIN, HIGH);

  btStop();
  WiFi.mode(WIFI_OFF);
  setCpuFrequencyMhz(10);

  FastLED.addLeds<APA102, APA102_SDI_PIN, APA102_CLK_PIN, BGR>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.setBrightness(160);
  delay(50);

  set_fastled(CRGB::Blue);

  Wire.begin(SDA_PIN, SCL_PIN);
  delay(100);

  lis.settings.accelSampleRate = 50;  //Hz.  Can be: 0,1,10,25,50,100,200,400,1600,5000 Hz
  lis.settings.accelRange = 2;      //Max G force readable.  Can be: 2, 4, 8, 16

  lis.settings.adcEnabled = 0;
  lis.settings.tempEnabled = 0;
  lis.settings.xAccelEnabled = 1;
  lis.settings.yAccelEnabled = 1;
  lis.settings.zAccelEnabled = 1;

  lis.begin();

  // int dataToWrite = B01001111;
  // lis.writeRegister(LIS3DH_CTRL_REG1, dataToWrite);
  
  // configIntterupts();
}

unsigned long t_sensor = millis();

void loop() {
  if(digitalRead(BUTTON_PIN) == 1){
    set_fastled(CRGB::Red);
    delay(500);
    esp_deep_sleep_start();
  }

  if(millis() >= t_sensor + 500){
    t_sensor = millis();
    float x = lis.readFloatAccelX();
    float y = lis.readFloatAccelY();
    float z = lis.readFloatAccelZ();
    printf("X: %f, Y: %f, Z: %f\r\n", x, y, z);
  }
}

void configIntterupts(){
  uint8_t dataToWrite = 0;

  // //LIS3DH_INT1_CFG   
  // //dataToWrite |= 0x80;//AOI, 0 = OR 1 = AND
  // //dataToWrite |= 0x40;//6D, 0 = interrupt source, 1 = 6 direction source
  // //Set these to enable individual axes of generation source (or direction)
  // // -- high and low are used generically
  // //dataToWrite |= 0x20;//Z high
  // //dataToWrite |= 0x10;//Z low
  // dataToWrite |= 0x08;//Y high
  // //dataToWrite |= 0x04;//Y low
  // //dataToWrite |= 0x02;//X high
  // //dataToWrite |= 0x01;//X low
  // lis.writeRegister(LIS3DH_INT1_CFG, dataToWrite);
  
  // //LIS3DH_INT1_THS   
  // dataToWrite = 0;
  // //Provide 7 bit value, 0x7F always equals max range by accelRange setting
  // dataToWrite |= 0x10; // 1/8 range
  // lis.writeRegister(LIS3DH_INT1_THS, dataToWrite);
  
  // //LIS3DH_INT1_DURATION  
  // dataToWrite = 0;
  // //minimum duration of the interrupt
  // //LSB equals 1/(sample rate)
  // dataToWrite |= 0x01; // 1 * 1/50 s = 20ms
  // lis.writeRegister(LIS3DH_INT1_DURATION, dataToWrite);
  
  //LIS3DH_CLICK_CFG   
  dataToWrite = 0;
  //Set these to enable individual axes of generation source (or direction)
  // -- set = 1 to enable
  //dataToWrite |= 0x20;//Z double-click
  dataToWrite |= 0x10;//Z click
  //dataToWrite |= 0x08;//Y double-click 
  dataToWrite |= 0x04;//Y click
  //dataToWrite |= 0x02;//X double-click
  dataToWrite |= 0x01;//X click
  lis.writeRegister(LIS3DH_CLICK_CFG, dataToWrite);
  
  //LIS3DH_CLICK_SRC
  dataToWrite = 0;
  //Set these to enable click behaviors (also read to check status)
  // -- set = 1 to enable
  //dataToWrite |= 0x20;//Enable double clicks
  dataToWrite |= 0x04;//Enable single clicks
  //dataToWrite |= 0x08;//sine (0 is positive, 1 is negative)
  dataToWrite |= 0x04;//Z click detect enabled
  dataToWrite |= 0x02;//Y click detect enabled
  dataToWrite |= 0x01;//X click detect enabled
  lis.writeRegister(LIS3DH_CLICK_SRC, dataToWrite);
  
  //LIS3DH_CLICK_THS   
  dataToWrite = 0;
  //This sets the threshold where the click detection process is activated.
  //Provide 7 bit value, 0x7F always equals max range by accelRange setting
  dataToWrite |= 0x0A; // ~1/16 range
  lis.writeRegister(LIS3DH_CLICK_THS, dataToWrite);
  
  //LIS3DH_TIME_LIMIT  
  dataToWrite = 0;
  //Time acceleration has to fall below threshold for a valid click.
  //LSB equals 1/(sample rate)
  dataToWrite |= 0x08; // 0x08: 8 * 1/50 s = 160ms
  lis.writeRegister(LIS3DH_TIME_LIMIT, dataToWrite);
  
  //LIS3DH_TIME_LATENCY
  dataToWrite = 0;
  //hold-off time before allowing detection after click event
  //LSB equals 1/(sample rate)
  dataToWrite |= 0x0F; // 4 * 1/50 s = 160ms, 
  lis.writeRegister(LIS3DH_TIME_LATENCY, dataToWrite);
  
  //LIS3DH_TIME_WINDOW 
  dataToWrite = 0;
  //hold-off time before allowing detection after click event
  //LSB equals 1/(sample rate)
  dataToWrite |= 0x8F; // 16 * 1/50 s = 320ms
  lis.writeRegister(LIS3DH_TIME_WINDOW, dataToWrite);

  //LIS3DH_CTRL_REG5
  //Int1 latch interrupt and 4D on  int1 (preserve fifo en)
  lis.readRegister(&dataToWrite, LIS3DH_CTRL_REG5);
  dataToWrite &= 0xF3; //Clear bits of interest
  dataToWrite |= 0x08; //Latch interrupt (Cleared by reading int1_src)
  //dataToWrite |= 0x04; //Pipe 4D detection from 6D recognition to int1?
  lis.writeRegister(LIS3DH_CTRL_REG5, dataToWrite);

  //LIS3DH_CTRL_REG3
  //Choose source for pin 1
  dataToWrite = 0;
  dataToWrite |= 0x80; //Click detect on pin 1
  // dataToWrite |= 0x40; //AOI1 event (Generator 1 interrupt on pin 1)
  // dataToWrite |= 0x20; //AOI2 event ()
  //dataToWrite |= 0x10; //Data ready
  //dataToWrite |= 0x04; //FIFO watermark
  //dataToWrite |= 0x02; //FIFO overrun
  lis.writeRegister(LIS3DH_CTRL_REG3, dataToWrite);
 
  // //LIS3DH_CTRL_REG6
  // //Choose source for pin 2 and both pin output inversion state
  // dataToWrite = 0;
  // // dataToWrite |= 0x80; //Click int on pin 2
  // // dataToWrite |= 0x40; //Generator 1 interrupt on pin 2
  // //dataToWrite |= 0x10; //boot status on pin 2
  // //dataToWrite |= 0x02; //invert both outputs
  // lis.writeRegister(LIS3DH_CTRL_REG6, dataToWrite);
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://makermoekoe.gitbook.io/picoclick-c3/extension-boards/motion-sensor.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
