Log in

View Full Version : 1Wire conversion



MOUNTAIN747
- 24th January 2025, 18:09
I am working with a pair of DS1820 temperature sensors. I need to display the temperature on a Sure 0832 dot matrix display. This means I need to take the DS1820 output and break it into each decimal digit of the resulting temperature. The 1Wire output is in 16 bit sign-extended 2,s complement number. I’m not sure about the best approach to this problem.
I could shift off bit 0-3 and have the next eight bits Binary if the S bit is 0. then I would have to convert to Decimal or use a lookup table. Once in Decimal I must breakout each digit of the number to send it to the display. This makes me wonder how PBP3 handles this conversion in “lcdout” to display in decimal. Is there a better method. Comments Please!
Wayne

richard
- 25th January 2025, 00:50
first off there are ds18s20 and ds18b20 devices each would need slightly different treatment.
then you need to decide the resolution and "sign" you wish to display.
if negative[below zero] temps are involved the the sign bit of the result must be properly accommodated before results are scaled.
once you have a unsigned scaled binary result pbp can extract the digits with the DIG function.
the digits can then be displayed along with the sign and decimal point if needed as you desired.

MOUNTAIN747
- 25th January 2025, 14:55
Thanks Richard, I had forgotten about the DIG function. Thanks for the reminder, I'll give it a try.

MOUNTAIN747
- 26th January 2025, 00:40
Continuing with the same project. I have run into this problem many times over the years and I have yet to understand it. Why does this "If Then" statement fail to compile.


if Bvar = 0 then Cimage
else Avar = Bvar
gosub GetImage
endif


I can rewrite it in any form with the same results. It does not compile.
I get an error code "Endif without a If...Then statment. It seems like a no brainer but I just don't' understand what I'm doing wrong.

richard
- 26th January 2025, 01:35
one of the reasons snippets are fairly useless is that assumptions have to be made, however assuming Cimage is a subroutine

the correct syntax is



if Bvar = 0 then
gosub Cimage
else
Avar = Bvar
gosub GetImage
endif

MOUNTAIN747
- 26th January 2025, 23:12
Your right as always! Not very forgiving is it. The format doesn't seem to fallow that of other functions.
thanks Richard

MOUNTAIN747
- 27th January 2025, 21:21
I've been trying to find some code to extract the 64-bit serial code from the 1wire devise. I think DT posted this routine but I have been unable to find it. Can anyone help?

Acetronics2
- 28th January 2025, 21:03
Hi,

This one could be useful ...



'* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
'* Universal thermostat -25/+75 C. by R.T.G. van Steenis *
'* Compiler : PicBasic Pro 2.45 *
'* B0 = Mode switch in (In) A0 = LCD Enable (Out) *
'* B1 = + switch in (In) A1 = LCD RS (Out) *
'* B2 = - switch in (In) A2 = "Warm" Output (Out) *
'* B3 = Not connected (Out) A3 = "Cold" Output (Out) *
'* B4 = LCD Bit 4 (Out) A4 = DQ DS1820 (In) *
'* B5 = LCD Bit 5 (Out) *
'* B6 = LCD Bit 6 (Out) *
'* B7 = LCD Bit 7 (Out PIC16F877A Code size = 1966 Words *
'* *
'* Oscillator XT (4 MHz.) - Power up timer enabled - MCR enable *
'* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *




'************************************************* ****************************
'* LCD Defines for EasyPic5 & 16F877A *
'************************************************* ****************************


'@ ERRORLEVEL -306
'@ __config _HS_OSC & _WDT_ON & _PWRTE_ON & _BODEN_ON & _LVP_OFF & _CP_OFF
'
' DEFINE LCD_DREG PORTB ' I/O port where LCD is connected
' DEFINE LCD_DBIT 0
' DEFINE LCD_RSREG PORTB
' DEFINE LCD_RSBIT 4 ' Register select pin
' DEFINE LCD_EREG PORTB
' DEFINE LCD_EBIT 5 ' Enable pin
' DEFINE LCD_BITS 4 ' 4-bit data bus
' DEFINE LCD_LINES 2 ' LCD has 2 character lines
'
' DEFINE OSC 8
' DEFINE BUTTON_PAUSE 100
'
''************************************************ *****************************
''Pinout for EasyPic5
''
''
' Heat Var PORTC.0
' Cool Var PORTC.2
' Waitbit Var PortC.4
' DQ Var PORTE.2 ' One-wire data pin
'
' Mode_B Var PORTA.0 'Pullups ...
' UP_B Var PORTA.1
' DOWN_B Var PORTA.2
''
''************************************************ *****************************
''Configs EasyPic5
''************************************************ *****************************
''
'ADCON1 = 7 ' Set PORTD and PORTE to digital
'CMCON = 7 ' Comparators OFF
'
'PORTA = %00000111
'PORTB = 0
'PORTC = 0
'PORTD = 0
'PORTE = 0
'
'TRISA = %00000111
'TRISB = 0
'TRISC = 0
'TRISD = 0
'TRISE = %00000100
'************************************************* ****************************
'
'
'************************************************* ****************************
'************************************************* ****************************
' Elektor LCD Defines


