[gelöst] Zwei DS18s20 auslesen

Hallo,

um zwei DS18s20 auszulesen benutze ich folgenden Sketch von FLUXX:

#include <OneWire.h>
#include <DallasTemperature.h>
 
OneWire  ds(2); //pin für ds1820
 
//DeviceAdressen der einzelnen ds1820 Temperatursensoren angeben. (loop anpassen)
DeviceAddress sensor1 = { 0x10, 0xDE, 0x29, 0x95, 0x2, 0x8, 0x0, 0x7E };
DeviceAddress sensor2 = { 0x10, 0x3, 0xCF, 0x95, 0x2, 0x8, 0x0, 0xB6 };
//DeviceAddress sensor3 = { 0x10, 0x11, 0x40, 0xC0, 0x1, 0x8, 0x0, 0x9A };
//DeviceAddress sensor4 = { 0x10, 0x77, 0x38, 0x57, 0x2, 0x8, 0x0, 0x3B };
 
char sensor1Name[] = "Aussen        : ";
char sensor2Name[] = "Waermetauscher: ";
//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);
}

Dies funktioniert auch.

Nur gibt es in der Funktion " writeTimeToScratchpad" ein delay von 1000 !!!
Dieser bremst mir doch meinn gesamten Sketch aus … oder etwa nicht.

Wenn ich dies delay rausnehme habe ich bei einem von beiden DS eine Temperatur von konstant 85 Grad (Fehler vom DS…wie auch bei anderen Sketches welche ich getestet habe).

Hat jemand eine Lösung parat ???

Danke erstmal

Hallo,
schau Dir in der Arduino-Software das Beispiel 'Blink without delay' an.

Dann die Sensorabfrage in eine Funktion programmieren und diese Zeitgesteuert aufrufen.

Gruss
Kurti

Ich weiß nicht wofür du das alles brauchst was du da machst, ich lese meine Sensoren so ein:

void SensorLesen(){ //alle angeschlossenen Sensoren werden eingelesen
 jetzt = millis();
 if(jetzt - vorher > 5000){ //Sensoren werden nur alle 5 sec gelesen, das reicht
  sensors.requestTemperatures(); 
  Temperatur[0] = sensors.getTempC(Sensor0); 
  Temperatur[1] = sensors.getTempC(Sensor1); 
  Temperatur[2] = sensors.getTempC(Sensor2); 
  Temperatur[3] = sensors.getTempC(Sensor3); 
  Temperatur[4] = sensors.getTempC(Sensor4); 
  Temperatur[5] = sensors.getTempC(Sensor5); 
 }
 vorher = millis();
  }

Super XD

Ich danke euch beiden für die schnelle und kompetente Hilfe !!!

So sieht es jetzt aus:

#include <OneWire.h>
#include <DallasTemperature.h>
 
OneWire  ds(2); //pin für ds1820
 
//DeviceAdressen der einzelnen ds1820 Temperatursensoren angeben. (loop anpassen)
DeviceAddress sensor1 = { 0x10, 0xDE, 0x29, 0x95, 0x2, 0x8, 0x0, 0x7E };
DeviceAddress sensor2 = { 0x10, 0x3, 0xCF, 0x95, 0x2, 0x8, 0x0, 0xB6 };
//DeviceAddress sensor3 = { 0x10, 0x11, 0x40, 0xC0, 0x1, 0x8, 0x0, 0x9A };
//DeviceAddress sensor4 = { 0x10, 0x77, 0x38, 0x57, 0x2, 0x8, 0x0, 0x3B };
 
char sensor1Name[] = "Aussen        : ";
char sensor2Name[] = "Waermetauscher: ";
//char sensor3Name[] = "Heizkeller: ";
//char sensor4Name[] = "Aquarium: ";
long millisvorher = 0;
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);
  Serial.println("jetzt");
}
 
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)
{
  if(millis() - millisvorher > 1000)
 {
    millisvorher = millis();
    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);
}

gern geschehen :slight_smile:
trotzdem weiß ich nicht was du da alles einliest.
mit sensors.getTempC bekommt man den Wert als float in Celsius,
was braucht man da noch mehr?????
gruß

kanst du mir ein Beispiel verlinken ?

@maverick1509:

Ich habe einen einfachen code …ich denke mal so meinst du das:

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

float S1;
float S2;
long vorhermillis = millis();

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

DeviceAddress Sensor1 = { 0x10, 0xDE, 0x29, 0x95, 0x2, 0x8, 0x0, 0x7E }; 
DeviceAddress Sensor2 = { 0x10, 0x3, 0xCF, 0x95, 0x2, 0x8, 0x0, 0xB6 }; 


void setup () 
{        
     Serial.begin(9600);
     sensors.begin();
              
     sensors.setResolution(Sensor1, 12); // set the resolution
     sensors.setResolution(Sensor2, 12); // set the resolution
}

void loop () 
{  
  if (millis() - vorhermillis > 1000)
  {  
    vorhermillis = millis();
    sensors.requestTemperatures();
    S1 = sensors.getTempC(Sensor1);
    S2 = sensors.getTempC(Sensor2);
    Serial.println(S1);
    Serial.println(S2);
  }
}

hier bekomme ich bei meinem zweiten DS auch wieder 85 Grad angezeigt :~

Du kannst die so verdrahten. Ich habe vier DS18S20 an einem Bus.

Kannst ja mal diesen Code ausprobieren. Ist allerdings für ein I2C Display.

#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h> // Für I2C LCD Display

// Data wire is plugged into pin 3 on the Arduino

