2x TempSensor DS18B20: Zauberei oder was?

Bin etwas am rumspielen mit zwei DS18B20 TempSensoren & OLED 128x64.

Ihr werdet es kaum glauben:

Mein Code funtioniert ! :o Nur ich weiß nicht warum... :grin:

Die beiden Sensoren so mit Widerstand angeschlossen. Jeweils die Datenleitung vom Sensor an Pin3 Arduino.

Ich bekomme beide Werte bestens angezeigt aber hääää:

Wie weiß der Arduino welcher Sensor 1 und 2 ist? :o

/*********************************************************************
This is an example for our Monochrome OLEDs based on SSD1306 drivers

  Pick one up today in the adafruit shop!
  ------> http://www.adafruit.com/category/63_98

This example is for a 128x64 size display using I2C to communicate
3 pins are required to interface (2 I2C and one reset)

Adafruit invests time and resources providing this open source code, 
please support Adafruit and open-source hardware by purchasing 
products from Adafruit!

Written by Limor Fried/Ladyada  for Adafruit Industries.  
BSD license, check license.txt for more information
All text above, and the splash screen must be included in any redistribution
*********************************************************************/

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

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2




// Data wire is plugged into pin 3 on the Trinket
#define ONE_WIRE_BUS 3
 
// Setup a oneWire instance to communicate with any OneWire devices 
// (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
 
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);



int T1;
int T2;




#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

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


  // Start up the sensor library
  sensors.begin();
  

  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC, 0x3D);  // initialize with the I2C addr 0x3D (for the 128x64)
  // init done
  
  // Show image buffer on the display hardware.
  // Since the buffer is intialized with an Adafruit splashscreen
  // internally, this will display the splashscreen.
  display.display();
  delay(2000);

  // Clear the buffer.
  display.clearDisplay();

  // draw a single pixel
  display.drawPixel(10, 10, WHITE);
  // Show the display buffer on the hardware.
  // NOTE: You _must_ call display after making any drawing commands
  // to make them visible on the display hardware!
  display.display();
  delay(2000);
  display.clearDisplay();


  T1=20;
  T2=15;

  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.print("Temperatur T1:");
  display.print(T1);
  display.write((char)247);
  display.println("C");

  display.setCursor(0,8);
  display.print("Temperatur T2:");
  display.print(T2);
  display.write((char)247);
  display.println("C");

  display.drawCircle(50, 50, 10, WHITE);
  display.drawTriangle(45,57,45,43,60,50, WHITE);
  
  display.display();
  delay(2000);
}
 

 
   
  

 
 
 



void loop() {

  // call sensors.requestTemperatures() to issue a global temperature
  // request to all devices on the bus
  sensors.requestTemperatures(); // Send the command to get temperatures
  //Serial.print(sensors.getTempCByIndex(0)); // Why "byIndex"? 
    // You can have more than one IC on the same bus. 
    // 0 refers to the first IC on the wire

  display.clearDisplay();
  display.setCursor(0,8);
  display.print("Temperatur T1:");
  display.print(sensors.getTempCByIndex(0));
  display.write((char)247);
  display.println("C");

  display.setCursor(0,16);
  display.print("Temperatur T2:");
  display.print(sensors.getTempCByIndex(1));
  display.write((char)247);
  display.println("C");

  display.display();

  delay(1000);
}

Hallo,

du bist doch auch schon etwas länger dabei, da sollte doch ein wenig Code-Lesen möglich sein, oder? :wink: :wink:

Das könnte daran liegen weil du Festwerte vorgibst.

 T1=20;
T2=15;

Und auch nirgendwo die Temperaturen einliest.

Dazu fehlt z.B. sowas:

sensors.requestTemperatures();
Serial.print(sensors.getTempCByIndex(0));

Scherheinz:
Das könnte daran liegen weil du Festwerte vorgibst.

 T1=20;

T2=15;




Und auch nirgendwo die Temperaturen einliest.

Dazu fehlt z.B. sowas:



sensors.requestTemperatures();
Serial.print(sensors.getTempCByIndex(0));

Das Einlesen macht er schon in der Loop.

Und da ist auch die Antwort auf seine Frage. Per Index (0 oder 1) wird der jeweilige Sensor eingelesen.

Ach stimmt, hatte anscheinend nicht ganz runter gescrollt :slight_smile:

Scherheinz:
Ach stimmt, hatte anscheinend nicht ganz runter gescrollt :slight_smile:

OK, aber dank der "Zauberei" ist stoni99 jetzt total irritiert. :wink:

