Termometr na Arduino i DS18B20
Temperatura to jedna z najważniejszych i najczęściej mierzonych wielkości fizycznych. Do jej mierzenia można zastosować nawet najprostszą, tanią diodę półprzewodnikową. Na rynku dostępne są także specjalne, kalibrowane układy przetwarzające temperaturę na napięcie (np. LM35).
My jedak pójdziemy o krok dalej i wykorzystamy do tego celu układ DS18B20, który zmierzoną wartość temperatury zamienia na postać cyfrową. Poza tym, zawiera w swej strukturze interfejs pozwalający na komunikacje z wykorzystaniem tylko jednego przewodu (tzw. 1-Wire).
Co będzie potrzebne?
- Arduino (oprogramowanie oraz dowolny klon płytki),
- układ DS18B20,
- wyświetlacz alfanumeryczny LCD ze sterownikiem zgodnym z HD44780,
- płytka stykowa, przewody
Połączenie Arduino, LCD oraz DS18B20
We wcześniejszym wpisie przedstawiony został sposób podłączenia wyświetlacza LCD do płytki Arduino.
W omawainym przypadku, do podłączenia wyświetlacza, wykorzystane zostały piny od 5 do 11. Pin 12 posłużył do podłączenia układu DS18B20 (środkowy pin układu).

DS18B20 - opis wyprowadzeń
Musimy także dodać rezystor o wartości 4,7k podłączając go do pinu 2 układu DS18B20 oraz do zasilania 5V.
Układ DS18B20 może pracować w dwóch trybach: pierwszy tzw. Normal
- GND (pin1) podłączony do GND,
- DQ (pin2) podłączony do pinu 12,
- VDD (pin3) podłączony do 5V,
- rezystor 4.7k pomiędzy DQ (pin2) oraz VDD (pin3)
Drugi tzw. Parasitic – nie wymaga doprowadzania zasilania (jest ono „podkradane” z pinu DQ)
- GND (pin1) oraz VDD (pin3) podłączone do GND,
- DQ (pin2) podłączony do pinu 10,
- rezystor 1k pomiędzy DQ (pin2) oraz 5V
Program
Na początek należy zaopatrzyć się w bibliotekę obsługującą układ DS18B20. Jest to najszybszy sposób, aby rozpocząć pracę z układem. Biblioteka dostępna jest poniżej:
Archiwum należy rozpakować do folderu hardware\libraries w miejscu, gdzie zainstalowane jest środowisko Arduino.
Aby sprawdzić, czy biblioteka jest prawidłowo zainstalowana należy uruchomić Arduino. Następnie należy sprawdzić, czy w przykładach pojawiła się pozycja widoczna na poniższym obrazku.

Biblioteka DallasTemperature
Gdy biblioteka jest już zainstalowana, możemy przejśc do napisania programu:
#include <LiquidCrystal.h> #include <DallasTemperature.h> DallasTemperature tempSensor; LiquidCrystal lcd(5, 6, 7, 8, 9, 10, 11); float temp, min = 150, max = -150; int p = 0; void setup(void) { lcd.clear(); tempSensor.begin(12); } void loop(void) { switch(tempSensor.isValid()) { case 1: lcd.clear(); lcd.print("Invalid CRC"); tempSensor.reset(); return; case 2: lcd.clear(); lcd.print("Not a valid device"); tempSensor.reset(); return; } temp = tempSensor.getTemperature(); if(temp < min) min = temp; if(temp > max) max = temp; lcd.setCursor(0,0); lcd.print("T = "); lcd.print(temp); lcd.write(0xDF); lcd.write('C'); if(p < 3) { lcd.setCursor(0,1); lcd.print("Min = "); lcd.print(min); lcd.write(0xDF); lcd.write('C'); p++; } else { lcd.setCursor(0,1); lcd.print("Max = "); lcd.print(max); lcd.write(0xDF); lcd.write('C'); p++; if(p == 6) p = 0; } }
Sprawdzamy działanie
Wgrywamy program do mikrokontrolera (Upload to I/O Board). Teraz możemy sprawdzić, czy wszystko działa jak należy.
Jeśli układ działa, na wyświetlaczu pojawi się aktualna temperatura, temperatura maksymalan oraz minimalna (dwie ostatnie wyświetlane na przemian).

