Erkennen an welchem Anschluss DS18B20 angeschlossen ist

Hallo,

ich möchte mir etwas bauen, an dem ich mehrere DS18B20 Temperatursensoren anschließen kann. Dies soll so realisiert sein, dass auf der Platine 4 Buchsen sind und ich an jeder einen Temperatursensor anschließen kann.
Der Arduino soll dann die Werte auslesen und an mehreren 7-Segmentanzeigen anzeigen.

Jetzt ist mein Problem, dass der Sensor an Buchse 1 immer an der Anzeige 1 (Buchse2->Anzeige2...) dargestellt werden soll. Ich weiß jedoch im Vorhinein nicht, welcher Sensor wo angeschlossen wird.

Wie ist sowas am besten realisierbar?

Meine Ideen bis jetzt:

  1. Vor jeder Buchse einen Transistor, damit ich die einzelnen Sensoren abschalten kann und dann im setup einen nach dem anderen zuschalte und mir dann merke wo der neue angeschlossen ist.

  2. Man darf immer nur einen Sensor nach dem anderen anschließen und der bekommt dann einfach die nächste freie Anzeige (nicht wirklich eine Lösung und außerdem müsste man bei jeder Stromunterbrechung alle Sensoren neu einstecken)

Wieso machst Du es derart kompliziert? Der DS18B20 hat den Vorteil, über einen Bus (OneWire) zu laufen... also kannst Du alle Sensoren an einen Port anschließen.
Was Dein Problem angeht: jeder DS18B20 hat eine eigene Adresse. Du kannst also von jedem Deiner Sensoren die Adresse anzeigen lassen, die Adresse beim Sensor vermerken und im Programm dann die Anzeigen nach der Adresse des Sensors bestimmen.
Um zu sagen, wie das genau geht, müsste man wissen, was Du für eine Lib benutzt

multi:
Jetzt ist mein Problem, dass der Sensor an Buchse 1 immer an der Anzeige 1 (Buchse2->Anzeige2...) dargestellt werden soll. Ich weiß jedoch im Vorhinein nicht, welcher Sensor wo angeschlossen wird.

Wenn immer der Sensor an Buchse1 an Anzeige1 dargestellt werden soll, ist das ja kein Problem.

Ich vermute, dass du einen bestimmten Sensor an Anzeige1 darstellen willst, egal wo er eingesteckt ist.

Ideen:

  1. Eine Anleitung zum Einstecken (Zeichnung, Beschriftung der Buchsen)
  2. kann man am Verhalten die Sensoren erkennen? z.B. beim Einschalten erwärmen sie sich in einer bestimmten Reihenfolge; man kann sie durch einschalten der Heizkreise 1-4 identifizieren etc.
  3. Übers Menue zuordenbar: "Jetzt Sensor X einstecken"
  4. Sensor IDs vorher auslesen und fest im Code zuordnen

DerLehmi:
Wieso machst Du es derart kompliziert? Der DS18B20 hat den Vorteil, über einen Bus (OneWire) zu laufen... also kannst Du alle Sensoren an einen Port anschließen.
Was Dein Problem angeht: jeder DS18B20 hat eine eigene Adresse. Du kannst also von jedem Deiner Sensoren die Adresse anzeigen lassen, die Adresse beim Sensor vermerken und im Programm dann die Anzeigen nach der Adresse des Sensors bestimmen.
Um zu sagen, wie das genau geht, müsste man wissen, was Du für eine Lib benutzt

Ich glaube ich hab meine Frage nicht ganz eindeutig Formuliert.
Die Idee war, alle Sensoren an einen Bus anzuschließen, aber es ist nicht immer klar, wie viele und welche Sensoren verwendet werden. (Beispiel: Ich kaufe mir 10 Sensoren und brauche heute vllt 2 und morgen aber 4; welche von den 10 das sind weiß ich davor eigentlich nicht, daher sind die Sensoradressen auch jedes mal anders)

guntherb:
Wenn immer der Sensor an Buchse1 an Anzeige1 dargestellt werden soll, ist das ja kein Problem.

Ich vermute, dass du einen bestimmten Sensor an Anzeige1 darstellen willst, egal wo er eingesteckt ist.

