Connecting ds18b20 to nrf9160dk

Hi, 

I am looking to connect the ds18b20 sensor to the nrf9160dk. I followed this post, but when I tried running it, I was getting a "create_nordic_project.py failed (1)" saying "error: cmake failed". 

I am a complete beginner when using the development kit so please bear with my questions. 

I have added "CONFIG_GPIO" in the prj.conf file, is there anything else I should be adding. 

Additionally, should I be making changes to the cmake file? The link above only mentioned the .c and .h file so I wasn't sure what else should be changed. 

If anyone could help me with this or could point me to resources that will help me solve this, I would really appreciate it. 

Update : The code is now running without any build errors but not printing any values. I had been using the hello_world sample to run it before which was giving the error, but then I tried switching to the blinky sample and running on that and it's building and running without any errors. (Would anybody know why this is).

My issue now is that it is not printing any values or anything to the Debug terminal on SES or the LTE Link Monitor. Does anyone know why this may be?

Parents
  • Hello Nandini,

    nrffan18 said:

    So in a situation, if I want to let the sensor know that it needs to go into a mode called "skip rom", the master needs to send 0xCC to the sensor starting with the least significant bit (datasheet on page 11). What commands would I use to do this. 

    Additionally after this mode has been set, I would need to call a "Read Scratchpad" function (also on page 11 of the datasheet) by sending 0x44. Would I need to use the same command that I used to send the "Skip ROM" to do this function or is there a different procedure?

    Why are you not using the drivers to do this? The function below performs e.g. the steps you described.

    /**@brief Function for reading temperature.
     */
    float ds18b20_get_temp(void)
    {
        unsigned char check;
        char temp1=0, temp2=0;
    
        check=ds18b20_reset();
        if(check)
        {
            ds18b20_send_byte(0xCC); //Skip ROM.
            ds18b20_send_byte(0x44); //Start temp conversion.
            //nrf_delay_ms(600UL);
            k_sleep(K_MSEC(600UL));
            check=ds18b20_reset();
            ds18b20_send_byte(0xCC); //Skip ROM.
            ds18b20_send_byte(0xBE); //Read temp from Scratchpad.
            temp1=ds18b20_read_byte();
            temp2=ds18b20_read_byte();
            check=ds18b20_reset();
            float temp=0;
            temp=(float)(temp1+(temp2*256))/16;
            return temp;
        }
          return 0;
    }

    Regards,

    Markus

Reply
  • Hello Nandini,

    nrffan18 said:

    So in a situation, if I want to let the sensor know that it needs to go into a mode called "skip rom", the master needs to send 0xCC to the sensor starting with the least significant bit (datasheet on page 11). What commands would I use to do this. 

    Additionally after this mode has been set, I would need to call a "Read Scratchpad" function (also on page 11 of the datasheet) by sending 0x44. Would I need to use the same command that I used to send the "Skip ROM" to do this function or is there a different procedure?

    Why are you not using the drivers to do this? The function below performs e.g. the steps you described.

    /**@brief Function for reading temperature.
     */
    float ds18b20_get_temp(void)
    {
        unsigned char check;
        char temp1=0, temp2=0;
    
        check=ds18b20_reset();
        if(check)
        {
            ds18b20_send_byte(0xCC); //Skip ROM.
            ds18b20_send_byte(0x44); //Start temp conversion.
            //nrf_delay_ms(600UL);
            k_sleep(K_MSEC(600UL));
            check=ds18b20_reset();
            ds18b20_send_byte(0xCC); //Skip ROM.
            ds18b20_send_byte(0xBE); //Read temp from Scratchpad.
            temp1=ds18b20_read_byte();
            temp2=ds18b20_read_byte();
            check=ds18b20_reset();
            float temp=0;
            temp=(float)(temp1+(temp2*256))/16;
            return temp;
        }
          return 0;
    }

    Regards,

    Markus