Działający termometr
Biblioteka DallasTemperature
W skład biblioteki wchodzą funkcje:
DallasTemperature
Opis:
Tworzy obiekt typu DallasTemperature.
Składnia:
DallasTemperature temp
Parametry:
temp: nazwa tworzonego obiektu
begin()
Opis:
Inicjuje obsługę układu DS1820 na wybranym wyprowadzeniu.
Składnia:
temp.begin(pin)
Parametry:
pin: numer wyprowadzenia Arduino do którego podłączony jest czujnik
temp: obiekt typu DallasTemperature
isValid()
Opis:
Funkcja służy do sprawdzenia poprawności komunikacji z czujnikiem.
Składnia:
temp.isValid()
Parametry:
temp: obiekt typu DallasTemperature
getTemperature()
Opis:
Funkcja inicjuje pomiar temperatury przez czujnik oraz zwraca wynik tej operacji w stopniach Celsjusza.
Składnia:
temp.getTemperature()
Parametry:
temp: obiekt typu DallasTemperature
reset()
Opis:
Resetuje komunikację z czujnikiem.
Składnia:
temp.reset()
Parametry:
temp: obiekt typu DallasTemperature
toFahrenheit()
Opis:
Funkcja zamienia wynik pomiaru temperatury w stopniach Celsjusza na stopnie Fahrenheita.
Składnia:
temp.toFahrenheit()
Parametry:
temp: obiekt typu DallasTemperature


