Hi,
I'm trying to use an ADXL345 accelerometer via SPI on a nRF52840 Dongle so it can communicate with Bluetooth to other devices. For the moment I'm testing my code on SES with the DK. Unfortunately, it seems that my values are getting stuck sometimes for no reason. All my registers are well initiated in the beginning and I get values but all of the sudden, the values can get stuck. However, if I put the accelerometer on an other position I finally get some values then it gets stuck again.
Following is the ADXL345.c that handles the functions:
#include "ADXL345.h" #define ADXL345_REG_DEVID 0x00 #define ADXL345_REG_DATAX0 0x32 #define ADXL345_REG_DATA_FORMAT 0x31 #define ADXL345_REG_POWER_CTL 0x2D #define ADXL345_REG_FIFO_CTRL 0x38 #define ADXL345_REG_FIFO_STS 0x39 #define ADXL345_REG_BW_RATE 0x2C # define ADXL345_REG_INT_MAP 0x2F #define ADXL345_SPI_INSTANCE 0 #define ADXL345_CS_PIN 38 #define ADXL345_MISO_PIN 39 //MISO= SDO #define ADXL345_MOSI_PIN 40 //MOSI=SDA #define ADXL345_SCK_PIN 27 static volatile bool spi_xfer_done; /* Flag used to indicate that SPI instance completed the transfer. */ static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(ADXL345_SPI_INSTANCE); //flag generated dans when interrupt of SPI com. Become True after a frame is sent. void spi_event_handler(nrf_drv_spi_evt_t const * p_event, void * p_context) { spi_xfer_done = true; } void SPI_Init(void){ //nrf_gpio_cfg_output(ADXL345_CS_PIN); //nrf_gpio_pin_set(ADXL345_CS_PIN); nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG; spi_config.ss_pin = ADXL345_CS_PIN; spi_config.miso_pin = ADXL345_MISO_PIN; spi_config.mosi_pin = ADXL345_MOSI_PIN; spi_config.sck_pin = ADXL345_SCK_PIN; spi_config.frequency = NRF_DRV_SPI_FREQ_1M; spi_config.mode = NRF_DRV_SPI_MODE_3; APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL)); } void ADXL345_SPI_readRegister(uint8_t address, uint8_t * rx_data, uint8_t bytes) { uint8_t tx_data; if(bytes > 1) { tx_data = (0x80|address)|0x40; } else { tx_data = 0x80|address; } nrf_gpio_pin_clear(ADXL345_CS_PIN); spi_xfer_done=false; APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, &tx_data, bytes+1, rx_data, bytes+1)); while(!spi_xfer_done){} nrf_gpio_pin_set(ADXL345_CS_PIN); } void ADXL345_SPI_writeRegister(uint8_t reg_addr, uint8_t * p_data, uint8_t bytes) { uint8_t tx_data[2]; uint8_t rx_data[2]; if(bytes > 1) { tx_data[0] = (reg_addr|0x40); } else { tx_data[0] = reg_addr; } tx_data[1]=*p_data; nrf_gpio_pin_clear(ADXL345_CS_PIN); spi_xfer_done=false; APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, tx_data, sizeof(tx_data), rx_data, 0)); while(!spi_xfer_done){} nrf_gpio_pin_set(ADXL345_CS_PIN); } void ADXL345_set_INT_MAP (int8_t data){ // Set Interrupts uint8_t rx_data[2]; uint8_t tx_data[2] = {ADXL345_REG_INT_MAP, data}; ADXL345_SPI_writeRegister(ADXL345_REG_INT_MAP, &tx_data[1], 1); NRF_LOG_INFO( "Set INT_MAP : done \r"); nrf_delay_us(1.6); //Read Interrupts ADXL345_SPI_readRegister(ADXL345_REG_INT_MAP, rx_data, 1); NRF_LOG_INFO( "Read INT_MAP with function: 0x%02X \r",rx_data[1]); nrf_delay_us(1.6); if (rx_data[1]!=tx_data[1]) { NRF_LOG_INFO( "INT_MAP sent: 0x%02X \n INT_MAP received: 0x%02X \n",tx_data[1], rx_data[1]);} else {NRF_LOG_INFO( "INT_MAP same value sent and received\n");} nrf_delay_us(1.6); } void ADXL345_set_resolution_range (int8_t data){ //Set resolution and range uint8_t rx_data[2]; uint8_t tx_data[2] = {ADXL345_REG_DATA_FORMAT, data}; ADXL345_SPI_writeRegister(ADXL345_REG_DATA_FORMAT, &tx_data[1], 1); NRF_LOG_INFO( "Set resolution and range: done \r"); nrf_delay_us(1.6); //Read resolution range ADXL345_SPI_readRegister(ADXL345_REG_DATA_FORMAT, rx_data, 1); NRF_LOG_INFO( "Read resolution and range with function: 0x%02X, adresse: 0x%02X \r",rx_data[1], rx_data[0]); nrf_delay_us(1.6); //Compare value sent and received if (rx_data[1]!=tx_data[1]) { NRF_LOG_INFO( "Resolution and range sent: 0x%02X \n Resolution and range received: 0x%02X \n",tx_data[1], rx_data[1]);} else {NRF_LOG_INFO( "Same resolution and range sent and received\n");} } void ADXL345_set_data_rate (int8_t data){ //Set data rate uint8_t rx_data[2]; uint8_t tx_data[2] = {ADXL345_REG_BW_RATE, data}; ADXL345_SPI_writeRegister(ADXL345_REG_BW_RATE, &tx_data[1], 1); NRF_LOG_INFO( "Set data rate with function: done \r"); nrf_delay_us(1.6); // Read data rate ADXL345_SPI_readRegister(ADXL345_REG_BW_RATE, rx_data, 1); NRF_LOG_INFO( "Read data rate with fonction: 0x%02X \r",rx_data[1]); nrf_delay_us(1.6); //Compare value sent and received if (rx_data[1]!=tx_data[1]) { NRF_LOG_INFO( "Data rate sent: 0x%02X \n Data rate received: 0x%02X \n",tx_data[1], rx_data[1]);} else {NRF_LOG_INFO( "Same data rate sent and received\n");} nrf_delay_us(1.6); } void ADXL345_set_FIFO_CTL (int8_t data){ // Set FIFO CTL uint8_t rx_data[2]; uint8_t tx_data[2] = {ADXL345_REG_FIFO_CTRL, data}; ADXL345_SPI_writeRegister(ADXL345_REG_FIFO_CTRL, &tx_data[1], 1); NRF_LOG_INFO( "Set FIFO CTL: done \r"); nrf_delay_us(1.6); //Read FIFO CTL ADXL345_SPI_readRegister(ADXL345_REG_FIFO_CTRL, rx_data, 1); NRF_LOG_INFO( "Read FIFO CTL with function: 0x%02X \r",rx_data[1]); nrf_delay_us(1.6); if (rx_data[1]!=tx_data[1]) { NRF_LOG_INFO( "FIFO_CTL sent: 0x%02X \n FIFO_CTL received: 0x%02X \n",tx_data[1], rx_data[1]);} else {NRF_LOG_INFO( "FIFO CTL same value sent and received\n");} nrf_delay_us(1.6); } void ADXL345_set_POWER_CTL (int8_t data){ //Set measurement mode uint8_t rx_data[2]; uint8_t tx_data[2] = {ADXL345_REG_POWER_CTL, data}; ADXL345_SPI_writeRegister(ADXL345_REG_POWER_CTL, &tx_data[1], 1); NRF_LOG_INFO( "Set measurement mode with function: done \r"); nrf_delay_us(1.6); //Read measurement mode ADXL345_SPI_readRegister(ADXL345_REG_POWER_CTL, rx_data, 1); NRF_LOG_INFO( "Read measurement mode avec fonction: 0x%02X \r",rx_data[1]); nrf_delay_us(1.6); //Compare value sent and received if (rx_data[1]!=tx_data[1]) { NRF_LOG_INFO( "Measurement mode sent: { 0x%02X, 0x%02X } \n Measure mode received: 0x%02X \n",tx_data[0], tx_data[1], rx_data[1]);} else {NRF_LOG_INFO( "Same measure mode sent and received \n");} nrf_delay_us(1.6); } void adxl345_init(void) { uint8_t rx_data[2]; nrf_gpio_cfg_output(ADXL345_CS_PIN); nrf_gpio_pin_set(ADXL345_CS_PIN); //nrf_delay_ms(10); /* //Read test ADXL345_SPI_readRegister(0x00, &rx_data[0], 1); NRF_LOG_INFO( "TEST: 0x%02X \r",rx_data[1]); */ nrf_delay_ms(10); ADXL345_set_data_rate (0x0A); ADXL345_set_resolution_range (0x00); ADXL345_set_POWER_CTL (0x08); ADXL345_set_FIFO_CTL (0x80); } bool adxl345_read_fifo_status(void) { // Read FIFO status and return true if there are values to read uint8_t tx_data[2] = {ADXL345_REG_FIFO_STS|0x80, 0}; uint8_t rx_data[2]; ADXL345_SPI_readRegister(ADXL345_REG_FIFO_STS, rx_data, 1); return (bool)((rx_data[1] & 0x3Fu) != 0u); } void adxl345_read_acceleration(int16_t *x, int16_t *y, int16_t *z) { uint8_t rx_data[7] = {0, 0, 0, 0, 0, 0, 0}; ADXL345_SPI_readRegister(ADXL345_REG_DATAX0, rx_data, 6); *x = (((int16_t)rx_data[2] << 8 | rx_data[1])); *y = (((int16_t)rx_data[4] << 8 | rx_data[3])); *z = (((int16_t)rx_data[6] << 8 | rx_data[5])); }
Following is tjhe main.c:
#include "ADXL345.h" #define SCALE_FACTOR_2G 3.9 #define SCALE_FACTOR_4G 7.8 #define SCALE_FACTOR_8G 15.6 int main(void) { //Initialize the LEDs on board to use them bsp_board_init(BSP_INIT_LEDS); // Initialize the Logger module and check if any error occured during initialization APP_ERROR_CHECK(NRF_LOG_INIT(NULL)); // Initialize the default backends for nrf logger NRF_LOG_DEFAULT_BACKENDS_INIT(); // print the log msg over uart port NRF_LOG_INFO("This is log data from nordic device.."); NRF_LOG_INFO("Initialisation \n"); int16_t x, y, z; float xg, yg, zg; int16_t x_offset, y_offset, z_offset; SPI_Init(); adxl345_init(); if (adxl345_read_fifo_status() != false){ adxl345_read_acceleration(&x_offset, &y_offset, &z_offset); } while (true) { if (adxl345_read_fifo_status() != false) { //NRF_LOG_INFO( "Range acceleromter: %X \n", adxl345_read_range()) adxl345_read_acceleration(&x, &y, &z); xg= (float)(x-x_offset) *SCALE_FACTOR_2G /(pow(10,3)); yg= (float)(y-y_offset) *SCALE_FACTOR_2G/(pow(10,3)); zg= (float)(z-z_offset) *SCALE_FACTOR_2G/(pow(10,3)); NRF_LOG_INFO("x avec facteur: "NRF_LOG_FLOAT_MARKER" g, x: %d \r", NRF_LOG_FLOAT(xg), x-x_offset); NRF_LOG_INFO("y avec facteur: "NRF_LOG_FLOAT_MARKER" g, y: %d \r", NRF_LOG_FLOAT(yg), y-y_offset); NRF_LOG_INFO("z avec facteur: "NRF_LOG_FLOAT_MARKER" g, z: %d \r\n", NRF_LOG_FLOAT(zg), z-z_offset); } NRF_LOG_FLUSH(); nrf_delay_ms(100); } }
On the hardware side, the soldering doesn't have any imperfection and the pins aren't touching each other.
Do you have any idea what could be the problem ?
By the way, I was using different pins for the communication with the DK but I changed them because I couldn't write sometimes on my registers.
Do you have any idea what might be wrong ?