Library 35- LIS302DL or LIS3DSH accelerometer
Maybe you’ve noticed one chip between four leds on STM32F4-Discovery board. This chip is accelerometer. On market, there are 2 versions of STM32F4-Discovery board. First release had LIS302DL (old board) and new release (current) has LIS3DSH device. LIS3DSH has 5 selectables full scales (2/4/6/8/16G), old LIS302DL has only 2 (2.3/9.2G).
I made a simple library which supports both devices. Library automatically recognize connected device, if there is any. You just have to check which is on board, because different devices have different possible settings. Both devices uses the same pinout on board. They use SPI for communication with STM32F4.
I have a new version of STM32F4-Discovery board, so LIS3DSH is in use. In that case i had to find someone who will test this for me. I found one, he is also very good with STM32F4 devices. His website is here.
Library
Features
- Supports LIS302DL accelerometer
- old STM32F4-Discovery boards
- Supports LIS3DSH accelerometer
- new STM32F4-Discovery boards
- Selectable full scales
- Supports sensor detection
Dependencies
- CMSIS
- STM32F4xx
- STM32F4xx RCC
- STM32F4xx GPIO
- STM32F4xx SPI
- TM
- TM SPI
- defines.h
- TM SPI
LIS302DL/LIS3DSH | STM32F4-Discovery | Description |
---|---|---|
MOSI | PA7 | Master out, Slave in for SPI1 |
MISO | PA6 | Master in, Slave out for SPI1 |
SCK | PA5 | Serial clock for SPI1 |
CS | PE3 | Chip select |
If you are working with custom application, and you want to use custom pinout, open defines.h file and edit settings:
1 2 3 4 5 6 7 8 |
/* Select custom SPI for accelerometer for your application */ //#define LIS302DL_LIS3DSH_SPI SPI1 //#define LIS302DL_LIS3DSH_SPI_PINSPACK TM_SPI_PinsPack_1 /* Select custom CS pin for accelerometer for your application */ //#define LIS302DL_LIS3DSH_CS_RCC RCC_AHB1Periph_GPIOE //#define LIS302DL_LIS3DSH_CS_PORT GPIOE //#define LIS302DL_LIS3DSH_CS_PIN GPIO_Pin_3 |
Remember: This library also works if you are working with custom application!
Functions and enumerations
New LIS3DSH is a little more powerful, has more selectable full scales and also high pass output filter. For that purpose you have more possible settings on initialization. Possible configuration with functions is described below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
/** * Typedef enumeration for returning from functions * * Parameters: * - TM_LIS302DL_LIS3DSH_Device_Error: * Returned from function when device is not recognized * - TM_LIS302DL_LIS3DSH_Device_LIS302DL: * Returned from functions when device is LIS302DL on old boards * - TM_LIS302DL_LIS3DSH_Device_LIS3DSH: * Returned from functions when device is LIS3DSH on new boards */ typedef enum { TM_LIS302DL_LIS3DSH_Device_Error, TM_LIS302DL_LIS3DSH_Device_LIS302DL, TM_LIS302DL_LIS3DSH_Device_LIS3DSH } TM_LIS302DL_LIS3DSH_Device_t; /** * Possible sensitivities for both devices * * Parameters: * - TM_LIS3DSH_Sensitivity_2G: * 2G sensitivity on LIS3DSH device * - TM_LIS3DSH_Sensitivity_4G: * 4G sensitivity on LIS3DSH device * - TM_LIS3DSH_Sensitivity_6G: * 6G sensitivity on LIS3DSH device * - TM_LIS3DSH_Sensitivity_8G: * 8G sensitivity on LIS3DSH device * - TM_LIS3DSH_Sensitivity_16G: * 16G sensitivity on LIS3DSH device * * - TM_LIS302DL_Sensitivity_2_3G: * 2.3G sensitivity on LIS3DSH device * - TM_LIS302DL_Sensitivity_9_2G: * 9.2G sensitivity on LIS3DSH device */ typedef enum { /* LIS3DSH */ TM_LIS3DSH_Sensitivity_2G, TM_LIS3DSH_Sensitivity_4G, TM_LIS3DSH_Sensitivity_6G, TM_LIS3DSH_Sensitivity_8G, TM_LIS3DSH_Sensitivity_16G, /* LIS302DL */ TM_LIS302DL_Sensitivity_2_3G, TM_LIS302DL_Sensitivity_9_2G } TM_LIS302DL_LIS3DSH_Sensitivity_t; /** * Filter values for both accelerometers * * Parameters: * - TM_LIS3DSH_Filter_800Hz: * 800 Hz high pass filter on LIS3DSH * - TM_LIS3DSH_Filter_400Hz: * 400 Hz high pass filter on LIS3DSH * - TM_LIS3DSH_Filter_200Hz: * 200 Hz high pass filter on LIS3DSH * - TM_LIS3DSH_Filter_50Hz: * 50 Hz high pass filter on LIS3DSH * * - TM_LIS302DL_Filter_2Hz: * 2 Hz filter on LIS302DL * - TM_LIS302DL_Filter_1Hz: * 1 Hz filter on LIS302DL * - TM_LIS302DL_Filter_500mHz: * 500 mHz filter on LIS302DL * - TM_LIS302DL_Filter_250mHz * 250 mHz filter on LIS302DL */ typedef enum { /* LIS3DSH */ TM_LIS3DSH_Filter_800Hz, TM_LIS3DSH_Filter_400Hz, TM_LIS3DSH_Filter_200Hz, TM_LIS3DSH_Filter_50Hz, /* LIS302DL */ TM_LIS302DL_Filter_2Hz, TM_LIS302DL_Filter_1Hz, TM_LIS302DL_Filter_500mHz, TM_LIS302DL_Filter_250mHz } TM_LIS302DL_LIS3DSH_Filter_t; /** * Data structure * * Parameters: * - int16_t X: * X axis value * - int16_t Y: * Y axis value * - int16_t Z: * Z axis value */ typedef struct { int16_t X; int16_t Y; int16_t Z; } TM_LIS302DL_LIS3DSH_t; /** * Detect LIS302DL or LIS3DSH device connected on F4-Discovery board * * Member of TM_LIS302DL_LIS3DSH_Device_t is returned */ extern TM_LIS302DL_LIS3DSH_Device_t TM_LIS302DL_LIS3DSH_Detect(void); /** * Initialize proper device * * Parameters: * - TM_LIS302DL_LIS3DSH_Sensitivity_t Sensitivity: * Select sensitivity for device. There are separate possible sensitivities for proper device * - TM_LIS302DL_LIS3DSH_Filter_t Filter: * Select filter for device. There are separate possible sensitivities for proper device * * Member of TM_LIS302DL_LIS3DSH_Device_t is returned */ extern TM_LIS302DL_LIS3DSH_Device_t TM_LIS302DL_LIS3DSH_Init(TM_LIS302DL_LIS3DSH_Sensitivity_t Sensitivity, TM_LIS302DL_LIS3DSH_Filter_t Filter); /** * Read axes from device * * Parameters: * - TM_LIS302DL_LIS3DSH_t* Axes_Data * Pointer to TM_LIS302DL_LIS3DSH_t struct * * Member of TM_LIS302DL_LIS3DSH_Device_t is returned */ extern TM_LIS302DL_LIS3DSH_Device_t TM_LIS302DL_LIS3DSH_ReadAxes(TM_LIS302DL_LIS3DSH_t* Axes_Data); |
Example
Below is simple example. You have to use STM32F4-Discovery board for this. It works like this:
- If LIS302DL device is detected, then RED and GREEN leds will be turned on for 2 seconds
- If LIS3DSH device is detected, then BLUE and ORANGE leds will be turned on for 2 seconds
- If all 4 leds are on, there was an error, because device is not recognized
- After 2 seconds leds will be off.
- If you move your board, leds will be on according to direction you move your board.
This example first checks for connected device. After you know which device is connected, you don’t need to always check that. You can simple just initialize device that you know is connected on board.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
/** * Keil project for LIS302DL or LIS3DSH accelerometer * * Before you start, select your target, on the right of the "Load" button * * @author Tilen Majerle * @email tilen@majerle.eu * @website http://stm32f4-discovery.net * @ide Keil uVision 5 * * On init, if you have old LIS302DL on STM32F4-Discovery board, * LED_GREEN and LED_RED will be turned on for 2 seconds, * if you have new LIS3DSH on STM32F4-Discovery board, * LED_BLUE and LED_ORANGE will be turned on for 2 seconds. * * If all leds are on, there was an error somewhere. */ /* Include core modules */ #include "stm32f4xx.h" /* Include my libraries here */ #include "defines.h" #include "tm_stm32f4_disco.h" #include "tm_stm32f4_delay.h" #include "tm_stm32f4_lis302dl_lis3dsh.h" int main(void) { TM_LIS302DL_LIS3DSH_t Axes_Data; /* Initialize system */ SystemInit(); /* Init delay */ TM_DELAY_Init(); /* Initialize LEDs */ TM_DISCO_LedInit(); /* Detect proper device */ if (TM_LIS302DL_LIS3DSH_Detect() == TM_LIS302DL_LIS3DSH_Device_LIS302DL) { /* Turn on GREEN and RED */ TM_DISCO_LedOn(LED_GREEN | LED_RED); /* Initialize LIS302DL */ TM_LIS302DL_LIS3DSH_Init(TM_LIS302DL_Sensitivity_2_3G, TM_LIS302DL_Filter_2Hz); } else if (TM_LIS302DL_LIS3DSH_Detect() == TM_LIS302DL_LIS3DSH_Device_LIS3DSH) { /* Turn on BLUE and ORANGE */ TM_DISCO_LedOn(LED_BLUE | LED_ORANGE); /* Initialize LIS3DSH */ TM_LIS302DL_LIS3DSH_Init(TM_LIS3DSH_Sensitivity_2G, TM_LIS3DSH_Filter_800Hz); } else { /* Device is not recognized */ /* Turn on ALL leds */ TM_DISCO_LedOn(LED_GREEN | LED_RED | LED_BLUE | LED_ORANGE); /* Infinite loop */ while (1); } /* Delay for 2 seconds */ Delayms(2000); while (1) { /* Read axes data from initialized accelerometer */ TM_LIS302DL_LIS3DSH_ReadAxes(&Axes_Data); /* Turn LEDS on or off */ /* Check X axes */ if (Axes_Data.X > 200) { TM_DISCO_LedOn(LED_RED); } else { TM_DISCO_LedOff(LED_RED); } if (Axes_Data.X < -200) { TM_DISCO_LedOn(LED_GREEN); } else { TM_DISCO_LedOff(LED_GREEN); } /* Check Y axes */ if (Axes_Data.Y > 200) { TM_DISCO_LedOn(LED_ORANGE); } else { TM_DISCO_LedOff(LED_ORANGE); } if (Axes_Data.Y < -200) { TM_DISCO_LedOn(LED_BLUE); } else { TM_DISCO_LedOff(LED_BLUE); } } } |
Project is available on my Github account, download library below.
Recent comments