Temperaturen von mehreren Dallas DS18B20 auslesen

Hallo ins Forum,

zunächst Glückwunsch und dank für dieses tolle Forum. Als Neuling im Umgang mit dem Arduino lese ich hier seit einiger Zeit mit großem Interesse.
Nach einigem Experimentieren und ersten Schritten, versuche ich mich nun an einem ersten eigenen Projekt.
Ich möchte zunächst 2 Dallas 18B20 auslesen und bei bestimmten Temperaturen ein Relais ein- bzw. ausschalten.

Das Auslesen eines Sensors funktioniert und das Relais schalten auch ein und aus. Allerdings schaltet es auch wenn es quasi wieder von oben in den Temperaturbereich kommt.

Wie kann ich dem Arduino beibringen, dass er erst wieder einschaltet wenn die untere Temperatur erreicht?

Sobald ich die Adressen zweier Sensoren definiere bekomme ich folgende Fhelermeldung:

"Temperatur_mit_DS18B20_3:13: error: 'DeviceAdress' does not name a type

DeviceAdress sensor1 = {0x28,0xFF,0xA4,0xF0,0x81,0x16,00x3,0x78};

Temperatur_mit_DS18B20_3:14: error: 'DeviceAdress' does not name a type

DeviceAdress sensor2 = {0x28,0xFF,0XCB,0x24,0x80,0x16,00x4,0x21};

exit status 1
'DeviceAdress' does not name a type"

Ich habe meinen Sketch mal angefügt:

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

#define ONE_WIRE_BUS A0
OneWire wire(ONE_WIRE_BUS);
DallasTemperature sensor(&wire);
LiquidCrystal lcd(12,11,5,4,3,2);
int relais_1=8;
int relais_2=9;


DeviceAdress sensor1 = {0x28,0xFF,0xA4,0xF0,0x81,0x16,00x3,0x78};
DeviceAdress sensor2 = {0x28,0xFF,0XCB,0x24,0x80,0x16,00x4,0x21};

char sensor1Name[] = "Hütte";
char sensor2Name[] = "Zapfanlage";

void setup() {

pinMode(relais_1,OUTPUT);
pinMode(relais_2,OUTPUT);
                                           //delay(1000);
lcd.begin(16,2);
delay(1000);
sensor.begin();

lcd.println("Temperaturen:");
}

void loop() {

sensor.requestTemperatures();

lcd.setCursor(0,1);
lcd.print(sensor.getTempCByIndex(0));
lcd.println("C°");

if(sensor.getTempCByIndex(0)>=24 && sensor.getTempCByIndex(0)<=26)
{
  digitalWrite(relais_1,LOW);
  digitalWrite(relais_2,LOW);
}
else
{
  digitalWrite(relais_1,HIGH);
  digitalWrite(relais_2,HIGH);
}
}

Ich hoffe, Ihr könnt mir helfen !?

Gruß - kardors

Hallo,

lege bitte den Code in Code Tags, Button </>.

Du vermischt die manuelle ID Festlegung mit der Erkennungsautomatik der Lib. Deshalb klappt das nicht mehr. Schau dir nochmal die Bsp. der Lib genauer an. Vielleicht hilft das schon.

DeviceAddress schreibt sich mit zwei 'd'

Außerdem willst du requestTemperaturesByAddress() verwenden. Wenn du byIndex() machst braucht du die Adressen nicht.

Vielen Dank für die schnellen Antworten !!!

@Serenifly

Vielleicht sollte ich erst mal was gegen meine ausgeprägte Legasthenie tun :o
Ohne Addressen aber mit"..byIndex" klappt es :slight_smile:

@Doc_Arduino
Kannst Du mir Deinen Hinweis näher erläutern und vielleict ein Beispiel geben. Wie gesagt, ich bin Arduino-Neuling und mir sagt Dein Tipp nichts. Habe zwar vor vielen Jahren mal in C und Basic programmiert. Aber die Kenntnisse sind tief verschüttet :wink:

Vielleicht könnt Ihr mir auch bei dem anderen Probelm helfen?

Dank und Gruß

kardors

Vielleicht sollte ich erst mal was gegen meine ausgeprägte Legasthenie tun

Den Fehler mache ich auch oft. Kommt einfach daher, dass es im Deutschen mit einem 'd' geschrieben wird