Children
  • Hi 

    I attempted to use the above function, but it is still not reading the values correctly, and the way it calculated the temperature is wrong. I managed to probe the data line with a logic analyzer and may have found the issue but I don't know how to fix it. So it looks like there is a delay when setting the pin to low/high from the state it was in before.

    I tried only running the SetResolution function and this screenshot is the reset function that is called in the beginning of setResolution function. It should only be low for 480 us but is low for 558 us.

    This delay is seen everywhere else, like this screenshot shows the first couple bits that are sent from the "sendbyte(SKIPROM)" command in SetResolution(). It is sending LSB first and should be sending 0,0,1,1,0,0,1,1. when sending 0's, it should only be low for 65us but it is low for 157 us (1st screenshot). And when sending high, it should be low for only 10 us but it is low for 80 us (2nd screenshot). This causes an issue because in order to Write 1 to the DS18B20 sensor, it needs to switch to the high state within 15 us after being low (setting it low is what initializes the timeslot). 

    So now I know why it was sending me wrong values but I have no idea how to fix it. Can anyone please provide some guidance on what I can do to make the delays in my code execute more accurately without so much delay in switching between setting the pin High/Low?

    Is the issue that the clock is too slow? Or is there something else I should be doing?

    And here is my main.c, I changed the delays a little bit. Every other file is exactly the same. ( I apologize in advance for the large amounts of commented code.)

    #include <drivers/gpio.h>
    #include <stdio.h>
    #include <zephyr.h>
    #include <device.h>
    #include <devicetree.h>
    
    #include "ds18b20.h"
    
    #define GPIO0_LABEL DT_PROP(DT_NODELABEL(gpio0), label)
    #define GPIO0_STATUS DT_PROP(DT_NODELABEL(gpio0), status)
    #define DS_PIN 21
    
    // Commands
    #define STARTCONVO 0x44
    #define READSCRATCH 0xBE
    #define WRITESCRATCH 0x4E
    #define SKIPROM 0xCC
    
    // Scratchpad locations
    #define TEMP_LSB        0
    #define TEMP_MSB        1
    
    // Device resolution
    #define TEMP_9_BIT  0x1F //  9 bit
    #define TEMP_10_BIT 0x3F // 10 bit
    #define TEMP_11_BIT 0x5F // 11 bit
    #define TEMP_12_BIT 0x7F // 12 bit
    
    typedef uint8_t ScratchPad[9];
    
    //Datasheet: https://datasheets.maximintegrated.com/en/ds/DS18B20.pdf
    
    static float temp = 0;
    static const struct device *gpio_dev;
    
    
    /**@brief Function for sending one bit to bus.
     */
    void ds18b20_send(uint8_t bit)
    {
        //nrf_gpio_cfg_output(DS_PIN);
        //nrf_gpio_pin_clear(DS_PIN);
        //nrf_delay_us(5);
        gpio_pin_set(gpio_dev, DS_PIN, 0);
        gpio_pin_configure(gpio_dev, DS_PIN, GPIO_OUTPUT);
        
        //k_usleep(10);
    
        if(bit==1)
        {   
            k_usleep(10);
            //nrf_gpio_pin_set(DS_PIN);
            gpio_pin_set(gpio_dev, DS_PIN, 1);
            k_usleep(55);
    
        }
        else
        {
            k_usleep(65);
            gpio_pin_set(gpio_dev, DS_PIN, 1);
            k_usleep(5);
    
        }
        //nrf_delay_us(80);
        //nrf_gpio_pin_set(DS_PIN);
    
        //k_usleep(60);
        //gpio_pin_set(gpio_dev, DS_PIN, 1);
        //k_usleep(2);
        
    }
    
    
    /**@brief Function for reading one bit from bus.
     */
    unsigned char ds18b20_read(void)
    {
        printf("In ds18b20_read function");
        unsigned char presence=0;
        
        //nrf_gpio_cfg_output(DS_PIN);
        //nrf_gpio_pin_clear(DS_PIN);
        //nrf_delay_us(2);
    
        //nrf_gpio_pin_set(DS_PIN);;
        //nrf_delay_us(15);
    
        //nrf_gpio_cfg_input(DS_PIN,NRF_GPIO_PIN_NOPULL);
    
        gpio_pin_configure(gpio_dev, DS_PIN, GPIO_OUTPUT_LOW);
        gpio_pin_set(gpio_dev, DS_PIN, 0);
        k_usleep(2);
    
        gpio_pin_set(gpio_dev, DS_PIN, 1);
        k_usleep(10);
    
        gpio_pin_configure(gpio_dev, DS_PIN, GPIO_INPUT);
        k_usleep(30);
    
        //if(nrf_gpio_pin_read(DS_PIN))
        if (gpio_pin_get_raw(gpio_dev, DS_PIN))
        {
            presence = 1;
        }
        else
        {
            presence = 0;
        }
    
        printf("\npresence = %d\n", presence);
        
        return presence;
    }
    
    
    /**@brief Function for sending one byte to bus.
     */
    void ds18b20_send_byte(uint8_t data)
    {
        printf("In send_byte func, the byte of data in hex is %x\n and int %d\n", data, data);
        uint8_t i;
        uint8_t x;
        for(i=0;i<8;i++)
        {
          x = data>>i;
          x &= 0x01;
          printf("x=%d\n",x);
          ds18b20_send(x);
        }
        //nrf_delay_us(100);
        //k_usleep(100);
    }
    
    
    /**@brief Function for reading one byte from bus.
     */
    unsigned char ds18b20_read_byte(void)
    {
        printf("entering ds18b20_read_byte function\n");
        unsigned char i;
        unsigned char data = 0;
        for (i=0;i<8;i++)
        {
            if(ds18b20_read()) data|=0x01<<i;
            //nrf_delay_us(15);
            k_usleep(15);
        }
        printf("data = %c", data);
        return(data);
    }
    
    
    /**@brief Function for sending reset pulse.
     */
    unsigned char  ds18b20_reset(void)
    {
      printf("entering reset loop");
      int presence=0;
      printf("presence before = %d\n", presence);
    
      //nrf_gpio_cfg_output(DS_PIN);
      //nrf_gpio_pin_clear(DS_PIN);
    
      //nrf_delay_us(500);
      //nrf_gpio_pin_set(DS_PIN);
    
      //nrf_gpio_cfg_input(DS_PIN,NRF_GPIO_PIN_NOPULL); // usikkert p? pull her. m? sjekkes
      //nrf_delay_us(30);
    
        gpio_pin_set(gpio_dev, DS_PIN, 0);
        gpio_pin_configure(gpio_dev, DS_PIN, GPIO_OUTPUT);
        
    
        k_usleep(480);
        gpio_pin_set(gpio_dev, DS_PIN, 1);
        gpio_pin_configure(gpio_dev, DS_PIN, GPIO_INPUT);
        k_usleep(30);
    
        if(gpio_pin_get_raw(gpio_dev, DS_PIN) == 0)
        {
            presence = 1;
        }
        else
        {
            presence = 0;
        }
        printf("presence after 30 us = %d", presence);
    
        //nrf_delay_us(470);
        k_usleep(470);
    
        if(gpio_pin_get_raw(gpio_dev, DS_PIN) == 1)
        {
            presence = 1;
        }
        else
        {
            presence = 0;
        }
      printf("presence after 470 us is %d", presence);
      return presence;
    
    }
    
    
    /**@brief Function for reading temperature.
     */
    float ds18b20_get_temp(void)
    {
        printf("ENtering get_temp method\n");
    
        unsigned int check;
        uint8_t temp1=0, temp2=0;
    
        check=ds18b20_reset();
        printf("check from reset = %d\n", check);
        if(check)
        {
            ds18b20_send_byte(SKIPROM); //Skip ROM.
            ds18b20_send_byte(0x44); //Start temp conversion.
            //nrf_delay_ms(600UL);
            k_msleep(600UL);
            check=ds18b20_reset();
            ds18b20_send_byte(SKIPROM); //Skip ROM.
            ds18b20_send_byte(0xBE); //Read temp from Scratchpad.
            temp1=ds18b20_read_byte();
            temp2=ds18b20_read_byte();
            check=ds18b20_reset();
            printf("temp1=%d and temp2 = %d\n", temp1, temp2);
            float temp=0;
            temp=(float)(temp1+(temp2*256))/16;
            printf("temp = %6f\n", temp);
            return temp;
        }
          return 0;
    }
    
    
    /**@brief Function for reading bit.
     */
    uint8_t OneWire_read_bit(void)
    {
        printf("Inside OneWire_read_bit \n");
        uint8_t r;
    
        //nrf_gpio_cfg_output(DS_PIN);
        //nrf_gpio_pin_clear(DS_PIN);
        //nrf_delay_us(3);
        //nrf_gpio_cfg_input(DS_PIN,NRF_GPIO_PIN_NOPULL);
        //nrf_delay_us(10);
        //r =nrf_gpio_pin_read(DS_PIN);
        //nrf_delay_us(53);
        gpio_pin_set(gpio_dev, DS_PIN, 0);
        gpio_pin_configure(gpio_dev, DS_PIN, GPIO_OUTPUT);
        k_usleep(3);
        //gpio_pin_set(gpio_dev, DS_PIN, 1);
        gpio_pin_configure(gpio_dev, DS_PIN, GPIO_INPUT);
        k_usleep(10);
        r = gpio_pin_get_raw(gpio_dev, DS_PIN);
        printk("\nr = %d", r); // COMMENTED THIS
        k_usleep(53);
        return r;
    }
    
    
    /**@brief Function for reading.
     */
    uint8_t OneWire_read()
    {
        printf("inside OneWire_read function\n");
    
        uint8_t bitMask;
        uint8_t r = 0;
        //bitMask = 0x00;
     
        /*for (int i=0; i<8; i++) {
          //bitMask = 0x01<<i;
          bitMask = 0x01 & OneWire_read_bit();
          bitMask = bitMask << i;
          r |= bitMask;
        }*/
    
        for (bitMask = 0x01; bitMask; bitMask <<= 1) {
    	if ( OneWire_read_bit()) r |= bitMask;
        }
        printf("the byte in hex is %x\n", r);
        return r;
    }
    
    
    /**@brief Function for reading scratchpad value
     */
    void ds18b20_readScratchPad(uint8_t *scratchPad, uint8_t fields)
    {
        printf("Inside readScratcpad function\n");
        ds18b20_reset();
        ds18b20_send_byte(SKIPROM);
        ds18b20_send_byte(READSCRATCH);
    
        for(uint8_t i=0; i < fields; i++)
        {
            scratchPad[i] = OneWire_read();
            printf("Scratcpad[%d] = %x", i, scratchPad[i]);
    
        }
        ds18b20_reset();
    }
    
    
    /**@brief Function for request temperature reading
     */
    void ds18b20_requestTemperatures(void)
    {
        printf("inside Request Temperatures function\n");
        ds18b20_reset();
        ds18b20_send_byte(SKIPROM);
        ds18b20_send_byte(STARTCONVO);
        k_msleep(750);
    }
    
    
    /**@brief Function for reading temperature method 2
     */
    float ds18b20_get_temp_method_2(void)
    {
        //printf("entering get_temp_method_2");
        //ds18b20_requestTemperatures();
        //unsigned char check;
    
        ScratchPad scratchPad;
        ds18b20_readScratchPad(scratchPad, 5);
        int16_t rawTemperature = (((int16_t)scratchPad[TEMP_MSB]) << 8) | scratchPad[TEMP_LSB];
        //printf("Raw temperature = %d\n", rawTemperature);
        //float temp = 0.0625 * rawTemperature;
        //printf("real temperature = %6f\n", temp);
    
        return temp;
    }
    
    
    /**@brief Function for setting temperature resolution
     */
    void ds18b20_setResolution(uint8_t resolution)
    {
        ds18b20_reset();
        printf("sending skip rom\n");
        ds18b20_send_byte(SKIPROM);
        printf("end of sending skip rom\n");
        printf("sending write scratch\n");
        ds18b20_send_byte(WRITESCRATCH);
        printf("end of sending write scratch\n");
        printf("sending T_H\n");
        // two dummy values for LOW & HIGH ALARM
        ds18b20_send_byte(0x7D); // 125 C
        printf("sending T_L\n");
        ds18b20_send_byte(0xC9); // -55C
        printf("sending conversion resolution\n");
        switch (resolution)
        {
            case 12:
                ds18b20_send_byte(TEMP_12_BIT);
                break;
    
            case 11:
                ds18b20_send_byte(TEMP_11_BIT);
                break;
    
            case 10:
                ds18b20_send_byte(TEMP_10_BIT);
                break;
    
            case 9:
            default:
                ds18b20_send_byte(TEMP_9_BIT);
                break;
        }
        ds18b20_reset();
        printf("exit set_Resolution() function");
    }
    
    void main()
    {
        gpio_dev = device_get_binding(GPIO0_LABEL);
    
        if (!gpio_dev) {
    	    printk("Error getting GPIO_0: failed.\n");
        }
        
        
        //ds18b20_reset();
        
        
        ds18b20_setResolution(10);
    
        /*
        temp = ds18b20_get_temp_method_2();
        //temp = ds18b20_get_temp();
        printf("Temperature: %.3f \r\n", temp);
    
        
        while(1)
        {
            k_msleep(2000);
            temp = ds18b20_get_temp_method_2();
            //temp = ds18b20_get_temp();
            printf("Temperature: %.3f \r\n", temp);
        }*/
    }
    
    
        
    
    
    /** @} */
    

Related