Fühler einzeln auslesen bei one Wire

Hallo, ich möchte mehrere 18B20 Temperaturfühler mit nem Uno auswerten. Das funktioniert soweit ganz gut. Übers serielle Monitoring kann ich alle Fühler auslesen.
Jetzt möchte ich über ein 2x16 Lcd die Temperaturen einzeln abrufen,weis aber nicht wie ich auf die jeweils einzelnen Fühler komme.
Im Display erscheint nur der Durchschnitt aller Fühler.
Benötigt Ihr hierfür den Sketch?

Im Display erscheint nur der Durchschnitt aller Fühler. Benötigt Ihr hierfür den Sketch?

Mindestens.
Evtl. auch die Version, die alles richtig macht, nur über SerialMonitor :wink:

https://milesburton.com/Dallas_Temperature_Control_Library

Kannst Du programmieren?
Grüße Uwe

Hier mein verwendeter:

#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

           // include the library code:
           #include <LiquidCrystal.h>

           // initialize the library with the numbers of the interface pins
           LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

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

void setup(void) {
 Serial.begin(9600);
              // set up the LCD's number of columns and rows:
              lcd.begin(16, 2);
              // Print a message to the LCD.
              lcd.print("Temperatur1=");
              lcd.setCursor(6, 1);
              lcd.print("Grad");
}

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);     // 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("  Temperature = ");
 Serial.print(celsius);
 Serial.print(" Celsius, ");
 Serial.print(fahrenheit);
 Serial.println(" Fahrenheit");
             {
              // set up the LCD's number of columns and rows:
              lcd.setCursor(0, 1);
              lcd.print(celsius 1:);     
               }
}

Meine Programierfähigkeiten beschränken sich auf lediglich copy paste programming!!!
Wie gesagt:
Ich möchte die Möglichkeit haben die einzelnen Adressen der Fühler abzurufen und die Temperaturen nach und nach über das 2x16 darzustellen!
Jedoch fällt mir hierfür nix gescheites ein!
Jemand ne Idee?

Verwende Code Tags! Der Linke Button mit </> drauf.

Dann siehe Post #2. Diese Library bietet dir eine eine Abstraktions-Ebene über der OneWire Library.

Es werden erst mal diese zwei Objekte angelegt:

OneWire oneWire(2);
DallasTemperature sensors(&oneWire);

Dann forderst du die Temperaturen an:

sensors.requestTemperatures();

Danach gibt es zwei Optionen um die Temperaturen auszulesen. Das kann man entweder per Index machen (dann geht es nach der Reihenfolge der Sensoren am Bus). Oder auch gezielt per Sensor Adresse.

Das hab ich leider nicht komplett verstanden. Also wo finde ich code tags? Bzw was ist denn das?

Kannst Du mir die Steps etwas genauer erläutern? Will ja auch dazu lernen?

Vielen Dank schonmal

madeair:
Das hab ich leider nicht komplett verstanden. Also wo finde ich code tags? Bzw was ist denn das?

Ich habe den Button mit einer roten Linie markiert:


Dallas18B20_mit_LCD_2x16.ino (3.68 KB)

Kann das jemand erklären das auch der Dümmste (d.h) ich versteht, wie er vorgehen soll?

Wie soll ich in meinem Sketch die einzelnen Fühler (Adressen) definieren, damit ich sie einzeln über einen lcd.print Befehl abrufen kann?

mfg Erwin

"Code" aktivieren und zwischen [ code] und [ /code] den Sketch als Text hineinkopieren.

#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

            // include the library code:
            #include <LiquidCrystal.h>

            // initialize the library with the numbers of the interface pins
            LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

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

