4 Stück DS18b20 einzeln abfragen mit bekannter Adresse

Moin,

ich habe 4x DS18b20 mit bekannten Adressen und möchte diese einzeln abfragen.

Dazu habe ich das "DallasTemperature Tester" Sketch soweit eingedampft, wie es mir möglich war:

#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS D6
#define TEMPERATURE_PRECISION 12 // Lower resolution
OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
DallasTemperature sensors(&oneWire); // Pass our oneWire reference to Dallas Temperature.
int numberOfDevices; // Number of temperature devices found
DeviceAddress tempDeviceAddress; // We'll use this variable to store a found device address

void printTemperature(DeviceAddress deviceAddress) // function to print the temperature for a device
{
  float tempC = sensors.getTempC(deviceAddress);
  if (tempC == DEVICE_DISCONNECTED_C)
  {
    Serial.println("Error: Could not read temperature data");
    return;
  }
  Serial.print("Temp [C]: ");
  Serial.println(tempC, 3);
}

void printAddress(DeviceAddress deviceAddress) // function to print a device address
{
  for (uint8_t i = 0; i < 8; i++)
  {
    if (deviceAddress[i] < 16) Serial.print("0");
    Serial.print(deviceAddress[i], HEX);
  }
}

void setup(void)
{
  delay(100);
  Serial.begin(9600);   // start serial port
  sensors.begin();   // Start up the library
  numberOfDevices = sensors.getDeviceCount();   // Grab a count of devices on the wire
  for (int i = 0; i < numberOfDevices; i++) // Loop through each device, print out address
  {
    if (sensors.getAddress(tempDeviceAddress, i))   // Search the wire for address
    {
      printAddress(tempDeviceAddress);
      Serial.println();
      sensors.setResolution(tempDeviceAddress, TEMPERATURE_PRECISION);    // set the resolution to TEMPERATURE_PRECISION bit (Each Dallas/Maxim device is capable of several different resolutions)
    }
  }
}

void loop(void)
{
  sensors.requestTemperatures(); // Send the command to get temperatures
  for (int i = 0; i < numberOfDevices; i++)   // Loop through each device, print out temperature data
  {
    if (sensors.getAddress(tempDeviceAddress, i))     // Search the wire for address
    {
      printAddress(tempDeviceAddress);
      Serial.print(" ");
      printTemperature(tempDeviceAddress);       // It responds almost immediately. Let's print out the data // Use a simple function to print out the data
    }
  }
  delay(30000);
}

Allerdings ist das ja so aufgebaut, dass immer alle Sensoren im 1-Wire Bus gesucht werden und alle Temperaturwerte ausgegeben werden.

Am Ende ist mein Ziel eine State Maschine, und je nach Zustand nur EIN Temperaturwert auszulesen. Ich brauche also jeden Temperaturwert einzeln. Wie fragt man denn nun einen einzelnen DS18b20 mit bekannter Adresse ab?

Vielen Dank und beste Grüße,
Chris

Ich mache das so:


#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 0       // ESP8266
#define TEMPERATURE_PRECISION 12
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress sensor1 = {0x28, 0x5, 0x50, 0x56, 0xB5, 0x1, 0x3C, 0xE1 };//Auußen
DeviceAddress sensor2 = { 0x28, 0x1F, 0xAC, 0x75, 0xD0, 0x1, 0x3C, 0x9A };//Innen



void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:
sensors.requestTemperatures();
  float temp1 = sensors.getTempC(sensor1);
  float temp2 = sensors.getTempC(sensor2);
}

Die Serial Ausgabe selber einfügen.
Es geht bestimmt schöner, aber funktioniert wie soll :wink:
Edit es fehlte wie @my_xy_projekt schreibt sensors.requestTemperatures();
Gruß Bernhard

Du verwendest nur die Funktion:

und übergibst genau die eine Adresse die Du abfragst.
Hinweis:

sensors.requestTemperatures();

kannst Du im loop() in Dauerschleife laufen lassen, aber dazu

 sensors.setWaitForConversion();

nicht vergessen -> Siehe Beispiel WaitForConversion2

Moin,
mir gefällt die Variante von Fony ausgesprochen gut, sehr schön kompakt, genau so brauche ich das.
Ich hab das mal getestet und auf meine Sensoren umgemünzt:

#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS D6   // ESP8266
#define TEMPERATURE_PRECISION 12
OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
DallasTemperature sensors(&oneWire);
DeviceAddress sensor1 = {0x28, 0xda, 0xbf, 0x98, 0x42, 0x20, 0x01, 0x29}; // T63
DeviceAddress sensor2 = {0x28, 0xff, 0xf4, 0x83, 0x90, 0x16, 0x05, 0xf1}; // T64
DeviceAddress sensor3 = {0x28, 0xff, 0x91, 0x64, 0x90, 0x16, 0x05, 0xfd}; // T65
DeviceAddress sensor4 = {0x28, 0xff, 0x19, 0x69, 0x90, 0x16, 0x05, 0x95}; // T66

void setup() {
  delay(200);
  Serial.begin(9600);   // start serial port
}

void loop() {
  float temp1 = sensors.getTempC(sensor1);
  Serial.print("Sensor 1: ");
  Serial.println(temp1, 3);
  delay(5000);
  float temp2 = sensors.getTempC(sensor2);
  Serial.print("Sensor 2: ");
  Serial.println(temp2, 3);
  delay(5000);
  float temp3 = sensors.getTempC(sensor3);
  Serial.print("Sensor 3: ");
  Serial.println(temp3, 3);
  delay(5000);
  float temp4 = sensors.getTempC(sensor4);
  Serial.print("Sensor 4: ");
  Serial.println(temp4, 3);
  delay(5000);
}

Da bleiben zwei Fragen offen:

  1. Kann das sein, dass da ein "sensors.begin(); // Start up the library" fehlt? Falls nicht ist mir das nicht klar, warum man das in dem anderen Sketch braucht.
  2. "#define TEMPERATURE_PRECISION 12" ist zwar deklariert, aber wird nirgendwo benutzt. Fehlt da nicht ein "sensors.setResolution(tempDeviceAddress, TEMPERATURE_PRECISION);"?!

Beste Grüße,
Chris

Ja

Ja

Es fehlt auch ein

sensors.requestTemperatures();

Und die delays stehen Dir im Weg.

Darüber hinaus solltest evtl darüber nachdenken das UserDataByte zu benutzen.
Das ist geil, wenn Du einen Sensor tauschen kannst, ohne in den Code eingreifen zu müssen...

Habe extra im meinem Prog nachgesehen funktioniert ohne.
nur wen Du die sehr oft heißt unter 1sek ausliest muss man

 sensors.setWaitForConversion();

einfügen, ich frage die Sensoren alle 2Min ab deshalb habe das nicht drinnen

das ist lustig, das Sketch läuft, es werden Temperaturen angezeigt, aber die ändern sich nicht :slight_smile:
Ich nehme an, das fehlende "sensors.requestTemperatures();" ist dafür verantwortlich.
Wo muss das hin? 1x im Loop, oder vor jeder einzelnen Sensorabfrage?
Was passiert dabei genau?
Ich stelle mir vor dass bei dem "sensors.requestTemperatures();" in den 1-Wire Bus hineingerufen wird, dass alle Sensoren die Temperatur messen sollen, die Sensoren speichern den Wert dann. Aber erst bei "sensors.getTempC(sensorX);" wird die Temperatur ausgelesen.
Ich frage das deshalb, weil ich später die Sensoren nacheinander und mit relativ viel Pause (1 Minute) abfragen will. Laufen nun alle 4 Sensoren mit jeweils einer Minute Abstand durch, so dauert ein Durchlauf insgesamt 4 Minuten.
Wenn ich nur 1x im Loop das "sensors.requestTemperatures();" durchführe ist der Temperaturwert vom letzten Sensor 4 Minuten alt, richtig?
Wenn ich später in der Statemachine das "sensors.requestTemperatures();" dauernd ausführe nehme ich an, dass es mein Sketch ausbremst und viel zu oft ausgeführt wird, bzw. dass der 1-Wire Bus unnötig unter Dauerfeuer steht.
Demnach müsste ich einfach direkt vor der "sensors.getTempC(sensorX);" die "sensors.requestTemperatures();" durchführen.
Um nicht auf die Umwandlung zu warten, bzw. extra noch "sensors.setWaitForConversion();" auszuführen könnte ich auch "sensors.requestTemperatures();" nach "sensors.getTempC(sensorX) ausführen, dann ist der Temperaturwert eben 1 Minute alt.