Nicht schlimm, das große leere Feld zwischen setup und loop hat mich ja auch verwirrt :slight_smile:

Scherheinz:
Nicht schlimm, das große leere Feld zwischen setup und loop hat mich ja auch verwirrt :slight_smile:

Ja, das war wohl eine "Gedankenpause" oder er wollte Tinte sparen. :wink:

Genau im Loop!

Aber beide Sensoren sind doch an Pin3 angeschlossen. Woher weiß denn die Software welcher von beiden bei Serial.print(sensors.getTempCByIndex(0)); eingelesen wird?

HotSystems:
Das Einlesen macht er schon in der Loop.

Und da ist auch die Antwort auf seine Frage. Per Index (0 oder 1) wird der jeweilige Sensor eingelesen.

Ich glaube der erste Sensor im Bus hat einen niedrigeren Index. Wenn du es ganz genau willst, musst du die Sensoren mit ihrer Adresse ansprechen. Dazu gibt es einen Test-Sketch um die Adressen auszulesen.

#include <OneWire.h>
 
OneWire ow(2); 
 
void setup(void) 
{
  Serial.begin(9600);
  lookUpSensors();
}
 
void lookUpSensors()
{
  byte address[8];
  int i=0;
  byte ok = 0, tmp = 0;
 
  Serial.println("--Suche gestartet--");
  while (ow.search(address))
  {
    tmp = 0;
    //0x10 = DS18S20
    if (address[0] == 0x10)
    {
      Serial.print("Device is a DS18S20 : ");
      tmp = 1;
    } 
    else
    {
      //0x28 = DS18B20
      if (address[0] == 0x28)
      {
        Serial.print("Device is a DS18B20 : ");
        tmp = 1;
      }
    }
    //display the address, if tmp is ok
    if (tmp == 1)
    {
      if (OneWire::crc8(address, 7) != address[7])
      {
        Serial.println("but it doesn't have a valid CRC!");
      } 
      else
      {
        //all is ok, display it
        for (i=0;i<8;i++)
        {
          if (address[i] < 9)
          {
            Serial.print("0");
          }
          Serial.print("0x");
          Serial.print(address[i],HEX);
          if (i<7)
          {
            Serial.print(", ");
          }
        }
        Serial.println("");
        ok = 1;
      }
    }//end if tmp
  }//end while
  if (ok == 0)
  {
    Serial.println("Keine Sensoren gefunden");
  }
  Serial.println("--Suche beendet--");
}
 
void loop(void) 
{
  //do nothing :)
}

Ja auslesen geht.

Aber was bedeutet das:

--Suche gestartet--
Device is a DS18B20 : 0x28, 0x18, 0xF3, 0xDE, 00x6, 00x0, 00x0, 0xC9
Device is a DS18B20 : 0x28, 0xFF, 0x27, 0xAE, 0x64, 0x15, 00x3, 0x97
--Suche beendet--

Hat jeder Sensor mehrere Adressen oder ist das eine lange Adresse?

Sind diese schon ab Werk vorgegeben und werden für jeden unterschiedlich eingestellt?
Weil: Ich habe keine Adressen vergeben. :o Steht auch nix drauf.

Um Sensor 2 gezielt anzusprechen muss ich also "0x28, 0xFF, 0x27, 0xAE, 0x64, 0x15, 00x3, 0x97" benutzen?

Mit "0x28" wird mir mitgeteilt das es sich um einen DS18B20 handelt richtig?

@stoni99
Mannooo....
Datenblatt lesen!

Jeder DSxxxxx hat eine eindeutige Kennung.
Manche DS haben nichts anderes, als nur eine Kennung.

"0x28" weiß ich nicht

Nein, das ist eine lange Adresse mit 8 Byte in hexadezimaldarstellung.
Grüße Uwe

Hab bei meinen DS18B20-Sensoren die Adressen direkt zugewiesen

DeviceAddress tempSensor_1 = { 0x28, ....... };
DeviceAddress tempSensor_2 = { 0x28, ....... };

In der Loop werden die dann gezielt abgefagt

sensor_1 = sensors.getTempC(tempSensor_1);

uwefed:
"0x28" weiß ich nicht

Das ist der Gerätecode.

DS18S20 - 0x10

DS18B20 - 0x28

DS1822 - 0x22

OK: Mit dem "Auslesen" der Gerätecodes und dem direktem "Anspechen mit Code" wird die Sache auch mir klar.

