phil99
 Guru
 Joined: 11/02/2018 Location: AustraliaPosts: 3013 |
| Posted: 05:51am 10 Mar 2025 |
|
|
|
More playing with Jim's program. Added some comments to help add unknown / non-genuine devices.
'DS18x20 test code by TassyJim Print ' Input "Type Pin number ",PinNbr Input "Type PicoMite GPxx number for the DS18B20 (include the GP) "; GPPin$ Dim INTEGER PinNbr = MM.Info(pinno GPPin$)
Print Print "Family name: ";FamilyName$(PinNbr) Print "Rom Code: ";getRomCode$(PinNbr) Print "ScratchPad: ";getScratchpad$(PinNbr)
If powerMode(PinNbr) Then Print "Power mode External" Else Print "Power mode Parasitic" EndIf
Print For n = 9 To 12 Print x = setResolution(PinNbr, n) Print "ScratchPad: ";getScratchpad$(PinNbr) Timer = 0 Print "Temperature: ";getTemp(PinNbr);"`C ";Timer;"mS,";n;" bit" Next n
Print :t=Timer : Print "Tempr() without Start", TEMPR(PinNbr);" `C",Timer-t;" mS" TEMPR START PinNbr,0 :t=Timer :ds18=TEMPR(PinNbr):t=Timer-t : Print "Tempr Start pin,0", ds18, t TEMPR START PinNbr,1 :t=Timer :ds18=TEMPR(PinNbr):t=Timer-t : Print "Tempr Start pin,1", ds18, t TEMPR START PinNbr,2 :t=Timer :ds18=TEMPR(PinNbr):t=Timer-t : Print "Tempr Start pin,2", ds18, t TEMPR START PinNbr,3 :t=Timer :ds18=TEMPR(PinNbr):t=Timer-t : Print "Tempr Start pin,3", ds18, t Print Print "*** The first RomCode value (a1) can be used to add extra devices to the FamilyName & getTemp functions" Print "look for *** comments in those functions" Print End
Function getRomCode$(PinNbr As INTEGER) ' get ROM Code - useful if you want more than 1 device on wire '*** The first value returned (a1) can be used to add extra devices to the FamilyName & getTemp functions 'look for *** comments in those functions Local INTEGER a1,a2,a3,a4,a5,a6,a7,a8 OneWire WRITE PinNbr,1,1,&h33 'read ROM code OneWire READ PinNbr,0,8,a1,a2,a3,a4,a5,a6,a7,a8 getRomCode$ = Hex$(a1,2)+" "+Hex$(a2,2)+" "+Hex$(a3,2)+" "+Hex$(a4,2)+" "+Hex$(a5,2)+" "+Hex$(a6,2)+" "+Hex$(a7,2)+" "+Hex$(a8 ,2) End Function
Function getScratchpad$(PinNbr As INTEGER) 'ONEWIRE Write PinNbr,1,9,&h55,a1,a2,a3,a4,a5,a6,a7,a8 'read from scratchpad OneWire WRITE PinNbr,1,2,&hcc,&hbe OneWire READ PinNbr,0,8,a,b,c,d,e,f,g,h getScratchpad$ = Hex$(a,2)+" "+Hex$(b,2)+" "+Hex$(c,2)+" "+Hex$(d,2)+" "+Hex$(e,2)+" "+Hex$(f,2)+" "+Hex$(g,2)+" "+Hex$(h,2) End Function
Function powerMode(PinNbr As INTEGER) As INTEGER ' check whether power external (1) or parasitic (0) OneWire RESET PinNbr OneWire WRITE PinNbr, 1,2,&hcc, &hb4 OneWire READ PinNbr,4,1,powerMode End Function
Function getFamily(PinNbr As INTEGER) As INTEGER getFamily = Val("&h"+Left$(getRomCode$(PinNbr),2)) End Function
Function FamilyName$(PinNbr As INTEGER) Local INTEGER fn fn = getFamily(PinNbr) Select Case fn Case 16 '&H10 FamilyName$ = "DS1820/DS18S20" Case 34 '&H22 FamilyName$ = "DS18S22" Case 40 '&H28 FamilyName$ = "DS18B20" Case 41 '&H29 FamilyName$ = "a non-genuine DS18B20" '*** Add extra cases here using the first value returned by Function getRomCode Case Else FamilyName$ = "Unknown" End Select End Function
Function setResolution(PinNbr As INTEGER,r As INTEGER) r = r-9 If r < 0 Then r = 0 If r > 3 Then r = 3 r = r*32+31 OneWire WRITE PinNbr, 1,5,&hcc, &h4E, &hFF,&hFF,r End Function
Function getTemp(PinNbr As INTEGER) As FLOAT Local INTEGER fn, t, T1, T2, a,b,c,d,e,f,g,h Local FLOAT Value fn = getFamily(PinNbr) power = powerMode(PinNbr) OneWire RESET PinNbr ' reset before command OneWire WRITE PinNbr, 8, 2, &hcc, &h44 ' start conversion
'read external when b goes high, for parasitic just wait If power = 0 Then Pause 750 Else t = Timer Do If Timer - t > 1000 Then Value = 1000 Print "*** Timeout ***" Exit Do EndIf OneWire READ PinNbr, 4 , 1 , b ' conversion done? Loop Until b = 1 ' Print Timer-t;" mS conversion time", EndIf If Value = 0 Then ' we have not timed out yet OneWire WRITE PinNbr, 1, 2, &hcc, &hbe ' command read data OneWire READ PinNbr, 2, 2, T1, T2 ' get the data OneWire RESET PinNbr Select Case fn Case 16 'DS18S20 or DS1820 OneWire WRITE PinNbr,1,2,&hcc,&hbe OneWire READ PinNbr,0,8,a,b,c,d,e,f,g,h If T2 And &h80 Then 'if MSB of T2=1 then negative 'Read 12bit resolution and adjust 'truncate 0.5deg value (or use integer division \) T1 = T1 And &hFE T1=T1 / 2 'make whole degrees 'add compensation values read from scratchpad T1=T1*16 'make lsb 1/16 degree T1 = T1 -4 +(16 - g) 'add 12 bit value 'take 2s complement T1 = (T1 Xor &hFF) + 1 Value = -T1/16 'make decimal value in degrees Else 'positive temp Value = T1 / 2 '9bit value 'Read 12bit resolution and adjust T1 = T1 And &hFE 'truncate 0.5deg(or use integer division \) Value = T1/2- 0.25 + (16 - g) /16 '12 bit value EndIf Case 34, 40 ' DS18S22 or DS18B20 If T2 And &b1000 Then 'negative temp 'make 2s complement (1s complement+1) T2 = (T2 Xor &hFF) T1 = (T1 Xor &hFF)+1 If T1=1 Then T2=T2+1 'add the carry if required Value = -((T2 And &b111) * 256 + T1) / 16 Else 'positive temp Value = ((T2 And &b111) * 256 + T1) / 16 EndIf Case 41 '&H29, a non genuine DS18B20 If T2 And &b1000 Then 'negative temp 'make 2s complement (1s complement+1) T2 = (T2 Xor &hFF) T1 = (T1 Xor &hFF)+1 If T1=1 Then T2=T2+1 'add the carry if required Value = -((T2 And &b111) * 256 + T1) / 16 Else 'positive temp Value = ((T2 And &b111) * 256 + T1) / 16 EndIf '*** Add extra cases here using the first value returned by Function getRomCode Case Else 'Unknown device ' *** use the output of this to create the scale factor of the unknown device 'Value = 1000 If T2 And &b1000 Then 'negative temp 'make 2s complement (1s complement+1) T2 = (T2 Xor &hFF) T1 = (T1 Xor &hFF)+1 If T1=1 Then T2=T2+1 'add the carry if required Value = -((T2 And &b111) * 256 + T1) / 1'<-This is where you put the scale factor Else 'positive temp Value = ((T2 And &b111) * 256 + T1) / 1'<-This is where you put the scale factor EndIf End Select EndIf getTemp= Value End Function Example output. This one always reads 85° until after a Tempr Start pin,2 or 3 command then is ok till next power cycle. > RUN
Type PicoMite GPxx number for the DS18B20 (include the GP) ? gp6
Family name: a non-genuine DS18B20 Rom Code: 29 61 64 12 3D D4 A4 B8 ScratchPad: 51 05 FF FF 7F FF FF FF Power mode External
ScratchPad: FF FF FF FF FF FF FF FF Temperature: 85.0625`C 17.934mS, 9 bit
ScratchPad: FF FF FF FF FF FF FF FF Temperature: 85.0625`C 17.951mS, 10 bit
ScratchPad: A8 82 FF FF AF FF FF FF Temperature: 680`C 17.91mS, 11 bit
ScratchPad: 51 05 FF FF 7F FF FF FF Temperature: 85.0625`C 17.935mS, 12 bit
Tempr() without Start 85 `C 210.435 mS Tempr Start pin,0 85 103.408 Tempr Start pin,1 85 203.84 Tempr Start pin,2 27.875 403.835 Tempr Start pin,3 27.875 803.819
*** The first RomCode value (a1) can be used to add extra devices to the FamilyName & getTemp functions look for *** comments in those functions
> RUN
Type PicoMite GPxx number for the DS18B20 (include the GP) ? gp6
Family name: a non-genuine DS18B20 Rom Code: 29 61 64 12 3D D4 A4 B8 ScratchPad: BF 01 FF FF 7B FF FF FF Power mode External
ScratchPad: FF FF FF FF FF FF FF FF Temperature: 27.9375`C 17.964mS, 9 bit
ScratchPad: FF FF FF FF FF FF FF FF Temperature: 27.9375`C 17.942mS, 10 bit
ScratchPad: DF 80 FF FF AF FF FF FF Temperature: 223`C 17.93mS, 11 bit
ScratchPad: BF 01 FF FF 7F FF FF FF Temperature: 27.9375`C 17.942mS, 12 bit
Tempr() without Start 27.875 `C 210.452 mS Tempr Start pin,0 27.875 104.167 Tempr Start pin,1 27.875 203.82 Tempr Start pin,2 27.6875 403.821 Tempr Start pin,3 27.6875 803.819
*** The first RomCode value (a1) can be used to add extra devices to the FamilyName & getTemp functions look for *** comments in those functions
Edit. Prompted by Volhout's mention of the RP2350 pin issue I reduced the pullup resistor from 10k to 1.2k. Now the Rom Code value of a1 is &H28, as it should be. Was &H29. It no longer reads 85°C in Jim's program but still requires an initial Tempr Start to get Tempr() to read correctly. Edited 2025-03-10 20:08 by phil99 |