Generell ist es aber eine gute Idee erst mal schnell nach Schreibfehlern zu suchen wenn man "does not name a type" als Fehler hat.

Kannst Du mir Deinen Hinweis näher erläutern und vielleict ein Beispiel geben.

Er meint wahrscheinlich das gleiche wie ich, auch wenn es nicht der eigentliche Fehler war. Entweder man nimmt Adressen oder Index. Aber beides zusammen ist überflüssig. Index kann auch ok sein. Kommt auf die Anwendung an. Aber die Zuordnung der Sensoren ändert sich dabei mit dem Aufbau des Busses.

Hallo,

ja ich meine das gleiche. :slight_smile:

Okay, in den Bsp. gibts das was du suchst nicht direkt. Sorry. Dachte das wäre so. Das WaitforConversation2 ist jedoch die Grundlage für das was du brauchst mit festen Adressen. Habe mal einen alten Sketch rausgekramt und nochmal getestet. Hab mir nochmal die aktuelle Lib Version gezogen. Die eine Warnung beim kompilieren liegt an der Lib. Da wird eine leere Default-Funktion angemeckert. Weiß auch nicht recht was die machen soll. Stört aber erstmal nicht.

OneWire Pin und Adressen anpassen und es sollte funktionieren. Die LED Flash Funktion soll nur zeigen das der Code nicht blockierend läuft.

/* Doc_Arduino from german Arduino Forum
   This is a modified "DallasTemperature" Library examples "WaitforConversion2" without hard delay
   Test of Arduino Mega 2560
   Arduino IDE v1.6.12
*/

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

#define ONE_WIRE_BUS 12     // Data wire is plugged into port 12 on the Arduino

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

// change of your sensors adress
DeviceAddress sensor1 = { 0x10, 0x40, 0xDD, 0xC3, 0x02, 0x08, 0x0, 0xB4 };
DeviceAddress sensor2 = { 0x10, 0x8A, 0x0B, 0xAC, 0x02, 0x08, 0x0, 0x2C };

byte resolution = 9;                      // DS18S20 only 9bit, other 9...12
unsigned long lastTempRequest = 750;      // start delay for first measurement
unsigned long ConversionDelay = 750;      // default 750ms, okay for all DS1820 types
boolean AllowDallasTempRequest = true;
float TempSensor1;                  // Zwischenspeicher zum auslesen
float TempSensor2;                  // Zwischenspeicher zum auslesen

byte _Flash_LED = 13;               // LED 13 auf Arduino Board

void setup(void)
{
  Serial.begin(9600);
  
  digitalWrite(_Flash_LED, LOW); 
  pinMode(_Flash_LED, OUTPUT);
  
  sensors.begin();
  // set the resolution (Each Dallas/Maxim device is capable of several different resolutions)
  sensors.setResolution(sensor1, resolution);
  sensors.setResolution(sensor2, resolution);
  sensors.setWaitForConversion(false);        // makes it async
}

void loop(void)
{ 
   
  // Request a temperature conversion 
  if ( AllowDallasTempRequest == true )
    {           
     sensors.requestTemperatures();
     lastTempRequest = millis(); 
     AllowDallasTempRequest = false;
    }
  
  // readout the Dallas sensors  
  if ( millis() - lastTempRequest >= ConversionDelay )  // waited long enough?
    {
     TempSensor1 = sensors.getTempC(sensor1);  // 1. Dallas Sensor auslesen (Device Adresse)
     TempSensor2 = sensors.getTempC(sensor2);  // 2. Dallas Sensor auslesen (Device Adresse)  
     AllowDallasTempRequest = true;
     
     Serial.print(F("Sensor 1: ")); Serial.print(TempSensor1); Serial.print('\t');
     Serial.print(F("Sensor 2: ")); Serial.println(TempSensor2);
    }
  
  // *** mach sinnvolle Dinge *** //
  LED_Flash_Down();
  
}   // End of Loop


// ----------------------------------------------------------------------------------- //
void LED_Flash_Down()        // LED Flashing
{
  static boolean state_LED = LOW;
  static unsigned long millis_LED = 0;
                  
     if (state_LED == LOW && millis() > millis_LED )  {
       digitalWrite(_Flash_LED, HIGH);        // LED einschalten für
       millis_LED = millis() + 300;           // 
       state_LED = HIGH;
     }
     if (state_LED == HIGH && millis() > millis_LED )  {
       digitalWrite(_Flash_LED, LOW);        // LED ausschalten für
       millis_LED = millis() + 700;          // 
       state_LED = LOW;
     }   
}