Bei mir funtionierte das auch ohne direktes Ansprechen des Sensors richtig. Die Lib ordnet wohl von allein nach Code-Wertigkeit und gibt die Rangfolge vor. (da hat doch echt schon einer mit dem Nixwisser stoni gerechnet... :grin: ) Warscheinlich hatte ich durch Zufall Fühler 1 mit einem kleineren Code. Der Programmiergott war mit mir! :stuck_out_tongue:

Ich werde wohl mal das Ganze mal sauber mit Fühler-Code versehen. Will ja hier nicht negativ auffallen... :grinning:

Direktes Ansprechen ist auf Dauer eh besser falls mal ein Fühler ausfallen sollte damit dann deine Zuordnung noch stimmt.
Ich hab es nie ausprobiert aber ich denke wenn du Fühler 0 und Fühler 1 hast und Fühler 0 ist bei einem Neustart des Arduino nicht mehr erreichbar, Fühler 1 zu Fühler 0 wird.
Dann tauschst du Fühler 1 obwohl 0 defekt ist

Es ist u.A. genau diese Art von Konfigurationsänderung, wofür das eingebaute EEProm erfunden wurde.

Hab es mal mit Adressierung geschrieben:

/*********************************************************************
This is an example for our Monochrome OLEDs based on SSD1306 drivers

  Pick one up today in the adafruit shop!
  ------> http://www.adafruit.com/category/63_98

This example is for a 128x64 size display using I2C to communicate
3 pins are required to interface (2 I2C and one reset)

Adafruit invests time and resources providing this open source code, 
please support Adafruit and open-source hardware by purchasing 
products from Adafruit!

Written by Limor Fried/Ladyada  for Adafruit Industries.  
BSD license, check license.txt for more information
All text above, and the splash screen must be included in any redistribution
*********************************************************************/

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

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2




// Data wire is plugged into pin 3 on the Trinket
#define ONE_WIRE_BUS 3
 
// Setup a oneWire instance to communicate with any OneWire devices 
// (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
 
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

DeviceAddress tempSensorVL = { 0x28, 0x18, 0xF3, 0xDE, 0x06, 0x00, 0x00, 0xC9 };
DeviceAddress tempSensorRL = { 0x28, 0xFF, 0x27, 0xAE, 0x64, 0x15, 0x03, 0x97 };

int T1;
int T2;




#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

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


  // Start up the sensor library
  sensors.begin();
  

  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC, 0x3D);  // initialize with the I2C addr 0x3D (for the 128x64)
  // init done
  
  // Show image buffer on the display hardware.
  // Since the buffer is intialized with an Adafruit splashscreen
  // internally, this will display the splashscreen.
  display.display();
  delay(2000);

  // Clear the buffer.
  display.clearDisplay();
}
 



void loop() {

  // call sensors.requestTemperatures() to issue a global temperature
  // request to all devices on the bus
  sensors.requestTemperatures(); // Send the command to get temperatures
  //Serial.print(sensors.getTempCByIndex(0)); // Why "byIndex"? 
    // You can have more than one IC on the same bus. 
    // 0 refers to the first IC on the wire

  display.clearDisplay();
  
  display.setTextSize(1);
  display.setTextColor(WHITE);
  
  display.setCursor(0,0);
  display.print("Temperatur T1:");
  display.print(sensors.getTempC(tempSensorVL));
  display.write((char)247);
  display.println("C");

  display.setCursor(0,8);
  display.print("Temperatur T2:");
  display.print(sensors.getTempC(tempSensorRL));
  display.write((char)247);
  display.println("C");

  display.display();

  delay(1000);
}

Hier muß man aufpassen:

Lt. Adressenausleseprogramm müsste folgendes drin stehen.

--Suche gestartet--
Device is a DS18B20 : 0x28, 0x18, 0xF3, 0xDE, 00x6, 00x0, 00x0, 0xC9
Device is a DS18B20 : 0x28, 0xFF, 0x27, 0xAE, 0x64, 0x15, 00x3, 0x97
--Suche beendet--

Das will die IDE aber nicht - gibt Fehlermeldung.

Es muß´drin stehen:

DeviceAddress tempSensorVL = { 0x28, 0x18, 0xF3, 0xDE, 0x06, 0x00, 0x00, 0xC9 };
DeviceAddress tempSensorRL = { 0x28, 0xFF, 0x27, 0xAE, 0x64, 0x15, 0x03, 0x97 };

Nur für den Fall das es noch mal jemanden gibt der sich genauso dumm anstellt wie stoni... :grin: