Multiple DS18B20 with Photon

The local one I have downloaded since the first day I get SparkIo. This local IDE doesn’t provide anything such as, import library or any option like this. The cloud based IDE is not doing anything with compiling when I was trying to compile it from Web IDE. When I use the example from the Web IDE, the Verify and Flash button is completely not clickable. There nothing associate with compiling

Spark Dev is a bit different from the Arduino IDE. It does support libraries and the way you use them is put them in the same folder as the .ino file. The thing that I learned the hard way is that the folder structure needs to be completely flat. You cannot have any other files in that directory or anything in sub-directories. Everything needs to be in the route of the project directory.

It works fine if you follow that process.

yes, I just find that out. Thank you.

When the Error message pop out, it doesn’t tells which file has error. How can we possible deal with this kind of error.

Got my photons recently and made an attempt at multiple ds18b20.
I didnt manage to do it with the current libs, just importing onewire library gives complie error.

So instead I spent some time porting the code I used on AVR, which went suprisingly well.

I will clean it up more over the weekend, but if you are desperate send me a message and I will post the work in progress :smile:

Published the library today under the name "DS18X20"
Github: https://github.com/MORA99/particle-ds18x20

Its a bit messy since its old C code, not a proper cpp class, if someone is up for the task of converting it that would be nice :slight_smile:

Thanks @MORA your implementation worked for me finally sigh.
I had tried all the other solutions for working with onewire and dallas temperature with my photon but i always run into some compilation error. This just worked. I have only one (DS18B20) so i’ve just tested it with one sensor. Thanks again.

That sounds similar to PoE way.

Mora,
I’m new to Particle Photon. I’ve successfully build several tests with X-Band motion detector, etc. so I’ve become relative comfortable with the Photon and most of the tools, like the IDE. But I’m now trying to implement your library for the DS18B20. (I’ve tried a couple of other implementations, but yours seemed the most current, used the Photon and I see from this thread that others have used them AND THEY WORKED!)

I’m having a problem with every library I’ve tried. I’m not seeing the DS18B20.
I got two DS18B20’s from Adafruit. I’ve tried both of them. I’ve connected the data lead from the DS18B20 through the 4K7 resistor that came with the sensor to D0 of my Photon. I’ powering my breadboard, Photon and DS18B20 with 4.72v.

My code is your onewire.cpp, unmodified.

Any help would be appreciated.
Ray

Your data line should be pulled high, so the resistor should go from data line on DS18B20 to either VIN or VCC on the photon.
And the datapin before the resistor should be connected to a photon digital pin.
GND to GND.

I generally dont use the parasitic power feature of the sensors, I always connect all 3 pins.

1 Like

I’ve got a small example explained over here. It’s only one sensor, but pictures are always nice to see how to hook one up :smile:

2 Likes

That got me running. I didn’t understand the hookup.

I appreciate to good work you’ve done, and the quick response.

Thanks!

Thanks! That got me up and running.

1 Like

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:

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?

2 Likes

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:

1 Like

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:

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:

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:

2 Likes

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