@ __CONFIG _XT_OSC & _WDT_ON & _PWRTE_ON & _MCLRE_ON & _BODEN_OFF & _LVP_OFF & _CP_OFF






DEFINE LCD_DREG PORTB ' LCD on port B
DEFINE LCD_DBIT 4 ' Data bits B4..B7
DEFINE LCD_RSREG PORTA ' RS on PORTA
DEFINE LCD_RSBIT 1 ' RS on A1
DEFINE LCD_EREG PORTA ' E on PORTA
DEFINE LCD_EBIT 0 ' E on A0
DEFINE LCD_BITS 4 ' LCD 4 bit mode
DEFINE LCD_LINES 2 ' 2 line LCD display


'************************************************* ****************************
'Pinout for Elektor


Heat Var PORTA.2
Cool Var PORTA.3
DQ Var PORTA.4 ' One-wire data pin

Mode_B Var PORTB.0
UP_B Var PORTB.1
DOWN_B Var PORTB.2
'************************************************* ****************************
' I/o Settings


PORTA = 0
PORTB = 0
TRISA= %11110000 ' RA0..3=Outputs RA4=Input
TRISB= %00000111 ' RB0..RB2=Inputs, RB3..RB7=Outputs
CMCON=7 ' Disable comparators


'************************************************* ****************************


'************************************************* ****************************
' Variables
'************************************************* ****************************


Temperature Var Word ' Temperature storage
TempC Var Word
Float Var Word
TargetTemp Var Word ' Desired Temperature
Hyst Var Word ' Hystereris
V Var Word ' Var. for display
Cadence Var Word


B1 Var Byte ' Byte for TargetTemp calculation
B2 Var Byte ' Byte for TargetTemp calculation
Sign Var Byte ' +/- sign
Mode Var Byte ' 0=Temp. display, 1=Set Temp, 2=Set Hysteresis
DS18B20_Bit Var Byte
FAM Var Byte
CRC Var Byte
ID Var Byte[7]


Twist Var Bit
Busy Var Bit
Disable_out Var 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)


Resolution CON 12
Offset CON 300


'************************************************* ****************************
'Initialization
'************************************************* ****************************


SELECT CASE Resolution

Case 9
DS18B20_bit = %00011111 ' 93.75ms, 0.5°C
Cadence = 900
Case 10
DS18B20_bit = %00111111 ' 187.5ms, 0.25°C <-- My favourite
Cadence = 810
Case 11
DS18B20_bit = %01011111 ' 375ms, 0.125°C
Cadence = 625
Case 12
DS18B20_bit = %01111111 ' 750ms, 0.0625°C (default)
Cadence = 250

END SELECT




DATA 46, 224, 20 ' Temp MSB, TEMP LSB, Hysteresis DIV 10


Heat=0 ' Warm Output Low
Cool=0 ' Cold Output Low
Disable_out = 1
Mode=0 ' Temperature display mode
Twist = 0




'************************************************* ****************************
' Program start
'************************************************* ****************************


PAUSE 500


READ 0, B1 'READ TargetTemp MSB
READ 1, B2 'READ TargetTemp LSB
TargetTemp=B1*256+B2 ' Calculate TargetTemp value (Default=20.0 C.)
READ 2, B1 'READ Hysteresis
Hyst=10*B1 ' Calculate Hysteresis value (Default= 2.0 C.)

LCDOUT $FE, 1, $FE, $0C ' Clear display, cursor off
PAUSE 250


'************************************************* ****************************
SensID:' Sensor Identification
'************************************************* ****************************


OWOUT DQ, 1, [ $33 ] 'READ Chip Family code
OWIN DQ, 2, [ FAM,ID[6],ID[5],ID[4],ID[3],ID[2],ID[1],CRC]

IF FAM = $05 THEN

LCDOUT $FE,$80, "DS 2405 "

PAUSE 1000

LCDOUT $FE,$80, " CRC: ",HEX2 CRC," FAM: ", HEX2 FAM

ENDIF

'************************************************* ****************************
' DS 1820 / DS 18S20
'************************************************* ****************************

IF FAM = $10 THEN

LCDOUT $FE,$80, "DS 18S20/1820"

PAUSE 2000

