Blog Datasheets Home About me Clients My work Services Contact

G2Labs Grzegorz Grzęda

Interfacing sensors with the nRF52

November 27, 2023

Interfacing Sensors with the nRF52

The nRF52 is a powerful microcontroller that integrates Bluetooth Low Energy (BLE) capabilities. It is widely used in IoT applications where wireless connectivity and sensor integration are essential. In this blog post, we will explore how to interface various sensors with the nRF52 using different communication protocols. We will cover examples of using I2C, SPI, and GPIO interfaces to communicate with sensors.

I2C Communication

I2C (Inter-Integrated Circuit) is a popular communication protocol used to interface sensors with microcontrollers. Let’s consider an example of interfacing an I2C-based temperature and humidity sensor (like the popular DHT11) with the nRF52.

First, ensure that the sensor is correctly connected to the nRF52’s I2C pins (SCL and SDA). The nRF52 has dedicated I2C hardware peripherals that simplify communication.

Next, initialize the I2C peripherals and configure the desired communication parameters such as clock frequency and addressing.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#include <stdbool.h>
#include "nrf_twi.h"

#define TWI_INSTANCE_ID 0

static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);

void twi_init(void)
{
    const nrf_drv_twi_config_t twi_config = {
       .scl                = ARDUINO_SCL_PIN,
       .sda                = ARDUINO_SDA_PIN,
       .frequency          = NRF_TWI_FREQ_400K,
       .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
       .clear_bus_init     = false
    };

    nrf_drv_twi_init(&m_twi, &twi_config, NULL, NULL);
    nrf_drv_twi_enable(&m_twi);
}

After initializing the I2C, we can start reading data from the sensor. The following code reads the temperature and humidity values from the DHT11 sensor.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "nrf_delay.h"
#include "app_error.h"

#define DHT11_ADDRESS 0x27

void read_dht11_sensor(uint8_t* temperature, uint8_t* humidity)
{
    uint8_t tx_buf[1] = {0x00};
    uint8_t rx_buf[2] = {0x00};
    uint32_t err_code;

    err_code = nrf_drv_twi_tx(&m_twi, DHT11_ADDRESS, tx_buf, sizeof(tx_buf), false);
    APP_ERROR_CHECK(err_code);

    nrf_delay_ms(2);

    err_code = nrf_drv_twi_rx(&m_twi, DHT11_ADDRESS, rx_buf, sizeof(rx_buf));
    APP_ERROR_CHECK(err_code);

    *humidity = rx_buf[0];
    *temperature = rx_buf[1];
}

With this code, we can retrieve the temperature and humidity data from the DHT11 sensor by calling the read_dht11_sensor function.

SPI Communication

SPI (Serial Peripheral Interface) is another communication protocol commonly used for sensor interfacing. It allows high-speed, full-duplex communication with devices like accelerometers, gyroscopes, and displays.

Let’s consider an example of interfacing an SPI-based accelerometer sensor (e.g., a 3-axis ADXL345) with the nRF52.

First, make the necessary hardware connections between the nRF52 and the ADXL345 sensor. Then, initialize the SPI hardware and configure communication parameters, such as clock frequency, mode, and bit order.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#include "nrf_drv_spi.h"
#include "app_error.h"

#define SPI_INSTANCE 0

static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE);

void spi_init(void)
{
    nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
    spi_config.ss_pin = SPI_SS_PIN;
    spi_config.miso_pin = SPI_MISO_PIN;
    spi_config.mosi_pin = SPI_MOSI_PIN;
    spi_config.sck_pin = SPI_SCK_PIN;
    spi_config.frequency = NRF_DRV_SPI_FREQ_4M;
    spi_config.mode = NRF_DRV_SPI_MODE_0;
    spi_config.bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST;

    APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, NULL, NULL));
}

After initializing the SPI, we can start reading data from the accelerometer. The following code reads the X, Y, and Z-axis acceleration values from the ADXL345 sensor.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#include "app_error.h"

#define ADXL345_READ 0x80
#define ADXL345_MULTI_BYTE 0x40
#define ADXL345_DATAX0 0x32

void read_adxl345_sensor(int16_t* x, int16_t* y, int16_t* z)
{
    uint8_t tx_data[2] = { ADXL345_READ | ADXL345_MULTI_BYTE | ADXL345_DATAX0, 0x00 };
    uint8_t rx_data[7] = {0x00};

    APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, tx_data, sizeof(tx_data), rx_data, sizeof(rx_data)));
    
    *x = (rx_data[1] << 8) | rx_data[0];
    *y = (rx_data[3] << 8) | rx_data[2];
    *z = (rx_data[5] << 8) | rx_data[4];
}

With this code, we can retrieve the accelerometer data from the ADXL345 sensor by calling the read_adxl345_sensor function.

GPIO Communication

In some cases, interfacing sensors with the nRF52 can be as simple as using GPIO pins for digital input/output. GPIOs can be used to interface various sensors like light detectors, buttons, and simple analog-to-digital converters.

Let’s consider an example of interfacing a simple button using a GPIO pin.

First, configure the GPIO pin as an input and set the desired pull-up/pull-down settings.

1
2
3
4
5
6
7
8
#include "nrf_gpio.h"

#define BUTTON_PIN 15

void button_init(void)
{
    nrf_gpio_cfg_input(BUTTON_PIN, NRF_GPIO_PIN_PULLUP);
}

Next, check the state of the button using the nrf_gpio_pin_read function.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#include "app_error.h"

bool is_button_pressed(void)
{
    uint32_t button_state = nrf_gpio_pin_read(BUTTON_PIN);
    
    if (button_state == 0)
    {
        return true;
    }
    
    return false;
}

With this code, we can determine whether the button is pressed or not by calling the is_button_pressed function.

Conclusion

In this blog post, we explored how to interface various sensors with the nRF52 microcontroller using different communication protocols. We covered examples of using I2C, SPI, and GPIO interfaces to communicate with sensors. With these examples as a starting point, you can easily integrate various sensors into your nRF52-based projects. Happy hacking!


➡️ Exploring PWM functionality on the nRF52


⬅️ Implementing SPI communication on the nRF52


Go back to Posts.