DS18b20 mehrer Temperatursensoren auslesen

Da jeder DS18b20 mit einer eigenen HEX Adresse ansprechbar ist können mit einem einfachen Script mehrere Fühler abgefragt werden. Der Vorteil bei dem One Wire Aufbau besteht darin das nur ein PIN benötigt wird,

#include <OneWire.h>
#include <DallasTemperature.h>

//Datenkabel ist am Digitalpin 2 angeschlossen
#define ONE_WIRE_BUS 3

// oneWire Bus initialisieren
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

void setup(void)
{
  Serial.begin(9600);
  sensors.begin();
}


void loop(void)
{
  sensors.requestTemperatures();
  
  Serial.println(sensors.getTempCByIndex(0)); // SENSOR 1
  Serial.println(sensors.getTempCByIndex(1)); // SENSOR 2
  Serial.println(sensors.getTempCByIndex(2)); // SENSOR 3
}

DS18s20 parallel messen

Der DS18s20 bietet dank der „1-Wire“ Technologie die Möglichkeit mehrer Sensoren an einem PIN abzufragen. Dazu werden alle DS18s20 einfach parallel geschalten. Unterscheiden kann der Arduino die einzelneren Sensoren dank der HEX Adressen. 

Wie kann man die Adressen auslesen?

Der Sketch zum auslesen der Daten ist auch sehr übersichtlich.

#include <OneWire.h>
#include <DallasTemperature.h>

float wert_sensor_1;
float wert_sensor_2;
float wert_sensor_3;
long vorhermillis = millis();

#define ONE_WIRE_BUS 3
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

/*
Sensoradressen eingeben
*/

DeviceAddress Adresse_Sensor1 = { 0x28, 0xFF, 0xFE, 0x3E, 0xA1, 0x16, 0x04, 0x6B }; 
DeviceAddress Adresse_Sensor2 = { 0x28, 0xFF, 0x3B, 0x91, 0xA1, 0x16, 0x05, 0xF6 }; 
DeviceAddress Adresse_Sensor3 = { 0x28, 0xFF, 0x7F, 0x77, 0xA1, 0x16, 0x05, 0x40 }; 


void setup () 
{        
    Serial.begin(9600);
    sensors.begin();
             
    sensors.setResolution(Adresse_Sensor1, 12); // set the resolution
    sensors.setResolution(Adresse_Sensor2, 12); // set the resolution
    sensors.setResolution(Adresse_Sensor3, 12); // set the resolution
}

void loop () 
{  
 if (millis() - vorhermillis > 1000)
 {  
   vorhermillis = millis();
   sensors.requestTemperatures();
   wert_sensor_1 = sensors.getTempC(Adresse_Sensor1);
   wert_sensor_2 = sensors.getTempC(Adresse_Sensor2);
   wert_sensor_3 = sensors.getTempC(Adresse_Sensor3);
   Serial.print("Sensor 1 : ");
   Serial.println(wert_sensor_1);
   Serial.print("Sensor 2 : ");
   Serial.println(wert_sensor_2);
   Serial.print("Sensor 3 : ");
   Serial.println(wert_sensor_3);   
 }
}

DS18b20 Adresse auslesen

Man kann mehrer DS18b20 parallel schalten. Im jedoch jeden einzelnen auslesen zu koennen benötigt man die jeweilige HEX Adresse des Temp. Fühler.

Mit dem diesem Sketch kann man an PIN 3 des Arduino die Adresse des Fühlers im Seriellen Monitor anzeigen.


#include <OneWire.h>

OneWire  ds(3);  // Anschluss an PIN 3

void setup(void) {
  Serial.begin(9600);
  discoverOneWireDevices();
}

void discoverOneWireDevices(void) {
  byte i;
  byte present = 0;
  byte data[12];
  byte addr[8];
  
  Serial.print("Nach 1 Leitung Sensor suchen\n\r");
  while(ds.search(addr)) {
    Serial.print("\n\rGefunden \'1-Wire\' fuehler mit der Adresse:\n\r");
    for( i = 0; i < 8; i++) {
      Serial.print("0x");
      if (addr[i] < 16) {
        Serial.print('0');
      }
      Serial.print(addr[i], HEX);
      if (i < 7) {
        Serial.print(", ");
      }
    }
    if ( OneWire::crc8( addr, 7) != addr[7]) {
        Serial.print("CRC is not valid!\n");
        return;
    }
  }
  Serial.print("\n\r\n\rDas war es... mehr kommmt nicht:)\r\n");
  ds.reset_search();
  return;
}

void loop(void) {
  // nothing to see here
}
  

Temperatur messen mit dem DS18B20

Besteht mal der Bedarf an einer Temperatur Messung ist der DS18B20 ideal dafuer geeignet. 

DS18B20 Wasserdicht

Gemessen wird mit einem One Wire Bus. Durch diesen Bus ist es moeglich an einem Daten-Pin des Arduino mehrer Messfuehler anzuschliessen. Denn Pins einsparen ist immer von Vorteil.

Beschaltung des DS18B20

Und nun noch der entsprechende Sketch.

#include <OneWire.h>

// OneWire DS18S20, DS18B20, DS1822 Temperature Example
//
// http://www.pjrc.com/teensy/td_libs_OneWire.html
//
// The DallasTemperature library can do all this work for you!
// http://milesburton.com/Dallas_Temperature_Control_Library

OneWire  ds(2);  // on pin 10 (a 4.7K resistor is necessary)

void setup(void) {
  Serial.begin(9600);
}

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();
 
  // the first ROM byte indicates which chip
  switch (addr[0]) {
    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);   

  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();

  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("  Temperature = ");
  Serial.print(celsius);
  Serial.print(" Celsius, ");
  Serial.print(fahrenheit);
  Serial.println(" Fahrenheit");
}