DS18B20 Fehler

Moin Leute. Ich hab versucht ein DS18B20 anzuschließen und die Werte auslesen, bekomme es aber nicht hin. Jemand ne Idee was ich falsch mache oder was ich nicht ganz richtig gemacht habe?
Gemacht nach diesem TUT: http://bildr.org/2011/07/ds18b20-arduino/ und http://www.kriwanek.de/arduino/sensoren/165-temperatursensoren-dallas-ds18b20.html

Dass sagt Serial Monitor:

-1000.00
-1000.00
-1000.00
-1000.00
-1000.00
-1000.00

DallasTemperature und OneWire ist auch in libraries

Also ich mache es so und das funktioniert wunderbar.

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

const int numSensors=6;           // Anzahl der angeschlossenen Sensoren
OneWire  ds(2);                   // Digitaler Pin an denen die Temperatursensoren angeschlosen sind

float temp = 0.0;                 // Speichert die Temperatur eines Sensors
DallasTemperature sensors(&ds);   // Dallas Temperatursensoren 

DeviceAddress sensorAdress[] = {
  0x10,0x16,0x2E,0x57,0x02,0x08,0x00,0x2F,
  0x10,0x11,0x40,0xC0,0x01,0x08,0x00,0x9A,
  0x28,0xE3,0xAE,0xBE,0x03,0x00,0x00,0x9F,
  0x28,0x92,0xB3,0xBE,0x03,0x00,0x00,0xA0,
  0x10,0x2D,0x2E,0x57,0x02,0x08,0x00,0x3A,
  0x28,0xC9,0xC6,0xBE,0x03,0x00,0x00,0xC9
};


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

  sensors.begin();
  sensors.requestTemperatures();
}




/*
  Temperaturen aller Sensoren im Terminal ausgeben
*/
void showTemperatures()
{
  sensors.requestTemperatures();   
  
  Serial.println();    
  for(byte i=0; i<numSensors; i++) {
    temp = sensors.getTempC(sensorAdress[i]);
    Serial.print("Sensor"+String(i+1)+": "); 
    Serial.print(temp,1);
    Serial.println();
  }
  Serial.println(); 
}




/******************************************************
  Hilfsfunktionen zum ermitteln der Temperatur
******************************************************/
void writeTimeToScratchpad(byte* address)
{
  ds.reset();
  ds.select(address);
  ds.write(0x44,1);
  delay(1000);
} 
 
void readTimeFromScratchpad(byte* address, byte* data)
{
  ds.reset();
  ds.select(address);
  ds.write(0xBE);
  for (byte i=0;i<9;i++) {
    data[i] = ds.read();
  }
}

Ich musste jetzt einige Dinge auf de Schnelle ändern da ich z.B. meine ds18b20 oder ds18s20 Adressen aus dem EEPROM in ein array lade aber es sollte so funktionieren.
Auf http://fluuux.de habe ich aber auch noch ein paar Beispiele.

Hast Du den Sensor richtig angeschlossen und richtig mit Versorgungsspannung versorgt?
Grüße Uwe

VCC und GND verbunden. Den mittleren (oder gelben, habe auch eins mit 1m Kabel) an PIN 2. Widerstand 4,7 verbunden VCC mit DATA.

Dieser Sketch: fluuux.de
Ausgabe:

Garten: -1.25 Celsius
Wohnzimmer: -1.25 Celsius
Heizkeller: -1.25 Celsius
Aquarium: -1.25 Celsius

OK, hoffe Problem gelöst. Habe nun ein 47k angehängt und nicht 4,7.

Ich schliesse den Sensor immer so an ...

... funktioniert ausgezeichnet !

Funktioniert auch wenn man GND und Data verbindet, ohne VCC/VDD

Dieser Sketch: fluuux.de is available for purchase - Sedo.com

Hast Du die Adressen im Sketch angepasst? Die sind jeweils spezifisch für den einzelnen Sensor und keine zwei sind gleich.

Ich hab doch keine Ahnung von Sensoren und der gleichen! Aber der Sketch den ich jetzt benutze,von OneWire, macht es automatisch, wie ichs verstanden hab.

