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();
- }
- 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);
O uso deste sensor com o Raspberry Pi fica para o próximo post.
Nenhum comentário:
Postar um comentário