This project came about after I purchased a "lot of 10" DS18B20 1-Wire temperature sensors. I was skeptical that the sensors were accurate and all reading the same(within tolerance) So, starting with code I got from www.rentron.com, I put together these two programs. The first will read the Address ID of each sensor. The second will allow you to read multiple sensors(using the Address ID) that are in parrallel on a bread board. The sensors are very sensitive and just picking them up will change their temperature, so it was difficult to see if they were all identical.
Ok, so here is the code that will read an individual DS18b20 and output the unique 64 bit serial code. Which include the Family Code, Serial Number and CRC.
This code assumes you are using a PIC16F690, so if you want to use a different micro you may need to modify the initialization to fit your needs.
This information is sent to a Debug window. If you are using a PICkit 2(and probably PICkit3 also) you program the chip, power it up and then goto the Tools Menu and choose UART Tool. This will open up another Terminal window where you choose 2400 baud in the upper left and then click on Connect.
You should then see the various parts of the 64 bit serial code being displayed every 5 seconds. You can simply leave the program running and hot swap sensors onto your breadboard. As each is read and displayed the text will be available to scroll back through. After you change out each sensor, you can then simply copy and paste each of the Serial Numbers into the second program which will then be able to read multiple devices that are all connected to the same pin on your microcontroller. In particular, the last line of the debug display is assembled with $ and , to make the code ready to past right into the program. If you look at the end of the second program you will see where to copy/paste the address ID to make the program work with your sensors.
Code:
'**************************************************************** '* Name : * '* Author : Bruce Reynolds modified By Dwight Merkley * '* Notice : * '* : * '* Date : 7/28/2003, 5/2011 * '* Version : 1.0 * '* Notes : PIC16f690 * '**************************************************************** Reset: TrisA = %00011000 'Port A3,A4 inupts rest outputs (A3 cannot output) TrisB = %00000000 'Port B all outputs TrisC = %00000000 'Port C all outputs ansel = 0 'and turn off analog AnselH = 0 'turn of rest of analogs CM1CON0 = 0 'turn off comparators CM2CON0 = 0 'turn off comparators SSPCON.bit5 = 0 ' disable serial port, pins are I/O OPTION_REG = %10000000 '1 turn off weak pull ups INTCON = %00000000 '=========================================== DQ var PortA.4 ' One-wire Data-Pin "DQ" on PortA.4 Busy VAR BIT ' Busy Status-Bit ID VAR BYTE[8] ' Array storage variable for 64-bit ROM code DEFINE DEBUG_REGG PORTA 'set debug port to porta DEFINE DEBUG_BIT 0 'use pin a0 of porta for debug DEFINE DEBUG_BAUD 2400 'set baud rate to 2400 DEFINE DEBUG_MODE 0 'communicate in true mode '===================================================================== portC=0 'turn off LED's on breadboard Begin: PAUSE 500 ' Wait .5 second Start_Convert OWOUT DQ, 1, [$33] ' Issue Read ROM command '/////////////////////////////////////////////////////////////////////////// ' ' READ ROM [$33] [(from Maxim documentation)] ' 'This command can only be used when there is one slave on the bus. ' 'It allows the bus master to read the slave’s 64-bit ROM code without ' 'using the Search ROM procedure. If this command is used when there ' 'is more than one slave present on the bus, a data collision will ' 'occur when all the slaves attempt to respond at the same time. '/////////////////////////////////////////////////////////////////////////// ID_Loop: OWIN DQ, 0, [STR ID\8]' Read 64-bit device data into the 8-byte array "ID" debug $0D,$0A 'do a linefeed and carrage return DEBUG "64bit = ",HEX2 ID[0],HEX2 ID[1],HEX2 ID[2],HEX2 ID[3],HEX2 ID[4],HEX2 ID[5],HEX2 ID[6],HEX2 ID[7],"h",$0D,$0A DEBUG "Family Code = ",HEX2 ID[0],"h",$0D,$0A DEBUG "Ser# = ",HEX2 ID[1],HEX2 ID[2],HEX2 ID[3],HEX2 ID[4],HEX2 ID[5],HEX2 ID[6],"h",$0D,$0A DEBUG "CRC Value = ",HEX2 ID[7],"h",$0D,$0A debug ">>> the following is complete ID of device <<<",$0D,$0A debug "[$",HEX2 ID[0],",$",HEX2 ID[1],",$",HEX2 ID[2],",$",HEX2 ID[3],",$",_ HEX2 ID[4],",$",HEX2 ID[5],",$",HEX2 ID[6],",$",HEX2 ID[7],"]",$0D,$0A PAUSE 5000 ' 5-second pause, replace sensor for next read GOTO Start_Convert END
Code:
'**************************************************************** '* Name : Temp.BAS * '* Author : Bruce Reynolds modified by Dwight Merkley * '* Notice : Copyright (c) 2003 Reynolds Electronics * '* : All Rights Reserved * '* Date : 7/28/2003, 5/2011 * '* Version : 1.0 * '* Notes : code originates from www.rentron.com * '* : PIC 16F690 * '**************************************************************** Reset: TrisA = %00011000 'Port A3,A4 inupts rest outputs (A3 cannot output) TrisB = %00000000 'Port B all outputs TrisC = %00000000 'Port C all outputs ansel = 0 'and turn off analog AnselH = 0 'turn of rest of analogs CM1CON0 = 0 'turn off comparators CM2CON0 = 0 'turn off comparators SSPCON.bit5 = 0 ' disable serial port, pins are I/O OPTION_REG = %10000000 '1 turn off weak pull ups INTCON = %00000000 '=========================================== DQ var PortA.4 ' One-wire Data-Pin "DQ" on PortA.4 Busy VAR BIT ' Busy Status-Bit Raw VAR WORD ' RAW Temperature readings TempC VAR WORD ' Temp in deg C TempF VAR WORD ' Temp in deg F Float VAR WORD ' Holds remainder for + temp C display Cold_Bit VAR Raw.Bit11' Sign-Bit for +/- Temp. 1 = Below 0 deg C Sign VAR BYTE ' +/- sign for temp display Dummy VAR BYTE ' Dummy for Div32 ID VAR BYTE[8] ' Array storage variable for 64-bit ROM code sensor var byte hexbyte var byte col var byte DEFINE DEBUG_REGG PORTA 'set debug port to porta DEFINE DEBUG_BIT 0 'use pin a0 of porta for debug DEFINE DEBUG_BAUD 2400 'set baud rate to 2400 DEFINE DEBUG_MODE 0 'communicate in true mode '------------------------------------------------------------------------------- 'these constants are available to program the sensor for 9,10,11,12 bit resolution 'DS18B20_9bit CON %00011111 ; 93.75ms, 0.5°C 'DS18B20_10bit CON %00111111 ; 187.5ms, 0.25°C <-- My favorite 'DS18B20_11bit CON %01011111 ; 375ms, 0.125°C 'DS18B20_12bit CON %01111111 ; 750ms, 0.0625°C (default) ' use the statement below in your program to set the resolution 'OWOUT comm_pin, 1, [$CC, $4E, 0, 0, DS18B20_9bit] 'set resolution of sensor '================================================================= '============ Main Program loop ================================== '================================================================= portC=0 'turn off LED's on breadboard '----------------------------------------------------------------- Begin: PAUSE 500 ' Wait .5 [1/2] seconds Main for sensor=1 to 9 'I am reading 9 DS18b20 sensors... change this to match how many sensors you are reading portC=sensor 'use the 4 breadboard led's to count binary as each sensor is read for hexbyte=0 to 7 'each sensor address is 8 bytes gosub getid 'go look up each sensors address id[hexbyte]=col 'load the ID array with the retrieved address byte next hexbyte 'go get the rest of the address bytes gosub readsensor 'now go read the current sensor gosub DisplayTemp 'now display the temp of the current sensor next sensor 'now go read another sensor portC=0 'done with all 9 sensors... turn off led's debug $0D,$0A 'reset terminal cursor to home, upper left end 'end here... use reset button to read them again. '============= subroutines ======================== ReadSensor: OWOUT DQ, 1, [$55,str id\8,$44] 'instructs sensors to match[$55] this[ID] rom code and 'initiates[$44] temperature conversion on matching sensor CkAgn: OWIN DQ, 4, [busy] ' Check for still busy converting IF busy = 0 THEN ckagn ' Still busy?, then loop owout dq,1,[$55,str id\8,$BE] 'instructs sensors to match[$55] this[ID] and start sending back scratchpad[$BE] OWIN DQ, 2, [Raw.LOWBYTE,Raw.HIGHBYTE]' Read two temperature bytes, then end communications return '------------------------------------------------------------- DisplayTemp: ' +32.0 to +257 F IF Cold_Bit = 1 THEN Cold ' If Cold_Bit = 1, it's below "0" deg C Sign = "+" Dummy = 625 * Raw ' Multiply to load internal registers with 32-bit value TempC = DIV32 10 ' Use Div32 value to calculate precise deg C TempC = (Raw & $0FF0) >> 4 ' Mask middle 8-bits, shift into lower byte Float = ((Raw.Lowbyte & $0F) * 625) ' Lower 4-bits of result * 625 debug dec sensor," TempC = ",Sign,DEC TempC,".",DEC Float," C ",$0D,$0A ' debug "Raw ", IBIN16 Raw," Dec=",dec (Raw>>3),$0D,$0A 'display the raw value RETURN ''------------------------------------------------------------ Cold: ' arrive here if temp is below zero C Sign = "-" ' Display - symbol for negative temp Dummy = 625 * ~Raw+1' Multiply to load internal registers with 32-bit value TempC = DIV32 10 ' Use Div32 value to calculate precise deg C debug dec sensor," TempC = ",Sign,DEC TempC DIG 4,DEC TempC DIG 3_ ,".",DEC3 TempC," C ",$0D,$0A ' debug "Raw", IBIN16 Raw," Dec ",(Raw>>3),$0D,$0A RETURN '============================================================= 'below is a list of the addresses of each of the 9 sensors I am reading 'these must match the sensors you are trying to read... 'use "Read Rom" program to determine the addresses of each of these sensors GetID: Select Case sensor Case 1 :LOOKUP hexbyte,[$28,$1E,$F5,$24,$03,$00,$00,$B8], col Case 2 :LOOKUP hexbyte,[$28,$4E,$F4,$24,$03,$00,$00,$5B], col Case 3 :LOOKUP hexbyte,[$28,$35,$FC,$24,$03,$00,$00,$05], col Case 4 :LOOKUP hexbyte,[$28,$4D,$2C,$25,$03,$00,$00,$ED], col Case 5 :LOOKUP hexbyte,[$28,$45,$F8,$24,$03,$00,$00,$82], col Case 6 :LOOKUP hexbyte,[$28,$FC,$FC,$24,$03,$00,$00,$0C], col Case 7: LOOKUP hexbyte,[$28,$BB,$02,$25,$03,$00,$00,$77], col Case 8 :LOOKUP hexbyte,[$28,$32,$24,$25,$03,$00,$00,$6F], col Case 9 :LOOKUP hexbyte,[$28,$4C,$A5,$24,$03,$00,$00,$6D], col end select return
http://www.rentron.com/PicBasic/PBP1-wire.htm
http://www.rentron.com/PicBasic/one-wire2.htm
http://www.rentron.com/PicBasic/one-wire3.htm
I simply took his working code and modified it to work with a debug window instead of an LCD and made it work with 9 temperature sensors. Bruce's code originally read two temp sensors and two 1-wire switches. As always take a look at the data sheet for what ever sensor or switch you are using and you can get a better idea of what is possible.
The third page link above actually has code that accuratly displays C and F as well as the raw 64 bit data.
It should be quite easy to modify this to work with most any PIC micro you might have available. Simply look through the code and you will se I used PortA.4 as the 1-wire connect pin.
I thought about combining these two programs into one and using one more PIC pin to tell the software to either run the first section of code to read an individual sensor or GOTO the second section to read multiple sensors. (have fun) Also if you don't have a PICkit you should be able to use any other programmer and an LCD, with some minor changes.
Again, Thanks to Bruce for providing the basis of this code.
Enjoy!!
P.S. I use MicroCodeStudio as my IDE but I would assume that you can just copy and pase this code into your own IDE. (Integrated Development Enviornment) I have also attached the two programs to this post. When I looked at the post I could see that some of the formatting is lost.
Don't forget to use a pull-up resistor on the 1-wire data line. Maxim recomends a 4.7K but I used a 10K.
For some reason I was unable to upload the native file using extension of .pbp, so I changed it to .txt. You should be able to open it up in a text editor and copy/paste into your IDE or possibly just change the extension back to .pbp
Re: CAN header and EXT asm question
Interface board with SPI controlled MCP 2515 and line driver to use with non CAN enabled PIC's
retepsnikrep Yesterday, 08:34https://www.aliexpress.com/item/1005006850683509.html
Line driver to use with CAN enabled PIC's....