Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

BoostC manual one-wire example won't work?

Status
Not open for further replies.

futz

Active Member
I'm probably doing it wrong, but I'm using this piece of code (straight from Page 81 of the BoostC manual) to read my 18B20:
Code:
		oo_busreset();
		oo_start_conversion();
		if(oo_wait_for_completion()){
			error=0xff;
		}
		if(oo_read_scratchpad()){
			error=0xff;
		}
		celsius=oo_get_data();
The numbers in celsius change as the sensor changes temperature, but they don't jive with what's in the 18B20 datasheet at all. I'm getting results like celsius=$bfaf. Makes no sense to me (so far). If I take the two middle nybbles as my temperature I get -122C? What?
 
The description in the manual is rather vague. The readscratchpad command would read the temperature data and so you would just have to get the first two bytes of the returned data. The following read_data command also reads data from the bus even though the previous command has already read the temperature. Very confusing.

I would be tempted to write my own functions. I have 16f88 asm code if it's any help.

Mike.
 
Despite the fact that I think this is a good little compiler, I think the example code and some of the 'driver source' they provide is very uneven in terms of quality and correctness. It seems they are short on examples, and could use some help in that area. Their forums are also a bit lacking in terms of posting and could also use some help... So in that regard I would follow Pommie's advice, and when you do get it, as I know you will, send the working example to Pavel and perhaps get some free plug ins, or your name up in lights.... :D

Recently I came across a thread here where AtomSoft ran into the same trouble as you, futz, where he couldn't get any breakpoints with his PicKit2 using Boost C. I don't have a working PicKit2 yet, so hesitate to post the question on the Boost forums.

I also see that 3V0 and MikeK8LH's questions on the 'click on error' in MPLab are not answered. I have this same thing, but have never questioned it, as I have used compilers in the past which also lacked this same feature... I guess I should add a post or two on that, and help pump up their forum, rather than just avoid it as it is so short on posts... :D

I think something has changed with the compiler and some past examples are broken. I searched ds1820 on the Boost forums and got several hits. One reply was
Hello,
The libary code for one wire library use the nop() instruction. They should rewrite this lib becasue now it´s not working with different clock frequency. A work around is to run goodies if you have pro licens and change the code your self. Or you can download the lib code from lika.be

On another thread: **broken link removed**

Daz,

I initially had a similar problem with the library.

I downloaded the source from Lieven Hollevoet's website and found that it worked fine once I modified the source. In the oo_wait_for_completion() function, I changed the line: while (oo_conversion_busy()) { to: while (!oo_conversion_busy()) {

If you check the datasheet for the one wire device, you will see that the device will pull the bus low(transmit 0) after a Convert T command is issued and will hold it until the conversion is finished. Without the change, the oo_conversion_busy() function is immediately returning False to the oo_wait_for_completion() function causing it to exit prematurely.

EDIT:
Lieven Hollevoet's site is http://www.lika.be/content/view/21/30/

Now I need to get back to that external EEPROM stuff for Atom because it is taking me too long to finish, and I've got tons of my own stuff to get onto this week.
 
Last edited:
Thanks guys. My first inclination was to write my own, but I decided to be lazy and see how their libs worked first. So far, not so good. But I'll work at it a little more before giving up. :p
 
I've been meaning to get familiar with Boost C and so I converted my 16f88 asm code to boost C and it's all working fine. Let me know if you want me to post it. I still have a little bugget at the moment, the device reports it's not present but then returns the correct temperature!!

Mike.
 
Ask Boost

Futz,

Post you question to the Source Boost forum **broken link removed**

The compiler developers are there and will work with you.

:D
 
The description in the manual is rather vague. The readscratchpad command would read the temperature data and so you would just have to get the first two bytes of the returned data. The following read_data command also reads data from the bus even though the previous command has already read the temperature. Very confusing.
Actually it doesn't. It extracts the temperature info from the previously read scratchpad data. Comment out the scratchpad read and all read_data returns is zero's.

But none of that matters anymore. I borrowed some code from Maxim AN162 and modified it to suit. Works perfect and it's simple to understand. :D **broken link removed** is displaying temperature now.

Much better than using "canned" libs. Doing it that way I would never understand what's going on "under the hood". Boring! :p
 
Last edited:
Good to hear you got it working. It's always better (in a fun way) to write your own routines and as you say, you get a much better understanding of the underlying system.

BTW, I was just going off the BoostC manual that states,
short oo_get_data()
(function) Reads data from one wire bus.

Mike.
 
That's a good 1-wire application note. I don't care for the table based CRC code though. Too much "overhead". Some alternatives to consider;

Code:
;******************************************************************
;
;  Mike McLaren's Dallas one-wire 8-bit CRC code for the DS18B20
;
;  clear the CRC variable then run each byte from the scratchpad
;  read or ROM read operation through the CRC_Calc subroutine. A
;  final CRC value of '0' indicates "good data".
;
;    void CRC_Calc ()
;    { crc ^= IOByte;
;      for (i = 0; i < 8; i++)
;      { if (crc & 1)
;          crc = (crc >> 1) ^ 0x8C;
;        else
;          crc =  crc >> 1;
;      }
;    }
;
;  entry: IOByte contains data byte
;   exit: CRC contains cumulative CRC data
;
CRC_Calc
        movlw   d'8'            ;                                 |B0
        movwf   BitCtr          ; setup bit counter               |B0
        movf    owByte,W        ;                                 |B0
        xorwf   CRC,F           ;                                 |B0
        movlw   h'8C'           ; W = x8+x5+x4+1 polynomial       |B0
CRC_Next
        clrc                    ;                                 |B0
        rrf     CRC,F           ;                                 |B0
        skpnc                   ;                                 |B0
        xorwf   CRC,F           ; toggle b7, b3, and b2 bits      |B0
        decfsz  BitCtr,F        ; all done? yes, skip, else       |B0
        goto    CRC_Next        ; process the next IOByte bit     |B0
        return                  ;                                 |B0
Code:
;
;  Scott Dattalo's 20 word/23 cycle version (incredible)
;
crc_8
        xorwf   CRC,f           ;                                 |B0
        clrw                    ;                                 |B0
        btfsc   CRC,0           ;                                 |B0
        xorlw   0x5e            ;                                 |B0
        btfsc   CRC,1           ;                                 |B0
        xorlw   0xbc            ;                                 |B0
        btfsc   CRC,2           ;                                 |B0
        xorlw   0x61            ;                                 |B0
        btfsc   CRC,3           ;                                 |B0
        xorlw   0xc2            ;                                 |B0
        btfsc   CRC,4           ;                                 |B0
        xorlw   0x9d            ;                                 |B0
        btfsc   CRC,5           ;                                 |B0
        xorlw   0x23            ;                                 |B0
        btfsc   CRC,6           ;                                 |B0
        xorlw   0x46            ;                                 |B0
        btfsc   CRC,7           ;                                 |B0
        xorlw   0x8c            ;                                 |B0
        movwf   CRC             ;                                 |B0
        return                  ;                                 |B0
Code:
;******************************************************************
ow.RdBuf
        movwf   DigCtr          ; save digit count (8 or 9)       |B0
        clrf    CRC             ; clear CRC var                   |B0
        movlw   owBuf           ; address of 9 byte 'owBuf'       |B0
        movwf   FSR             ; setup indirect access           |B0
ow.RdByte
        movlw   8               ;                                 |B0
        movwf   BitCtr          ; bit counter = 8                 |B0
ow.RxBit
        DelayUS(tSlot-tClk-tRd) ; delay 50 usecs                  |B0
        owRdBit                 ; returns C = data bit            |B0
        rrf     INDF,F          ;                                 |B0
        decfsz  BitCtr,F        ; all 8 bits? yes, skip, else     |B0
        goto    ow.RxBit        ; read next bit                   |B0
;
;       crc ^= IOByte;
;       for (i = 0; i < 8; i++)
;       { if (crc & 1)
;           crc = (crc >> 1) ^ 0x8C;
;         else
;           crc =  crc >> 1;
;       }
;
        movf    INDF,W          ; W = current byte                |B0
        xorwf   CRC,F           ;                                 |B0
        bsf     BitCtr,3        ; bit counter = 8                 |B0
        movlw   h'8C'           ; W = x8+x5+x4+1 polynomial       |B0
NxtCRC
        clrc                    ;                                 |B0
        rrf     CRC,F           ;                                 |B0
        skpnc                   ;                                 |B0
        xorwf   CRC,F           ; toggle b7, b3, and b2 bits      |B0
        decfsz  BitCtr,F        ; all done? yes, skip, else       |B0
        goto    NxtCRC          ; process next bit                |B0
;
        incf    FSR,f           ; inc 'owBuf' array postion       |B0
        decfsz  DigCtr,F        ; all 8/9 bytes? yes, skip, else  |B0
        goto    ow.RdByte       ; collect another byte            |B0
        return                  ;                                 |B0
 
Last edited:
Hey Futz,

Do you have a DS18S20 by any chance? If so, are you in a position to test this code?

I thought I would pull the family ID from the serial number and if it wasn't 0x28 (DS18B20) I would use this routine to format the two byte DS18S20 temperature data as full resolution DS18B20 data after reading the scratchpad. Count_Remain = scratchpad+6 on the DS18S20.