void setup(void) {
  Serial.begin(9600);
               // set up the LCD's number of columns and rows:
               lcd.begin(16, 2);
               // Print a message to the LCD.
               lcd.print("Temperatur1=");
               lcd.setCursor(6, 1);
               lcd.print("Grad");
}

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

  
              {
               // set up the LCD's number of columns and rows:
               lcd.setCursor(0, 1);
               lcd.print(celsius 1:);
               
               
               
              
                }
 }
  // include the library code:
 #include <OneWire.h>
 #include <LiquidCrystal.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

           

            // initialize the library with the numbers of the interface pins
            LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

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

void setup(void) {
  Serial.begin(9600);
               // set up the LCD's number of columns and rows:
               lcd.begin(16, 2);
               // Print a message to the LCD.
               lcd.print("Temperatur1=");
               lcd.setCursor(6, 1);
               lcd.print("Grad");
               
              
}

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

  
              {
               // set up the LCD's number of columns and rows:
               lcd.setCursor(0, 1);
               lcd.print(celsius);
               
               
               
              
                }
 }

Also hab den Sketch im Code eingefügt!

Denke ich muß irgend ne lib mit Dallas.... noch zusätzlich einfügen

So ein neuer Versuch:

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



// Data wire is plugged into port 2 on the Arduino
 #define ONE_WIRE_BUS 10
 #define TEMPERATURE_PRECISION 9
   // initialize the library with the numbers of the interface pins
            LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
            
            
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

// arrays to hold device addresses
DeviceAddress insideThermometer, outsideThermometer;

void setup(void)
{
  // start serial port
  Serial.begin(9600);
  Serial.println("Dallas Temperature IC Control Library Demo");
  // set up the LCD's number of columns and rows:
               lcd.begin(16, 2);
               // Print a message to the LCD.
               lcd.print("Temperatur Innen");
               lcd.setCursor(6, 1);
               lcd.print("Grad");
  
  
  
  
  // Start up the library
  sensors.begin();

  // locate devices on the bus
  Serial.print("Locating devices...");
  Serial.print("Found ");
  Serial.print(sensors.getDeviceCount(), DEC);
  Serial.println(" devices.");

  // report parasite power requirements
  Serial.print("Parasite power is: "); 
  if (sensors.isParasitePowerMode()) Serial.println("ON");
  else Serial.println("OFF");

  // assign address manually.  the addresses below will beed to be changed
  // to valid device addresses on your bus.  device address can be retrieved
  // by using either oneWire.search(deviceAddress) or individually via
  // sensors.getAddress(deviceAddress, index)
  //insideThermometer = { 0x28, 0x1D, 0x39, 0x31, 0x2, 0x0, 0x0, 0xF0 };
  //outsideThermometer   = { 0x28, 0x3F, 0x1C, 0x31, 0x2, 0x0, 0x0, 0x2 };

  // search for devices on the bus and assign based on an index.  ideally,
  // you would do this to initially discover addresses on the bus and then 
  // use those addresses and manually assign them (see above) once you know 
  // the devices on your bus (and assuming they don't change).
  // 
  // method 1: by index
  if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0"); 
  if (!sensors.getAddress(outsideThermometer, 1)) Serial.println("Unable to find address for Device 1"); 

  // method 2: search()
  // search() looks for the next device. Returns 1 if a new address has been
  // returned. A zero might mean that the bus is shorted, there are no devices, 
  // or you have already retrieved all of them.  It might be a good idea to 
  // check the CRC to make sure you didn't get garbage.  The order is 
  // deterministic. You will always get the same devices in the same order
  //
  // Must be called before search()
  //oneWire.reset_search();
  // assigns the first address found to insideThermometer
  //if (!oneWire.search(insideThermometer)) Serial.println("Unable to find address for insideThermometer");
  // assigns the seconds address found to outsideThermometer
  //if (!oneWire.search(outsideThermometer)) Serial.println("Unable to find address for outsideThermometer");

  // show the addresses we found on the bus
  Serial.print("Device 0 Address: ");
  printAddress(insideThermometer);
  Serial.println();

  Serial.print("Device 1 Address: ");
  printAddress(outsideThermometer);
  Serial.println();

  // set the resolution to 9 bit
  sensors.setResolution(insideThermometer, TEMPERATURE_PRECISION);
  sensors.setResolution(outsideThermometer, TEMPERATURE_PRECISION);

  Serial.print("Device 0 Resolution: ");
  Serial.print(sensors.getResolution(insideThermometer), DEC); 
  Serial.println();

  Serial.print("Device 1 Resolution: ");
  Serial.print(sensors.getResolution(outsideThermometer), DEC); 
  Serial.println();
}

// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    // zero pad the address if necessary
    if (deviceAddress[i] < 16) Serial.print("0");
    Serial.print(deviceAddress[i], HEX);
  }
}

// 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.print(DallasTemperature::toFahrenheit(tempC));
   // set up the LCD's number of columns and rows:
   lcd.setCursor(0, 1);
   lcd.print(tempC);
   
}

// function to print a device's resolution
void printResolution(DeviceAddress deviceAddress)
{
  Serial.print("Resolution: ");
  Serial.print(sensors.getResolution(deviceAddress));
  Serial.println();    
}

// main function to print information about a device
void printData(DeviceAddress deviceAddress)
{
  Serial.print("Device Address: ");
  printAddress(deviceAddress);
  Serial.print(" ");
  printTemperature(deviceAddress);
  Serial.println();
}

void loop(void)
{ 
  // call sensors.requestTemperatures() to issue a global temperature 
  // request to all devices on the bus
  Serial.print("Requesting temperatures...");
  sensors.requestTemperatures();
  Serial.println("DONE");

  // print the device information
  printData(insideThermometer);
  printData(outsideThermometer);
}

Das selbe Problem: wie kann ich bei folgender Zeile: lcd.print(tempC)
die einzelnen Temperaturen abfragen um sie getrennt auf dem LCD anzuzeigen?
Also einmal die Device Adresse für Innentemperatur?

Du kopierst einfach nur willkürlich Code ohne auch nur ansatzweise zu verstehen was der machst. Versuche nachvollziehen was da gemacht wird, dann siehst du vielleicht dass das größtenteils nur zum Test und zur Demonstration der Bibliothek dient. Das meiste kann man entfernen.

Den Test Sketch brauchst du nur im die Adressen auszulesen. Die musst du dir in eine Text Datei kopieren.
Nachtrag hierzu: Der Sketch dazu ist "Tester" (nicht "Multiple"). Damit bekommst du alle Adressen am Bus angezeigt

In deinem eigentlichen Sketch legst du dir dann Variablen mit den Adressen an. z.B.:

DeviceAddress sensor1 = { 0x28, 0x1D, 0x39, 0x31, 0x2, 0x0, 0x0, 0xF0 };
DeviceAddress sensor2 = { 0x28, 0x2D, 0x39, 0x31, 0x2, 0x0, 0x0, 0xF0 };

Halt mit den Adressen deiner Sensoren

Das einzige was du danach brauchst ist requestTemperatures() und getTempC()

DeviceAddress sensor1 = { 0x28, 0x1D, 0x39, 0x31, 0x2, 0x0, 0x0, 0xF0 };
DeviceAddress sensor2 = { 0x28, 0x2D, 0x39, 0x31, 0x2, 0x0, 0x0, 0xF0 };

OneWire oneWire(2);     //hier wird der Pin übergeben an dem deine Sensoren hängen!!
DallasTemperature sensors(&oneWire);

unsigned long previousMillis;

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

void loop()
{
   if(millis() - previousMillis > 10 * 1000UL)
   {
       previousMillis = millis();

       sensors.requestTemperatures();

       float temp1 = sensors.getTempC(sensor1);
       float temp2 = sensors.getTempC(sensor2);

       .....
   }
}

Das liest die Sensoren alle 10 Sekunden (10 * 1000ms) aus.

setResolution() ist vielleicht noch relevant. 9 Bit für 0,5° Auflösung. 10 Bit für 0,25°