Reading temperature from DS18B20 on PSoC 5

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
NaAh_4673366
Level 3
Level 3
5 likes given First like received First like given

Hi everyone,

I wrote a code to read the temperature from a 1-Wire based digital thermometer DS18B20 and show it using UART communication. But I always get the temperature 127.

I could not find out the reason. Can anyone please help? Thanks.

I am using CY8CKIT-059PSoC5LP

0 Likes
7 Replies
odissey1
Level 9
Level 9
First comment on KBA 1000 replies posted 750 replies posted

NaAh,

You can borrow the code from

Component to read DS18B20 digital temperature sensors

or use existing component as-is

If you want to develop own code, I suggest to start with tested component from the link above and to make sure you are able to read the sensor correctly. Typical issue is too small pull-up resistor, and incorrect 1-wite timing intervals.

/odissey1

0 Likes
EvPa_264126
Level 7
Level 7
500 replies posted 250 replies posted 100 likes received

signals of your project:dallas.jpg

lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

Since your code is very difficult for me, I added my code to print the result.

In the following man.c, I did a couple of things.

(1) Print out all data read

(2) Print temp_msb and temp_lsb following the datasheet of DS18B20

When I un-comment the line below

        // scratchpad[0] = 0x91 ; scratchpad[1] = 0x01 ; /* this is +25.0625 */

Tera Term output was

000-TeraTerm-log.JPG

Note: Since I don't have the sensor, the reading was all 0x00,

but as I forced scratchpad[0] = 0x91, scratchpad[1] = 0x01

the result temp was shown as 85.0000

So please use attached code to check

- If the sensor reading is correct

- If the values displayed are correct

main.c

=======================

/* ========================================

*

*

*

* ========================================

*/

#include "project.h"

#include "stdio.h"

#define STR_LEN 64

char    str[STR_LEN+1] ;

void    print(char *str)

{

    UART_PutString(str) ;

}

void cls(void)

{

    print("\033c") ; /* reset */

    CyDelay(20) ;

    print("\033[2J") ; /* clear screen */

    CyDelay(20) ;

}

void splash(char *prog_name)

{

    cls() ;

    if (prog_name && *prog_name) {

        print(prog_name) ;

    }

    print(" (") ;

    print(__DATE__) ;

    print(" ") ;

    print(__TIME__) ;

    print(")\n") ;

}

#define RESET_PULSE 480

#define PRESENCE_PULSE 70

#define END_SLOT 410

#define TIME_SLOT 60

#define RECOVERY_TIME 10

#define WRITE_0_SLOT 60

#define WRITE_1_SLOT 10

#define READ_INIT_DELAY 6

#define READ_VALID_DELAY 6

#define SKIP_ROM 0xCC

#define WRITE_SCRPAD 0x4E

#define RESOL_12BIT 0x7F

#define START_CONVERT 0x44

#define READ_SCRPAD 0xBE

char string[50];

int ow_Reset(void)

{

int presence;

Wire1_Write(0); //pull DQ line low

CyDelayUs(RESET_PULSE); // leave it low for 480us

Wire1_Write(1); // allow line to return high

CyDelayUs(PRESENCE_PULSE); // wait for presence

presence = Wire1_Read(); // get presence signal

CyDelayUs(END_SLOT); // wait for end of timeslot

return presence; // presence signal returned

} // 0=presence, 1 = no part

void OW_Write_Bit(int bit)

{  

   

    /* Write is initiated from this step*/

    Wire1_Write(0);

   

    // Write '0' bit

    if(bit==0)

    {

        /* Minimum 60us for logic_0 */

        CyDelayUs(WRITE_0_SLOT);

        // Releases the bus

        Wire1_Write(1);

    }

    // Write '1' bit

    else

    {

        /* Release to 1 before 15us for logic_1 */

        CyDelayUs(WRITE_1_SLOT);

        // Releases the bus

        Wire1_Write(1);

        // Complete the time slot

        CyDelayUs(50);

      

    }

    

    /* Minimum recovery time 1us between write steps is ncessary, 10us is used */

    CyDelayUs(RECOVERY_TIME);

}