Code:
;
;  TempH:L = (TempH:L / 2) * 16 + (16 - Count_Remain)
;
 
That's a good 1-wire application note. I don't care for the table based CRC code though. Too much "overhead".
I only have one sensor, so I simplified their code bigtime! I don't know nothin about CRC's yet. :D I'll have to recomplexify things a bit when I add a second sensor.

I absolutely hated their method of doing the delays. That got completely reworked.
 
Last edited:
Hey Futz,

Do you have a DS18S20 by any chance? If so, are you in a position to test this code?

I thought I would pull the family ID from the serial number and if it wasn't 0x28 (DS18B20) I would use this routine to format the two byte DS18S20 temperature data as full resolution DS18B20 data after reading the scratchpad. Count_Remain = scratchpad+6 on the DS18S20.

Code:
;
;  TempH:L = (TempH:L / 2) * 16 + (16 - Count_Remain)
;
Seems to work well. Of course I'm not taking advantage of all the info, so I don't know for 100% sure. But my 18B20 int-rip-apart-and-reassemble-the-two-middle-nybbles-as-a-byte code works perfect. :D

Should put one of these sensors on the Junebug and connect an LCD or somehow get it to a bigger display. Two digits isn't enough to really test it properly, at least without too much work.

Also, even though there's a "mikeflag" flag bit to tell which type of sensor it is, it isn't used at present. Since I have only an 18S20 plugged in, I just left out the 18B20 part of the code that the flag would force a branch to if the Family Code was $28.

Here's the function it's in:
Code:
void readtemp(void)
{
	int miketemp;
	unsigned char store[10];
	unsigned char romstore[9];
	unsigned char x,msb,lsb,digit1,digit2,countremain;
	bit mikeflag=0;
	owreset();
	owwritebyte(0xcc);			//skip ROM
	owwritebyte(0x44);			//start conversion
	delay_ms(100);

	owreset();
	owwritebyte(0x33);			//read ROM
	for(x=0;x<8;x++)
		romstore[x]=owreadbyte();
	delay_ms(100);
	if(romstore[0] != 0x28)
		mikeflag=1;
	
	owreset();
	owwritebyte(0xcc);			//skip ROM
	owwritebyte(0xbe);			//read scratchpad
	for(x=0;x<9;x++)
		store[x]=owreadbyte();
	countremain=store[6];
	msb=store[1];lsb=store[0];
	MAKESHORT(miketemp,lsb,msb);
	[COLOR="Red"]miketemp=(miketemp/2)*16+(16-countremain);[/COLOR]
	HIBYTE(msb,miketemp);LOBYTE(lsb,miketemp);
	msb=msb<<4;lsb=lsb>>4;
	x=0;
	x=x|msb|lsb;
	fix(x);					//convert for display
}
 
Recently I came across a thread here where AtomSoft ran into the same trouble as you, futz, where he couldn't get any breakpoints with his PicKit2 using Boost C. I don't have a working PicKit2 yet, so hesitate to post the question on the Boost forums.
PICkit 2 debugging support isn't nearly so universally available as ICD2 debugging support (yet). Some chips just aren't properly supported, and they may or may not ever be (like the now obsolete 18F248). Lucky for me I have a nice fast Inchworm+/Unicorn (ICD2) that debugs my 18F248's just fine, thank you very much. :p

Does anyone know anything about the ICD2 stuff mentioned on Page 21 of the BoostC manual? I've had some slight strangeness when debugging even with the Inchworm+. Restarting everything fixed it. Maybe I should play with their suggestions and see if it clears up.

I also see that 3V0 and MikeK8LH's questions on the 'click on error' in MPLab are not answered. I have this same thing, but have never questioned it, as I have used compilers in the past which also lacked this same feature...
Doesn't bother me a bit, as I always have line numbers turned on. As long as it tells me the line number the error is on (it does!) I have no problem finding it. I merely aim my eye at the code window and sometimes scroll up or down a bit. :p

To turn on line numbers, just go to Edit/Properties and select the 'C' File Types tab. Check the Line Numbers box in the upper left and hit OK. That's all!
 
Last edited:
Futz,

Thanks for checking out tha DS18S20 code snippet. I've been meaning to update my little 12F675 serial 4-channel 1-wire temperature board with that code so that it would support all three DS1820 types...

Take care... Mike
 
Last edited:
Thanks for checking out tha DS18S20 code snippet. I've been meaning to update my little serial 4-channel 1-wire temperature board with that code so that it would support all three DS1820 types...
Mike! You're famous again! :p Using your countremain calculation I finished fixing the code for my **broken link removed** so it works with either the 18B20 or the 18S20.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top