Understanding the OneWire code

Continuing the discussion from Photon Maker Kit - DS18B20 - temperature sensing issues/questions:

I’m working on a temperature sensor logger. It will have 3 different thermocouples, but I’m going to keep them on individual digital pins (because I don’t want to bother with figuring out how to get the right one out of the “onewire” setup).

I’m having trouble understanding the code here:

What do the two lines “OneWire oneWire(tempSensorPin);” and “DallasTemperature sensors(&oneWire);” do? And for that matter, what are “oneWire” and “sensors” when it’s all done?

#include "OneWire/OneWire.h"
#include "spark-dallas-temperature/spark-dallas-temperature.h"

double tempC = 0.0;
double tempF = 0.0;
int tempSensorPin = D2;

OneWire oneWire(tempSensorPin);
DallasTemperature sensors(&oneWire);

void setup() {
    sensors.begin();
    Particle.variable("tempc", tempC);
    Particle.variable("tempf", tempF);
}

void loop() {
  sensors.requestTemperatures();
  double tempCheck = sensors.getTempCByIndex(0);
  
  if ( tempCheck > -50 && tempCheck < 50) // might want to guard against a spurious high value as well
  {
    tempC = tempCheck;
    tempF = tempC * 9.0 / 5.0 + 32.0;
  }
  delay(1000);
}

This is what’s known as instantiation of an object.

These lines call the constructors of the classes referenced by the first part of the line and the second part will be the object “variable” to access the so constructed (by use of the provided construction parameters inside the parentheses) object.

To understand what the difference between a class and an object/instance is, what a constructor does and how to use objects you may want to get some C++ primer literature.

So, essentially:

OneWire oneWire(tempSensorPin);

says there’s a thing attached to a certain sensor pin that we’ll call “oneWire” and we build/communicate with it by following the procedure in the “OneWire” library.

and DallasTemperature sensors(&oneWire);

says there’s a temperature sensor (or many) attached to the “oneWire” that we’ll call “sensors” and it will be built/communicated with following the procedure in the “DallasTemperature” library.

Is that vaguely correct?

So to do multiple, my code would look like this:

OneWire oneWire_0(tempSensorPin);
OneWire oneWire_1(tempSensorPin);
DallasTemperature sensors_0(&oneWire_0);
DallasTemperature sensors_1(&oneWire_1);

void setup() {
    sensors_0.begin();
    sensors_1.begin();
    Particle.variable("tempc", tempC);
    Particle.variable("tempf", tempF);
}

void loop() {
  sensors_0.requestTemperatures();
  sensors_1.requestTemperatures();
  double tempCheck_0 = sensors_0.getTempCByIndex(0);
  double tempCheck_1 = sensors_1.getTempCByIndex(0);
  
  delay(1000);
}

Roughly speaking yes, but in order to have multiple OneWire objects you’d want each of them tied to its own pin.
The way you got it there the one and only pin used wouldn’t care which object is controlling it and hence you would always talk to both hardware sensors just the same.

Got it. Yeah, that was a typo in my quick example. My plan is 3 pins, 3 sensors, 3 completely separate objects handling it all. Thanks for your help.

int tcouple_pin0 = D0;  // Pool Water, Thermocouple 0
int tcouple_pin1 = D1;  // Pool Water, Thermocouple 1
int tcouple_pin2 = D2;  // Pool Air,   Thermocouple 2

OneWire oneWire_0(tcouple_pin0);
OneWire oneWire_1(tcouple_pin1);
OneWire oneWire_2(tcouple_pin2);

DallasTemperature tCouple_0(&oneWire_0);
DallasTemperature tCouple_1(&oneWire_1);
DallasTemperature tCouple_2(&oneWire_2);