Temperatursensor DS18B20 mit dem Arduino Uno und LCD Display

Ich habe den Maxim Temperatur Sensor DS18B20 bekommen. Er ist bereits dicht vergossen und wird mit einem 3-poligen Anschlusskabel geliefert (rot schwarz gelb)

Er hat einen 1-wire Bus, das heisst es müssen nur die Datenleitung und GND zum Anschluss verwendet werden. Mit einem 4,7 kOhm Widerstand von der Datenleitung gegen 5V wird am Arduino die „parasitäre“ Stromversorgung hergestellt. Der Sensor bekommt so die Stromversorgung mit über die Datenleitung.
Bei Leitungslängen über 6m sollte die 5V Versorgung zusätzlich angeschlossen werden, das ist hier aber nicht notwendig.

Der DS18B20 misst die Temperatur von -55 bis +125°C. Im Bereich von -10°C bis +85°C hat er einem maximalen Fehler von 0,5 °C. Die Auflösung kann bis 12 Bit gewählt werden. Das entspricht einer Auflösung von 0,0625 Grad. Dadurch sind sehr genaue Differenz Messungen möglich. Die Rechenzeit für einen 12 Bit Wert beträgt 750ms.

Der Sensor Anschluss

Auf einem Steckbrett werden nur gelb-Daten an Pin 4 und schwarz an Arduino GND angeschlossen. Dazu ein 4,7 kOhm Widerstand von der Datenleitung zum Arduino 5V Anschluss. Rot vom Sensor bleibt frei.

DS18B20 Anschluss

Der Aufbau

Mit dem DS18B20 , dem Arduino Uno und dem LCD Display. Das LCD Display ist verkabelt wie im Frequenzzähler Beitrag beschrieben. Die Sensor Datenleitung liegt am Arduino Uno auf Pin 4.

DS18B20 UNO LCD

Das Programm

Hier gibt es die OneWire Library und eine Beschreibung. Das Beispiel aus der Library wurde hier verwendet und um eine LCD Display Ausgabe erweitert.

// DS18B20 Temperatur Sensor
//
// Doku und OneWire Library hier
// http://playground.arduino.cc/Learning/OneWire-DE
//
// Matthias Busse 7.6.2014 Version 1.0

#include < OneWire.h>
OneWire  ds(4);  // Pin 4 mit 4,7 kOhm gegen 5V gelegt

#include < LiquidCrystal.h>
LiquidCrystal lcd(12, 13, 11, 7, 8, 9, 10);

void setup(void) {
  Serial.begin(38400); // Serielle Ausgabe
  lcd.begin(20,4);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Temp. Sensor");
  lcd.setCursor(0,1); // Display ausgeben
  lcd.print(" MBS  Ver. 1.00 ");
  delay(1000);
}

void loop(void) {
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;
  
  if ( !ds.search(addr)) {
    Serial.println("No more addresses.");
    Serial.println();
    ds.reset_search();
    delay(250);
    return;
  }
  Serial.print("ROM =");
  for( i = 0; i < 8; i++) {
    Serial.write(' ');
    Serial.print(addr[i], HEX);
  }
  if (OneWire::crc8(addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");
      return;
  }
  Serial.println();
  switch (addr[0]) { // the first ROM byte indicates which chip
    case 0x10:
      Serial.println("  Chip = DS18S20");  // or old DS1820
      type_s = 1;
      break;
    case 0x28:
      Serial.println("  Chip = DS18B20");
      type_s = 0;
      break;
    case 0x22:
      Serial.println("  Chip = DS1822");
      type_s = 0;
      break;
    default:
      Serial.println("Device is not a DS18x20 family device.");
      return;
  } 
  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1); // start conversion, with parasite power on at the end
  delay(1000);       // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad
  Serial.print("  Data = ");
  Serial.print(present, HEX);
  Serial.print(" ");
  for ( i = 0; i < 9; i++) { // we need 9 bytes
    data[i] = ds.read();
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" CRC=");
  Serial.print(OneWire::crc8(data, 8), HEX);
  Serial.println();
  // Convert the data to actual temperature
  // because the result is a 16 bit signed integer, it should
  // be stored to an "int16_t" type, which is always 16 bits
  // even when compiled on a 32 bit processor.
  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    // at lower res, the low bits are undefined, so let's zero them
    if (cfg == 0x00) raw = raw & ~7;      // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    // default is 12 bit resolution, 750 ms conversion time
  }
  celsius = (float)raw / 16.0;
  fahrenheit = celsius * 1.8 + 32.0;
  Serial.print("  Temperatur = ");
  Serial.print(celsius);
  Serial.print(" Celsius, ");
  Serial.print(fahrenheit);
  Serial.println(" Fahrenheit");
  lcd.setCursor(0,1);         // LCD Display ausgeben
  lcd.print("                ");
  lcd.setCursor(0,1);
  lcd.print(celsius);
  lcd.print((char)223);       // Grad Symbol ausgeben
  lcd.print("C  ");
  lcd.print(fahrenheit);
  lcd.print((char)223);
  lcd.print("F");
}

Es wird eine Messung pro Sekunde durchgeführt und in Grad Celsius und Fahrenheit ausgegeben.

Weiter zu Teil 2.

Ähnliche Beiträge

Der Luftdruck und Temperatur Sensor BMP085 ( Genauigkeit: 1 °C)
Luftdruck und Temperatur als NMEA 0183 Datensatz ausgeben.

von Matthias Busse

 

3 Gedanken zu „Temperatursensor DS18B20 mit dem Arduino Uno und LCD Display

  1. Pingback: Temperatursensor DS18B20 mit dem Arduino Uno Teil 2 | Shelvin – Elektronik ausprobiert und erläutert

  2. Michael Madl

    Guten Tag Herr Busse
    wir haben ein Problem bei einem Arduino Projekt mit externer Spannungsversorgung um Lüfter über Temperatursensoren zu schalten. Würden sie uns da möglicherweise zeitnah weiterhelten? Sollte bis nächste Woche laufen. Wir wollten die Spannung eines 12 Volt Netzteiles mit einem Mosfet aufteilen und dann mit 5 Volt die Sensoren und mit 12 Volt die Lüfter ansteuern. Aber leider zeigt uns dann das Display am Arduino -127 Grad an bzw kommt der Fehler auch wenn man LED über den Arduino ansteuert.
    Können sie uns da weiterhelfen?
    gruß Michael Madl

    Antworten

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.