Stimmen meine Annahmen so?

Beste Grüße,
Chris

das fehlte wirklich

sensors.requestTemperatures();

Habe #1 geändert

wurde im Header definiert wozu nochmal? wird wahrscheinlich wegoptimiert

Das handelt die lib selbst ab.

setWaitForConversion(false) ist dafür gedacht um selbst zu entscheiden wann der Sensor ausgelesen wird.
Ist schön, wenn Du mehrere Sensoren hast und deren Auflösung unterschiedlich ist, bzw. Du z.B. einen DS18B20 hast, den aber im 9-bit Modus betreibst.

Birgt aber die Gefahr, wenn man nicht aufpasst, das die Conversation nicht vollständig ist.... Müsste man abfragen mit

isConversionComplete()

:wink:

Hast Du mal in die ganzen vielen Beispiele geschaut?

Ja das ist mir bekannt, das Probl ist das fast alle Sensoren sind nicht mehr Originale Dallas außer man kauft sie bei zertifiziertem Händler wo die kosten über 3€. Maine können wenigstens Prasitenmodus China Sensoren = die günstigen so wie die vom AZ können das nicht mehr auch nicht Resolution ändern ( meine können das auch nicht) man kann auf 9 setzen ausgelesen werden mit 12 :nauseated_face:

Ja, aber das beantwortet meine Frage / das Verhalten nicht?!

Das ist das Material, was aus der Qualiprüfung gefallen ist. :frowning: Es funktionert, aber eben nicht wie im DaBla vorgesehen.
Bei ParasitePower ist die Umladezeit kritisch.
Ich hab hier auch einen Satz 18B20 gehabt, der nicht mit 4,7K sondern nur mit 3,3K Direktspeisung lief...
Da 3,3K auch im regulären Betrieb tun, hab ich die jetzt alle soweit runter gezogen :wink:

Die Abfrage erfolgt doch softwareseitig. Oder geht das setzen an sich nicht?

Es gibt auf GitHub ein Test Prog hat sich herausgestellt nur der erster ist Original gekauft vor 2J

Naja, ich denke schon. Wo steht den das request() in den Beispielen :slight_smile:

setResolution(9); 

brigt nix

getResolution ()

zeigt 12

Ok, das ist komisch. Parasite Power? Dann könnte das problematisch sein.
Ich würde die mal direkt speisen.
Wie ist das erste HEX der Adresse?

24 und 28 also falset
die laufen mit + -
mit Parasite habe nur getestet

Ups. Das ist eigenartig. Sowas gibt es nicht ;(
Die 0x28 ist richtig für 18B20. Der 1820 und 18S20 ist 0x10.

Laut dem Test soll kein Original sein, die Aufschrift auf den Sensoren ist auch nicht gelasert nur gedruckt wie ich das kann erkennen, jedenfalls ist die nicht so wie beim Original. Mag sein das Dallas was geändert hat, ist mir auch Wurst Hauptsache die Lügen nicht mit den angezeigten Werten, Letze 5 gekaufte Differenz 0,5° gleich bleibend also in Norm :wink:

1 Like