LCDOUT $FE,$80, " CRC: ",HEX2 CRC," FAM: ", HEX2 FAM

ENDIF

'************************************************* ****************************
' DS 18B20 Config
'************************************************* ****************************

IF FAM = $28 THEN

LCDOUT $FE,$80, "DS 18B20 "

OWOUT DQ, 1, [$CC, $4E, 0, 0, DS18B20_bit] 'Skip ROM search and write N_bits
' resolution to scratch pad

'************************************************* ****************************
'DS 18B20 PAR Test
'************************************************* ****************************


HIGH DQ
PAUSE 10 'Keep DQ High for 10 ms
INPUT DQ

'************************************************* ****************************

PAUSE 2000

'************************************************* ****************************
' Show CRC and FAM
'************************************************* ****************************

LCDOUT $FE,$80, " CRC: ",HEX2 CRC," FAM: ", HEX2 FAM

ENDIF


'************************************************* ****************************
' Show ID
'************************************************* ****************************

LCDOUT $FE,$C0," ID:",HEX2 ID[1],HEX2 ID[2],HEX2 ID[3],HEX2 ID[4],HEX2 ID[5],HEX2 ID[6]

PAUSE 2000

'************************************************* ****************************
' Clear Screen
'************************************************* ****************************

LCDOUT $FE,1



'************************************************* ****************************
'************************************************* ****************************
MainLoop:

'************************************************* ****************************
' Select and Save Function
'************************************************* ****************************

If Mode_B=0 then ' Mode switch pressed

Pause 50 ' Debounce
LcdOut $FE, $8F, "*" ' Show that command is accepted

If Mode_B=0 then MainLoop ' Wait until button is released

Mode=Mode+1 ' Increment mode

If Mode=2 then ' Save Target Temperature (Mode1 -> Mode2)


WRITE 0,TargetTemp / 256 ' TargetTemp MSB


WRITE 1,TargetTemp MOD 256 ' TargetTemp LSB
EndIf

If Mode > 2 Then ' Save Hysteresis (Mode 2 -> Mode 0)
Mode=0 ' Only 0, 1, 2 are valid


WRITE 2, Hyst / 10 ' Divide Hyst value to fit in Byte
EndIf

EndIf


'************************************************* ****************************
' set Temperature
'************************************************* ****************************

If Mode =1 then ' Set Target Temperature

LcdOut $FE, $80, "SET TEMPERATURE " ' Show function
V=TargetTemp ' TargetTemp in V
Gosub SelectSign ' Select +/blank/-
Gosub DisplayTemp ' Display Target Temperature

If (UP_B=0) Or (DOWN_B=0) then ' Up or Down button pushed

'************************************************* ***************************
' Decrease set Temp
'************************************************* ***************************

If DOWN_B=0 then ' Down button

If TargetTemp > 7500 then ' Not lower than -25 C. (10000-MinTemp * 100)
TargetTemp=TargetTemp-25 ' Decrease temperuture with 0.25 C.
EndIf

EndIf

'************************************************* ****************************
' Increase set Temp
'************************************************* ****************************

If UP_B=0 then ' Up button

If TargetTemp < 17500 then ' Not higher than 75 C. (10000+MaxTemp * 100)
TargetTemp=TargetTemp+25 ' Increase temperature with 0.25 C.
EndIf

EndIf

'************************************************* ****************************
' Display set Temp
'************************************************* ****************************


GoSub SetTargetTemp ' Display TargetTemp and delay 0.25 Sec.
EndIf

EndIf

'************************************************* ****************************
' Set Hysteresis
'************************************************* ****************************


If Mode=2 then ' Set Hysteresis

LcdOut $FE, $80, "HYSTERESIS " ' Show function
Sign=" " ' No sign
V= 10000+Hyst ' Set value for V
Gosub DisplayTemp ' Display Hysteresis

If (UP_B=0) Or (DOWN_B=0) then ' Up or down button pushed
Sign=" " ' No sign for Hysteresis

'************************************************* ****************************
' Decrease Hysteresis
'************************************************* ****************************


If DOWN_B=0 then ' Down button
If Hyst > 10 then Hyst=Hyst-10 ' Not less than 0.1 C.
EndIf

'************************************************* ****************************
' Increase Hysteresis
'************************************************* ****************************


If UP_B=0 then ' Up button
If Hyst < 1000 then Hyst=Hyst+10 ' Not more than 10.0 C.
EndIf

'************************************************* ****************************
' Scale and show Hysteresis
'************************************************* ****************************

V= 10000+Hyst ' Set value for V
Gosub DisplayTemp ' Display Hysteresis
Pause 250 ' Delay 0.25 Sec.
EndIf
EndIf

