Multiple DS18B20 with Photon


#21

For a multi-house HVAC project, I need to use many (About 30) water temperature sensors…

My original choice of water temperature sensor was one with PWM output, needing one digital I/O pin per sensor.
In this thread: Calculating a median value we ( @Ric, @BulldogLowell, @ScruffR, @peekay123, @Moors7 and others ) worked on a a sketch to read the temperatures of 16 of these sensors with one Particle. That works fine!

However, for several reasons, I would like to use the DS18B20 sensors. The main reason is that I can monitor even more sensors with less pins (= Only one!).
Today I started to try out the DS18B20 one-wire sensor, and I managed to read out one without problems.

But when I look at all the discussions in this forum about using Multiple DS18B20 with Photon, I am confused by the various methods and libraries used by many of you.

Below, I post a basic “under construction” sketch, to display the temperatures of 8 of these sensors on the serial monitor. Of course, at this moment it measures only one sensor, but it does that 8 times in a row in the loop():

Can anyone show me a simple way to make it read 8 different sensors on the bus?

Once I will be able to do that, I can adapt it to my purposes.

    /******************************************************************************************************
    DS18B20_temperature_monitor.ino
    
    Connections:  Sensor    Particle
                  ------    --------
                  Red       +5V (Vin)
                  Black     Gnd
                  Yellow    Any I/O (D2) => Attention: 4k7 pull-up resistor between yellow wire and +5V (May be reduced to 1k)
    *******************************************************************************************************/
    
    // Libraries for off-line use in the "Particle DEV" program:
     #include "Particle-OneWire.h"
     #include "DS18B20.h"
     DS18B20 ds18b20 = DS18B20(D2); // Sets Pin D2 for Temp Sensor
    
     float T1, T2, T3, T4, T5, T6, T7, T8;// Floating variables for calculations
    
    
    void setup()
    {
     pinMode(D2, INPUT);
     Serial.begin(9600);
    }
    
    
    void loop()
    {
     T1 = getTemp();
     delay(500);
     T2 = getTemp();
     delay(500);
     T3 = getTemp();
     delay(500);
     T4 = getTemp();
     delay(500);
     T5 = getTemp();
     delay(500);
     T6 = getTemp();
     delay(500);
     T7 = getTemp();
     delay(500);
     T8 = getTemp();
     delay(500);
    
     Serial.print(T1,1); Serial.print("-");
     Serial.print(T2,1); Serial.print("-");
     Serial.print(T3,1); Serial.print("-");
     Serial.print(T4,1); Serial.print("-");
     Serial.print(T5,1); Serial.print("-");
     Serial.print(T6,1); Serial.print("-");
     Serial.print(T7,1); Serial.print("-");
     Serial.println(T8,1);
    
     delay(500);
    }
    
    
    
    float getTemp()
    {
      float Reading;
      if(!ds18b20.search())
      {
        ds18b20.resetsearch();
        Reading = ds18b20.getTemperature();
        if (Reading >0 && Reading <120) // Don't use "impossible" values!
        {    
         return Reading;
        }
      }
    }

BTW: Actually, I made this sketch for displaying the 8 temperatures on a mini OLED display, but I removed that part for simplification:

Thanks a lot for your time!
:hand: :older_man:


#22

Here’s the way I’m doing it with 3 sensors. I’m only using the OneWire library. I used one of the demo programs in the library to get the addresses of the devices first, and hard coded those into the sketch.

#include "OneWire/OneWire.h"  

OneWire ds = OneWire(D4);  // 1-wire signal on pin D4
byte addrs[3][8] = {{0x28, 0x1B, 0x1C, 0xE3, 0x03, 0x0, 0x0, 0xC5}, {0x28, 0x8, 0x56, 0xE3, 0x3, 0x0, 0x0, 0x93}, {0x28, 0xD, 0xD3, 0xE2, 0x3, 0x0, 0x0, 0xEE}};
float temps[3];
float celsius, fahrenheit;

void setup() {
  Serial.begin(9600);
  delay(3000);
}