Nein, der von fluuux.de nicht. Derjenige von bildr.org zeigt einfach den Wert des ersten gefundenen Sensors an, oder -1000, wenn kein Sensor gefunden wurde, er beinhaltet allerdings auch einen Fehler, ist also nicht zu empfehlen.

Hast Du die Beispiele der DallasTemperature-Bibliothek (MilesBurton.com) schon ausprobiert? Der Simple-Sketch sollte die Temperaturen aller angeschlossenen Sensoren ausgeben.

Kannst Du ein Foto von Deiner Verdrahtung machen?

Es lag nicht an dem Sketch sondern an dem Widerstand. Ich hatte ein 4,7 ohm, dann hab ich ein 47 ohm genommen und damit ging das dann.

Ich hoffe, Du hast kOhm gemeint...

Ich habe alle meine OneWire-Sensoren mit 4.7k? angeschlossen und die funktionieren super. Hast Du den Pull-Up auf der Arduino-Seite oder auf der Sensor-Seite eingebaut? Wie lang ist das Kabel zwischen dem Sensor und dem Arduino?

Da hier gerade DS18b20 Fehler diskutiert werden, habe ich dazu auch eine Frage.

Hier hatte ich schon mal gezeigt wie ein erster Sketch funktioniert hat.

Adressen Teil:

//DeviceAdressen der einzelnen ds1820 Temperatursensoren. (loop anpassen)
  DeviceAddress sensor1 = { 0x28, 0x5E, 0x91, 0xAA, 0x3, 0x0, 0x0, 0xF  }; 
                 // ROM =     28    5E    91    AA    3    0    0    F        C3
  DeviceAddress sensor2 = { 0x28, 0xF5, 0x73, 0xAA, 0x3, 0x0, 0x0, 0xF2 }; 
                 // ROM =     28    F5    73    AA    3    0    0    F2       C2
  DeviceAddress sensor3 = { 0x28, 0xCF, 0x1E, 0xCA, 0x3, 0x0, 0x0, 0xBD }; 
                 // ROM =     28    CF    1E    CA    3    0    0    BD       IC
  char data[12];  
  char sensor1Name[] = "C3 : ";
  char sensor2Name[] = "C2 : ";
  char sensor3Name[] = "IC : ";
 //..................................................................................

Inzwischen nutze ich den Match-Rom Befehl damit ich nur einmal die 750ms Delay habe.

  }
 // ...Match-Rom Befehl...............................................
 void OW_Match_ROM(byte* address, byte ow_befehl) {  // Match-ROM Befehl
   ds.reset();  //reset the bus
   ds.select(address);   //select sensor
   ds.write(ow_befehl);  // Befehl senden
   
 }
 // ...Skip-Rom Befehl...............................................
 void OW_Skip_ROM(byte ow_befehl) {  // Skip-ROM Befehl
   ds.reset();  //reset the bus
   ds.write(0xCC);  // Skip-ROM Befehl senden
   ds.write(ow_befehl);  // Befehl senden
 }
 // ...Read Scratchpad...............................................
 void OW_Read_Scratchpad(byte* address, byte data_zahl) {  // Read Scratchpad
   OW_Match_ROM(address, 0xBE);                            // Match-ROM Befehl 0xBE
   for (byte i=0;i<data_zahl;i++) {                        // Data-Zahl Bytes einlesen
      data[i] = ds.read();                                 // Bytes lesen
   }
 }
 // ...Temperatur_berechnen...............................................
 float Temperatur_berechnen(byte* address) {               // Temperatur berechnen
   float TEM; //** zusätzliche Variable 
   OW_Read_Scratchpad(address, 9);                         // 9 Byte vom Scratchpad einlesen  
   TEM = ((data[1] << 8) + data[0] )*0.0625;               //** 12Bit = 0,0625 C per Bit andere Berechnung
   return TEM;                                             //** NEUE Variable der einfacheren Berechnung
 } 
 // ...Temperaturen_einlesen...............................................
 void Temperaturen_einlesen(void) {                        // Temperaturen einlesen
   temp1 = Temperatur_berechnen(sensor1);                  // Temperatur Nr.1 einlesen
   temp2 = Temperatur_berechnen(sensor2);                  // Temperatur Nr.2 einlesen
   temp3 = Temperatur_berechnen(sensor3);                  // Temperatur Nr.3 einlesen
   OW_Skip_ROM(0x44);                                      // Temperaturmessung starten
   delay (750);
 }