Ideen:

  1. Eine Anleitung zum Einstecken (Zeichnung, Beschriftung der Buchsen)
  2. kann man am Verhalten die Sensoren erkennen? z.B. beim Einschalten erwärmen sie sich in einer bestimmten Reihenfolge; man kann sie durch einschalten der Heizkreise 1-4 identifizieren etc.
  3. Übers Menue zuordenbar: "Jetzt Sensor X einstecken"
  4. Sensor IDs vorher auslesen und fest im Code zuordnen
  1. Wie meinst du das? Aber das würde ja das Problem mit der Stromunterbrechung auch nicht wirklich lösen.
  2. Das ganze Gerät soll zum Bierbrauen oder auch zur Gärtemperaturüberwachung genutzt werden, deswegen ist das leider nicht immer eindeutig. :confused:
  3. Wäre vllt eine Idee aber dann ist wieder das Problem mit der Stromunterbrechung.
  4. Will ich eigentlich nicht, da das ganze doch recht unflexibel wäre.

Spricht außer dem höheren Aufwand den etwas gegen die Transistoren zum ein- und ausschalten der Sensoren? Das würde ja im Endeffekt genau das machen was guntherb vorgeschlagen hat händisch zu machen.

multi:
Ich glaube ich hab meine Frage nicht ganz eindeutig Formuliert.

Yepp, das glaube ich auch.

multi:
Die Idee war, alle Sensoren an einen Bus anzuschließen ...
Spricht außer dem höheren Aufwand den etwas gegen die Transistoren zum ein- und ausschalten der Sensoren?

Wenn alle an einem Bus hängen, dann kannst du sie nicht einzeln abschalten.

Meine Idee wäre, alle Sensoren einzeln zu kennzeichnen und die ID auszulesen.
Die IDs kannst du dann im Code hinterlegen und entweder fest zuordnen oder - über Display - variabel zuordnen.
Oder du läßt dir auf dem Display die verfügbaren Sensoren und deren Temperaturen anzeigen, und findest durch erwärmen (Finger auflegen) raus, welcher welcher ist.

Ich hab mal eine kleine Zeichnung gemach, wie ich mir das konkret vorstelle.

Dadurch könnte ich einen Transistor nach dem anderen einschalten und schauen, welcher Sensor sich neu am Bus meldet und somit dann an dieser Buchse hängen muss.

Ich verstehe das mit den Buchsen nicht.
Wenn die Sensoren alle an einem Bus hängen, ist es völlig egal an welcher Buchse die sind.

Noch eine Zeichnung, wie das fertige Gerät aussehen könnte...
Da wäre es halt jetzt schön wenn der rechteste Sensor auch automatisch auf der rechteste Anzeige wäre.

Aber vermutlich ist es wohl doch einfacher wenn man die Sensoren manuell konfiguriert und das dann im EEPROM abspeichert.

Das bringt aber auch nur dann einen Nutzen, wenn Du die Sensoren beschriftest, damit Du beim nächsten Mal weißt, welcher in welche Buchse kommt.

Gruß Tommy

Die einzige Möglichkeit, die ich sehe, ist:

Die Sensoren nicht als Bus verdrahten, sondern jeden Data-Pin eines Sensorsteckers auf einen eigenen Pin und im Code einen eigene Onewire Instanz pro Sensor vereinbaren

Dann hast du eine eindeutige Zuordnung von Sensor am Stecker1 zu einem Pin und zu einer Anzeige.

Ich habe das noch nie probiert, bin aber ziemlich sicher, dass das funktionert.

Was Gunther in #9 schreibt hatte ich in der Vergangenheit mal angewendet.
4 Sensoren an jeweils einem eigenen Arduinopin. Im Beispiel an Pin 8, 9, 10 und 11
Dann braucht man sich um die Adressen der Sensoren nicht zu kümmern. Die Messungen bleiben den 4 Pins (4 Buchsen) zugeordnet.

#include <OneWire.h>

#define DS18B20_1 8                // Datenpin Temperatursensor 1
#define DS18B20_2 9                // Datenpin Temperatursensor 2
#define DS18B20_3 10               // Datenpin Temperatursensor 3
#define DS18B20_4 11               // Datenpin Temperatursensor 4

OneWire Sensor1(DS18B20_1);
OneWire Sensor2(DS18B20_2);
OneWire Sensor3(DS18B20_3);
OneWire Sensor4(DS18B20_4);