#define ONE_WIRE_BUS 3
//#define LCD2_WIDTH 16                    //Anzahl Spalten des Display (16)
//#define LCD2_HEIGHT 2                    //Anzahl Zeilen des Display (2)
#define LCD3_WIDTH 16                    //Anzahl Spalten des Display (16)
#define LCD3_HEIGHT 2                    //Anzahl Zeilen des Display (2)



LiquidCrystal_I2C lcd2(0x20,16,2); // set the second LCD address to 0x21
LiquidCrystal_I2C lcd3(0x21,16,2);  // I2C LCD Adresse auf 0x20 gesetzt, 16 Zeichen / 2 Zeilen LCD

// OneWire DS18S20, DS18B20, DS1822 Temperature Example

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

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

// Assign the addresses of your 1-Wire temp sensors.
// See the tutorial on how to obtain these addresses:
// http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html

DeviceAddress T1 = { 0x10, 0x20, 0xDE, 0x5F, 0x02, 0x08, 0x00, 0xCA };
DeviceAddress T2 = { 0x10, 0x28, 0xED, 0x5F, 0x02, 0x08, 0x00, 0xA1 };
DeviceAddress T3 = { 0x10, 0x0C, 0xEE, 0x5F, 0x02, 0x08, 0x00, 0x85 };
DeviceAddress T4 = { 0x10, 0x2A, 0xCF, 0x5F, 0x02, 0x08, 0x00, 0xB4 };

void setup(void)
{
  
  // LCD I2C Displays Initilaisieren und Hintergrundbeleuchtung aktivieren
   lcd2.init();
   lcd2.backlight();                   
  
   lcd3.init();
   lcd3.backlight(); 
    
  Wire.begin();                                      // I2C-Bus einrichten
  
  // start serial port
  Serial.begin(9600);
  
  // Start up the library
  sensors.begin();
  
  // set the resolution to 10 bit (good enough?)
  //sensors.setResolution(T1, 10);
  //sensors.setResolution(T2, 10);
  //sensors.setResolution(T3, 10);
  //sensors.setResolution(T4, 10);
}

void printTemperature(DeviceAddress deviceAddress)
{
  float tempC = sensors.getTempC(deviceAddress);
  if (tempC == -127.00) {
    Serial.print("Error getting temperature");
  } else {
    //lcd.print("C");
    //lcd2.print(tempC);
    lcd3.print(tempC);
    //Serial.print(" F: ");
    //Serial.print(DallasTemperature::toFahrenheit(tempC));
  }
}

void loop(void)
{
  delay(4000);
  //Serial.print("Getting temperatures...\n\r");
  sensors.requestTemperatures();
  
  lcd3.begin(LCD3_WIDTH, LCD3_HEIGHT,1);
  lcd3.setCursor(0,0);
  lcd3.print("T1 ");
  printTemperature(T1);
  //Serial.print("\n\r");
  
  lcd3.setCursor(9,0);
  lcd3.print("T2 ");
  printTemperature(T2);
  //Serial.print("\n\r");
  
  //lcd2.begin(LCD2_WIDTH, LCD2_HEIGHT,1);
  lcd3.setCursor(0,1);
  lcd3.print("T3 ");
  printTemperature(T3);
  //Serial.print("\n\r\n\r");
  
  lcd3.setCursor(9,1);
  lcd3.print("T4 ");
  printTemperature(T4);
}

Micky

Ds18S20 One wire bus.jpg

@Micky hast du so verdrahtet? Normal werden die Pins 1 und 3 verbunden.
@ Erl1 versuch mal einen anderen Widerstand, schalt einfach mal zwei 4,7 parallel

maverick1509:
@Micky hast du so verdrahtet? Normal werden die Pins 1 und 3 verbunden.

Wenn Du mehr als einen Sensor zu bedienen und ein paar Meter zu überbrücken hast, funktioniert an einem einfachen Bus-Interface mit PullUp-Widerstand und Mikrocontroller eine parasitäre Stromversorgung gar nicht mehr, sondern es wird eine dreipolige Verkabelung zu den Sensoren benötigt:

  • 5V
  • GND
  • Data

maverick1509:
@Micky hast du so verdrahtet? Normal werden die Pins 1 und 3 verbunden.

Genau so habe ich verdrahtet. Das mit 4 Sensoren und mindestens 22 Meter Kabel.

Micky

Nochmals Danke für eure Hilfe !

@maverick1509: Der zweite Wiederstand parellel hat nichts gebracht.

Anschliessen kann ich parasiträr oder "normal".

Allerdings habe ich mir die Sensoren nochmal unter der Lupe angeschaut...
ES HANDELT SICH NICHT UM DS18s20 (wie von mir bestellt) sondern um DS1820 !

Nochmal kurz zusammengefasst funktionieren beide Sensoren mit dem ersten Sketch.
Mit dem einfacheren Sketch von maverick1509 funktioniert nur einer !?

Es sind welche in Umlauf da steht DS1820 drauf es handelt sich aber um DS18S20. Zum Beispiel die von Reichelt.

Wie hast Du die nun angeschlossen?

Micky

@erl1 wenn du noch ein paar DS18B20 brauchst, ich habe noch einige wasserfeste im Gehäuse mit ca. 50cm
Anschluss da, ich habe mir nämlich welche mit 3m gekauft, da die besser für meine Anwendung passten.
gruß
Bernward

@Micky: Momentan “normal” angeschlossen siehe Anhang.

@maverick1509: wegen der Sensoren … schickst du mir eine PM !!?

ds1820.jpeg

Besser spät als nie 8)

Die Sensoren waren nicht in Ordnung ich habe mir 5 andere besorgt ... mit diesen geht es.
@ maverick1509: Danke für dein Angebot der Sensoren. Ich hatte einfach eine lange "Schaffenspause"