Instalação
Esta biblioteca não inclui a comunicação 1-wire, para isto ela usa a OneWire que vimos no post anterior. A instalação é semelhante à da OneWire, basta expandir o zip no subdiretório libraries do diretório onde são gravados os sketches. Precisei renomear o subdiretório, pois a IDE não aceita espaços e caracteres alfanuméricos.
Primeiro Teste
Mantendo a montagem do post anterior, abri o exemplo Tester, alterei a porta para 10 e executei. A saída está abaixo:
Dallas Temperature IC Control Library Demo
Locating devices...Found 3 devices.
Parasite power is: ON
Found device 0 with address: 289C7BB504000041
Setting resolution to 9
Resolution actually set to: 9
Found device 1 with address: 281D25DC040000A8
Setting resolution to 9
Resolution actually set to: 9
Found device 2 with address: 28274CB6040000E3
Setting resolution to 9
Resolution actually set to: 9
Requesting temperatures...DONE
Temperature for device: 0
Temp C: 21.00 Temp F: 69.80
Temperature for device: 1
Temp C: 21.50 Temp F: 70.70
Temperature for device: 2
Temp C: 21.50 Temp F: 70.70
Como a saída mostra, através da biblioteca conseguimos descobrir quantos dispositivos estão conectados, se eles são alimentados pela linha de dados e quais os seus endereços. Podemos também controlar a resolução (número de bits do ADC) e disparar a leitura em vários dispositivos com uma única chamada.
O Uso da Biblioteca
Vamos examinar o código do exemplo (simplificado abaixo):
#include <OneWire.h> #include <DallasTemperature.h> #define ONE_WIRE_BUS 10 #define TEMPERATURE_PRECISION 9 // Setup a oneWire instance to communicate with any OneWire devices OneWire oneWire(ONE_WIRE_BUS); // Pass our oneWire reference to Dallas Temperature. DallasTemperature sensors(&oneWire); int numberOfDevices; // Number of temperature devices found DeviceAddress tempDeviceAddress; void setup(void) { // start serial port Serial.begin(9600); Serial.println("Dallas Temperature IC Control Library Demo"); // Start up the library sensors.begin(); // Grab a count of devices on the wire numberOfDevices = sensors.getDeviceCount(); // locate devices on the bus Serial.print("Locating devices..."); Serial.print("Found "); Serial.print(numberOfDevices, DEC); Serial.println(" devices."); // report parasite power requirements Serial.print("Parasite power is: "); if (sensors.isParasitePowerMode()) Serial.println("ON"); else Serial.println("OFF"); // Loop through each device, print out address for(int i=0;i<numberOfDevices; i++) { // Search the wire for address if(sensors.getAddress(tempDeviceAddress, i)) { Serial.print("Found device "); Serial.print(i, DEC); Serial.print(" with address: "); printAddress(tempDeviceAddress); Serial.println(); Serial.print("Setting resolution to "); Serial.println(TEMPERATURE_PRECISION, DEC); // set the resolution to TEMPERATURE_PRECISION bit (Each Dallas/Maxim device is capable of several different resolutions) sensors.setResolution(tempDeviceAddress, TEMPERATURE_PRECISION); Serial.print("Resolution actually set to: "); Serial.print(sensors.getResolution(tempDeviceAddress), DEC); Serial.println(); }else{ Serial.print("Found ghost device at "); Serial.print(i, DEC); Serial.print(" but could not detect address. Check power and cabling"); } } } // function to print the temperature for a device void printTemperature(DeviceAddress deviceAddress) { float tempC = sensors.getTempC(deviceAddress); Serial.print("Temp C: "); Serial.print(tempC); Serial.print(" Temp F: "); Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit } void loop(void) { // call sensors.requestTemperatures() to issue a global temperature // request to all devices on the bus Serial.print("Requesting temperatures..."); sensors.requestTemperatures(); // Send the command to get temperatures Serial.println("DONE"); // Loop through each device, print out temperature data for(int i=0;i<numberOfDevices; i++) { // Search the wire for address if(sensors.getAddress(tempDeviceAddress, i)) { // Output the device ID Serial.print("Temperature for device: "); Serial.println(i,DEC); // It responds almost immediately. Let's print out the data printTemperature(tempDeviceAddress); // Use a simple function to print out the data } //else ghost device! Check your power requirements and cabling } }
Ok, não parece muito complicado. Os métodos possuem nomes e parâmetros simples, mesmo sem olhar a documentação dá para entender o código.
Abrindo o Capô
Uma olhada no código fonte da biblioteca trouxe algumas surpresas. A biblioteca não mantém nenhuma informação sobre a rede 1-wire (exceto o pino onde ela está ligado). Em quase todo acesso ela enumera os dispositivos conectados, o que parece desnecessário. Poderia ser útil caso dispositivos sejam conectados ou desconectados durante a execução, porém aí esbarramos em um outro problema. As funções usadas no exemplo se referem aos dispositivos pela sua ordem de enumeração, o que mudaria neste caso.
O disparo da leitura "simultaneamente" também pode apresentar problemas. Caso esteja sendo usada a alimentação pelo pino de dados, a biblioteca espera um tempo fixo (conforme a precisão programada). Se a alimentação é independente, é testado se a conversão terminou em apenas um dos sensores. Portanto, teremos problemas se os sensores estiverem configurados com precisões diferentes ou apresentarem tempos de resposta diferente.
Concluindo
Esta biblioteca é bem prática para projetos rápidos, desde que todos os sensores estejam configurados iguais e tenham desempenho semelhante e não haja alteração dinâmica na rede.
Se quisermos algo mais sofisticado ou seguro, vamos precisar escrever a nossa própria biblioteca. É o que pretendo tentar no futuro.
8 comentários:
Bom dia, estou tentando utilizar o DS18B20 já montado testei diversos programas inclusive este que você apresentou e obtenho apenas temperaturas negativas -2032 ºC que totalmente incompatível já que a temperatura deveria estar na faixa de 20ºC. Já testei diversas montagem e programas e todos me dão uma temperatura negativa totalmente fora da faixa. Você tem alguma ideia do que pode ser?
Aguardo retorno.
O programa localizou o DS18B20 e mostrou o endereço? Você tentou o programa da parte 1 e ele identificou corretamente o modelo do chip? Se sim para as duas coisas, eu desconfiaria que o DS18B20 está pifado (você testou com mais de um?).
Como posso fazer para o sensor analisar durante 1 minuto se ouve alteração >=6 graus para mais nesse 1 minuto e fazer determinado comando que eu vou criar. É possível isso?
Rafael: Quem fará isto é o Arduino, não o sensor. Por exemplo, o seu programa pode ler a temperatura, dar um delay de 1 minuto, ler de novo e comparar as duas temperaturas. Isto pode ser suficiente se a sua temperatura está sempre subindo, mas se ela estiver oscilando pode ser melhor você usar uma média móvel e ficar monitorando continuamente.
Como eu faço para salvar o dado de 1 minuto para comparar depois?
Rafael: float tempC = sensors.getTempC(deviceAddress); salva na variável tempC a temperatura informada pelo dispositivo de endereço deviceAddress. Se você não conhece a linguagem C e a programação do Arduino, recomendo você dar uma estudada nelas primeiro.
Fiz uma ligação em “modo normal” de vários sensores (mais especificamente 4 sensores) DS18B20. Coloquei-os medindo a mesma posição no quarto, porém mostraram valores diferentes entre si. A diferença não é muito grande (em torno de meio grau celsius). Gostaria de saber se isso tem algo a ver com o resistor utilizado (4,7 kohm) e se eu poderia melhorar a precisão da medida usando resistores diferentes para cada sensor.
Lúcio, o resistor está relacionado à comunicação e não afeta a precisão. Segundo o datasheet, a precisão no pior caso é justamente esta que você observou +/- 0,5 C. Além disso, se você estiver usando a resolução de 9 bits o bit menos significativo da leitura corresponde também a 0,5C. Você pode experimentar aumentar a resolução para 10, 11 ou 12 bits. Isto vai aumentar o tempo de leitura e não vai melhorar a precisão em si, mas o valor lido será mais fiel. Por exemplo, imagine que o valor lido está oscilando entre 20,9 e 21,1 (devido à precisão). Trabalhando com 9 bits a leitura só poderá oscilar entre 20,5 e 21, pois não tem como reportar um valor intermediário.
Postar um comentário