Bei nur 2 Sensoren würde ich auch 2 Pins nehmen und jeweils auf index 0 abfragen. Dann kannst du Sensoren tauschen wie du willst und kommst nie durcheinander.

Danke,

werde es ausprobieren!

Gruß - kardors

Hallo zusammen,

wollte nun Vollzug melden und meinen fertigen Sketch herzeigen :wink:

Ist vielleicht (noch) nicht besonders professionell, aber funktioniert !

Ich steuere damit zwei Steckdosen in meinem Gartenhaus, die einaml die Heizung einschalten, wenn's zu kalt wird und zum anderen meine wassergekühlte uralt Zapfanalge einschalten, wenn's dem Bier zu warm wird :slight_smile:

Hier der Sketch:

#include <LiquidCrystal.h>          // Einbinden des LCD
#include <OneWire.h>                // Einbinden OneWire
#include <DallasTemperature.h>      // Einbinden des Dallas Sensors
#include <avr/wdt.h>

#define ONE_WIRE_BUS A0             // OneWire an Port A0
#define TEMPERATURE_PRECISION 12

OneWire ourWire(ONE_WIRE_BUS);      // Einrichten des OneWire für den Datenabruf der Sensoren
DallasTemperature sensor(&ourWire); // Sensoren an OneWire binden

DeviceAddress tempDeviceAddress;     // Speicherort der Sensoradressen
int numberOfDevices;                 // Anzahl der gefundenen Sensoren

LiquidCrystal lcd(12,11,5,4,3,2);   // Ports für den LCD

int relais_1=8;                     // Ports für die Schaltrelais
int relais_2=9;
int relais_3=6;
int relais_4=7;

int poti = A1;                      // Poti an analog A1
int potitemp;                       // Erstellung einer Variablen "potitemp"

int led_heizung=0;                  //rote led an = Heizung an
int led_zapfanlage=1;               //blaue led an = Zapfanlage kühlt



void setup() {
  
  pinMode(relais_1,OUTPUT);
  pinMode(relais_2,OUTPUT);
  pinMode(relais_3,OUTPUT);
  pinMode(relais_4,OUTPUT);

  digitalWrite(relais_1,HIGH);
  digitalWrite(relais_2,HIGH);
  digitalWrite(relais_3,HIGH);
  digitalWrite(relais_4,HIGH);

  pinMode(0,OUTPUT);
  pinMode(1,OUTPUT);
  
  digitalWrite(0,LOW);
  digitalWrite(1,LOW);

                                     
  lcd.begin(16,2);
  delay(1000);
  
  sensor.begin();
  
  lcd.setCursor(0,0); 
  lcd.print("Raum:");

  lcd.setCursor(11,0);
  lcd.print("P:");
  
  lcd.setCursor(0,1);
  lcd.print("Zapfanlage:");

  wdt_enable(WDTO_8S);
   
}

void loop() 

{
  potitemp = map(analogRead(poti),0,1024,0,18);    //potival = Solltemperatur 0- 18 C
  //delay(1000);
  
  sensor.requestTemperatures();

  lcd.setCursor(5,0);
  lcd.print(sensor.getTempCByIndex(0),1);
  lcd.setCursor(9,0);
  lcd.print("C");

  lcd.setCursor(13,0);
  lcd.print("    ");
  lcd.setCursor(13,0);
  lcd.print(potitemp);
  lcd.setCursor(15,0);
  lcd.println("C");

  lcd.setCursor(11,1);
  lcd.print(sensor.getTempCByIndex(1),1);
  lcd.println("C ");

wdt_reset();

  if(sensor.getTempCByIndex(0) <= potitemp && digitalRead(relais_1) == HIGH && digitalRead(relais_2)== HIGH)
  {
    digitalWrite(relais_1,LOW);
    digitalWrite(relais_2,LOW);
    digitalWrite(1,HIGH);
    
  }
  else if (sensor.getTempCByIndex(0) >= (potitemp + 4) && digitalRead(relais_1) == LOW && digitalRead(relais_2)== LOW)
  {
    digitalWrite(relais_1,HIGH);
    digitalWrite(relais_2,HIGH);
    digitalWrite(1,LOW);

wdt_reset();

  }

  if(sensor.getTempCByIndex(1) >= 5 && digitalRead(relais_3) == HIGH && digitalRead(relais_4)== HIGH)
  {
    digitalWrite(relais_3,LOW);
    digitalWrite(relais_4,LOW);
    digitalWrite(0,HIGH);
  }
  else if (sensor.getTempCByIndex(1) <= 0 && digitalRead(relais_3) == LOW && digitalRead(relais_4)== LOW)
  {
    digitalWrite(relais_3,HIGH);
    digitalWrite(relais_4,HIGH);
    digitalWrite(0,LOW);

wdt_reset();
  }
  
}

