DS18B20 sensor by address on MKR 1010

Hello there

My board is a MKR wifi 1010 and I use 2 digital temp sensors DS18B20.

I need to access them by their 64 bits address because index look up fail when I disconnect one of them. My project is for 2 fermentation tank and I need to disconnect the probe when I wash the tank.

I have been able to get the addresses with an UNO easilly
I can't reach them on the MKR1010 under their addresses
I can reach them on the MKR 1010 under index lookup but I do not want to use this because of above issue...

I think I know where is the issue in the code but I do not know how to fix it...
In the UNO code, the words uint8_t and getTempC are blued as if they are recognized but are not blued in the MKR code.

I have read many post on that but cannot point the fix to apply. Pretty sure this is about the library and the board...

UNO code:

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

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

// Addresses of DS18B20s

uint8_t sensor1[8] = { 0x28, 0xE1, 0x6F, 0x96, 0xF0, 0x01, 0x3C, 0xC2 };
uint8_t sensor2[8] = { 0x28, 0xE0, 0xBA, 0x49, 0xF6, 0x44, 0x3C, 0x57 };

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

void loop(void)
{
  sensors.requestTemperatures();

  Serial.print("Sensor 1: ");
  float tempC1 = sensors.getTempC(sensor1);
  Serial.print(tempC1);

  Serial.print("Sensor 2: ");
  float tempC2 = sensors.getTempC(sensor2);
  Serial.print(tempC2);

  Serial.println();
  delay(1000);
}

MKR 1010 code:

// DallasTemperature - Version: Latest 
#include <DallasTemperature.h>

#include <ArduinoIoTCloud.h>
#include <Arduino_ConnectionHandler.h>
#include "thingProperties.h"


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

#define ONE_WIRE_BUS 8

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

// Addresses of DS18B20s
uint8_t sensor1[8] = { 0x28, 0xE1, 0x6F, 0x96, 0xF0, 0x01, 0x3C, 0xC2 };
uint8_t sensor2[8] = { 0x28, 0xE0, 0xBA, 0x49, 0xF6, 0x44, 0x3C, 0x57 };

#define R1 7
#define t1 8

#define L2 11
#define R2 9
#define t2 10

float hist = 0.5;
float temp_Min_1;
float temp_Min_2;
float temp_Max_1;
float temp_Max_2;

int L1 = 6;

bool toggle1;
bool toggle2;


void setup() {
  //initialyse Serial
  Serial.begin(9600);
  delay(500);
  
  //initialyse sensors
  sensors.begin();
  
  //initialyse relay
  pinMode(R1, OUTPUT);
  pinMode(R2, OUTPUT);
  
  //initialyse LED
  pinMode(L1, OUTPUT);
  pinMode(L2, OUTPUT);
  
  toggle1=false;
  toggle2=false;

  // Defined in thingProperties.h
  initProperties();

  // Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);

  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();
}


void loop() {
  ArduinoCloud.update();
  
  bool requestTemperaturesByAddress(const uint8_t*);
  // sends command for one device to perform a temperature conversion by index
  //bool requestTemperaturesByIndex(uint8_t);

  // returns temperature raw value (12 bit integer of 1/16 degrees C)
  //int16_t getTemp(const sensor1);
  
if (toggle1){
  
  t1 = sensors.getTempC(sensor1);
  digitalWrite(R1,HIGH);
  Serial.println(set_temp_1);
  Serial.println(temp_Max_1);
  Serial.println(temp_Min_1);
  Serial.println(t1);
  Serial.println();
  delay(1000);
  }
  else{
    digitalWrite(R1,LOW);
  }
}

void onOnoff1Change()  {
  
  if (onoff1) {
    digitalWrite(L1,HIGH);
    toggle1=true;
  } else {
    digitalWrite(L1,LOW);
    toggle1=false;
}
}
void onOnoff2Change()  {
}

void onSetTemp1Change()  {
 temp_Max_1 = set_temp_1 + hist/2;
 temp_Min_1 = set_temp_1 - hist/2;
}

void onSetTemp2Change()  {

}

Welcome to the forum.

There are a few things to do.

  1. Could you scroll up and change the title of this topic ? The sensor is called a DS18B20. You might be the only one in the world that has shortened it to DS18.
  2. Tell us where you bought your DS18B20. It is probably counterfeit. The counterfeit sensor do not work well with low temperatures or above 70°C or with parasite power or with 3.3V.
  3. Do you have a normal 1-Wire bus with three wires ? What is the value of your pullup resistor for the 1-Wire bus ?
  4. Make a small test sketch, remove everything that is not related to the problem. Remove all the relay and cloud things.
  5. Look at a few examples: https://github.com/milesburton/Arduino-Temperature-Control-Library/tree/master/examples. They mostly do the same. The common command "sensors.requestTemperatures();" is used instead of "requestTemperaturesByAddress();". I suggest you do the same.
  6. Show us your test sketch.
  1. LOL, I forgot the full name of the probe and forgot to change the title after I found it.
  2. Those are from Gikfun through Amazon. temp range used for those is 10ºC to 90ºC. Seems OK to me based on my process. They are powered with 5V on the MKR1010.
  3. They came with a custom board with the pullup res. I have tested them and direct wiring with 4.7kohms
  4. Already did that, works 100% on UNO and 0% on MKR1010
  5. Thanks for the link, I'll use a 2 pin wiring and search by index instead.
  6. I'll upload the 2 pin sketch later

