- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Labels:
-
PSoC 5 Device Programming
-
PSoC 5LP
- Tags:
- psoc5lp
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
signals of your project:
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
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
}
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Please check the timings
#define READ_INIT_DELAY 6
#define READ_VALID_DELAY 6
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());
}