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