'************************************************* ****************************
' Wait for End setting
'************************************************* ****************************


If Mode > 0 then Mainloop ' Setting TargetTemperature or Hysteresis


LcdOut $FE, $80, " TEMPERATURE " ' Show function

'************************************************* ****************************
' Sensor Presence Test
'************************************************* ****************************



LOW DQ ' OneWire line Low
PauseUs 480 ' Keep down for 480 µS
Input DQ ' Make Pin Input

PauseUs 70 ' Wait 70 µS

If DQ then ' No presence pulse from DS1820

LcdOut $FE, $1, "** No sensor! **" ' Show message
Disable_out = 1
Pause 500 ' Wait 0.5 Sec.
Goto MainLoop ' Check again

Endif

Pauseus 400 ' Wait 400µs more and see

IF DQ = 0 THEN

LcdOut $FE, $1, " sensor shorted!" ' Show message
Disable_out = 1
Pause 500 ' Wait 0.5 Sec.
Goto MainLoop ' Check again

Endif

Disable_out = 0 ' Sensor Ok : Output allowed

'************************************************* ****************************
' Temp reading
'************************************************* ****************************


OWOut DQ, 1, [$CC, $44 ] ' Start temperature conversion

WaitBit = 1 ' Show conversion ON

' REPEAT
'
' OWIn DQ, 4, [Busy] ' Check for still busy converting
'
' UNTIL BUSY


'************************************************* ****************************
' DS18B20 PAR Test
'************************************************* ****************************


HIGH DQ
PAUSE ( 1000 - Cadence )
INPUT DQ

WaitBit = 0


'************************************************* ****************************
' Conversion completed
'************************************************* ****************************

OWOUT DQ, 1, [$CC, $BE ] ' Skip ROM search & read scratchpad memory
OWIN DQ, 2, [Temperature.Lowbyte, Temperature.Highbyte]'READ two bytes / end comms

PAUSE Cadence ' 1 Measure/s !!!


'************************************************* ****************************
' Temperature Calculation
'************************************************* ****************************

Convert_Temp:


IF FAM = $10 THEN Temperature = Temperature * 8

IF Temperature.15 THEN

Temperature = ~Temperature + 1
Twist = 1

ENDIF

TempC = ( Temperature & $7FF ) >> 4 ' Partie Entière '4

Float = ((Temperature.Lowbyte & $0F ) * 25 )>> 2 ' Partie décimale 100èmes

Temperature = TempC*100 + Float 'Préparation 1/100 degrés


IF Twist THEN

V= 10000 - Temperature ' 25 C=12500 0 C=10000 -10 C=9000
Twist = 0
else
V= 10000 + Temperature
EndIf

'************************************************* ****************************
' Offset Correction for DS 1820
'************************************************* ****************************

IF FAM = $10 THEN V = V + Offset

'************************************************* ****************************
' Show status
'************************************************* ****************************


IF NOT Disable_out THEN


If V < TargetTemp - Hyst then ' Below Target temperature - Hysteresis
Heat=1 ' Activate Warm Output
Cool=0 ' Deactivate Cold Output
EndIf


If V > TargetTemp + Hyst then ' Above Target temperature + Hysteresis
Heat=0 ' Deactivate Warm output
Cool=1 ' Activate Cold Output
EndIf


GoSub SelectSign ' +/blank/- Sign
GoSub DisplayTemp ' Temperature to LCD

Else


Heat = 0 : Cool = 0

Endif


Goto MainLoop ' Do it forever


'************************************************* ****************************
'************************************************* ****************************
' SUBROUTINES
'************************************************* ****************************
'************************************************* ****************************


SelectSign:


If v = 10000 then ' Temperature = 0 C.
Sign=" " ' No sign
Else
If v < 10000 then ' <> 0
Sign="-" ' Temperature below 0 C.
Else
Sign="+" ' Temperature above 0 C.
EndIf
EndIf
Return


'************************************************* ****************************
'************************************************* ****************************


DisplayTemp:


If V >= 10000 then ' Above 0 C.
Temperature = V-10000
Else
Temperature = 10000-V ' Below 0 C.
EndIf





LcdOut $FE, $C0," ", Sign, DEC (Temperature / 100), ".", DEC2 Temperature,178,"C "


Return


'************************************************* ****************************
'************************************************* ****************************


SetTargetTemp:


V=TargetTemp
Gosub SelectSign
Gosub DisplayTemp
Pause 250

Return


'************************************************* ****************************
'************************************************* ****************************


END


I ran it aboard an EasyPic 5 Board ... but connections are described in the beginning of the listing ... :D

MOUNTAIN747
- 29th January 2025, 23:35
Got it working
Thanks Ace