Make a BLE Temperature Sensor with the nRF51 - LEKULE

Breaking

19 Oct 2015

Make a BLE Temperature Sensor with the nRF51

How to create a BLE temp sensor using the nRF51.

Overview

This is part of a series of articles on the nRF51. The nRF51 is a system-on-chip with a Cortex M0 and a BLE radio chip all in one. This article demonstrates how to use the built-in die temperature sensor on the nRF51. The die temperature is not the same as ambient temperature, but can be calibrated to ambient temperature by using a correction factor.

Previous Articles

BLE using nRF51: ARM-GCC Build Environment
BLE using nRF51: Creating a BLE Peripheral

Requirements

  • Device that has the nRF51
  • Device that supports Android and BLE
    • Used in article: Android v5.1.1
  • The toolchain setup in the previous article.

Modifying the nRF51 Software

The software from the Creating a BLE Peripheral needs to be modified to read the temperature and convert it to something that can be sent over BLE. The following function uses a built-in call to the softdevice to read the TEMP register inside the nRF51. The value is divided by 4 since temperature is recorded in 0.25C increments.

 

                    int32_t temperature_data_get(void)
{
    int32_t temp;
    uint32_t err_code;
    
    err_code = sd_temp_get(&temp);
    APP_ERROR_CHECK(err_code);
    
    return temp/4;
}

                  

The temperature is read in the main application once a second. The data is converted to 8 bits and sent to the custom BLE characteristic. There is currently no low power scheme being used in this example. If you wanted low power you could run the temperature reading in a timer and sleep the rest of the time. The variable TEMP_CAL_OFFSET can be determined by reading the temperature from the console in a room where the temperature is known. TEMP_CAL_OFFSET is then just the difference between the measured temperature and the actual temperature of the room.

                    // Enter main loop.
    while(1)
    {
        nrf_delay_ms(1000);
        temp_c = (int8_t)temperature_data_get() + TEMP_CAL_OFFSET;
        temp_f = (int8_t)((float)temp_c*9/5+32);
        char2_data[0] = temp_c;
        char2_data[1] = temp_f;
        err_code = custom_service_update_data(m_conn_handle,char2_data);
        APP_ERROR_CHECK(err_code);

        DEBUG_PRINTF("Actual temperature: %d C -- %d F", temp_c,temp_f);
    }
                  

Displaying on Android

The Android application consists of two text fields to display the temp in units of Celsius or Fahrenheit. The values are updated when the text fields are pressed.


Source Code


 

APK


 

Testing

To test I measured the temperature in the room and then watched the temperature decrease when I placed the dongle in the freezer.


Conclusion

This project can be improved by using BLE notifications. Notifications are perfect for values that don't change very often. The characteristic is only updated when the value has changed. The Android device can register for these notifications so the temp is automatically displayed rather than being requested by clicking. Secondly, if the sensor was going to be ran on batteries the code can be modified to use the sd_evt_wait function to sleep until a timer event wakes up to read the temperature.

No comments: