Ragazzi ho visto il codice ma non è molto bello, non fate il check sul CRC dei dati, la libreria ha un bug per le temperature negative, dovete correggerlo se andate sotto zero, ecco il codice che ho utilizzato per il mio termometro, utilizza un display LCD ed ha funzionalità di risparmio energetico, non dovreste avere problemi ad estrapolare il codice di controllo e lettura del termometro. La libreria è OneWire Arduino Library, connecting 1-wire devices (DS18S20, etc) to Teensy
Ciao
// Termometer DS18B20
#include <LiquidCrystal.h>
#include <OneWire.h>
// WatchDog is used to save energy instead
#include <avr/power.h>
#include <avr/sleep.h>
#include <avr/wdt.h>
const byte lcd_rs = 7;
const byte lcd_e = 5;
const byte lcd_d4 = 4;
const byte lcd_d5 = 3;
const byte lcd_d6 = 2;
const byte lcd_d7 = 1;
LiquidCrystal lcd(lcd_rs, lcd_e, lcd_d4, lcd_d5, lcd_d6, lcd_d7);
OneWire ds(9);
volatile boolean f_wdt=1;
// Watchdog Interrupt Service / is executed when watchdog timed out
ISR(WDT_vect) {
f_wdt=1; // set global flag
}
void setupWatchdog(byte wdp0, byte wdp1, byte wdp2, byte wdp3) {
// WDTCSR - Watchdog timer Control Register, used for configuring the time-out, mode of operation, etc.
// MCUSR - MCU Status Register, used to tell the cause of the last reset, such as brown-out reset, watchdog reset, etc.
// NOTE: for security reasons, there is a timed sequence for clearing the WDE and changing the time-out configuration.
// If you don't use this sequence properly, you'll get unexpected results.
cli(); //disable global interrupts
wdt_reset();
MCUSR &= ~(1<<WDRF); // Clear the reset flag
// In order to change WDE or the prescaler, we need to set WDCE (This will allow updates for 4 clock cycles)
WDTCSR |= (1<<WDCE) | (1<<WDE); // Set WD_ChangeEnable and WD_resetEnable to alter the register
WDTCSR = wdp0<<WDP0 | wdp1<<WDP1 | wdp2<<WDP2 | wdp3<<WDP3; // set new watchdog timeout value
WDTCSR |= _BV(WDIE); // Enable the WD interrupt (note no reset)
sei(); //enable global interrupts
}
void Sleep()
{
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
// Set sleep enable (SE) bit:
sleep_enable();
// Put the device to sleep:
sleep_mode(); // ZZZ....
// Upon waking up, sketch continues from this point.
sleep_disable();
}
void sleep250ms()
{
setupWatchdog(0,0,1,0);
Sleep();
}
void sleep500ms()
{
setupWatchdog(1,0,1,0);
Sleep();
}
void sleepSecond()
{
setupWatchdog(0,1,1,0);
Sleep();
}
void setup() {
// Stabilize voltage
delay(5);
// Disable ADC, SPI and TWI
power_adc_disable(); // Disable the Analog to Digital Converter module.
power_spi_disable(); // Disable the Serial Peripheral Interface module.
power_twi_disable(); // Disable the Two Wire Interface module.
power_usart0_disable(); // Disable the USART 0 module.
lcd.begin(16, 2);
lcd.clear();
lcd.print("Thermometer v1");
sleepSecond();
lcd.clear();
}
byte deviceFounds = 0;
void loop() {
if (f_wdt==1) // wait for timed out watchdog
f_wdt=0;
byte data[12];
byte addr[8];
float celsius;
// Search for the next device. The addrArray is an 8 byte array. If a device is found, addrArray is filled with the device's address and true is returned.
// If no more devices are found, false is returned.
if (!ds.search(addr)) {
if(deviceFounds == 0)
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("No devices found"); // No more addresses
lcd.setCursor(0, 1);
lcd.print("Try check probe"); // No more addresses
sleepSecond();
}
deviceFounds = 0;
// Begin a new search. The next use of search will begin at the first device.
ds.reset_search();
sleep250ms();
return;
}else{
deviceFounds++;
}
// Compute a CRC check on an array of data.
if (OneWire::crc8(addr, 7) != addr[7]) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Address Error");
lcd.setCursor(0, 1);
lcd.print("CRC is not valid");
sleepSecond();
return;
}
// Reset the 1-wire bus. Usually this is needed before communicating with any device.
ds.reset();
// Select a device based on its address. After a reset, this is needed to choose which device you will use,
// and then all communication will be with that device, until another reset.
ds.select(addr);
// Write a byte, and leave power applied to the 1 wire bus.
ds.write(0x44); // start conversion, with parasite power on at the end
// from Datasheet max conversion time is 750ms
sleep500ms();
sleep250ms();
ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
for (byte i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
}
// Check data with CRC
if (OneWire::crc8(data, 8) != data[8]) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Data Error");
lcd.setCursor(0, 1);
lcd.print("CRC is not valid");
sleepSecond();
return;
}
// convert the data to actual temperature
int raw = (data[1] << 8) | data[0];
byte cfg = (data[4] & 0x60); // default is 12 bit resolution, 750 ms conversion time
celsius = (float)raw / 16.0;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Temperatura");
/*
for( i = 0; i < 8; i++) {
lcd.print(addr[i], HEX);
} */
lcd.setCursor(0, 1);
lcd.print(celsius);
lcd.print("C");
}