void loop() {
  
  ds.reset();            
  ds.skip();          // Make all devices start the temperature conversion
  ds.write(0x44, 1);     // tell it to start a conversion, with parasite power on at the end
  //ds.write(0x44, 0);        // or start conversion in powered mode (bus finishes low)

  delay(1000);     //  wait 1 sec for conversion

  ds.reset();
  
  for (int i=0; i<3; i++) {
      ds.select(addrs[i]);
      ds.write(0xBE,0);         // Read Scratchpad
    
       byte data0 = ds.read();
       byte data1 = ds.read();
       ds.reset();
      
      int16_t raw = (data1 << 8) | data0;
    
      celsius = (float)raw * 0.0625;
      fahrenheit = celsius * 1.8 + 32.0;
      temps[i] = fahrenheit;
  }
  
  Serial.printlnf("Temp 1: %.1f   Temp 2: %.1f  Temp 3: %.1f", temps[0], temps[1], temps[2]);
  delay(10000);
}

My devices are the DS18B20-PAR which can only use parasitic power (only 2 wires), so I pass 1 as the second parameter to ds.write(0x44, 1). If you’re using powered devices, then you would pass 0 there. You probably couldn’t power 30 devices at once in parasitic mode from a Photon pin. Which method are you planning on using?


#23

If you are looking at 30 or so sensors, you may want to consider reviewing some of the topographical hardware issues you may face.

I had this bookmarked from when I did an attic space monitor with 12 sensors. It was Arduino ethernet based, very reliable now, but it took me a while to balance the impedance of the circuit.

Sensors seem very accurate, by the way, not that a hot attic is a test of that.

PS: Use Your Arrays!!!

:slight_smile:


#24

Thanks @Ric!

I am using the waterproof type of sensors and do not plan to use the “parasitic” method as it limits the number of sensors too much.

Probably it’s fine indeed to use that hardcoded method if you have only a few sensors on the same bus.
I will try it out asap with a few sensors.

It would be nice though to be able to use a method that discovers the sensors on the bus and identifies the sensors by index… Maybe the library @MORA introduced above can do this?
:grinning:


#25

Thanks for this tip @BulldogLowell!
Your LINK is interesting reading indeed if you plan to use many one-wire devices!
My intention is to keep the weight and length between sensors and Photons as low as possible.
Arrays rock indeed!
:stuck_out_tongue_winking_eye:


#26

Yes, my library can scan a (or several) busses for sensors and list their factory id.
You can loop trough several busses and start temperature conversion, and then return a second later to read them.

If you want to cut down on IO pins you can even do it trough an analog multiplexor, as long as each output line as a pullup, very cheap solution to multiple busses :slight_smile:


#27

Do you have an example for many sensors?
:older_man:

With the example in the library below I don’t see how to do that.
Sorry but my experience is not big…

    #include "ds18x20/ds18x20.h"
    #include "ds18x20/onewire.h"
    
    uint8_t sensors[80];
    
    void log(char* msg)
    {
        Spark.publish("log", msg);
        delay(500);
    }
    
    void setup()
    {
        ow_setPin(D0);
    }
    
    void loop()
    {
        uint8_t subzero, cel, cel_frac_bits;
        char msg[100];
        log("Starting measurement");    
        
        DS18X20_start_meas( DS18X20_POWER_PARASITE, NULL ); //Asks all DS18x20 devices to start temperature measurement, takes up to 750ms at max resolution
        delay(1000); //If your code has other tasks, you can store the timestamp instead and return when a second has passed.
    
        uint8_t numsensors = ow_search_sensors(10, sensors);
        sprintf(msg, "Found %i sensors", numsensors);
        log(msg);
    
        
        for (uint8_t i=0; i<numsensors; i++)
        {
            if (sensors[i*OW_ROMCODE_SIZE+0] == 0x10 || sensors[i*OW_ROMCODE_SIZE+0] == 0x28) //0x10=DS18S20, 0x28=DS18B20
            {
                //log("Found a DS18B20");
    			if ( DS18X20_read_meas( &sensors[i*OW_ROMCODE_SIZE], &subzero, &cel, &cel_frac_bits) == DS18X20_OK ) {
    				char sign = (subzero) ? '-' : '+';
    				int frac = cel_frac_bits*DS18X20_FRACCONV;
    				sprintf(msg, "Sensor# %d (%02X%02X%02X%02X%02X%02X%02X%02X) =  : %c%d.%04d\r\n",i+1,
    				sensors[(i*OW_ROMCODE_SIZE)+0],
    				sensors[(i*OW_ROMCODE_SIZE)+1],
    				sensors[(i*OW_ROMCODE_SIZE)+2],
    				sensors[(i*OW_ROMCODE_SIZE)+3],
    				sensors[(i*OW_ROMCODE_SIZE)+4],
    				sensors[(i*OW_ROMCODE_SIZE)+5],
    				sensors[(i*OW_ROMCODE_SIZE)+6],
    				sensors[(i*OW_ROMCODE_SIZE)+7],
    				sign,
    				cel,
    				frac
    				);
    				log(msg);
    			}
    			else
    			{
    			    Spark.publish("log", "CRC Error (lost connection?)");
    			}
            }
        }
        delay(10000);
    }