You answers raises more questions.

Can you give a link to the modules that you bought ?
What temperature range do you actually use in your project ?

If you power the module with 5V, then there is current from 5V into the digital pin of a processor running at 3.3V. That is not okay. It is better to use 3.3V for everything with a 3.3V board.

Have you read this about your board:

Always use 3 wires for the 1-Wire bus. The parasite power with two wires will probably not work with a counterfeit DS18B20 and 3.3V.

There is no need to use "by index".
The "sensors.requestTemperatures();" starts reading the temperatures, and then you can get the temperature for each sensor with its address.
Just like this example: Multiple.ino
I think that is the same as your sketch for the Uno.

You sketch for the Uno uses a different method than the sketch for the MKR WiFi 1010 and the line "bool requestTemperaturesByAddress(const uint8_t*);" is a bug. I think you are making it too hard for yourself. Always follow the KISS rule.

Try using OneWire.h Library

//12-bit default resolution; external power supply

#include<OneWire.h>

OneWire ds(10);     //Sensor Data line is connected with DPin-10
byte addr1[8];         //to hold 64-bit ROM Codes of DS1
byte addr2[8];        //to ho;d 64-bit ROM-code DS2
byte data[9];        //buffer to hold data coming from DS18B20
float celsius;

void setup()
{
  Serial.begin(9600);
  ds.reset();
  ds.search(addr1);  //collect 64-bit ROM code from sensor (DS1)
  ds.search(addr2);
}

void loop()
{
  probe1();
  delay(2000);
  probe2();
  delay(2000);
}

void probe1()
{
  //----------------------------
  ds.reset();       //bring 1-Wire into idle state
  ds.select(addr1); //slect with DS-1 with address addr1
  ds.write(0x44);    //conversion command
  delay(1000);   //data ready withinh DS18B20 or poll status word
  //---------------------------

  ds.reset();
  ds.select(addr1);  //selectimg the desired DS18B20
  ds.write(0xBE);    //Function command to read Scratchpad Memory (9Byte)
  ds.read_bytes(data, 9); //data comes from DS and are saved into buffer data[8]
  //---------------------------------

  int16_t raw = (data[1] << 8) | data[0]; //---data[0] and data[1] contains temperature data : 12-bit resolution-----
  celsius = (float)raw / 16.0;  //12-bit resolution
  Serial.println(celsius);
}

void probe2()
{
  ds.reset();       //bring 1-Wire into idle state
  ds.select(addr2); //slect with DS-1 with address addr1
  ds.write(0x44);    //conversion command
  delay(1000);   //data ready withinh DS18B20 or poll status word
  //---------------------------

  ds.reset();
  ds.select(addr2);  //selectimg the desired DS18B20
  ds.write(0xBE);    //Function command to read Scratchpad Memory (9Byte)
  ds.read_bytes(data, 9); //data comes from DS and are saved into buffer data[8]
  //---------------------------------

  int16_t raw = (data[1] << 8) | data[0]; //---data[0] and data[1] contains temperature data : 12-bit resolution-----
  celsius = (float)raw / 16.0;  //12-bit resolution
  Serial.println(celsius);
}

isn't the #include onewire.h in start of the sketch enough?

MKR1010 have a 5v pin and the previous setup worked fine but was limited. I just wanted to rewrite it to be able to turn on&off one tank and let the other run.
I'm not sure about the voltage on the I/O but the setup was not burning!

I bought the module on Amazon: Amazon.ca

There is always 3 wires... 5V, ground and signal. I'm not sure how you can make work a 3 pin sensor with only 1 wire...

As I said, and this is the subject of this post, reading by address returns no data unlike index can..

Edit: I read about the counterfeit probe and probably get them: "If the ROM does not follow the pattern 28-xx-xx-xx-xx-00-00-xx then the DS18B20 sensor is a clone" the addresses I have are not on this pattern. this may be the issue...

Line "bool requestTemperaturesByAddress(const uint8_t*) is probably wrong at some points and was more a test to understant the behaviour of this. I have a couple of project done and still outside of comfort zone! this is the way I learn.

Also, as I'm new on the forum, I read some point you should maybe re-read too...
https://forum.arduino.cc/faq

The "1-Wire" is the name for the bus: https://en.wikipedia.org/wiki/1-Wire. So yes, that is three wires :wink:

Please use 3.3V.