Mit einem "Timer" statt "delay" habe ich es noch nicht hinbekommen.

Nur jetzt suche ich nach einem Weg den mit "CRC" korrekt übertragene Werte zu erkennen.
Da die Temperaturwerte, zwar dauernd ausgelesen werden, ich sie aber nur sporadisch im Moment der Gewichtsänderungen mit anzeige,
werden manchmal unplausible falsche Werte angezeigt.

Mit CRC würde ich jetzt gerne immer nur die "gültigen Temperaturwerte" in Variablen vorher übernehmen und sie erst dann übernehmen,
wenn die Gewichtsänderung eingetreten ist.
Denn auf "richtige Werte" will ich nicht warten, deenn dann könnte sich inzwischen das Gewicht ändern, ohne dass es registriert wird.
Ein korrekt ausgelesener Wert der schon 5 Minuten früher eingelesen wurde ist mir auch recht.

Diesen Sketch habe ich eben noch mal getestet. Mit dem Arduino UNO und dem LCD Keypad Shield ROBOT Type läuft der Test.

// DALLAS_TEST_OK                     getestet 16-04-2013
#include <OneWire.h>
#include <LiquidCrystal.h>
                                      // Apus² Test modifiziert und angepasst.
OneWire  ds(2);                       // 1Wire Instance on Arduino digital pin 2
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);  // LCD instance for LCD Keypad Shield ROBOT Type
                                      // Define some values used by the panel and buttons:
byte i;
byte present = 0;
byte data[12];
byte addr[8];
float Temp;

void setup(void) {
  Serial.begin(9600);            // Start serial interface with 9600 Baud
  lcd.begin(16,2);              // Start the LCD library for 16 x 2 display 
  lcd.setCursor(0,0);
  lcd.print(" TESTPROGRAMM ");
  lcd.setCursor(0,1);
  lcd.print(" Dallas DS18B20 ");
  delay(3000);
  lcd.clear();
}

void loop(void) {
  if ( !ds.search(addr)) {
    // No more Dallas chips present:
    Serial.print("No more addresses.\n");
    ds.reset_search();
    delay(250);
    return;
  }

  // Output 64 Bit hardware id of Dallas Chip:
  Serial.print("R=");
  for( i = 0; i < 8; i++) {
    Serial.print(addr[i], HEX);
    Serial.print(" ");
  }

  // Check for invalid CRC in address:
  if ( OneWire::crc8( addr, 7) != addr[7]) {
    Serial.print("CRC is not valid!\n");
    return;
  }

  // Check for family code which is not DS18B20:
  if ( addr[0] != 0x28) {
    Serial.print("Device is not a DS18B20 family device.\n");
    return;
  }

  // The DallasTemperature library can do all this work for you!
  ds.reset();
  ds.select(addr);
  ds.write(0x44,0);          // start conversion, with parasite power off

  delay(1000);               // maybe 750ms is enough, maybe not

  // Check whether chip is present:
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);             // Read Scratchpad

  Serial.print("P=");         // Present = 1
  Serial.print(present,HEX);
  Serial.print(" ");
  for ( i = 0; i < 9; i++) {   // we need 9 bytes of data
    data[i] = ds.read();
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" CRC=");
  Serial.print( OneWire::crc8( data, 8), HEX);
  // Calculate temperature. data[1] High Byte, data[0] Low Byte.
  Temp =  ((data[1] << 8) + data[0] ) * 0.0625;  // 12Bit = 0,0625 C per Bit
  Serial.print( " T=");
  Serial.print( Temp, 2);
  Serial.print( " C");
  Serial.println();
  display_1WSensor();
}

void display_1WSensor(){
  // display Sensor data on LCD:
  char line[17];
  // Hardware ID:
  sprintf(line, "%02X%02X%02X%02X%02X%02X%02X%02X", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7]);
  lcd.setCursor(0,0);         // move to the begining of the second line
  lcd.print(line);
  // Temperature in Hex:
  lcd.setCursor(0,1);
  sprintf(line, "D=%02X%02X", data[1], data[0]);
  lcd.print(line);
  // Temperature as Degree Celsius:
  lcd.setCursor(7,1); 
  //sprintf(line, "T=%f C", Temp); funktioniert nicht, Fehler in Compiler?
  dtostrf(Temp, 5, 2, line);  // funktionierende Alterntative: http://dereenigne.org/electronics/arduino/arduino-float-to-string
  lcd.print("T=");
  lcd.print(line);
  lcd.print(" C");
}

