Sensor de temperatura I2C LM75
Principio de funcionamiento
El IC LM75 es un sensor de temperatura de banda prohibida (band gap) de semiconductor de silicio.
En los semiconductores, la banda prohibida es la zona de energía de los electrones que no puede verse incrementada con un incremento del campo eléctrico al no existir estados disponibles para moverse más rápidamente. Esta banda prohibida está comprendida entre la banda de valencia (de menor energía) y la banda de conducción (de mayor energía). La excitación térmica (el incremento de temperatura, a los efectos que nos interesan) puede hacer que algunos electrones adquieran suficiente energía como para pasar a la banda de conducción.
Como explicaba en el anterior artículo sobre la medida electrónica de la temperatura, en los metales, si bien el número de portadores no depende de la temperatura (todos los electrones están disponibles siempre) su movilidad sí que se ve afectada por la temperatura, de forma que la resistencia en los metales aumenta con la temperatura por la disminución de la velocidad de los electrones debida al aumento de su agitación térmica y a la dispersión de electrones que produce.
En el caso de los semiconductores, debido a la presencia de esta banda prohibida el número de portadores sí que depende de la temperatura (según la distribución de Fermi-Dirac) haciendo que aumente la conductividad con la temperatura. En los semiconductores, el aumento de la temperatura produce un aumento de la resistencia pero también produce un (mayor) aumento de la conductividad.
Los sensores de temperatura de banda prohibida (band gap) de semiconductor de silicio, como es el caso del LM75, funcionan según este principio, permitiendo determinar la temperatura cuantificando su influencia en la tensión en un diodo de silicio.
Componentes del hardware del LM75
El LM75 también dispone de un conversor analógico-digital por modulación Sigma-Delta que se encarga de obtener el valor numérico (digital) de la temperatura, valor que posteriormente se almacena (cada 100 ms) en uno de sus registros desde el que puede leerse por medio del bus I2C.
Además del registro que contiene la temperatura medida, el LM75 dispone de un registro en el que se puede almacenar una temperatura máxima así como de un comparador que es capaz de generar una señal si la temperatura medida supera la almacenada en este segundo registro. Para no volver a lanzar el aviso hasta que la temperatura medida no baje de cierto nivel, un tercer registro permite almacenar un valor para la temperatura de histéresis.
La configuración del funcionamiento del LM75 se almacena en un cuarto registro con el que se determinan las condiciones según las cuales se genera el aviso, la forma de lanzar esta señal de aviso (modo interrupción o modo comparación) así como la activación del dispositivo (modo de funcionamiento normal o de bajo consumo) entre otros parámetros.
Especificaciones técnicas e implementación del LM75
El rango de temperaturas que el LM75 es capaz de medir varía desde los −55 °C hasta los +125 °C y la resolución numérica es de 0.125 °C aunque la precisión es solamente de ±2 °C en el mejor caso, cuando la temperatura está comprendida entre los −25 °C y los +100 °C y una precisión de ±3 °C con las temperaturas más extremas, entre los −55 °C y los +125 °C.
La implementación (hardware) del LM75 en un circuito es muy sencilla, no necesita más componentes que las resistencias pull-up del bus I2C y puede alimentarse con una tensión entre 2,8 V y 5,5 V. En el mismo bus I2C se pueden disponer hasta ocho termómetros LM75 configurando su dirección con las tres patillas A0, A1 y A2 a nivel alto o bajo, como suele ser habitual en estos casos.
Por contra, el uso del LM75 como sonda es incómodo debido a los encapsulados en los que se presenta, TSSOP (TSSOP8) o SOIC (SO8) y normalmente se utiliza para medir temperatura ambiente o para medir la temperatura de componentes dispuestos en el entorno de la PCB en la que se ubique el termómetro LM75.
Al inicio, el LM75 está configurado para detectar una temperatura máxima de +80 °C, una temperatura de histéresis de +75 °C y el modo de funcionamiento de comparador, es decir, el modo que emula el funcionamiento de un termostato: activa el aviso al alcanzar la temperatura máxima y sólo si baja de la de histéresis vuelve a generar el aviso.
Explotación del LM75 desde un microcontrolador por medio del bus I2C
Gracias al uso del bus I2C la explotación del LM75 es muy sencilla, basta con acceder a la dirección que ocupe en el bus para almacenar o leer la configuración y para obtener el valor de la temperatura medida.
La dirección I2C base del LM75 es 0B01001XXX y se complementa, como se explica más arriba, con los últimos tres bits de dirección que se establecen por hardware con las patillas A0, A1 y A2 a nivel alto (valor uno) o bajo (valor cero).
El LM75 como termómetro
El registro que almacena la última temperatura medida (TEMP) se encuentra en la dirección 0x00, el de la configuración (CONF) en la dirección 0x01, el registro que almacena la temperatura de histéresis en la dirección 0x02 y el de la temperatura máxima o sobre-temperatura (TOS) tiene la dirección 0x03. Excepto el de la temperatura actual (TEMP) todos funcionan como lectura y escritura.
Utilizando algunos ejemplos de código desarrollado para Arduino (que se ha convertido casi en referencia universal) se puede aclarar más el funcionamiento del LM75. El ejemplo útil más básico consiste en usar el LM75 como termómetro leyendo el registro de la última temperatura medida.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
#define DIRECCION_LM75 0B01001000 // Dirección del LM75 con A0, A1 y A2 a nivel bajo
#define TEMPERATURA_ACTUAL_LM75 0x00 // Registro que almacena la temperatura medida
//#define TIEMPO_CONVERSION_LM75 100 // El LM75 convierte la temperatura (AD) cada 100 ms así que el intervalo entre lecturas debe ser mayor.
#define TIEMPO_ENTRE_LECTURAS_DE_TEMPERATURA 3000 // Intervalo entre lecturas consecutivas de la temperatura en ms
#include <Wire.h>
int temperatura; // Valor de la temperatura actual cargado del LM75
void setup()
{
Serial.begin(9600); // Inicializar las comunicaciones serie (para mostrar en la consola el valor de la temperatura)
Wire.begin(); // Inicializar las comunicaciones I2C
}
void loop()
{
Wire.beginTransmission(DIRECCION_LM75); // Acceder al LM75 por su dirección en el bus I2C
Wire.write(TEMPERATURA_ACTUAL_LM75); // Solicitar la lectura del registro de la temperatura actual
Wire.endTransmission(); // Liberar el bus I2C
Wire.requestFrom(DIRECCION_LM75,2); // Pedir dos bytes (el valor del registro de la temperatura actual)
temperatura=(Wire.read()<<8)|Wire.read(); // Leer el primer byte, rotarlo 8 posiciones y añadir el valor del segundo byte
Wire.endTransmission(); // Liberar el bus I2C
Serial.println((float)temperatura/32/8,DEC); // Sólo son relevantes los 11 bits más significativos con una precisión de un octavo de grado (1/8 = 0.125 °C)
delay(TIEMPO_ENTRE_LECTURAS_DE_TEMPERATURA); // Esperar un poco antes de volver a leer la temperatura
}
|
El proceso es el habitual cuando se trabaja con un dispositivo I2C:
- Añadir la librería I2C al código con
#include <Wire.h>
- Inicializar la librería I2C usando
Wire.begin();
- Acceder al sensor de temperatura LM75 mediante
Wire.beginTransmission(DIRECCION_LM75)
- Enviar la dirección del registro al que se accede usando
Wire.write(REGISTRO)
- Liberar el bus I2C con
Wire.endTransmission()
- Volver a acceder al LM75
- Pedir el valor del registro con
Wire.requestFrom(DIRECCION,CANTIDAD)
- Verificar que se han recibido datos usando
Wire.available()
- Leer el valor solicitado
Wire.read()
(tantas veces como bytes lo formen) - Aunque no es imprescindible, al terminar, liberar el bus I2C
Además del protocolo habitual para obtener o almacenar información en los registros del dispositivo utilizando el bus I2C, para explotar los datos que el el LM75 proporciona hay que considerar el formato en el que representa internamente la temperatura.
Obtención del valor almacenado en los registros de temperatura del LM75
En la línea 22 del código del ejemplo anterior puede verse cómo cargar la información que almacenan los tres registros de temperatura del LM75. Utiliza dos bytes (16 bits) de los cuales solamente son válidos los 11 bits más significativos. Para leer la temperatura como un entero (con el signo codificado en complemento a dos) primero se carga el byte más significativo sobre una variable int
de Arduino y se rota 8 bits a la izquierda, con lo que queda en la parte más significativa del int
. Posteriormente se lee el segundo byte y se añade a la variable int
con una operación OR
Interpretación del valor de temperatura cargado del LM75
En la línea 24 se puede ver cómo interpretar el valor de la temperatura. En primer lugar es necesario dividir entre 32 como un entero (rotar los 11 bits relevantes sin perder el signo) y dividir entre 8, que es el número de «pasos» con que se representa la temperatura (octavos de grado) para obtener un valor de tipo float
con los correspondientes decimales. Como los compiladores (incluyendo el del toolchain de Arduino) optimizan la división entera entre 32, no es necesario preservar el signo y rotar «manualmente» los bits, ya que la operación no es (apreciablemente) más rápida.
Verificar la recepción de datos desde el bus I2C
Aunque el código anterior funcionará sin problemas pese a no verificar si han llegado los datos solicitados al dispositivo por el bus I2C, lo más ortodoxo (y recomendable) es esperar a que lleguen los datos en el número adecuado. Como la velocidad de transmisión y la resistencia a errores son más que suficientes, es frecuente encontrar código en el que simplemente se solicitan los datos y se leen sin esperar. Para los ejemplos es útil hacerlo así puesto que no distraen de la intención principal pero para el código de producción lo recomendable es hacerlo tal como se sugiere en el séptimo punto de la lista del proceso de comunicación I2C. En el código del siguiente ejemplo se resaltan los cambios recomendables para usar el LM75 en la fase de explotación.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
#define DIRECCION_LM75 0B01001000 // Dirección del LM75 con A0, A1 y A2 a nivel bajo
#define TEMPERATURA_ACTUAL_LM75 0x00 // Registro que almacena la temperatura medida
//#define TIEMPO_CONVERSION_LM75 100 // El LM75 convierte la temperatura (AD) cada 100 ms así que el intervalo entre lecturas debe ser mayor.
#define TIEMPO_ENTRE_LECTURAS_DE_TEMPERATURA 3000 // Intervalo entre lecturas consecutivas de la temperatura en ms
#define TIMEOUT_I2C 30 // Esperar 30 ms antes de renunciar a leer el bus I2C
#include <Wire.h>
int temperatura; // Valor de la temperatura actual cargado del LM75
unsigned long cronometro_i2c; // Cronómetro para medir el tiempo de espera de la lectura del bus I2C (y cancelar la operación si se supera el máximo)
void setup()
{
Serial.begin(9600); // Inicializar las comunicaciones serie (para mostrar en la consola el valor de la temperatura)
Wire.begin(); // Inicializar las comunicaciones I2C
}
void loop()
{
Wire.beginTransmission(DIRECCION_LM75); // Acceder al LM75 por su dirección en el bus I2C
Wire.write(TEMPERATURA_ACTUAL_LM75); // Solicitar la lectura del registro de la temperatura actual
Wire.endTransmission(); // Liberar el bus I2C
Wire.requestFrom(DIRECCION_LM75,2); // Pedir dos bytes (el valor del registro de la temperatura actual)
cronometro_i2c=millis();
while(Wire.available()<2&&(unsigned long)(millis()–cronometro_i2c)>TIMEOUT_I2C); // Esperar a que lleguen dos bytes al bus I2C o pase el tiempo máximo para abandonar
if(Wire.available()==2) // Si han llegado dos bytes
{
temperatura=(Wire.read()<<8)|Wire.read(); // Leer el primer byte, rotarlo 8 posiciones y añadir el valor del segundo byte
}
Wire.endTransmission(); // Liberar el bus I2C
Serial.println((float)temperatura/32/8,DEC); // Sólo son relevantes los 11 bits más significativos con una precisión de un octavo de grado (1/8 = 0.125 °C)
delay(TIEMPO_ENTRE_LECTURAS_DE_TEMPERATURA); // Esperar un poco antes de volver a leer la temperatura
}
|
Configurar el funcionamiento del LM75
La configuración más básica del LM75 consiste en establecer la temperatura máxima para generar el aviso y la de histéresis, que determinará cuando se desactiva y puede repetirse. Para configurar estos valores solamente hay que almacenarlos en los registros correspondientes.
Al igual que el registro de la temperatura actual, los registros de temperatura máxima (de aviso) y de temperatura de histéresis utilizan dos bytes pero a diferencia del primero no consideran 11 bits (un octavo de grado) sino 9 (medio grado) de forma que, aunque se almacenara un valor menor, solamente se considerarían intervalos de esta resolución.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
#define DIRECCION_LM75 0B01001000 // Dirección del LM75 con A0, A1 y A2 a nivel bajo
#define TEMPERATURA_ACTUAL_LM75 0x00 // Registro que almacena la temperatura medida
#define TEMPERATURA_MAXIMA_LM75 0x03 // Registro que almacena la temperatura máxima (al superarla avisa cambiando el estado del pin OS) 80 °C al inicio
#define TEMPERATURA_HISTERESIS_LM75 0x02 // Registro que almacena la temperatura por debajo de la cual la máxima vuelve a generar un cambio en el pin OS (temperatura de histéresis) 75 °C al inicio
//#define TIEMPO_CONVERSION_LM75 100 // El LM75 convierte la temperatura (AD) cada 100 ms
#define TIEMPO_ENTRE_AVISOS_DE_TEMPERATURA 3000 // Intervalo entre avisos consecutivos de exceso de temperatura en ms
#define TIMEOUT_I2C 30 // Esperar 30 ms antes de renunciar a leer el bus I2C
#define TEMPERATURA_AVISO 32.5 // Avisar a los 32.5 °C (Solamente se consideran 9 bits, es decir, medios grados)
#define TEMPERATURA_HISTERESIS 31.0 // No volver a avisar (a los 32.5 °C) hasta que no se baje a los 31.0 °C
#define PIN_AVISO_LM75 2 // Pin de Arduino al que se conecta la salida OS del LM75
#include <Wire.h> // Cargar la librería de las comunicaciones I2C
int temperatura; // Valor de la temperatura actual cargado del LM75
unsigned long cronometro_i2c; // Cronómetro para medir el tiempo de espera de la lectura del bus I2C (y cancelar la operación si se supera el máximo)
unsigned long cronometro_avisos=0; // Cronómetro para controlar que se avise del exceso de temperatura a un intervalo máximo (como máximo cada TIEMPO_ENTRE_AVISOS_DE_TEMPERATURA)
void setup()
{
pinMode(PIN_AVISO_LM75,INPUT); // Usar como entrada el pin de Arduino al que se conecta la salida OS del LM75
Serial.begin(9600); // Inicializar las comunicaciones serie
Wire.begin(); // Inicializar las comunicaciones I2C
//Configurar la temperatura de aviso
Wire.beginTransmission(DIRECCION_LM75); // Iniciar la comunicación con el LM75
Wire.write(TEMPERATURA_MAXIMA_LM75); // Acceder al registro que almacena la temperatura máxima (temperatura de aviso)
Wire.write((byte)((int)(TEMPERATURA_AVISO*8.0)>>3)); // Desplazar 5 bits a la izquierda y 8 a la derecha
Wire.write((byte)((int)(TEMPERATURA_AVISO*8.0)<<5)); // Desplazar 5 bits a la izquierda
Wire.endTransmission(); // Liberar el bus I2C
//Configurar la temperatura de histéresis
Wire.beginTransmission(DIRECCION_LM75); // Iniciar la comunicación con el LM75
Wire.write(TEMPERATURA_HISTERESIS_LM75); // Acceder a la temperatura de histéresis
Wire.write((byte)((int)(TEMPERATURA_HISTERESIS*8.0)>>3)); // Desplazar 5 bits a la izquierda y 8 a la derecha
Wire.write((byte)((int)(TEMPERATURA_HISTERESIS*8.0)<<5)); // Desplazar 5 bits a la izquierda
Wire.endTransmission(); // Liberar el bus I2C
// El aviso se activará cuando la temperatura sea TEMPERATURA_AVISO o superior
// y no se desactivará hasta que sea TEMPERATURA_HISTERESIS o inferior
}
void loop()
{
if(!digitalRead(PIN_AVISO_LM75)) // Si la señal OS del LM75 está a nivel bajo (polaridad por defecto del aviso)
{
if((millis()–cronometro_avisos)>TIEMPO_ENTRE_AVISOS_DE_TEMPERATURA) // Si ha transcurrido el tiempo entre avisos (además de estar activa la señal)
{
cronometro_avisos=millis(); // Reiniciar el cronómetro de aviso de la temperatura
Wire.beginTransmission(DIRECCION_LM75); // Acceder al LM75 por su dirección en el bus I2C
Wire.write(TEMPERATURA_ACTUAL_LM75); // Solicitar la lectura del registro de la temperatura actual
Wire.endTransmission(); // Liberar el bus I2C
Wire.requestFrom(DIRECCION_LM75,2); // Pedir dos bytes (el valor del registro de la temperatura actual)
cronometro_i2c=millis(); // Iniciar el cronómetro que controla si ha pasado el tiempo máximo de espera de recepción de datos desde el bus I2C
while(Wire.available()<2&&(unsigned long)(millis()–cronometro_i2c)>TIMEOUT_I2C); // Esperar a que lleguen dos bytes al bus I2C o pase el tiempo máximo para abandonar
if(Wire.available()==2) // Si han llegado dos bytes
{
temperatura=(Wire.read()<< 8)|Wire.read(); // Leer el primer byte, rotarlo 8 posiciones y añadir el valor del segundo byte
Serial.println((float)temperatura/32/8,DEC); // Sólo son relevantes los 11 bits más significativos con una precisión de un octavo de grado (1/8 = 0.125 °C)
}
Wire.endTransmission(); // Liberar el bus I2C
}
}
}
|
Puesto que en el anterior código solamente se cambia la configuración de las temperaturas relacionadas con el aviso, el resto del funcionamiento corresponde con la configuración por defecto.
En esta configuración por defecto hay dos características que son relevantes, en primer lugar el modo de aviso, por defecto el que se denomina «modo termostato» que consiste en activar el aviso al alcanzar la temperatura máxima (o de aviso) y no desactivarlo hasta bajar hasta la temperatura de histéresis. La alternativa es el «modo interrupción», en el que la señal se activa al superar la máxima o al alcanzar un valor menor al de la de histéresis y se resetea con la lectura de cualquier registro, normalmente el de temperatura actual.
La segunda característica es que la señal de aviso se activa a nivel bajo, es decir, el pin OS está a nivel alto hasta llegar a la temperatura máxima de aviso. Dado que la polaridad de la señal de aviso (el nivel a que se activa) es configurable, en algunos montajes sencillos será suficiente utilizar esta señal (hardware) para explotar el LM75, por ejemplo, conectando o desconectando un ventilador al alcanzar el sistema cierta temperatura.
También es posible configurar el funcionamiento del LM75 de manera que no avise inmediatamente después de alcanzar la temperatura de aviso sino hacerlo después de varias incidencias. Este comportamiento es muy útil cuando se trabaja en el límite de temperatura o cuando varía muy rápidamente. El LM75 se puede configurar para avisar después de rebasar una, dos, cuatro o seis veces la temperatura máxima.
En el registro de configuración también existe un bit para desactivar («apagar») el LM75 y entrar en un modo de bajo consumo del que se sale volviendo a cambiar este bit o simplemente al realizar la próxima lectura de un registro.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
#define DIRECCION_LM75 0B01001000 // Dirección del LM75 con A0, A1 y A2 a nivel bajo
#define TEMPERATURA_ACTUAL_LM75 0x00 // Registro que almacena la temperatura medida
#define TEMPERATURA_MAXIMA_LM75 0x03 // Registro que almacena la temperatura máxima (al superarla avisa cambiando el estado del pin OS) 80 °C al inicio
#define TEMPERATURA_HISTERESIS_LM75 0x02 // Registro que almacena la temperatura por debajo de la cual la máxima vuelve a generar un cambio en el pin OS (temperatura de histéresis) 75 °C al inicio
#define CONFIGURACION_LM75 0x01 // Registro del LM75 que almacena la configuración. El valor por defecto es cero
#define ENCENDER_LM75 0B00000000 // Encender el LM75 almacenando este valor (OR el resto) en el registro de configuración
#define APAGAR_LM75 0B00000001 // Apagar el LM75 (modo de bajo consumo) almacenando el valoren el registro de configuración
#define AVISO_LM75_COMPARAR 0B00000000 // Activo cuando se supera la temperatura máxima inactivo cuando la temperatura es menor que la de histéresis (modo termostato)
#define AVISO_LM75_INTERRUPCION 0B00000010 // Activo cuando se supera la temperatura máxima. Se resetea al leer el valor. No se volverá a activar hasta que no se alcance (primero) la de histéresis
#define AVISAR_LM75_BAJO 0B00000000 // Establece el nivel bajo en el pin OS cuando se supere la temperatura máxima
#define AVISAR_LM75_ALTO 0B00000100 // Establece el nivel alto en el pin OS cuando se supere la temperatura máxima
#define AVISAR_LM75_A_1 0B00000000 // Avisar cuando se supere una vez la temperatura (con riesgo de que un error producido por ruido en la conversión lance un aviso incorrecto)
#define AVISAR_LM75_A_2 0B00001000 // Avisar de temperatura superada cuando se mida dos veces
#define AVISAR_LM75_A_4 0B00010000 // Avisar de temperatura superada cuando se mida cuatro veces
#define AVISAR_LM75_A_6 0B00011000 // Avisar de temperatura superada cuando se mida seis veces
//#define TIEMPO_CONVERSION_LM75 100 // El LM75 convierte la temperatura (AD) cada 100 ms
#define TIEMPO_ENTRE_LECTURAS_DE_TEMPERATURA 2000 // Intervalo entre lecturas de la temperatura en ms
#define TIMEOUT_I2C 30 // Esperar 30 ms antes de renunciar a leer el bus I2C
#define TEMPERATURA_AVISO 32.5 // Avisar a los 32.5 °C (Solamente se consideran 9 bits, es decir, medios grados)
#define TEMPERATURA_HISTERESIS 31.0 // No volver a avisar (a los 32.5 °C) hasta que no se baje a los 31.0 °C
#define PIN_AVISO_LM75 7 // Pin de Arduino al que se conecta la salida OS del LM75
#include <Wire.h> // Cargar la librería de las comunicaciones I2C
int temperatura; // Valor de la temperatura actual cargado del LM75
unsigned long cronometro_i2c; // Cronómetro para medir el tiempo de espera de la lectura del bus I2C (y cancelar la operación si se supera el máximo)
unsigned long cronometro_avisos=0; // Cronómetro para controlar que se avise del exceso de temperatura a un intervalo máximo (como máximo cada TIEMPO_ENTRE_AVISOS_DE_TEMPERATURA)
void setup()
{
pinMode(PIN_AVISO_LM75,INPUT); // Usar como entrada el pin de Arduino al que se conecta la salida OS del LM75
Serial.begin(9600); // Inicializar las comunicaciones serie
Wire.begin(); // Inicializar las comunicaciones I2C
// El aviso se activará, a nivel alto (AVISAR_LM75_ALTO), cuando la temperatura sea TEMPERATURA_AVISO o superior cuatro veces consecutivas (AVISAR_LM75_A_4, que vale 0B00010000)
// y no se desactivará hasta que sea TEMPERATURA_HISTERESIS o inferior
// Configurar la temperatura de aviso
Wire.beginTransmission(DIRECCION_LM75); // Iniciar la comunicación con el LM75
Wire.write(TEMPERATURA_MAXIMA_LM75); // Acceder al registro que almacena la temperatura máxima (temperatura de aviso)
Wire.write((byte)((int)(TEMPERATURA_AVISO*8.0)>>3)); // Desplazar 5 bits a la izquierda y 8 a la derecha
Wire.write((byte)((int)(TEMPERATURA_AVISO*8.0)<<5)); // Desplazar 5 bits a la izquierda
Wire.endTransmission(); // Liberar el bus I2C
// Configurar la temperatura de histéresis
Wire.beginTransmission(DIRECCION_LM75); // Iniciar la comunicación con el LM75
Wire.write(TEMPERATURA_HISTERESIS_LM75); // Acceder a la temperatura de histéresis
Wire.write((byte)((int)(TEMPERATURA_HISTERESIS*8.0)>>3)); // Desplazar 5 bits a la izquierda y 8 a la derecha
Wire.write((byte)((int)(TEMPERATURA_HISTERESIS*8.0)<<5)); // Desplazar 5 bits a la izquierda
Wire.endTransmission(); // Liberar el bus I2C
// Configurar el número de veces que debe superarse la temperatura para generar un aviso y la polaridad del aviso
Wire.beginTransmission(DIRECCION_LM75); // Iniciar la comunicación con el LM75
Wire.write(CONFIGURACION_LM75); // Acceder al registro de configuración
Wire.write(AVISAR_LM75_ALTO|AVISAR_LM75_A_4); // Componer la configuración con operaciones OR sobre los diferentes (bits) valores
Wire.endTransmission(); // Liberar el bus I2C
}
void loop()
{
if((millis()–cronometro_avisos)>TIEMPO_ENTRE_LECTURAS_DE_TEMPERATURA) // Si ha transcurrido el tiempo entre lecturas
{
cronometro_avisos=millis(); // Reiniciar el cronómetro de aviso de la temperatura
Wire.beginTransmission(DIRECCION_LM75); // Acceder al LM75 por su dirección en el bus I2C
Wire.write(TEMPERATURA_ACTUAL_LM75); // Solicitar la lectura del registro de la temperatura actual
Wire.endTransmission(); // Liberar el bus I2C
Wire.requestFrom(DIRECCION_LM75,2); // Pedir dos bytes (el valor del registro de la temperatura actual)
cronometro_i2c=millis(); // Iniciar el cronómetro que controla si ha pasado el tiempo máximo de espera de recepción de datos desde el bus I2C
while(Wire.available()<2&&(unsigned long)(millis()–cronometro_i2c)>TIMEOUT_I2C); // Esperar a que lleguen dos bytes al bus I2C o pase el tiempo máximo para abandonar
if(Wire.available()==2) // Si han llegado dos bytes
{
temperatura=(Wire.read()<<8)|Wire.read(); // Leer el primer byte, rotarlo 8 posiciones y añadir el valor del segundo byte
Serial.print(«Temperatura «);
if(digitalRead(PIN_AVISO_LM75)) // Si la señal OS del LM75 está activa (a nivel alto)
{
Serial.print(«demasiado alta»);
}
else
{
Serial.print(«correcta»);
}
Serial.print(» («);
Serial.print((float)temperatura/32/8,DEC); // Sólo son relevantes los 11 bits más significativos con una precisión de un octavo de grado (1/8 = 0.125 °C)
Serial.println(«)»);
}
Wire.endTransmission(); // Liberar el bus I2C
}
}
|
Publicar comentario