29 komentarzy do “Termometr na Arduino i DS18B20”
Nijak nie mogę uruchomić tego. Wysypuje się przy kompilowaniu, Twój przykład jak i oryginalny z transmisją szeregową zwracają ten sam błąd.
Załączam zrzut może ktoś będzie wiedział o co chodzi:
http://i33.tinypic.com/2a4zcp2.jpg
@Grejzen: Jaką wersję oprogramowania Arduino posiadasz? Biblioteka została prawidłowo zainstalowana?
Wersje mam najnowsza tj. 0017. Instalowałem biblioteki z tego artykułu, jak i biblioteki z oryginalnego wątku o DallasTemperature na forum Arduino. Zawsze ten sam błąd.
@Grejzen: A inne przykłady kompilują się poprawnie? Np. Blink
Pozostałe przykłady kompilują się bez problemu. Przykład z OneWire też się kompiluje ale jakieś krzaczki wysyla
U mnie wszystko działa, ale nie wyświetlają się minimalna i maksymalna wartość – może jest to spowodowane tym, że nie świeci w ogóle dolna połówka wyświetlacza. (wyświetlacz 2×16 z podświetleniem)?
@Maciek [vobo]: Spróbuj wcisnąć reset, gdy program jest już załadowany do mikrokontrolera – czasami wyświetlacz źle się inicjuje.
@Grejzen: działasz pod Linuxem? Jeśli tak, to zajrzyj na stronę arduino, gdzie znajdziesz dodatkowe kroki wymagane przy instalacji oprogramowania.
Działam tylko i wyłącznie pod Windowsem.
Michał, a możesz przesłać mi Twoją wersje ze wszystkimi bibliotekami? Na grejzen [ małpa ] gmail [ kropka] com.
już działa dolna połówka wyświetlacza
wystarczyło dopisać w sekcji „void setup” następującą linijkę:
lcd.begin(2, 16);
teraz działa cały wyświetlacz
pozdrawiam,
Maciek
Witam!
Robię podobny projekt tylko rozbudowany o większą ilość czujników i kontroler obrotów. Wszystko mi na razie działa ok, nie licząc wyświetlacza. Mianowicie na wyświetlaczu 2×16 lini przez większość czasu mam „krzaczki”, natomiast po podłączeniu wyświetlacza 4×16 wszystko jest ok. Większy mi się nie zmieści w moim projekcie, a szkoda mi niepotrzebnie kupować wyświetlacz. Sytuacja jest tym dziwiniejsza, że wyświetlacz działa dobrze na prostych porgramach, nie chce dla mojego:
#include
#include
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
static const int ONE_WIRE_PIN = 12;
NewOneWire oneWire(ONE_WIRE_PIN);
DallasTemperature tempSensor0(oneWire, 0);
DallasTemperature tempSensor1(oneWire, 1);
DallasTemperature tempSensor2(oneWire, 2);
void setup(void) {
lcd.begin(16, 2);
TCCR1B = TCCR1B & 0b11111000 | 0×01;
Serial.begin(9600);
tempSensor0.begin();
tempSensor1.begin();
tempSensor2.begin();
tempSensor0.setResolution(9);
tempSensor1.setResolution(9);
tempSensor2.setResolution(9);
// sends convert temperature to all devices on the NewOneWire connection.
// only one device on each bus needs to do this. ideally, it should be
// on your highest resolution device so if a longer delay is necessary,
// it will be the long enough.
tempSensor0.globalTempRequest();
tempSensor0.conversionDelay();
//Serial.println(„Dallas Temperature IC Control Library”);
}
void printId(DallasTemperature &sensor) {
for (uint8_t i = 0; i < 8; i++) {
Serial.print(sensor.getSlaveAddr()[i], HEX);
//lcd.print(sensor.getSlaveAddr()[i], HEX); //jeżeli na LCD puszcze tylko ta linijke to wyswietla ja dobrze
}
}
void display(DallasTemperature &sensor) {
// Ask the library whether the device is valid
Serial.print("sensor ");
Serial.print(sensor.getIndex(), DEC);
Serial.print(" ");
printId(sensor);
Serial.print(": ");
switch(sensor.isValid())
{
case 1:
Serial.println("Invalid CRC");
sensor.reset(); // Attempts to redetect IC
return;
case 2:
Serial.println("Not a valid device");
sensor.reset(); // Attempts to redetect IC
return;
}
// getTemperature returns a float.
float temperature = sensor.getTemperature();
lcd.print(temperature);
Serial.print(temperature);
Serial.println("C");
}
void loop(void) {
lcd.clear();
lcd.setCursor(0,0);
display(tempSensor0);
lcd.setCursor(8,0);
display(tempSensor1);
lcd.setCursor(0,1);
display(tempSensor2);
Serial.println();
delay(1000);
}
Ma ktoś jakiś pomysł?
Po pierwsze: gdzie podłączasz sygnał RW wyświetlacza? Sprawdź, czy połączenie jest pewne.
Po drugie: nie bardzo rozumiem co chcesz osiągnąć poprzez ten fragment kodu:
TCCR1B = TCCR1B & 0b11111000 | 0×01;Mało tego, ten zapis jest nieco bez sensu
RW jest na stale do masy. A ten zapis powoduje zwiększenie częstotliwości PWM dla wentylatorów, żeby cewki nie piszczały. 0×01 daje 32MHz
Chyba raczej 16MHz, chyba że o czymś nie wiem. Czy wywalenie tej linii nie poprawia sytuacji?
Pins 9 and 10: controlled by timer 1
Setting Divisor Frequency
0×01 1 31250
0×02 8 3906.25
0×03 64 488.28125
0×04 256 122.0703125
0×05 1024 30.517578125
Nie pomaga wyrzucenie tej linii.
Wcześniej działał dobrze, wydaje mi się że jak sprawdzałem bibliotekę LiquidCrystal_I2C to od tego czasu nie działa dobrze. Możliwe że uszkodziłem go jakoś? I czemu na prostych programach działa?
No właśnie 31,25kHZ a nie 32MHz.
Spróbuj na czystej instalacji Arduinio tzn. utwórz nowy katalog, wrzuć tam Aduino, LiquidCrystal i DallasTemperature.
W sumie to podałem w przybliżeniu częstotliwość
A ważne dla mnie było żeby cewki nie piszczały. Tylko faktycznie w tej części kodu nie jest to potrzebne- okroiłem program, żeby tylko wyświetlacz sprawdzić. W sumie zamówiłem nowy wyświetlacz 2×20 linii. I zobaczymy jak pójdzie.
Czy do zrobienia tego układu należy zakupić potencjometr liniowy czy logarytmiczny?
Ja zastosowałem potencjometr montażowy o charakterystyce liniowej, ale nie jest to bardzo istotne, gdyż służy on jedynie do regulacji kontrastu wyświetlacza.
Jaka jest maxymalna długość przewodów od czujnika do procesora? Chciałbym mierzyć temperaturę na zewnątrz lecz odległość, gdzie znajdował by się układ od okna to ok. 4m.
Dla 1wire przewód o długości 4 metrów, to praktycznie żaden problem.
Osobiście przeprowadzałem próby na 10 metrowym przewodzie, które zakończyły się sukcesem.
A gdy będę dosztukowywał przewody, to straty będą dość duże na pomiarze temperatury?
Dane w standardzie 1wire wysyłane są w sposób cyfrowy, więc albo je odbierzesz, albo nie. Nie wystąpi sytuacja „straty” – jeśli odbierzesz dane i sprawdzisz sumę kontrolną, to na pewno temperatura będzie prawidłowa.
Z serii nudnych pytań następna seria. Czy do zrobienia tego układu można zastosować wyświetlacz ledowy bez sterownika HD44780. Chodzi mi o ten:
http://www.sklep.avt.pl/p/pl/47220/wyswietlacz+czerwony+2+cyfry+14-2mm+wa.html
Możesz użyć ten wyświetlacz tylko jeśli dokonasz zmian w projekcie.
Powyższy kod jest napisany dla wyświetlacza LCD ze sterownikiem HD44780.
Jak poprawnie odczytać temperaturę na NTC w arduino.
Proszę o jakiś przykład.
Proszę:
http://www.libelium.com/squidbee/index.php?title=Adding_a_temperature_sensor
Witam, czy jest możliwość napisania aplikacji, która sczytywała informacje o temperaturze z czujnika w programie na komputerze?
Nie wiem, czy dobrze rozumiem pytanie… powiem tak – jest możliwość napisania aplikacji, która odczyta temperaturę z czujnika – wystarczy dane z przedstawionego projektu wysłać poprzez port szeregowy do komputera i odebrać w napisanym programie.