CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

DS18b20 running problem

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
mahdihir



Joined: 01 Dec 2013
Posts: 7
Location: Iran

View user's profile Send private message Send e-mail

DS18b20 running problem
PostPosted: Tue Apr 21, 2015 6:11 am     Reply with quote

My dear friends.
I hope you are doing well.

I need to run a DS18b20 sensor with 4 digit 7 segment.

but the value is shown in display is not the correct temperature.



main cod is:
/////////////////////////////////////
#include <16F1937.h>

#device *=16
#device adc=10

#FUSES NOWDT, HS, PUT, NOPROTECT, NODEBUG, BROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=20000000)

#include<1wire.c>
#include<lcd.c>
#include<ds1820.c>



/* --- configure DS1820 temparture sensor --- */
#define DS1820_DATAPIN PIN_A0

const char n[] ={0xfe, 0xb0, 0x6d, 0x79, 0x33, 0x5B, 0x5F, 0x70, 0xFF, 0x7b , 0x01 , 0x80}; //0 1 2 3 4 5 6 7 8 9 - dot
static char m[] ={0x00, 0X7f, 0XBF, 0XDF, 0XEF };
//static unsigned char Digit;

unsigned int16 digit1_temp, digit2_temp, digit3_temp, digit4_temp, o ;
float temp;

int i ;
//signed int16 d1;
void main()
{
// port_E_pullups(0x0F);


while(TRUE)
{

output_C(0X00);
output_B(0X00);





///////digits
temp = ds1820_read();
o=temp*10;
digit1_temp=o%10;
digit2_temp=o/10%10;
digit3_temp=o/100%10;
digit4_temp=o/1000;

delay_ms(800);



////////////////////////////////////////////// show tempreture
for (i=0; i<50; i++) {
output_c(n[digit4_temp]);
output_B(m[1]);
delay_ms(2);
//output_c(n[0]);

output_c(n[digit3_temp]);
output_B(m[2]);
delay_ms(2);
//output_c(n[0]);

output_c(n[digit2_temp]);
output_B(m[3]);
delay_ms(2);
//output_c(n[0]);

output_c(n[digit1_temp]);
output_B(m[4]);
delay_ms(2);
//output_c(n[0]);
}
}
}
//////////////////////////////////////////////////




the 1wire.c
//////////////////////////////////////////////

// (C) copyright 2003 j.d.sandoz / jds-pic !at! losdos.dyndns.org

// released under the GNU GENERAL PUBLIC LICENSE (GPL)
// refer to http://www.gnu.org/licenses/gpl.txt

// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

/***********************1Wire Class***********************/
/*Description: This class handles all communication */
/* between the processor and the 1wire */
/* sensors.
/*********************************************************/

/*-------1-wire definitions-------*/
#define ONE_WIRE_PIN PIN_A0

/*******************1-wire communication functions********************/

/************onewire_reset*************************************************/
/*This function initiates the 1wire bus */
/* */
/*PARAMETERS: */
/*RETURNS: */
/*********************************************************************/

void onewire_reset() // OK if just using a single permanently connected device
{
output_low(ONE_WIRE_PIN);
delay_us( 500 ); // pull 1-wire low for reset pulse
output_float(ONE_WIRE_PIN); // float 1-wire high
delay_us( 500 ); // wait-out remaining initialisation window.
output_float(ONE_WIRE_PIN);
}

/*********************** onewire_write() ********************************/
/*This function writes a byte to the sensor.*/
/* */
/*Parameters: byte - the byte to be written to the 1-wire */
/*Returns: */
/*********************************************************************/

void onewire_write(int data)
{
int count;

for (count=0; count<8; ++count)
{
output_low(ONE_WIRE_PIN);
delay_us( 2 ); // pull 1-wire low to initiate write time-slot.
output_bit(ONE_WIRE_PIN, shift_right(&data,1,0)); // set output bit on 1-wire
delay_us( 60 ); // wait until end of write slot.
output_float(ONE_WIRE_PIN); // set 1-wire high again,
delay_us( 2 ); // for more than 1us minimum.
}
}

/*********************** read1wire() *********************************/
/*This function reads the 8 -bit data via the 1-wire sensor. */
/* */
/*Parameters: */
/*Returns: 8-bit (1-byte) data from sensor */
/*********************************************************************/

int onewire_read()
{
int count, data;

for (count=0; count<8; ++count)
{
output_low(ONE_WIRE_PIN);
delay_us( 2 ); // pull 1-wire low to initiate read time-slot.
output_float(ONE_WIRE_PIN); // now let 1-wire float high,
delay_us( 8 ); // let device state stabilise,
shift_right(&data,1,input(ONE_WIRE_PIN)); // and load result.
delay_us( 120 ); // wait until end of read slot.
}

return( data );
}



///////////////////////////////////////////////////////////
the ds1820.c
//////////////////////////////////////////////////////////

float ds1820_read()
{
int8 busy=0, temp1, temp2;
signed int16 temp3;
float result;

onewire_reset();
onewire_write(0xCC);
onewire_write(0x44);

while (busy == 0)
busy = onewire_read();

onewire_reset();
onewire_write(0xCC);
onewire_write(0xBE);
temp1 = onewire_read();
temp2 = onewire_read();
temp3 = make16(temp2, temp1);

result = (float) temp3 / 2.0; //Calculation for DS18S20 with 0.5 deg C resolution
// result = (float) temp3 / 16.0; //Calculation for DS18B20 with 0.1 deg C resolution

delay_ms(200);
return(result);
}












thanks
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Tue Apr 21, 2015 6:49 am     Reply with quote

Start by using the "code" button. You've been here long enough to know how it works.

What is wrong with the temperature reading?
Is it:_

A) A totally silly value?
B) Always a bit high/low?
C) Always a lot high/low?
D) Always the same?

Have you tried sending the raw readings to a PC via RS232?

Mike
temtronic



Joined: 01 Jul 2010
Posts: 9205
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Apr 21, 2015 7:51 am     Reply with quote

I'm with Mike on this...

Have you tried sending the raw readings to a PC via RS232?

... you need to
figure out is it a bad sensor or bad program.

If you dump out the raw data and 'do the math' yourself, you'll see where the problem is.

Also read the datasheet to see what the data should be.If your room temperature is 70*c and you get 85*c that's a problem, but if you get 80*C that might be within tolerance.

Jay
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Tue Apr 21, 2015 8:37 am     Reply with quote

Code:
result = (float) temp3 / 2.0; //Calculation for DS18S20 with 0.5 deg C resolution
// result = (float) temp3 / 16.0; //Calculation for DS18B20 with 0.1 deg C resolution


This was the problem for me about 3 days ago that i tried that code.


I "changed" it to this and it worked:

Code:
//result = (float) temp3 / 2.0; //Calculation for DS18S20 with 0.5 deg C resolution
result = (float) temp3 / 16.0; //Calculation for DS18B20 with 0.1 deg C resolution


i didnt spend more time trying to figure out why the first line does not work.
if you do, let us Know.

G.
_________________
CCS PCM 5.078 & CCS PCH 5.093
Ttelmah



Joined: 11 Mar 2010
Posts: 19451

View user's profile Send private message

PostPosted: Tue Apr 21, 2015 9:30 am     Reply with quote

That depends on which chip you actually have.

You need to verify with a magnifying glass whether you have the 'S' or 'B' chips. The former returns counts in 1/16th degree steps, the latter in 1/2 degree steps. If your chip manufacturer does not match the data sheet you are using, get the one from the manufacturer you have, and see how their device labeling works (beware, some have numbers like
DS18
20SB

(on surface mount parts). This is actually an 'S' chip, not a 'B'....
temtronic



Joined: 01 Jul 2010
Posts: 9205
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Apr 21, 2015 10:43 am     Reply with quote

also....

this...

"the ds1820.c"


may not be the correct driver.

I seem to recall 3 variations of the temp sensor and there were minor timing differences. I did use the 'parasitic' version as it allowed for 2 wire operation with 100' of 2 conductor cable.

just something else to consider.

jay
ELCouz



Joined: 18 Jul 2007
Posts: 427
Location: Montreal,Quebec

View user's profile Send private message

PostPosted: Tue Apr 21, 2015 12:17 pm     Reply with quote

temtronic wrote:
also....

this...

"the ds1820.c"


may not be the correct driver.

I seem to recall 3 variations of the temp sensor and there were minor timing differences. I did use the 'parasitic' version as it allowed for 2 wire operation with 100' of 2 conductor cable.

just something else to consider.

jay


Also the 1-wire driver for that have a waiting loop that can hang to whole PIC if no ds18b20 are detected or have failed...

I prefer the TMP75, TMP175 or TMP275 from TI... straight easy I2C! No delays instant reading (*** excluding conversion time for 9 /10 /11 and 12-bit adc)

up to 27 devices on I2C too (TMP175)! (distance might be a factor thought)

EDIT: However with the NXP PCA9600 you can extend the I2C to 100 meters easily!
_________________
Regards,
Laurent

-----------
Here's my first visual theme for the CCS C Compiler. Enjoy!
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Tue Apr 21, 2015 3:25 pm     Reply with quote

.... i should pay more attention to the comments.
i have the DS18B20 Razz
_________________
CCS PCM 5.078 & CCS PCH 5.093
Ttelmah



Joined: 11 Mar 2010
Posts: 19451

View user's profile Send private message

PostPosted: Wed Apr 22, 2015 12:53 am     Reply with quote

Yes.....
Very Happy

Explains a lot. I suspect though that you had 8* the reading you expected, so at least you were working for everything else..

However looking at the original code for this thread, there area lot of steps to everything here:

Debugging must always be a 'divide and conquer' operation. This is what is being pointed to:

1) Get the PIC actually working. Can you display numbers?. Can you (for instance), get a counter working, counting at the correct rate?.
2) Then get the sensor working. This is Temtronics point. Don't try the complexity of tying the display to the sensor, get the number from the sensor, and make sure this is a sensible number.
3) Only once you have each part working _separately_, try to tie them together.

As comments, first there are too many delays.
The sensor needs a delay, between readings while the line is used to power it, but you have 200mSec in this, then another 800mSec in the main code, then another 400mSec while the value is displayed. At least two of these delays can be got rid of.
Then the maths is awful. Get rid of the float. The display just displays integer values, so just change the one wire code to return a suitable integer. If you are only wanting degrees C, then stay with integer in the driver. Just multiply by five, and return this as an integer, not a float.
Then the conversion to digits is done about the most inefficient way possible. Look at ldiv, which returns both the quotient, and remainder, in one operation.

Normally the display would be done using an interrupt, so the value is displayed continuously _while_ the other code is reading the new value. The current approach is going to have the display doing nothing for nearly a second, and then just displaying the value for a little while, then returning to displaying the last segments output, while it goes off and reads a new value. Not exactly easy to read. At the least, turn the display off while taking the new reading, or have the display handled via an interrupt.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group