Les picaxes disposent de commandes spécifiques pour les capteurs de température numériques DS18B20.
Leur gamme de mesure va de -55 °C à + 125 °C
Ces commandes: Readtemp et Readtemp12 ne permettent pas d'accéder à toutes les possibilités des modules One Wire Dallas, mais simplifient beaucoup leur utilisation.
Readtemp renvoie une variable type byte (nombre de 0 à 255, sur un octet).
Les valeurs positives de 0 à 125 (soit de 0 à 125°C) sont directement disponibles.
Les valeurs négatives suivent les valeurs positives à partir de 128 et s'obtiennent en soustrayant 128 de la variable byte. Pour l'affichage, il faut leur attribuer le signe"-".
Cette valeur entière n'est pas un arrondi, mais une troncature.
Ex: 19,9 °C devient 19°C d'où une erreur de lecture pouvant aller jusquà 1°C.
L'exemple de la doc est assez clair, (même si il contient de petites erreurs rectifiées ci-dessous):
#picaxe 08M2
main:
readtemp C.1,b1 ; read value into b1
if b1 > 127 then negat ; test for negative
serout C.2,N2400,(#b1) ; transmit value to serial LCD
goto main
negat:
let b1 = b1 - 128 ; adjust neg value
serout C.2,N2400,(“-”) ; transmit negative symbol
serout C.2,N2400,(#b1) ; transmit value to serial LCD
goto main
Readtemp12 renvoie un code de 12 bits dans une variable de type word ( nombre de 0 à 65535, sur deux octets)
Les valeurs positives:
Ex: 25,0625 °C = 0000 0001 1001 0001
Le calcul est simple:
0000000110010001=401
401 * 0,0625 = 25,0625
Pour le picaxe, pas très fort en maths, c'est moins évident, il ne connait que les nombres entiers (et pas tous).
On peut décomposer ces deux octets en deux parties:
Les 12 premiers bits sont la partie entière de la température: 11001 = 25°C
Les 4 derniers forment la partie décimale. Avec 4 bits, on peut compter de 0 à 15.
La résolution est donc de 1/16 de degré: 0001 = 1/16 = 0,0625°C
On peut donc calculer la partie décimale et l'afficher avec la précision voulue, en dizièmes, centièmes ou millièmes de degrés.
Total: 25 + 0,0625 = 25,0625
Les valeurs négatives: Ex: -25,0625 °C = 1111 1110 0110 1111
On reconnait immmédiatement le "complément à 2" de la valeur positive.
Cette astuce est utilisée en binaire pour retrouver le fait que la somme d'une valeur positive et de la valeur opposée donne 0 Ex: 5+(-5) = 0
Ici, pour 25,0625:
0000 0001 1001 0001
+ 1111 1110 0110 1111
= 1 0000 0000 0000 0000
Il y a bien un 1 à gauche dans le résultat qui gène un peu, mais comme la variable est codée sur deux octets, ce 1 disparait et on est content.
Il faut donc tester la variable pour connaitre son signe et le mémoriser si il est négatif. On peut ensuite restituer la valeur positive par la formule:
(Valeur positive) = (Valeur négative) XOR ($FFFF) + 1
EX:
( 1111 1110 0110 1111 ) XOR ( 1111 1111 1111 1111 )= (0000 0001 1001 0000)
et (0000 0001 1001 0000) +1 = (0000 0001 1001 0001)
On peut aussi remarquer que l'opération : (valeur positive)=-(valeur négative) donne le même résultat...
Il faudra évidemment ajouter le "-" à l'affichage.
Application de ce capteur : Thermostat à deux seuils
Cahier des charges:
Lecture de la température.
Fixation de deux seuils de déclenchement par potentiomètres.
1er seuil de 0 à 12,7 °C
2ème seuil de 12,7 à 25,5 °C
Fermeture d'un contact lorsque la température est entre les deux seuils.
Lecture des valeurs sur LCD 1602.
Résolution 0,1°C
Voici le schéma de cette application:
(L'utilisation d'un LCD série "maison" simplifierait le câblage et le programme)
(Cliquez sur le dessin pour agrandir)

Résultat:
 |  |
En dehors de la fenêtre, on ne fait rien | A l'intérieur, le rouge est mis |
Un peu de code pour le picaxe: (On peut sans doute améliorer)
'Test code DS18B20 pour 14M2
'Thermostat deux seuils (MM)
#picaxe14M2 'directive 14M2
setfreq m16 'fréq 16MHz
dirsB=%1111111 'défini les ports B en sorties
SYMBOL RS = B.0 ; 0 = Command 1 = Data
SYMBOL E = B.1 ; 0 = Idle 1 = Active
SYMBOL DB4 = B.2 ; LCD Data Line 4
SYMBOL DB5 = B.3 ; LCD Data Line 5
SYMBOL DB6 = B.4 ; LCD Data Line 6
SYMBOL DB7 = B.5 ; LCD Data Line 7
SYMBOL RSCMDmask = %00000000 ; Select Command register
SYMBOL RSDATmask = %00000001 ; Select Data register
SYMBOL cpt = b1
SYMBOL car = b2
SYMBOL rsbit = b3
symbol uval =b4
symbol decival =b5
symbol dval =b6
symbol maxi =b7
symbol mini =b8
symbol valeur =w10
symbol temp =w9
'Nibble commands - To initialise 4-bit mode
DATA 0,( $33 ) ; %0011---- %0011---- 8-bit / 8-bit
DATA 1,( $32 ) ; %0011---- %0010---- 8-bit / 4-bit
'Byte commands - To configure the LCD
DATA 2,( %00101000 ) ; %001LNF00 Display Format
DATA 3,( %00001100 ) ; %00001DCB Display On
DATA 4,( %00000110 ) ; %000001IS Cursor Move
‘ ; L : 0 = 4-bit Mode 1 = 8-bit Mode
‘ ; N : 0 = 1 Line 1 = 2 Lines
‘ ; F : 0 = 5x7 Pixels 1 = N/A
‘ ; D : 0 = Display Off 1 = Display On
‘ ; C : 0 = Cursor Off 1 = Cursor On
‘ ; B : 0 = Cursor Steady 1 = Cursor Flash
‘ ; I : 0 = Dec Cursor 1 = Inc Cursor
‘ ; S : 0 = Cursor Move 1 = Display Shift
DATA 5,( $01 ) ; Clear Screen
'Texte sur l'afficheur
DATA 10,("Temp(ßC):") 'ß =Alt+0223 = ° sur l'afficheur
DATA 22,("Min")
DATA 30,(" Max")
PowerOnReset:
for cpt = 0 TO 5
read cpt,car
gosub SendInitCmdByte
next
'*******DEBUT CODE PERSO *****************************************
debut:
readadc C.0,mini
mini=mini/2 'mini de 0 à 12,7°C
readadc C.4,maxi
maxi=maxi/2+127 'maxi de 12,7 à 25,4 °C
readtemp12 C.2,w13 ; lecture température
bit0=0
If W13>4096 then 'test valeur négative
bit0=1 'mémo si négatif
w13=w13 Xor $FFFF + 1 'transformation en positif
end if
'****** AFFICHAGE TEMPERATURE ******************************************************
w12=w13/16 'entiers=les 3 premiers octets
w11=w13//16 'décimals=le dernier octet: 0.0625 x w11
w11=625*W11/1000 'reste une décimale
temp=w12*10+w11 'recomposition T en /10 de degrés
car= $80 | $00 'curseur début ligne1
gosub SendCmdByte
for cpt = 10 TO 18 'lecture texte ligne 1"
read cpt,car
gosub SendDataByte
next
valeur=temp
car=" " 'espace
if bit0=1 then
car="-" 'signe si négatif
endif
gosub SendDataByte
gosub decoupe
gosub ecrit
'******* AFFICHAGE MINI ***************************************************
car= $80 | $40 'curseur début ligne2
gosub SendCmdByte
for cpt =22 to 24 'lecture texte "
read cpt,car
gosub SendDataByte
next
valeur=mini
gosub decoupe
gosub ecrit
'******* AFFICHAGE MAXI ****************************************
for cpt =30 TO 34 'lecture suite texte "
read cpt,car
gosub SendDataByte
next
valeur=maxi
gosub decoupe
gosub ecrit
'******* THERMOSTAT *********************************************
If temp>mini and temp<maxi then
high C.1 'dans la plage =ON
endif
mini=mini-5 MIN 5 :maxi=maxi+5 MAX 254
If temp<mini OR temp>maxi then
low C.1 'en dehors OFF
endif
wait 60
goto Debut
'*******************************************************
decoupe:'Ici, decoupage de la valeur à afficher
dval= valeur/10 'partie entière
decival=valeur//10 + 48 'dixième
uval=dval//10 + 48 'unités
dval=dval/10 +48 'dizaines
return
'***************************************************
ecrit: 'on écrit de gauche à droite
car=dval 'affichage des dizaines
gosub SendDataByte
car=uval 'affichage des unités
gosub SendDataByte
car="," 'position de la virgule
gosub SendDataByte
car=decival 'affichage des dizièmes
gosub SendDataByte
return
'***************FIN CODE PERSO *********************
SendInitCmdByte:
PAUSE 15 ; Delay 15mS
SendCmdByte:
rsbit = RSCMDmask ; Send to Command register
SendDataByte:
pins = car & $F0 / 4 | rsbit ; Put MSB out first
PULSOUT E,1 ; Give a 10uS pulse on E
pins = car & $0F * 4 | rsbit ; Put LSB out second
PULSOUT E,1 ; Give a 10uS pulse on E
rsbit = RSDATmask ; Send to Data register next
RETURN