byte data[12], i;
int16_t raw;
float temp_1;                       // Temperatur 1
float temp_2;                       // Temperatur 2
float temp_3;                       // Temperatur 3
float temp_4;                       // Temperatur 4

void start_DS18B20_1() {
  Sensor1.reset();       // reset one wire buss
  Sensor1.skip();        // select only device
  Sensor1.write(0x44);   // start conversion
}
void start_DS18B20_2() {
  Sensor1.reset();       // reset one wire buss
  Sensor1.skip();        // select only device
  Sensor1.write(0x44);   // start conversion
}
void start_DS18B20_3() {
  Sensor1.reset();       // reset one wire buss
  Sensor1.skip();        // select only device
  Sensor1.write(0x44);   // start conversion
}
void start_DS18B20_4() {
  Sensor1.reset();       // reset one wire buss
  Sensor1.skip();        // select only device
  Sensor1.write(0x44);   // start conversion
}

void lesen_DS18B20_1() {
  Sensor1.reset();
  Sensor1.skip();
  Sensor1.write(0xBE);
  for ( i = 0; i < 9; i++) {
    data[i] = Sensor1.read();
  }
  // Convert the data to actual temperature
  raw = (data[1] << 8) | data[0];
  temp_1 = (float)raw / 16.0;
}
void lesen_DS18B20_2() {
  Sensor2.reset();
  Sensor2.skip();
  Sensor2.write(0xBE);
  for ( i = 0; i < 9; i++) {
    data[i] = Sensor2.read();
  }
  // Convert the data to actual temperature
  raw = (data[1] << 8) | data[0];
  temp_2 = (float)raw / 16.0;
}
void lesen_DS18B20_3() {
  Sensor3.reset();
  Sensor3.skip();
  Sensor3.write(0xBE);
  for ( i = 0; i < 9; i++) {
    data[i] = Sensor3.read();
  }
  // Convert the data to actual temperature
  raw = (data[1] << 8) | data[0];
  temp_3 = (float)raw / 16.0;
}
void lesen_DS18B20_4() {
  Sensor4.reset();
  Sensor4.skip();
  Sensor4.write(0xBE);
  for ( i = 0; i < 9; i++) {
    data[i] = Sensor4.read();
  }
  // Convert the data to actual temperature
  raw = (data[1] << 8) | data[0];
  temp_4 = (float)raw / 16.0;
}

void setup() {
  Serial.begin(115200);        // connect to the serial port
}

void loop() {
  start_DS18B20_1();
  start_DS18B20_2();
  start_DS18B20_3();
  start_DS18B20_4();
  delay(1000);                 // den Sensoren Zeit zur Messung lassen
  lesen_DS18B20_1();
  lesen_DS18B20_2();
  lesen_DS18B20_3();
  lesen_DS18B20_4();

  Serial.print("T1: "); Serial.println(temp_1, 3);
  Serial.print("T2: "); Serial.println(temp_2, 3);
  Serial.print("T3: "); Serial.println(temp_3, 3);
  Serial.print("T4: "); Serial.println(temp_4, 3);
}

Das Programm ist ungetestet!

Gruß Peter

Der Code ist ein perfektes Beispiel für die völlig falsche Verwendung von Funktionen :slight_smile: Funktionen haben unter anderem den Sinn Code-Duplizierung zu vermeiden. Weshalb man Parameter übergeben kann

Serenifly:
Der Code ist ein perfektes Beispiel für die völlig falsche Verwendung von Funktionen :slight_smile: Funktionen haben unter anderem den Sinn Code-Duplizierung zu vermeiden. Weshalb man Parameter übergeben kann

Ich gebe dir da ja recht.

Aber um das halbwegs elegant zu machen, müßte man die onewire Instanzen auch als Array deklarieren, das geht aber nicht.
Oder kann ich ein Array von Funktionspointern deklarieren?

Ich habs versucht, aber ich kriegs nicht hin.

guntherb:
Aber um das halbwegs elegant zu machen, müßte man die onewire Instanzen auch als Array deklarieren, das geht aber nicht.

Natürlich kann man ein Array aus Objekten anlegen. Wieso soll das nicht gehen? Man muss nur beim Initialisieren den Konstruktor explizit aufrufen.

Aber das ist gar nicht nötig. Ich meinte, dass man einfach die Instanz die die Funktion verwenden soll als Referenz übergibt

void start_DS18B20(OneWire& sensor)
{
}

