Frage zu Dallas DS18B20

Hallo zusammen

Habe ein paar fragen zu DS 18b20 Bekomme falsche Werte

Garten: 48.94 Celsius
Wohnzimmer: 40.88 Celsius
Heizkeller: 42.00 Celsius
Aquarium: 43.19 Celsius

Garten müsste 22 Grad haben
habe einen Arduino Mega 2560

Es sind anlegefühler

Habe den sketch von Fluuux habe nur die Sensoradressen eingegeben

Pin 2 und 4,7k nach +5v

Arduino – gezielt einen ds1820 Temperatur-Sensor auslesen

#include <OneWire.h>
#include <DallasTemperature.h>
 
OneWire  ds(2); //pin für ds1820
 
//DeviceAdressen der einzelnen ds1820 Temperatursensoren angeben. (loop anpassen)
DeviceAddress sensor1 = { 0x28, 0x7C, 0x97, 0xC7, 0x4, 0x0, 0x0, 0x3C };
DeviceAddress sensor2 = { 0x28, 0x5, 0xC5, 0xAC, 0x4, 0x0, 0x0, 0x20 };
DeviceAddress sensor3 = { 0x28, 0xD6, 0xBA, 0xC8, 0x4, 0x0, 0x0, 0x21 };
DeviceAddress sensor4 = { 0x28, 0x55, 0x14, 0xA8, 0x4, 0x0, 0x0, 0x93 };
//DeviceAddress sensor5 = { 0x28, 0x9A, 0x6C, 0xC8, 00x4, 00x0, 00x0, 0xEB }; 


char sensor1Name[] = "Garten: ";
char sensor2Name[] = "Wohnzimmer: ";
char sensor3Name[] = "Heizkeller: ";
char sensor4Name[] = "Aquarium: ";
 
void setup(void)
{
  Serial.begin(9600);
}
 
void writeTimeToScratchpad(byte* address)
{
  //reset the bus
  ds.reset();
  //select our sensor
  ds.select(address);
  //CONVERT T function call (44h) which puts the temperature into the scratchpad
  ds.write(0x44,1);
  //sleep a second for the write to take place
  delay(1000);
}
 
void readTimeFromScratchpad(byte* address, byte* data)
{
  //reset the bus
  ds.reset();
  //select our sensor
  ds.select(address);
  //read the scratchpad (BEh)
  ds.write(0xBE);
  for (byte i=0;i<9;i++){
    data[i] = ds.read();
  }
}
 
float getTemperature(byte* address)
{
  int tr;
  byte data[12];
 
  writeTimeToScratchpad(address);
 
  readTimeFromScratchpad(address,data);
 
  //put in temp all the 8 bits of LSB (least significant byte)
  tr = data[0];
 
  //check for negative temperature
  if (data[1] > 0x80)
  {
    tr = !tr + 1; //two's complement adjustment
    tr = tr * -1; //flip value negative.
  }
 
  //COUNT PER Celsius degree (10h)
  int cpc = data[7];
  //COUNT REMAIN (0Ch)
  int cr = data[6];
 
  //drop bit 0
  tr = tr >> 1;
 
  return tr - (float)0.25 + (cpc - cr)/(float)cpc;
}
 
void loop(void)
{
  float temp1 = getTemperature(sensor1);
  float temp2 = getTemperature(sensor2);
  float temp3 = getTemperature(sensor3);
  float temp4 = getTemperature(sensor4);
 
  Serial.print(sensor1Name);
  Serial.print(temp1);
  Serial.println(" Celsius");
 
  Serial.print(sensor2Name);
  Serial.print(temp2);
  Serial.println(" Celsius");
 
  Serial.print(sensor3Name);
  Serial.print(temp3);
  Serial.println(" Celsius");
 
  Serial.print(sensor4Name);
  Serial.print(temp4);
  Serial.println(" Celsius");
 
  Serial.println();
  delay(1000);
}

bye juergen

juergen01:
Habe den sketch von Fluuux habe nur die Sensoradressen eingegeben

