O HDC1080 é um sensor de umidade e temperatura bastante preciso (precisão de 0,2C na temperatura) com interface I2C (com endereço fixo, portanto não dá para ter mais de um sensor no mesmo barramento I2C). Embora o datasheet fale que pode operar a 5V, a placa indica 3.3V.
O primeiro teste foi ligando ao Arduino. Por simplificação, liguei direto SCL e SDA (veja aqui como ligar da forma correta). Bem, a própria Texas faz isso....
As ligações ficam assim:
HDC1080 Arduino UNO
GND GND
3.3V 3.3V
SDA SDA (A4)
SCL SCL (A5)
O código abaixo se limita a fazer o dump de alguns registradores, disparar uma leitura de temperatura e umidade, aguardar a sua execução e ler o resultado bruto://
// Teste do sensor de temperatura e humidade HDC1080
//
#include <Wire.h>
// Endereço I2C do sensor
#define SENSOR_ADDR 0x40
// Registradores do sensor
#define HDC1080_TEMP 0x00
#define HDC1080_UMID 0x01
#define HDC1080_CONF 0x02
#define HDC1080_ID0 0xFB
#define HDC1080_ID1 0xFC
#define HDC1080_ID2 0xFD
#define HDC1080_MFG 0xFE
#define HDC1080_DEV 0xFF
// Rotinas locais
static void read_tempumid(uint16_t *pTemp, uint16_t *pUmid);
static uint16_t read_reg(uint8_t reg);
static void write_reg(uint8_t reg, uint16_t val);
// Iniciação
void setup() {
Serial.begin (9600);
Wire.begin();
// Espera terminar o reset
while (read_reg(HDC1080_CONF) & 0x8000) {
delay (100);
}
// Mostra informações do chip
Serial.print("Fabricante: ");
Serial.println(read_reg(HDC1080_MFG), HEX);
Serial.print(" Modelo: ");
Serial.println(read_reg(HDC1080_DEV), HEX);
// Garante a configuração desejada
write_reg(HDC1080_CONF, 0x1000);
}
// Laco principal
void loop() {
uint16_t temp, umid;
// Faz a leitura
read_tempumid (&temp, &umid);
// Mostra resultado bruto
Serial.println();
Serial.println(temp);
Serial.println(umid);
// Dá um tempo
delay(10000);
}
// Dispara uma leitura de temperatura e umidade e
// pega o resultado.
static void read_tempumid(uint16_t *pTemp, uint16_t *pUmid) {
// Esta escrita dispara a leitura
Wire.beginTransmission(SENSOR_ADDR);
Wire.write (HDC1080_TEMP);
Wire.endTransmission();
// Aguarda fazer a leitura
delay(50);
// Lê o resultado
if (Wire.requestFrom(SENSOR_ADDR, 4) == 4) {
*pTemp = Wire.read() << 8;
*pTemp |= Wire.read();
*pUmid = Wire.read() << 8;
*pUmid |= Wire.read();
} else {
// algo deu errado
*pTemp = *pUmid = 0;
}
}
// Lê um registrador
// Não usar para ler temperatura e umidade!
static uint16_t read_reg(uint8_t reg) {
uint16_t val;
Wire.beginTransmission(SENSOR_ADDR);
Wire.write (reg);
Wire.endTransmission();
if (Wire.requestFrom(SENSOR_ADDR, 2) == 2) {
val = Wire.read() << 8;
val |= Wire.read();
} else {
val = 0; // algo deu errado
}
return val;
}
// Escreve em um registrador
static void write_reg(uint8_t reg, uint16_t val) {
Wire.beginTransmission(SENSOR_ADDR);
Wire.write (reg);
Wire.write (val >> 8);
Wire.write (val & 0xFF);
Wire.endTransmission();
}
Algumas observações:- Os registradores do HDC1080 são de 16 bits, com o byte mais significativo sendo transferido primeiro.
- Os valores lidos dos registradores de fabricante e modelo correspondem ao HDC1080
- Estou usando o modo onde são feitas as leituras consecutivas de temperatura e umidade. Quando é selecionado o registrador de temperatura ou umidade, as leituras são disparadas. Em seguida é necessário aguardar o fim da leitura e depois ler os quatro bytes de resposta.
- Por este motivo, não dá certo tentar ler normalmente os registradores de temperatura e umidade.
// Calcula e mostra a temperatura em celsius
uint32_t aux;
aux = temp * 1650L;
aux = (aux >> 16) - 400L;
temp = (uint16_t) aux;
Serial.print(temp/10);
Serial.print(",");
Serial.println(temp%10);
// Calcula e mostra a umidade em %
aux = umid * 100L;
aux = aux >> 16;
umid = (uint16_t) aux;
Serial.println(umid);
Cabe destacar que eu preferi evitar o uso de ponto flutuante e fiz as contas com inteiros. A temperatura é calculada com uma casa decimal e a umidade só a parte inteira. Não me preocupei com arredondamento, pois as precisões são de 0,2C e 2%.O uso deste sensor com o Raspberry Pi fica para o próximo post.


Nenhum comentário:
Postar um comentário