void lesen_DS18B20(OneWire& sensor)
{
}

Bei der zweiten Funktion sollte man sich aber das Ergebnis mit dem Rückgabewert zurückgeben lassen. Dann braucht man auch keine globalen Variablen

Oder kann ich ein Array von Funktionspointern deklarieren?

Das geht auch. Braucht man aber nicht

Hi

In diesem Fall würde ich, da ich die Busfunktionalität gar nicht brauche mit dem ganzen Drum herum, auf einen anderen Sensor wechseln.
DHT, TSIC oder LM75 kämen mir spontan in den Sinn, müssten Alle Singel-Sensoren sein und sich mit dem Arduino abfrühstücken lassen.

Wenn bei dem DS18B20 geblieben werden soll, könnte man die Sensoren auch suchen lassen - die Reihenfolge, in Der Diese gefunden werden, ist immer gleich - allerdings nur mit diesen Sensoren.
Wenn man einen der Sensoren raus nimmt, rücken 'die Restlichen' nur aneinander (beim zurück Stecken sortiert Der sich aber wieder Da ein, wo Er zuvor stand) - ein weiterer Sensor mit unbekannter ID kann - mehr oder weniger - überall in der Reihe auftauchen.

Man könnte Das dann so machen, daß man zuerst nur einen Sensor an Buchse 1 anschließt - Dieser wird als Einziger gefunden.
Nun schließt man einen zweiten Sensor an Buchse Zwei an, der Code sucht nach 'weiteren Sensoren' und findet entweder den Neuen, oder den bereits bekannten Sensor als Erstes.
Wenn der Neue zuerst gefunden wird, eine Anzeige, daß Buchse Zwei und Drei getauscht werden müssen.
Identisch mit Sensor 3.
Wenn der Sensor 3 als erstes gefunden wird, müssen die Sensoren Eins und Zwei je eine Stelle nach Rechts.
Wenn Sensor 3 als Zweites gefunden wird, müssen Sensor 2 und 3 getauscht werden.

Denke aber, daß Das eine unnötige Rumstöpselei ist und, wenn das Umstöpseln vergessen oder übersehen wird, wird der Messwert an einer falschen Stelle angezeigt - was so nicht tragbar ist.

Andere Herangehensweise, wenn die Sensoren nacheinander eingesteckt werden:

  • einlesen des neuen Sensor, die Nummer wird intern gemerkt und kommt auf Anzeige 1
  • die weiteren Sensoren identisch, der Benutzer muß halt explizit die Reihenfolge der Buchsen einhalten.

Wenn alle Sensoren gefunden wurden, kann man die Nummern im Eeprom abspeichern lassen, wo Diese auch nach Neustart ausgelesen werden.

Oder eben, wie schon geschrieben, für jeden Sensor einen eigenen Pin - Da kann dann nur dieser eine Sensor gefunden werden.

Solange noch 'Beinchen' frei und Platz im Speicher ist, spricht Da auch Nichts gegen - ein Vorteil wäre hier sogar, daß man einen DS18B20 einfach tauschen kann, ohne in Schwierigkeiten zu kommen.

Darf man fragen, warum Du auf 1-wire setzt? Andere Sensoren sind nicht großartig schlechter aber günstiger zu bekommen - gerade, wenn man die Sensoren eh einzeln anfährt (gehe davon aus, daß Du nicht mit 'Beinchen' geizen musst).

MfG

Serenifly:
Natürlich kann man ein Array aus Objekten anlegen. Wieso soll das nicht gehen? Man muss nur beim Initialisieren den Konstruktor explizit aufrufen.

Sorry, bin ich zu doof für.
Ich habe ja mal im Studium, so vor gut 3 Jahrzehnten, C gelernt und auch ein bißchen SW Architektur, aber das ist mir zu hoch. Um mit Handwerklichen Entsprechungen zu arbeiten: ich kann zwar Mauern, aber keine Stuckdecken. :confused:

Aber ich bin ja auch nicht der TO, nur interessierter Mitleser.
Und meine Stärken liegen eindeutig mehr in der Hardware, das hatte ich schließlich dann auch zum Beruf gemacht. Aber trotzdem interessiert es mich:
wie genau soll das "Natürlich kann man ein Array aus Objekten anlegen" funktionieren?
Ich habs jetzt ausgiebig versucht und (mit OneWire) nicht hinbekommen. :-[