Das ist irgendwie ein ganz merkwürdiger Sketch:
Einerseits bindet der Sketch die anerkanntermaßen gut arbeitende Komfort-Library “DallasTemperature” mit in den Sketch ein, andererseits verwendet der Sketch zur Temperaturermittlung gar nicht die gut funktionierenden Funktionen dieser Library, sondern rechnet auf irgendeine Art selbst mit den ausgelesenen Daten herum.

Ich kann Dir als Alternative den beiliegenden Sketch anbieten, der komplett ohne die Dallastemperature Library auskommt.

Da meine Auslesefunktion die Temperatur in Zehntelgrad als Integer zurückliefert, müßte der Wert (wie ich es in der loop zeige) erst noch durch 10.0 geteilt werden, wenn Du am liebsten mit “float” Variablen arbeitest.

#include <OneWire.h>

OneWire  ds(A5);  // am Pin ist ein 4.7K PullUp-Widerstand notwendig

byte sensors[4][8]={
   { 0x28, 0x7C, 0x97, 0xC7, 0x4, 0x0, 0x0, 0x3C },
   { 0x28, 0x5, 0xC5, 0xAC, 0x4, 0x0, 0x0, 0x20  },
   { 0x28, 0xD6, 0xBA, 0xC8, 0x4, 0x0, 0x0, 0x21 },
   { 0x28, 0x55, 0x14, 0xA8, 0x4, 0x0, 0x0, 0x93 }
};

char sensor1Name[] = "Garten: ";
char sensor2Name[] = "Wohnzimmer: ";
char sensor3Name[] = "Heizkeller: ";
char sensor4Name[] = "Aquarium: ";


int readDS18B20(byte* addr)
{
  byte i;
  byte type_s;
  byte data[12];
  byte present = 0;
  
  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();
//  Serial.print("Present: ");Serial.println(present);
  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
  }
  return (raw * 10 / 16.0); // Celsius in Zehntelgrad
}


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

void loop(void) {
  float f;
  f=readDS18B20(&sensors[0][0])/10.0;
  Serial.print(sensor1Name);Serial.println(f,1);
  f=readDS18B20(&sensors[1][0])/10.0;
  Serial.print(sensor2Name);Serial.println(f,1);
  f=readDS18B20(&sensors[2][0])/10.0;
  Serial.print(sensor3Name);Serial.println(f,1);
  f=readDS18B20(&sensors[3][0])/10.0;
  Serial.print(sensor4Name);Serial.println(f,1);
  Serial.println("--- loop end ---");
}

Hallo zusammen
Hallo jurs der sketch ist klasse

die Werte stimmen alle

Nun habe Ich ein anderes Problem Ich möchte die 4 Werte in einen
String umwandeln mit SPRINTF bekomme aber nur ein Fragezeichen

Floating Ausgabe mit SPRINTF
Hast Du dafür eine Loesung

Wie lang koenen die Kabel zu den Fuehlern sein brauche so 40m

bye juergen

juergen01:
Hallo jurs der sketch ist klasse

Na ja.
Basiert auf dem Beispiel “DS18x20_Temperature” zur OneWire-Library.
Und enthält “delay(1000)” während der Messung. Ich finde das Mist.

juergen01:
die Werte stimmen alle

Vorsicht: Bei nicht vorhandenem Sensor kommt bei dem oben geposteten Sketch “0.0” als Messwert heraus. Das liegt allerdings mitten im Messbereich des Sensors. Ich habe wenigstens das mal verbessert und eine CRC-Prüfung der Messdaten mit eingebaut: Falls die CRC-Summe nicht stimmt (z.B. weil es den Sensor gar nicht gibt), wird 127.0 als Messwert zurückgeliefert. Ich glaube, die DallasTemperature Library macht das auch so. Und daran, dass dieser Wert oberhalb der maximal messbaren Temperatur liegt, kannst Du dann nach der Temperaturmessung erkennen, dass es sich um einen ungültigen Wert handelt.

