Raspberry Pi IoT In C - The DS18B20 Temperature Sensor
Written by Harry Fairhead   
Tuesday, 17 May 2022
Article Index
Raspberry Pi IoT In C - The DS18B20 Temperature Sensor
Initialization
A Temperature Function

A Temperature Function

Packaging all of this into a single function is easy:

float getTemperature(uint8_t pin) {
    if (presence(pin) == 1) return -1000;
    writeByte(pin, 0xCC);
    if (convert(pin) == 5000) return -3000;
    presence(pin);
    writeByte(pin, 0xCC);
    writeByte(pin, 0xBE);
    int i;
    uint8_t data[9];
    for (i = 0; i < 9; i++) {
        data[i] = readByte(pin);
    }
    uint8_t crc = crc8(data, 9);
    if(crc!=0) return -2000;
    int t1 = data[0];
    int t2 = data[1];
    int16_t temp1 = (t2 << 8 | t1);
    float temp = (float) temp1 / 16;
    return temp;
}

Notice that the function returns -1000 if there is no device, -2000 if there is a CRC error and -3000 if the device fails to provide data. These values are outside the range of temperatures that can be measured.

The Complete Program

The complete program to read and display the temperature is:

#include <bcm2835.h>
#include <stdio.h>
int presence(uint8_t pin);
void writeBit(uint8_t pin, int b);
void writeByte(uint8_t pin, int byte);
uint8_t readBit(uint8_t pin);
int convert(uint8_t pin);
int readByte(uint8_t pin);
float getTemperature(uint8_t pin);
uint8_t crc8(uint8_t *data, uint8_t len);
int main(int argc, char **argv) {
    if (!bcm2835_init())
        return 1;
    if (presence(RPI_BPLUS_GPIO_J8_07) == 1) {
        printf("No device \n");
    } else {
        printf("Device present \n");
    }
    fflush(stdout);
    float t;
    for (;;) {
        do {
            t = getTemperature(RPI_BPLUS_GPIO_J8_07);
        } while (t<-999);
        printf("%f\r\n",t);
        fflush(stdout);
    };
    bcm2835_close();
    return 0;
}
int presence(uint8_t pin) {
    bcm2835_gpio_fsel(pin ,BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(pin,  LOW);
    bcm2835_delayMicroseconds(480);
    bcm2835_gpio_fsel(pin,  BCM2835_GPIO_FSEL_INPT);
    bcm2835_delayMicroseconds(70);
    uint8_t b = bcm2835_gpio_lev(pin);
    bcm2835_delayMicroseconds(410);
    return b;
}
void writeBit(uint8_t pin,  int b) {
    int delay1,  delay2;
    if (b == 1) {
        delay1 = 6;
        delay2 = 64;
    } else {
        delay1 = 60;
        delay2 = 10;
    }
    bcm2835_gpio_fsel(pin,  BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(pin,  LOW);
    bcm2835_delayMicroseconds(delay1);
    bcm2835_gpio_fsel(pin,  BCM2835_GPIO_FSEL_INPT);
    bcm2835_delayMicroseconds(delay2);
}
void writeByte(uint8_t pin,  int byte) {
    int i;
    for (i = 0; i < 8; i++) {
        if (byte & 1) {
            writeBit(pin,  1);
        } else {
            writeBit(pin,  0);
        }
        byte = byte >> 1;
    }
}
uint8_t readBit(uint8_t pin) {
    bcm2835_gpio_fsel(pin,  BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(pin,  LOW);
    bcm2835_delayMicroseconds(8);
    bcm2835_gpio_fsel(pin,  BCM2835_GPIO_FSEL_INPT);
    bcm2835_delayMicroseconds(2);
    uint8_t b = bcm2835_gpio_lev(pin);
    bcm2835_delayMicroseconds(60);
    return b;
}
int convert(uint8_t pin) {
    int i;
    writeByte(pin,  0x44);
    for (i = 0; i < 5000; i++) {
        bcm2835_delayMicroseconds(100000);
        if (readBit(pin) == 1)break;
    }
    return i;
}
float getTemperature(uint8_t pin) {
    if (presence(pin) == 1) return -1000;
    writeByte(pin,  0xCC);
    if (convert(pin) == 5000) return -3000;
    presence(pin);
    writeByte(pin,0xCC);
    writeByte(pin,0xBE);
    int i;
    uint8_t data[9];
    for (i = 0; i < 9; i++) {
        data[i] = readByte(pin);
    }
    uint8_t crc = crc8(data,  9);
    if (crc != 0) return -2000;
    int t1 = data[0];
    int t2 = data[1];
    int16_t temp1 = (t2 << 8 | t1);
    float temp = (float) temp1 / 16;
    return temp;
}
int readByte(uint8_t pin) {
    int byte = 0;
    int i;
    for (i = 0; i < 8; i++) {
        byte = byte | readBit(pin) << i;
    };
    return byte;
}
uint8_t crc8(uint8_t *data,  uint8_t len) {
    uint8_t i;
    uint8_t j;
    uint8_t temp;
    uint8_t databyte;
    uint8_t crc = 0;
    for (i = 0; i < len; i++) {
        databyte = data[i];
        for (j = 0; j < 8; j++) {
            temp = (crc ^ databyte) & 0x01;
            crc >>= 1;
            if (temp)
                crc ^= 0x8C;
            databyte >>= 1;
        }
    }
    return crc;
}

In chapter but not included in this extract

  • Other Commands

 Exploring Edison - The DS18B20 1-Wire Temperature Sensor

Summary

  • The DS18B20 temperature sensor is one of the most commonly encountered 1-wire bus devices.

  • It is small, low-cost and you can use multiple devices on a single bus.

  • Using the DS12B20 uses the same low-level function as presented in the previous two chapters.

  • After a convert command is sent to the device, it can take 750ms before a reading is ready.

  • To test for data ready you have to poll on a single bit. – Reading 0 means data not ready and reading 1 means data ready.

  • When the data is ready you can read the scratchpad memory where the data is stored.

  • The DS18B20 has other commands that can be used to set temperature alarms etc, but these are rarely used when you have the resources of a full Linux machine to process the data.

 

Raspberry Pi And The IoT In C Second Edition

By Harry Fairhead

FrontCover800

Buy from Amazon.

Contents

  1. Why Pi For IoT?
  2. Getting Started
  3. Getting Started With The GPIO
  4. Simple Output
  5. Some Electronics
  6. Simple Input
  7. GPIO The Linux Way
       Extract 1:The Linux GPIO Driver 
  8. Advanced Input – Events, Threads, Interrupts
       Extract 1: Events & Interrupts 
  9. Pulse Width Modulation - Servos And More
       Extract 1:Basic Pulse Width Modulation 
  10. Using The I2C Bus
  11. The DHT22 Sensor Implementing A Custom Protocol
  12. Exploring - 1‑Wire Bus Basics ***NEW!
  13. Using iButtons
  14. DS18B20 Temperature Sensor
      Extract 1: The DS18B20 Temperature Sensor 
  15. The Multidrop 1‑Wire Bus
  16. The Serial Port
      Extract 1: 1-wire Via Serial 
  17. Getting Started With The SPI Bus
  18. A to D With The SPI Bus
  19. Connecting With The Web - Sockets
  20. Memory-Mapped GPIO
  21. Almost Real-Time Linux
  22. Appendix I GPIO Sysfs Interface

 <ASIN:1871962633>

<ASIN:B08KLNT2JC>

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.

Banner


Wasmer 5 Adds iOS Support
12/11/2024

The Wasmer team has released Wasmer 5.0. The WebAssembly runtime adds experimental support for more back ends including V8, Wasmi and WAMR. It also now has iOS support, and upgraded compilers includin [ ... ]



OpenAI Library For .NET Exits Beta
19/11/2024

A few months ago the OpenAI .NET library was released as a beta. It has now reached version 2.0.0 and the time has come to leave beta and, with a few amendments enter production readiness.


More News

espbook

 

Comments




or email your comment to: comments@i-programmer.info



Last Updated ( Tuesday, 17 May 2022 )