/** * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. * * SPDX-License-Identifier: BSD-3-Clause */ #include #include #include "pico/stdlib.h" #include "pico/binary_info.h" #include "hardware/i2c.h" /* Example code to talk to a LIS3DH Mini GPS module. This example reads data from all 3 axes of the accelerometer and uses an auxillary ADC to output temperature values. Connections on Raspberry Pi Pico board, other boards may vary. GPIO PICO_DEFAULT_I2C_SDA_PIN (On Pico this is 4 (physical pin 6)) -> SDA on LIS3DH board GPIO PICO_DEFAULT_I2C_SCK_PIN (On Pico this is 5 (physical pin 7)) -> SCL on LIS3DH board 3.3v (physical pin 36) -> VIN on LIS3DH board GND (physical pin 38) -> GND on LIS3DH board */ // By default this device is on bus address 0x18 const int ADDRESS = 0x18; const uint8_t CTRL_REG_1 = 0x20; const uint8_t CTRL_REG_4 = 0x23; const uint8_t TEMP_CFG_REG = 0xC0; #ifdef i2c_default void lis3dh_init() { uint8_t buf[2]; // Turn normal mode and 1.344kHz data rate on buf[0] = CTRL_REG_1; buf[1] = 0x97; i2c_write_blocking(i2c_default, ADDRESS, buf, 2, false); // Turn block data update on (for temperature sensing) buf[0] = CTRL_REG_4; buf[1] = 0x80; i2c_write_blocking(i2c_default, ADDRESS, buf, 2, false); // Turn auxillary ADC on buf[0] = TEMP_CFG_REG; buf[1] = 0xC0; i2c_write_blocking(i2c_default, ADDRESS, buf, 2, false); } void lis3dh_calc_value(uint16_t raw_value, float *final_value, bool isAccel) { // Convert with respect to the value being temperature or acceleration reading float scaling; float senstivity = 0.004f; // g per unit if (isAccel == true) { scaling = 64 / senstivity; } else { scaling = 64; } // raw_value is signed *final_value = (float) ((int16_t) raw_value) / scaling; } void lis3dh_read_data(uint8_t reg, float *final_value, bool IsAccel) { // Read two bytes of data and store in a 16 bit data structure uint8_t lsb; uint8_t msb; uint16_t raw_accel; i2c_write_blocking(i2c_default, ADDRESS, ®, 1, true); i2c_read_blocking(i2c_default, ADDRESS, &lsb, 1, false); reg |= 0x01; i2c_write_blocking(i2c_default, ADDRESS, ®, 1, true); i2c_read_blocking(i2c_default, ADDRESS, &msb, 1, false); raw_accel = (msb << 8) | lsb; lis3dh_calc_value(raw_accel, final_value, IsAccel); } #endif int main() { stdio_init_all(); #if !defined(i2c_default) || !defined(PICO_DEFAULT_I2C_SDA_PIN) || !defined(PICO_DEFAULT_I2C_SCL_PIN) #warning i2c/lis3dh_i2c example requires a board with I2C pins puts("Default I2C pins were not defined"); #else printf("Hello, LIS3DH! Reading raw data from registers...\n"); // This example will use I2C0 on the default SDA and SCL pins (4, 5 on a Pico) i2c_init(i2c_default, 400 * 1000); gpio_set_function(PICO_DEFAULT_I2C_SDA_PIN, GPIO_FUNC_I2C); gpio_set_function(PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C); gpio_pull_up(PICO_DEFAULT_I2C_SDA_PIN); gpio_pull_up(PICO_DEFAULT_I2C_SCL_PIN); // Make the I2C pins available to picotool bi_decl(bi_2pins_with_func(PICO_DEFAULT_I2C_SDA_PIN, PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C)); float x_accel, y_accel, z_accel, temp; lis3dh_init(); while (1) { lis3dh_read_data(0x28, &x_accel, true); lis3dh_read_data(0x2A, &y_accel, true); lis3dh_read_data(0x2C, &z_accel, true); lis3dh_read_data(0x0C, &temp, false); // Display data printf("TEMPERATURE: %.3f%cC\n", temp, 176); // Acceleration is read as a multiple of g (gravitational acceleration on the Earth's surface) printf("ACCELERATION VALUES: \n"); printf("X acceleration: %.3fg\n", x_accel); printf("Y acceleration: %.3fg\n", y_accel); printf("Z acceleration: %.3fg\n", z_accel); sleep_ms(500); // Clear terminal printf("\e[1;1H\e[2J"); } #endif return 0; }