#28

This line returns the amount of sensors found.
First argument is the limit to how many sensors you want, second argument is a pointer to an array where the sensors will be stored.

Then you loop over them with

for (uint8_t i=0; i<numsensors; i++)

Where each sensor takes up OW_ROMCODE_SIZE spots in the array, I believe its currently 11.


#29

OK, thanks @MORA!
The sketch indeed publishes every step as an event. Great!

This is the output I got in “Dashboard”: (! Sorted alphabetically, not in timestamp sequence!)

{"data":"Found 0 sensors","ttl":"60","published_at":"2016-03-15T15:38:53.031Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Found 0 sensors","ttl":"60","published_at":"2016-03-15T15:39:01.581Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Found 0 sensors","ttl":"60","published_at":"2016-03-15T15:39:05.587Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Found 0 sensors","ttl":"60","published_at":"2016-03-15T15:39:09.601Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Found 0 sensors","ttl":"60","published_at":"2016-03-15T15:39:13.609Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Found 0 sensors","ttl":"60","published_at":"2016-03-15T15:39:17.621Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Found 0 sensors","ttl":"60","published_at":"2016-03-15T15:39:21.634Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Found 0 sensors","ttl":"60","published_at":"2016-03-15T15:39:25.643Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Found 0 sensors","ttl":"60","published_at":"2016-03-15T15:39:29.653Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Found 0 sensors","ttl":"60","published_at":"2016-03-15T15:39:33.663Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Found 0 sensors","ttl":"60","published_at":"2016-03-15T15:39:37.675Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Found 0 sensors","ttl":"60","published_at":"2016-03-15T15:39:41.688Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Found 0 sensors","ttl":"60","published_at":"2016-03-15T15:39:45.698Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Found 0 sensors","ttl":"60","published_at":"2016-03-15T15:39:49.706Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Found 0 sensors","ttl":"60","published_at":"2016-03-15T15:39:53.719Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Found 0 sensors","ttl":"60","published_at":"2016-03-15T15:39:57.734Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Found 0 sensors","ttl":"60","published_at":"2016-03-15T15:40:06.276Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Found 0 sensors","ttl":"60","published_at":"2016-03-15T15:40:10.294Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Found 0 sensors","ttl":"60","published_at":"2016-03-15T15:40:14.298Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Found 0 sensors","ttl":"60","published_at":"2016-03-15T15:40:18.308Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Found 0 sensors","ttl":"60","published_at":"2016-03-15T15:40:22.324Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Found 1 sensors","ttl":"60","published_at":"2016-03-15T15:38:48.502Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Found 1 sensors","ttl":"60","published_at":"2016-03-15T15:38:57.051Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Found 1 sensors","ttl":"60","published_at":"2016-03-15T15:40:01.751Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Sensor# 1 (28FF219F611503F9) = : +23.7500\r\n","ttl":"60","published_at":"2016-03-15T15:38:49.019Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Sensor# 1 (28FF219F611503F9) = : +23.7500\r\n","ttl":"60","published_at":"2016-03-15T15:38:57.566Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Sensor# 1 (28FF219F611503F9) = : +23.8125\r\n","ttl":"60","published_at":"2016-03-15T15:40:02.270Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Starting measurement","ttl":"60","published_at":"2016-03-15T15:38:51.519Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Starting measurement","ttl":"60","published_at":"2016-03-15T15:38:55.537Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Starting measurement","ttl":"60","published_at":"2016-03-15T15:39:00.078Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Starting measurement","ttl":"60","published_at":"2016-03-15T15:39:04.075Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Starting measurement","ttl":"60","published_at":"2016-03-15T15:39:08.088Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Starting measurement","ttl":"60","published_at":"2016-03-15T15:39:12.098Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Starting measurement","ttl":"60","published_at":"2016-03-15T15:39:16.109Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Starting measurement","ttl":"60","published_at":"2016-03-15T15:39:20.124Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Starting measurement","ttl":"60","published_at":"2016-03-15T15:39:24.130Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Starting measurement","ttl":"60","published_at":"2016-03-15T15:39:28.143Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Starting measurement","ttl":"60","published_at":"2016-03-15T15:39:32.160Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Starting measurement","ttl":"60","published_at":"2016-03-15T15:39:36.172Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Starting measurement","ttl":"60","published_at":"2016-03-15T15:39:40.178Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Starting measurement","ttl":"60","published_at":"2016-03-15T15:39:44.192Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Starting measurement","ttl":"60","published_at":"2016-03-15T15:39:48.197Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Starting measurement","ttl":"60","published_at":"2016-03-15T15:39:52.209Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Starting measurement","ttl":"60","published_at":"2016-03-15T15:39:56.225Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Starting measurement","ttl":"60","published_at":"2016-03-15T15:40:00.238Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Starting measurement","ttl":"60","published_at":"2016-03-15T15:40:04.769Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Starting measurement","ttl":"60","published_at":"2016-03-15T15:40:08.783Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Starting measurement","ttl":"60","published_at":"2016-03-15T15:40:12.788Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Starting measurement","ttl":"60","published_at":"2016-03-15T15:40:16.800Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}
{"data":"Starting measurement","ttl":"60","published_at":"2016-03-15T15:40:20.810Z","coreid":"xxxxxx-coreID-xxxxxxxxxxxxx","name":"log"}

As you can see, I have only one sensor on the bus for this test, and most of the times, the search fails…
The reason is certainly not bad connections or the pull-up resistor, because when I upload my other sketch for one sesor, it works perfectly every time!

Any idea?


#30

The search function in the OneWire library worked fine for me; that’s how I got the addresses of my 3 sensors. The code for that is in the Address_Scanner.ino file that is included with that library.


#31

I’m still trying to see why I get so many failed measurements with your library…
But this could be something:

Does this apply to sensors using parasitic power only?


#32

Nope it works with powered too, I noticed theres a fork of my lib on github where ATOMIC_BLOCK is added, so maybe others had issues with it, I will get that change merged back soon, but if you are up for it, you could fork it and import it privately.

I just tested 3 sensors, and while it works, I am not logging how many failed runs I get, just submits good runs to my server.


#33

Hi @MORA, thanks for checking that!
Actually I am not as experienced yet, that I have a github account.
(I’m only 62 and working in C++ since 1 year :older_man:)

I have no idea what this means:

I hope it’s not as explosive as it sounds :sweat_smile:

Currently, I’m testing with 3 sensors and still get a very erratic response:
The 3 sensors are not all reporting at the same pace and very unpredictible…

As some of my applications require quick response to temperature changes, it looks rather unusable right now… :disappointed:

I hope we can find a way to improve the reliability of readings.
Strangely, if I use the other sketch for one sensor, it works very reliable…


#34

Its not :smile:
https://docs.particle.io/reference/firmware/photon/#atomic_block-

onewire is by design a bit sensitive to timing, so wrapping the critical parts of the code in those tags means the photon wont interrupt the onewire routine messing up the signalling and causing an error.

Normally I dont care that a reading gets lost, since I get a new one in a few seconds, but obviously if every read fails it becomes a bit of a problem…

Which pullup resistor are you using, and are you powering the sensors from 5V or 3.3V ?
How much cable ?


#35

Oh I see! “Atomic block”… Interesting!

Here’s my set-up:

    Connections:
    Sensor  Particle
     ---------------
    Vcc     +5V (Vin)
    Gnd     Gnd
    DQ      D2

I am using 5V to power the sensors and put a 4k7 pull-up resistor between DQ (signal) and +5V


#36

Same setup as I use, you could try lowering the resistor.
I currently use 2.7k, but have used down to 1k in the past.

You can test the atomic block too, if you just use it in the main application, bit crude, but good for testing.

#include "ds18x20/ds18x20.h"
#include "ds18x20/onewire.h"

uint8_t sensors[80];

void log(char* msg)
{
    Spark.publish("log", msg);
    delay(500);
}

void setup()
{
    ow_setPin(D0);
}

void loop()
{
    uint8_t subzero, cel, cel_frac_bits;
    char msg[100];
    log("Starting measurement");    

ATOMIC_BLOCK() {
    DS18X20_start_meas( DS18X20_POWER_PARASITE, NULL ); //Asks all DS18x20 devices to start temperature measurement, takes up to 750ms at max resolution
}
    delay(1000); //If your code has other tasks, you can store the timestamp instead and return when a second has passed.

uint8_t numsensors;
ATOMIC_BLOCK() {
    numsensors = ow_search_sensors(10, sensors);
}
    sprintf(msg, "Found %i sensors", numsensors);
    log(msg);


    for (uint8_t i=0; i<numsensors; i++)
    {
        if (sensors[i*OW_ROMCODE_SIZE+0] == 0x10 || sensors[i*OW_ROMCODE_SIZE+0] == 0x28) //0x10=DS18S20, 0x28=DS18B20
        {
            //log("Found a DS18B20");
            int res;
            ATOMIC_BLOCK() {    
                res = DS18X20_read_meas( &sensors[i*OW_ROMCODE_SIZE], &subzero, &cel, &cel_frac_bits);
            }
            
			if (res  == DS18X20_OK ) {
				char sign = (subzero) ? '-' : '+';
				int frac = cel_frac_bits*DS18X20_FRACCONV;
				sprintf(msg, "Sensor# %d (%02X%02X%02X%02X%02X%02X%02X%02X) =  : %c%d.%04d\r\n",i+1,
				sensors[(i*OW_ROMCODE_SIZE)+0],
				sensors[(i*OW_ROMCODE_SIZE)+1],
				sensors[(i*OW_ROMCODE_SIZE)+2],
				sensors[(i*OW_ROMCODE_SIZE)+3],
				sensors[(i*OW_ROMCODE_SIZE)+4],
				sensors[(i*OW_ROMCODE_SIZE)+5],
				sensors[(i*OW_ROMCODE_SIZE)+6],
				sensors[(i*OW_ROMCODE_SIZE)+7],
				sign,
				cel,
				frac
				);
				log(msg);
			}
			else
			{
			    Spark.publish("log", "CRC Error (lost connection?)");
			}
        }
}
    delay(10000);
}

#37

Fantastic! Sounds good, I’ll test the “atomic block” straight away and if that’s not improving the reliability, I will try with smaller pull-up resistors.

Thanks for your great help!
:hand: :older_man:


#38

Wow! :open_mouth: What an ATOMIC improvement!!!
With your new sketch, I did not see a single misfiring at all…
No need anymore to experiment with different resistors.
Possibly I may need that tip when I start using longer wiring, we’ll see…

Well, the only thing I need to find now is how I can put these loop() commands in a function and populate variables with the name referring to the Sensor number: T1, T2, T3…

Thanks again for putting me on the right track @MORA!
:clap:


#39

Good, I will get the changes made in the lib in the weekend, so you and others wont need to do it in code.

Do you want to use the sensors locally or is it for sending to a site ?
For sending to a server I send the entire ID of the sensor (it wont change, its actually laser etched on the device in tiny letters), and then on the server I rename them, so its up to my server to map AABBCC… to “Kitchen”

If you want to use them locally, you can hardcode the addresses.
The command DS18X20_read_meas just needs a pointer to an array with the sensor address, so you could have arrays/defines for the sensor names.


#40

That would be great, thanks!

Here is the final sketch which works without a glitch, what a difference!
I put all commands in a separate function, so that I can keep the loop() clean for other tasks.

    /* Automatically detects and reads multiple DS18B20 "onewire" temperature sensors
    
    A library is used, ported to particle by @MORA:
    https://community.particle.io/t/multiple-ds18b20-with-photon/13332/26?u=fidel

    These are the ROM codes of my 3 sensors:
    Sensor# 1 = 28FF219F611503F9 (Waterproof wired sensor)
    Sensor# 2 = 10E96B0A030800AC (TO92 #1)
    Sensor# 3 = 10444E0B0308001F (TO92 #2)
    */
    
    #include "ds18x20.h"
    #include "onewire.h" // Note: Make sure also crc8.h library is present!
    
    
    
    void setup()
    {
      ow_setPin(D2); // Changed from D0 => D2
    }
    
    
    
    void loop()
    {
     collectTemp();
     delay(5000);// Was 10s
    }
    
    
    
    void collectTemp()
    {
      uint8_t sensors[80];
      uint8_t subzero, cel, cel_frac_bits;
      uint8_t numsensors;
      char msg[100];
    
      ATOMIC_BLOCK()
      {
       DS18X20_start_meas( DS18X20_POWER_PARASITE, NULL ); //Asks all DS18x20 devices to start temperature measurement, takes up to 750ms at max resolution
      }
    
      delay(1000);                                         //(was 1000) If your code has other tasks, you can store the timestamp instead and return when a second has passed.
    
      ATOMIC_BLOCK()
      {
       numsensors = ow_search_sensors(10, sensors);  // This line returns the amount of sensors found. First argument = limit of how many sensors you want (Was = 10). Second argument = a pointer to an array where the sensors will be stored.
      }
    
      for (uint8_t i=0; i<numsensors; i++)
      {
       if (sensors[i*OW_ROMCODE_SIZE+0] == 0x10 || sensors[i*OW_ROMCODE_SIZE+0] == 0x28) //0x10=DS18S20, 0x28=DS18B20
       {
        int res;
    
        ATOMIC_BLOCK()
        {
         res = DS18X20_read_meas( &sensors[i*OW_ROMCODE_SIZE], &subzero, &cel, &cel_frac_bits);
        }
    
        if (res  == DS18X20_OK )
        {
          char sign = (subzero) ? '-' : '+';
          int frac = cel_frac_bits*DS18X20_FRACCONV;
          sprintf(msg, "Sensor# %d (%02X%02X%02X%02X%02X%02X%02X%02X) =  : %c%d.%04d\r\n",i+1,
          sensors[(i*OW_ROMCODE_SIZE)+0],
          sensors[(i*OW_ROMCODE_SIZE)+1],
          sensors[(i*OW_ROMCODE_SIZE)+2],
          sensors[(i*OW_ROMCODE_SIZE)+3],
          sensors[(i*OW_ROMCODE_SIZE)+4],
          sensors[(i*OW_ROMCODE_SIZE)+5],
          sensors[(i*OW_ROMCODE_SIZE)+6],
          sensors[(i*OW_ROMCODE_SIZE)+7],
          sign,
          cel,
          frac
          );
          log(msg);
        }
        else
        {
          Spark.publish("log", "CRC Error (lost connection?)");
        }
       }
      }
    }
    
    
    
    void log(char* msg)
    {
      Spark.publish("log", msg);
      delay(500);// Was 500
    }

I want to use the temperature readings for the HVAC system locally, so that I can operate the relays with the same Photon.
It would be sufficient for me if in the function collectTemp() the same number of variables would be created as there are sensors.

Variable T1 would be the temperature of sensor 1 etc…
From there I can use these variables in the loop().

It would be great if you could give me some help to adapt this function to do this… :bow: