View previous topic :: View next topic |
Author |
Message |
Gordon23
Joined: 17 Feb 2024 Posts: 6 Location: UK
|
DS18B20 - Whole number only |
Posted: Sat Feb 17, 2024 3:49 am |
|
|
Hi,
I have used the DS18B20 example project, with a PICF18855, i have not changed the code, or the driver ds18b20. (only included my header file to the top of the main.c file)
I have connected my PIC to a terminal program via my UART lead.
I have the following header for my device:-
#include <16F18855.h>
#use delay(internal=12MHz)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=PORT1,FORCE_SW)
I found i had to use 12mhz to make it work at all -
It is working, but i can only see whole results, i.e. temp=19C - it does vary when touch etc.
Am i doing something wron with the output?
Any pointers would be grateful.
Thanks. |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Sat Feb 17, 2024 5:24 am |
|
|
Hi,
the code should be so short you could post it complete. One question: why are you using software UART? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Sat Feb 17, 2024 6:44 am |
|
|
comments..
'high' numbered PIC... does it have PPS ?
Peripheral Pin Select requires you to 'map' them before using them AND not all pins can be mapped to all perhipherals.
whole number only could be the 'print format' you're using. Do you send to a local LCD module or via RS232 to a PC running a terminal program ?
One Wire requires a certain speed to run properly.
As others have said, need to see your 'short' program to debug.
I've used that temp sensor a lot so I know it works with the PIC18F46k22, and others. |
|
|
Gordon23
Joined: 17 Feb 2024 Posts: 6 Location: UK
|
|
Posted: Sat Feb 17, 2024 10:13 am |
|
|
Is it OK to publish the CCS code?
I have used the digital therm example, and the ds18b20 driver, i have not modified them in any way. (just included my header).
I am using a terminal program, i must have the pin setup as i am received data, looks like i am seeing just one byte, not the remainder.
So i think i am not formatting or sending this correctly, the CCS example is for the e3 mini.
Thanks |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Sat Feb 17, 2024 10:47 am |
|
|
Don't post any CCS header files.
Publish what you have written. A simple #include <ccs file> will suffice if you have not modified the CCS file.
Be sure to include your specific compiler version. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Sun Feb 18, 2024 12:21 pm |
|
|
You understand that you need to cast the returned value before you
divide it to give a fractional result.
So you have an integer value from the sensor as temperature *16.
If you are making a floating point degrees value from this you need to use:
degrees = temp/16.0;
or
degrees = (float)temp/16;
If instead you code as:
degrees = temp/16;
This will use _integer_ division, so you will only get integer degrees in
the result. Degrees must be a float. |
|
|
Gordon23
Joined: 17 Feb 2024 Posts: 6 Location: UK
|
|
Posted: Sun Feb 18, 2024 2:02 pm |
|
|
Thank you Ttelmah.
This worked perfect, i think i perhaps picked the worng project to get started with, but i will take some time trying to undertand.
Thanks |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Sun Feb 18, 2024 3:39 pm |
|
|
It's quite easy. You declare your Temp variable as int16. You read the sensor and get a 40 in Temp. Now you divide Temp/16 and get a 2. This is integer division that doesn't care about fractions, only whole numbers. You could declare Temp as a float at the start or use casting as Mr. Ttelmah wrote. In that case Temp/16 will give you a 2.5, which is the correct result or better, the result you are looking for. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Sun Feb 18, 2024 5:28 pm |
|
|
FWIW, found this 'somewhere' on this PC....
stuff I can kinda recall( it's been YEARS...)
reading is changed into *C scaled integers...
that's converted to *F ,cause I like *F...
LCD module display raw DStemp sensor bits
as well as temperature in *C and *F
I used 1 temp sensor per I/O pin
dsbits is the 16 bits from the DS temp sensor..
void display2() {
dscopy=dsbits; //save a copy of original dsbits
if(dsbits&0x8000)
{
dscopy=dsbits;
dsbits=~dsbits+1;
dstemp=dsbits;
dstemp =(dstemp>>4)& 0x00FF; //-ve *C rdg
}
else
{
dstemp=dsbits;
dstemp=(dstemp>>4) & 0x00FF; //+ve *C rdg
}
// scaled integer temperature
s=dstemp; //*C temp
s=s*10000; //scaled *C temp
//add on fractional part of raw temperature
if(dsbits&0x0001) s=s+625; //add fractions
if(dsbits&0x0002) s=s+1250; //as
if(dsbits&0x0004) s=s+2500; //required
if(dsbits&0x0008) s=s+5000; //1255000 = 125.500*C
sf=s;
sf=sf*9;
sf=sf/5;
if(dscopy&0x8000) {
sf=320000-sf;
if(sf<1)np='-';
}
else {
sf=320000+sf;
np=' ';
}
lcd_gotoxy(1,1);
printf(lcd_putc,"DS %4lx",dsbits);
lcd_gotoxy(1,2);
printf(lcd_putc,"current");
lcd_gotoxy(1,3);
printf(lcd_putc,"%c",np);
lcd_gotoxy(2,3);
printf(lcd_putc,"%7.4w",sf); |
|
|
|