int OW_Read_Bit(void)

{

   

    /* Initiate read by pulling line low */

    Wire1_Write(0);

    /* Minimum time 1us, to initiate delay */

    CyDelayUs(READ_INIT_DELAY);

    Wire1_Write(1);

    /* Data valid before 15us, should be sampled before that*/

    CyDelayUs(READ_VALID_DELAY);

    // Sample the bit value from the slave

    return(Wire1_Read());

    // Complete the time slot and 10us recovery

    CyDelayUs(58);

}

//-----------------------------------------------------------------------------

// Write 1-Wire data byte

//

void OW_Write_Byte(int data)

{

        int loop;

        // Loop to write each bit in the byte, LS-bit first

        for (loop = 0; loop < 8; loop++)

        {

                OW_Write_Bit(data & 0x01);

                // shift the data byte for the next bit

                data >>= 1;

        }

}

//-----------------------------------------------------------------------------

// Read 1-Wire data byte and return it

//

int OW_Read_Byte(void)

{

        int loop, result=0;

        for (loop = 0; loop < 8; loop++)

        {

                // shift the result to get it ready for the next bit

                result >>= 1;

                // if result is one, then set MS bit

                if (OW_Read_Bit())

                        result |= 0x80;

        }

        return result;

}

int main(void)

{

    int i ;

    int16_t tempx16 ;

   

    CyGlobalIntEnable; /* Enable global interrupts. */

    UART_Start();

    splash("5LP DS18B20 Test") ;

   

    char scratchpad[10];

    int temp_lsb,temp_msb;

    int k;

    //int temp_c;

    //int tempr;

    //uint8 connect;

   

    ow_Reset();

    /* As only single sensor is present in channel-Skip command */

    OW_Write_Byte(SKIP_ROM);

    /*Write Scratch Pad command*/

    OW_Write_Byte(WRITE_SCRPAD);

   

    /* Alarm registers are unused, Writing Random values*/

    /*TH*/

    OW_Write_Byte(0x55);

    /*TL*/

    OW_Write_Byte(0xA2);

    /* Config(resoluion)7F- 12 bit resolution */

    OW_Write_Byte(RESOL_12BIT);

   

    for(;;)

    {

        ow_Reset();

        /*Skip address check command */

       OW_Write_Byte(SKIP_ROM);

       /* Start Convert*/

       OW_Write_Byte(START_CONVERT);

   

       /* Wait until conversion completes */

       CyDelayUs(104);

       ow_Reset();

      

       /*Skip address check command */

       OW_Write_Byte(SKIP_ROM);

       /*Read Scratch Pad command*/

       OW_Write_Byte(READ_SCRPAD);

   

        /*Copy the scratpad from slave*/

        for( k=0;k<9;k++)

        {

        scratchpad=OW_Read_Byte();

        }

       

        print("Data Read : ") ;

        for (i = 0 ; i < 9 ; i++ ) {

            snprintf(str, STR_LEN, "0x%02X ", scratchpad) ;

            print(str) ;

        }

        print(" : ") ;

        #if 0

        for (

            temp_msb = scratchpad[1]; // Sign byte + lsbit

            temp_lsb = scratchpad[0]; // Temp data plus lsb

            if (temp_msb <= 0x80){temp_lsb = (temp_lsb/2);} // shift to get whole degree

            temp_msb = temp_msb & 0x80; // mask all but the sign bit

            if (temp_msb >= 0x80) {temp_lsb = (~temp_lsb)+1;} // twos complement

            if (temp_msb >= 0x80) {temp_lsb = (temp_lsb/2);}// shift to get whole degree

            if (temp_msb >= 0x80) {temp_lsb = ((-1)*temp_lsb);} // add sign bit

            sprintf(string,"\n\rTempC= %d degrees C", (int)temp_lsb ); // print temp. C

           

            UART_PutString(string);

        #endif

       

        /* test data : To test, uncomment one line */

        // scratchpad[0] = 0xD0 ; scratchpad[1] = 0x07 ; /* this is +125 */

        // scratchpad[0] = 0x50 ; scratchpad[1] = 0x05 ; /* this is +85 */  

        // scratchpad[0] = 0x91 ; scratchpad[1] = 0x01 ; /* this is +25.0625 */

        // scratchpad[0] = 0xA2 ; scratchpad[1] = 0x00 ; /* this is +10.125 */      

        // scratchpad[0] = 0x08 ; scratchpad[1] = 0x00 ; /* this is +0.5 */

        // scratchpad[0] = 0x00 ; scratchpad[1] = 0x00 ; /* this is 0.0 */

        // scratchpad[0] = 0xF8 ; scratchpad[1] = 0xFF ; /* this is -0.5 */

        // scratchpad[0] = 0x5E ; scratchpad[1] = 0xFF ; /* this is -10.125 */   

        // scratchpad[0] = 0x6F ; scratchpad[1] = 0xFE ; /* this is -25.0625 */

        // scratchpad[0] = 0x90 ; scratchpad[1] = 0xFC ; /* this is -55.0 */       

       

        temp_msb = scratchpad[1] ; /*   S,   S,   S,   S,    S,  2^6,  2^5,  2^4 */

        temp_lsb = scratchpad[0] ; /* 2^3, 2^2, 2^1, 2^0, 2^-1, 2^-2, 2^-3, 2^-4 */

        tempx16 = (temp_msb << 😎 | temp_lsb ; /* make a int16_t from 2 bytes */

        if (tempx16 < 0) {

            print("-") ;

            tempx16 = -1 * tempx16 ;

        }

        snprintf(str, STR_LEN, "%d", (tempx16 >> 4)) ; /* integer part */

        print(str) ;

        snprintf(str, STR_LEN, ".%04d\n\r", (tempx16 % 16) * 625) ; /* fraction part */

        print(str) ;

    }

}

=======================

attached is the modified project of yours.

moto

0 Likes

Hi MoTa_728816

I am getting this by running your code:

1wire.PNG

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

That screen shot means you are not correctly reading the value of the sensor.

Since I don't have the sensor I can't debug that part.

Please read the datasheet and fix your code

or consider using the "working" sample from /odissey1-san.

moto

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

Once thing I could notice was OW_Read_Bit(), CyDelayUs(58) is never called.

So I would suggest to modify it to

==========================

int OW_Read_Bit(void)

{

    int read_bit ; // <====

    /* Initiate read by pulling line low */

    Wire1_Write(0);

    /* Minimum time 1us, to initiate delay */

    CyDelayUs(READ_INIT_DELAY);

    Wire1_Write(1);

    /* Data valid before 15us, should be sampled before that*/

    CyDelayUs(READ_VALID_DELAY);

    // Sample the bit value from the slave

   read_bit = Wire1_Read() ; // <=====

//    return(Wire1_Read()); // <====

    // Complete the time slot and 10us recovery

    CyDelayUs(58);

    return( read_bit ) ; // <====

}

==========================

moto

0 Likes

Please check the timings

#define READ_INIT_DELAY 6

#define READ_VALID_DELAY 6
1w.jpg
my be:

int OW_Read_Bit(void)

{

    CyDelayUs(20);// Complete the time slot and 10us recovery

    Wire1_Write(0);

    /* Minimum time 1us, to initiate delay */

    CyDelayUs(10);

    Wire1_Write(1);

    /* Data valid before 15us, should be sampled before that*/

    CyDelayUs(5);

    // Sample the bit value from the slave

    return(Wire1_Read());

}

0 Likes