Da Du wohl bevorzugt mit float Werten arbeitest, habe ich auch den Rückgabewert der Messfunktion auf float zurückgeschrieben.

juergen01:
Nun habe Ich ein anderes Problem Ich möchte die 4 Werte in einen
String umwandeln mit SPRINTF bekomme aber nur ein Fragezeichen

Floating Ausgabe mit SPRINTF
Hast Du dafür eine Loesung

Die sprintf-Funktion der AVR libc kann keine Gleitkommazahlen formatieren. Das wurde weggelassen, damit der Code nicht zu sehr aufgebläht wird. Gleitkommazahlen müssen mit der Funktion dtostrf formatiert werden.

Siehe geändertes Programmbeispiel.

juergen01:
Wie lang koenen die Kabel zu den Fuehlern sein brauche so 40m

Wie lang die Kabel maximal sein können, hängt von der Topologie des OneWire-Bus ab, die Du Dir zusammenstrippelst, und von der Qualität des verwendeten Kabels. Mit hochwertigem Cat.5 Netzwerkkabel lassen sich bei einer optimalen, reinen Bus-Topologie wohl bis zu 100 m Länge verwenden. Aber wenn Du keine reine Bus-Topologie hast und an Deinem OneWire Stummel-Abzweige oder sogar Stern-Topologien zu finden sind, wird die maximale Kabellänge vermutlich nur einen ganz kleinen Bruchteil davon betragen.

#include <OneWire.h>

OneWire  ds(2);  // am Pin ist ein 4.7K PullUp-Widerstand notwendig

byte sensors[4][8]={
   { 0x28, 0x7C, 0x97, 0xC7, 0x4, 0x0, 0x0, 0x3C },
   { 0x28, 0x5, 0xC5, 0xAC, 0x4, 0x0, 0x0, 0x20  },
   { 0x28, 0xD6, 0xBA, 0xC8, 0x4, 0x0, 0x0, 0x21 },
   { 0x28, 0x55, 0x14, 0xA8, 0x4, 0x0, 0x0, 0x93 }
};

char sensor1Name[] = "Garten: ";
char sensor2Name[] = "Wohnzimmer: ";
char sensor3Name[] = "Heizkeller: ";
char sensor4Name[] = "Aquarium: ";


float readDS18B20(byte* addr)
{
  byte i;
  byte type_s;
  byte data[12];
  byte present = 0;
  
  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();
//  Serial.print("Present: ");Serial.println(present);
  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(" ");
  }
  if (OneWire::crc8(data, 8) != data[8]) return 127.0;
  /*
  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
  }
  return (raw / 16.0); // Celsius in Zehntelgrad
}


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

void loop(void) {
  float f;
  char buffer[10];

  f=readDS18B20(&sensors[0][0]);
  Serial.print(sensor1Name);
  if (f>125) Serial.println("Error");
  else
  {
    dtostrf(f,4,1,buffer);
    Serial.println(buffer);
  }  

  f=readDS18B20(&sensors[1][0]);
  Serial.print(sensor2Name);
  if (f>125) Serial.println("Error");
  else
  {
    dtostrf(f,4,1,buffer);
    Serial.println(buffer);
  }  

  f=readDS18B20(&sensors[2][0]);
  Serial.print(sensor3Name);
  if (f>125) Serial.println("Error");
  else
  {
    dtostrf(f,4,1,buffer);
    Serial.println(buffer);
  }  

  f=readDS18B20(&sensors[3][0]);
  Serial.print(sensor4Name);
  if (f>125) Serial.println("Error");
  else
  {
    dtostrf(f,4,1,buffer);
    Serial.println(buffer);
  }  
  
  Serial.println("--- loop end ---");
}

Hallo zusammen

Hallo jurs

Mt dem Delay das stimmt das das nicht sehr gut Ist kann man in der sekunde
kein unterprogamm ablaufen lassen

Ich habe CAT7 Kabel verlegt habe heute die Sensoren instaliert ist OK
Ich bekomme die richtigen Werte

bye juergen