Continuando, las hojas de datos de los sensores de temperatura DS18B20 pueden verse aquí:
18b20.pdf
Cada sensor DS18B20 tiene un único ID de 64 bytes que lo identifica (64-BIT LASERED ROM).
El primer byte de todo ID es un identificador de tipo de sensor ( 28h) . Como se ve, en este diseño cada sensor se maneja con una línea de datos separada (RA0 y RA1) entonces no hace falta identificar varios sensores conectados en una misma línea, el programa sólo lee los dos primeros bytes del ID de los dos sensores para verificar su presencia. En caso que un sensor no esté conectado o no responda, el display mostrará un guion (-) en lugar de su ID.
En el video anterior, en los segundos 12 y 14 se ven los ID de ambos sensores que indican que efectivamente están en línea, en uno 28 91, en el otro 28 XX.
Luego de este testeo de presencia, arranca la medición de temperatura y se muestra en los displays, los dos dígitos de arriba corresponden al Sensor DS0 que será el de temperatura interna del Reloj, y los dos dígitos de abajo corresponden al Sensor DS1 que será el de temperatura externa o ambiente.
Ambos sensores DS18B20 trabajan en alta precisión de 12 bits por lo cual los displays que tienen sólo dos dígitos, muestran alternadamente decenas - unidades y unidades - decimales de los valores de temperatura.
Esto puede verse a partir del segundo 15 del video, los display alternan entre 21 y 1.5 ó 1.4 indicando una temperatura de 21.5 ó 21.4 ºC. Los dos sensores pueden verse ahí cercanos a la plaqueta con sus cables, por lo cual medirán valores similares.
A partir del segundo 31 del video puede verse el seteo de temperatura de encendido del ventilador del Reloj con los switches de Down (RA3) en 40, 39, 38... y de Up (RA2) en 30, 31, 32...45
Entonces en este caso el DS0 responde con los códigos exadecimales 28 91, y el DS1 responde 28 XX (el XX no se ve porque es un valor exadecimal no displayable). Los restantes 62 bytes de los ID no son leidos pues no hacen falta ya que como vimos, el DS0 se maneja exclusivamente con la linea RA0 y el DS1 con la linea RA1.
Entonces, la secuencia del programa para leer los dos primeros bytes del ID del sensor DS0 de acuerdo al procedimiento aconsejado en su hoja de datos, actuando el PIC como Master y el DS0 como Slave, será la siguiente:
1) Coloca RA0 como salida (TRISA0 = 0) y coloca un estado Bajo ("0") durante 480 uS (Master Reset Pulse)
2) Coloca RA0 como entrada (TRISA0=1), espera de 15 uS a 60 uS y sensa el estado Bajo ("0") de respuesta del DS0 (Slave Presence Pulse) de 60 a 240 uS.
Si el pulso de presencia es detectado significa que el sensor está conectado y listo, en cambio si no se detecta durante un timeout de 480 uS, significa que el sensor no está o no funciona. En ese caso el programa mostrará guiones en el display indicando que el Master Reset falló.
3) Una vez que se detecta la presencia del sensor DS0 y este libera la línea de datos, pasa RA0 nuevamente como salida
4) El Master (PIC) envía sobre la línea, el Read ID Command byte (33h) y a continuación invierte RA0 como entrada
5) Lee el primer byte del ID, lo guarda en memoria. Lee el segundo byte del ID y lo guarda en memoria. Los restantes 62 bytes del ID no son leidos
6) Muestra ambos valores leidos en el display.
A continuación, la secuencia del programa para leer los dos primeros bytes del ID del sensor DS1 será la misma sobre su línea RA1.
Y ambos valores leídos se mostrarán a continuación en el display como puede verse en el video.
Luego de leer y mostrar ambos ID de ambos sensores, el programa entrará en el lazo de medición, muestra y comparación de la temperatura en ambos sensores.
Estos estarán por defecto en su máxima resolución de 12 bits y tendrán un tiempo de conversión de 750 mS.
La medición de temperatura en el DS0 se inicia con la siguiente secuencia:
1) Coloca RA0 como salida y envía el pulso de Reset (Master Reset Pulse)
2) Coloca RA0 como entrada y se verifica el pulso de respuesta del DS0 (Slave Presence Pulse)
3) Coloca RA0 como salida
4) El Master (PIC) envía sobre la linea, el Skip ROM Command byte (CCh)
5) El Master (PIC) envía sobre la linea, el Start Conversion Command byte (44h)
6) Coloca RA0 como entrada, el DS0 (Slave) colocará un Bajo "0" en la línea mientras dura la conversión de temperatura (750 mS)
7) A continuación, La medición de temperatura en el DS1 se inicia con misma secuencia sobre la línea RA1
8 ) Entra en el lazo de espera de fin de conversión sensando el estado Bajo "0" en RA0 forzado por el DSO mientras convierte
9) Una vez que el tiempo de conversión del DS0 finaliza indicado por la liberación de la línea RA0, se verifica también la finalización de conversión en el DS1 indicado por la liberación de la línea RA1.
Ambos sensores disparan su conversión en forma casi simultánea por lo cual ambos tendrán la medición lista en el mismo período de 750 mS
Una vez que se verifica que ambos sensores terminaron su conversión de temperatura, se leen los valores con la siguiente secuencia:
1) Coloca RA0 como salida y envía el pulso de Reset (Master Reset Pulse)
2) Coloca RA0 como entrada y se verifica el pulso de respuesta del DS0 (Slave Presence Pulse)
3) Coloca RA0 como salida
4) El Master (PIC) envía sobre la línea, el Skip ROM Command byte (CCh)
5) El Master (PIC) envía sobre la línea, el Read Scratchpad Command byte (44h), los dos primeros bytes recibidos serán el valor de temperatura en 12 bits
6) Coloca RA0 como entrada
7) Lee el primer byte del Scratchpad, son los 8 bits de menor peso (LS byte) donde están las unidades y los decimales
8 ) Lee el segundo byte del Scratchpad, son los 8 bits de mayor peso (MS byte) donde están los signos y las decenas
El formato de ambos bytes y los pesos de los bits será el siguiente:
LS byte 2^3 2^2 2^1 2^0 2^-1 2^-2 2^-3 2^-4 (unidades y decimales)
MS byte S S S S S 2^6 2^5 2^4 (bits de signo y decenas)
Los S son los bits de Signo que serán 0s con temperaturas positivas, el rango a mostrar será de 00.0 ºC a 99.9 ºC
Ejemplos de lectura de temperatura (ver manual del DS18B20)
- Temp= +125 °C , se lee 07D0h, o sea 7x16+13 = 125 . El ultimo digito son los decimales, que son cero
- Temp= +25.0625°C, se lee 0191h, o sea 2x16+5+ 0,0625 x 1 (la resolución en 12 bits es 0,0625 ºC)
- Temp= +0.5°C, se lee 0008h, o sea 0,0625 x 8 = 0,5
La conversión de los valores binarios leídos en los bytes MS y LS a los valores BCD a mostrar en los displays será por tablas en EPROM
El contenido de la tabla de conversión para decenas y unidades será simple, se direcciona con decenas y unidades en binario (hexadecimal) y se obtiene el valor a mostrar en BCD:
Tabla: (arranca en la posición 00h de la EPROM)
de 0x00 ; 00
de 0x01 ; 01
de 0x02 ; 02
de 0x03 ; 03
de 0x04 ; 04
de 0x05 ; 05
de 0x06 ; 06
de 0x07 ; 07
de 0x08 ; 08 - Ejemplo: si los MS y LS bytes son 0080 , el valor BCD a mostrar en decenas y unidades será 08
de 0x09 ; 09
de 0x10 ; 0A
de 0x11 ; 0B
de 0x12 ; 0C
de 0x13 ; 0D - Ejemplo: si los MS y LS bytes son 00D0 , el valor BCD a mostrar en decenas y unidades será 13
de 0x14 ; 0E
de 0x15 ; 0F
...la tabla continua hasta los valores finales...
de 0x90 ; 5A
de 0x91 ; 5B
de 0x92 ; 5C
de 0x93 ; 5D
de 0x94 ; 5E
de 0x95 ; 5F - Ejemplo: si los MS y LS bytes son 05F0 (16x5+15), el valor BCD a mostrar en decenas y unidades será 95
de 0x96 ; 60
de 0x97 ; 61
de 0x98 ; 62
de 0x99 ; 63 - Ejemplo: si los MS y LS bytes son 0630 (16x6+3) , el valor BCD a mostrar en decenas y unidades será 99
El contenido de la tabla de conversión para los decimales será el siguiente, se direcciona con el nibble de decimales ( 2^-1 2^-2 2^-3 2^-4) del LS byte en binario (hexadecimal), y se obtiene el valor redondeado a mostrar en BCD (la resolución en 12 bits es 1/16 o sea 0,0625 ºC)
Tabla (empieza en la posición 70h de la EPROM):
de 0x00 ;70 0 0,0000
de 0x01 ;71 1 0,0625 - se redondea en 1
de 0x01 ;72 2 0,1250
de 0x02 ;73 3 0,1875 - Ejemplo: el nibble de decimales es 3 (03h), la dirección de memoria será 73h, el valor de temp será
de 0x02 ;74 4 0,2500 0,0625x3=0,1875 ºC, el valor redondeado retornado para mostrar será 2
de 0x03 ;75 5 0,3125
de 0x04 ;76 6 0,3750 -se redondea en 4
de 0x04 ;77 7 0,4375 -se redondea en 4
de 0x05 ;78 8 0,5000
de 0x06 ;79 9 0,5625 -se redondea en 6
de 0x06 ;7A A 0,6250
de 0x07 ;7B B 0,6875 - Ejemplo: el nibble de decimales es B (0Bh), la dirección de memoria será 7Bh, el valor de temp. será
de 0x07 ;7C C 0,7500 0,0625x11=0,6875 ºC, el valor redondeado retornado para mostrar será 7
de 0x08 ;7D D 0,8125
de 0x09 ;7E E 0,8750
de 0x09 ;7F F 0,9375
Luego agregaré algo del código que hace todo esto.
Saludos