Anregungen oder Verbesserungen,auch Kritik, nehme ich gerne entgegen.

Gruß kardors

Hallo,

muss mich nun doch nochmal mit einer Farge zu meinem Projekt an euch wenden.

Wie beschrieben, funktionierte alles eine Weile tadellos. Vor einigen Tage habe ich aber festgestellt, dass der Arduino immer wieder abstürzt und auf dem Display nur wirre Zeichen dargestellt sind.

Die Steckdosen reagieren dann auch nicht mehr.

Erst die Trennung vom Strom und der Neustart nach wieder anschliessen erweckt ihn dann wieder zum Lesen und alles funktioniert, für einige Zeit.

Sollte der "Watchdog" dem nicht vorbeugen ?

An den Minusgraden der letzten Tage sollt es wohl nicht liegen!?

Gruß -kardors

Die Abstürze können mehrere Ursachen haben, siehe hier:
http://forum.arduino.cc/index.php?topic=447962

Watchdog muss aktiviert werden und auch entsprechend programmiert.
Ob der Bootloader den Watchdog unterstützt weiß ich aber nicht. Das wäre zu prüfen!

Ich bin Neuling und möchte an mehreren Aquarien mit den DS18B20 mit je 3m Kabellänge die Temperaturen messen und dann abhängig die jeweiligen Regelheizer über Relays einschalten.
Ich habe ein 4-zeiliges Display das an SCL und SDA angeschlossen ist.
Der Relayblock hat 8 Relays und zum Einstecken der Regelheizer gibt es 8 Euro-Einbaubuchsen.
Mehr als 8 Sensoren kann man scheinbar nicht gleichzeitig anschließen. Dann kommt es zu wirren Zeichen. Liegt das am Datentyp der in der Dallas-Libray definiert ist? Vermutlich Byte.
Solange die Relay nicht angesprochen, bzw. mit den 8 Digitalausgängen verbunden sind, erfolgt die Ausgabe auf dem Display problemlos mit 8 angeschlossenen Sensoren.
Sobald ich jedoch die Relays schalten will, gibt es Probleme. ESP32 überfordert?
Logigleveleshifter die die 3,2V auf 5V für den Relayblock anheben, funktionieren scheinbar auch nicht. Ganz verrückt wird es jedoch, sobald ich Ausgangsseitig an den Relays 230V-Netzspannung schalten möchte. Dann spielt der ESP verrückt und schaltet scheinbar sogar ganz ab.
Leider finde ich so gar keine Ursache. Bringt der Umstieg auf den Mega 2560 mich da weiter, der ja mit 5V arbeitet?

Warum kaperst Du damit einen Uralt-Thread, der mit Deinem Thema nichts zu tun hat? Eröffne lieber einen eigenen Thread.

Ein Schaltplan und Dein Sketch (in Codetags) wären hilfreich.

Gruß Tommy

Ernst-Brill:
......
Leider finde ich so gar keine Ursache. Bringt der Umstieg auf den Mega 2560 mich da weiter, der ja mit 5V arbeitet?

Und wir sollen jetzt mit den wenigen Infos eine Ursache finden ?
Warum sollte da ein Mega besser sein ?

Du beachtest offensichtlich die einfachen Grundlagen nicht, so dass du dein System durch simple Störungen durcheinander bringst.

Also wie Tommy schon schrieb, ohne Schaltbild und Sketch können wir nur raten.

Zwischenzeitlich bin ich etwas weiter.
Die Sensoren spreche ich über deren Adresse an.
Zudem benutze ich nun millis () und warte nach .requestTemperatures () 1 Sekunde bis zum ersten. GetTempC ().
Mein ESP32 war überlastet. Nun setze ich den Mega2560 mit 5V ein.
Die Anzahl der DS18B20 habe ich auf 7 begrenzt und die Relays auf 6.
Das System läuft nun mit 4,96V und 0,42A am USB-Anschluss des PC wenn alle 6 Relays geschaltet sind. Also scheinbar an der obersten Lastgrenze.
Da ich mit den 7 Sensoren und den 6 Relays auskomme überlege ich nun, ob das System eventuell
auch noch 6 Potis zum Einstellen der 6 Solltemperaturen klarkommt, denn bisher gebe ich diese im Programm fest vor.

Ernst-Brill:
Mein ESP32 war überlastet.

Der Esp32 (240 MHz Dual Core CPU) war nur zu schnell für deine Lernkurve!

Solltest unbedingt lernen einen eigenen Thread für deine Probleme zu öffnen.

Wieso war der ESP überlastet ?
Das solltest du mal näher erklären.
Der ESP ist deutlich leistungsfähiger, wenn du alles richtig machst.

Allerdings alles aus dem USB-Port zu betreiben, ist keine optimale Lösung.
Was die Potis betrifft, wird auch hier kein zusätzliches Problem auftreten, wenn du diese richtig anschließt.

Mit den 7 Sensoren, 6 Potis und 6 Relais ist der Mega hoffnungslos unterfordert. Und ein ESP32 fängt deswegen nicht mal an, loszutakten.

Du solltest unbedingt auch dicke Elkos und ein externes Netzteil verwenden. Die Relais haben gerne etwas Reserve, der Anzugstrom ist viel höher als der Haltestrom.

Okay. Ich bin zwischenzeitlich wieder etwas schlauer geworden.
Endlich habe ich verstanden, wie man das 8-fach-Relay mit externer Spannung versorgt, damit der Microcontroler weniger belastet wird. Ich habe dann gehofft, dass das Problem beseitigt ist. War aber leider wieder eine irrige Annahme.
Ich habe mit 8 DS18B20 angefangen. -> Sehr schnell Lesefehler der Sensoren, die dann -195,00°C anzeigen.
Dann habe ich die Anzahl der Sensoren schrittweise reduziert. Mit lediglich 4 Sensoren läuft das Programm nun schon den 2. Tag.
Da der aktuell eingesetzte Mega ja nicht überfordert ist, liegt das Problem folglich wo anders.
Die Daten werden von allen Sensoren ja gleichzeitig mit .requestTemperatures() über oneWire abgerufen. Erst danach ermittelte ich die einzelnen Temperaturen mit.getTempC (sensorAdresse). Mit 1 Sekunde Wartezeit sollte das ja zumindest funktionieren, was aber nicht der Fall ist. Normalerweise sind 750mS notwendig.
Im Moment fallen mir 2 Dinge ein, die ich probieren will:

  1. Den Widerstand zwischen 5V und Datenleitung verkleinern. 8 Sensoren mit je 3m Kabel ist eine Menge.
  2. OneWire ist zu langsam für mehr als 4 Sensoren. Das Busprotokoll kenne ich nicht und kann es auch nicht überprüfen.
    Deshalb werde ich eine 2. OneWire-Verbindung versuchen und jeder der Verbindungen je 4 Temperatursensoren zuordnen.
    Ob das funktioniert, wird sich zeigen.

Aber eventuell habt ihr ja bessere Ideen.

Hi

An einem meiner 'Sensor-Knoten' (Knoten heißen die Teilnehmer im CAN-Bus) hängen 13 DS18B20 (die wasserdichte Version).
-195° hätte ich noch nicht gesehen - von -127° hatte ich schon gehört als 'Sensor nicht gefunden'-Wert.

Wie suchst Du Deine Sensoren?
Selber lasse ich die in der Lib integrierte ROM-Suche durchlaufen, dabei wird 'der Reihe nach' JEDE mögliche Kombination angesprochen - wenn Da 'Wer ist', wird Dessen ID gespeichert - in loop() selber rassel ich die so gefundenen Sensoren durch (also alle 750ms wird der 12Bit-Sensor abgefragt, Die mit weniger Bits auch öfter).
Alle Sekunde wird ein weiterer Sensor-Wert in den Bus geschickt und dort von anderen Knoten empfangen/verarbeitet.

Also: Du machst was falsch.
Was? Keine Ahnung, Dein Sketch ist ja noch geheim und so gut bin ich im Weissagen nun auch nicht - zumindest klappt's beim Lotto bisher nicht so recht.

MfG