Hier die Monitorausgabe

R=28 E2 6A AA 3 0 0 A3 P=1 83 1 4B 46 7F FF D 10 66  CRC=66 T=24.19 C
R=28 75 DD 1B 3 0 0 97 P=1 86 1 4B 46 7F FF A 10 5E  CRC=5E T=24.37 C
R=28 8B 6F AA 3 0 0 24 P=1 7E 1 4B 46 7F FF 2 10 25  CRC=25 T=23.87 C
R=28 47 62 AA 3 0 0 2A P=1 83 1 4B 46 7F FF D 10 66  CRC=66 T=24.19 C
No more addresses.
R=28 E2 6A AA 3 0 0 A3 P=1 82 1 4B 46 7F FF E 10 70  CRC=70 T=24.12 C
R=28 75 DD 1B 3 0 0 97 P=1 86 1 4B 46 7F FF A 10 5E  CRC=5E T=24.37 C
R=28 8B 6F AA 3 0 0 24 P=1 7E 1 4B 46 7F FF 2 10 25  CRC=25 T=23.87 C
R=28 47 62 AA 3 0 0 2A P=1 83 1 4B 46 7F FF D 10 66  CRC=66 T=24.19 C
No more addresses.
R=28 E2 6A AA 3 0 0 A3 P=1 83 1 4B 46 7F FF D 10 66  CRC=66 T=24.19 C
R=28 75 DD 1B 3 0 0 97 P=1 85 1 4B 46 7F FF B 10 5F  CRC=5F T=24.31 C
R=28 8B 6F AA 3 0 0 24 P=1 7E 1 4B 46 7F FF 2 10 25  CRC=25 T=23.87 C
R=28 47 62 AA 3 0 0 2A P=1 83 1 4B 46 7F FF D 10 66  CRC=66 T=24.19 C
No more addresses.
R=28 E2 6A AA 3 0 0 A3 P=1 82 1 4B 46 7F FF E 10 70  CRC=70 T=24.12 C
R=28 75 DD 1B 3 0 0 97 P=1 85 1 4B 46 7F FF B 10 5F  CRC=5F T=24.31 C
R=28 8B 6F AA 3 0 0 24 P=1 7D 1 4B 46 7F FF 3 10 24  CRC=24 T=23.81 C
R=28 47 62 AA 3 0 0 2A P=1 83 1 4B 46 7F FF D 10 66  CRC=66 T=24.19 C
No more addresses.

Im Sketch steht schon die CRC Abfrage mit drin.
Warum er sich dauernd ändert und wie ich das in dem anderen Code einfügen kann, versuche ich nun herauszubekommen,
oder es kann mir jemand erklären. :slight_smile:

Gruss Apus² [ vom Thema Auf SD-Karte registrierende Waage ]

Warum er sich dauernd ändert und wie ich das in dem anderen Code einfügen kann, versuche ich nun herauszubekommen, oder es kann mir jemand erklären.

Der CRC ist so etwas wie eine Prüfsumme über die übertragenen Daten. Wenn sich darin etwas ändert, muss sich auch der CRC ändern.

Der CRC wird in der folgenden Zeile geprüft:

  if ( OneWire::crc8( addr, 7) != addr[7]) {

Du kannst diese also einfach in Deinen Sketch übernehmen.

pylon:
Ich hoffe, Du hast kOhm gemeint...

Ich habe alle meine OneWire-Sensoren mit 4.7k? angeschlossen und die funktionieren super. Hast Du den Pull-Up auf der Arduino-Seite oder auf der Sensor-Seite eingebaut? Wie lang ist das Kabel zwischen dem Sensor und dem Arduino?

Nun habe ich ein 4k7 angezapft und es funktioniert auch super. Das Kabel ist nur paar cm, vom Breadboard die kleinen Kabel halt. Das ganze ist auch auf dem Breadboard aufgebaut.