DS18B20 Sensors not found after update to PlatformIO/VSCode

Continuing the discussion from Apologies - Multi-file project help:

All was working fine but…Updates to PlatformIO and VSCode have burnt another week in trying to resolve why my stable code will no longer work. This is the 4th time I’ve had to resolve update issues destroying the build process. That said, now my previously functioning code for Dallas 18B20s wont recognise any sensors, no erros, just wont see any sensors. If I use a library example all is good but my head just isn’t into trying to re-work my original code, I simply can’t see the issue.

I have a resources.h file:

#ifndef RESOURCES_H
#define RESOURCES_H
#endif
#ifndef ARDUINO_H
#define ARDUINO_H
#endif

#include "OneWire.h" 
#include <Wire.h>
//#include <Wire.h>
#include <SPIFFS.h>
#include <ArduinoJson.h>
#include <NewPing.h>
#include <DallasTemperature.h>
#include <ezTime.h>
#include <elapsedMillis.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>   
#include <Adafruit_INA260.h>
#include <HTTPClient.h>
#include <ESPAsyncWebServer.h>
#include <AsyncTCP.h>
#include "ESPmDNS.h"
#include <ESPAsyncWiFiManager.h> 
#include <WiFiUdp.h>
#include <CircularBuffer.h>                              
#include <BME280.h>
#include "connectivity.h"
#include "display.h"
#include "weatherData.h"
#include "temperature.h"
#include "depth.h"
#include "ina260.h"
#include "weatherData.h"
#include "json.h"                                             
#include <Tone32.h>
#include "dbActions.h"

// Define variables here
#define BUZZER_PIN 13
#define BUZZER_CHANNEL 0
#define TRIGGER_PIN  32             // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN    33              // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 300            // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm
#define ENHANCED ;                                    // Nextion Display defined as ENHANCED version
#define RXD2 16
#define TXD2 17 
#define ldrPin 36
#define dispShortDelay 1000
#define splashDelay 6000
#define disScrChange 4000
#define tsDelay 5;
#define ntpLookup 30;                                  // NTP Lookup schedule in minutes (code converts to seconds and millis)

extern OneWire oneWire;                             //
//#define ONE_WIRE_BUS 04                             // Wont work in Temperature.cpp or .h
//#define TEMPERATURE_PRECISION 9                     // Set DS18B20 resolution to 9 bit

extern String apiKeyValue;

extern String criticalErrCode;
extern bool configReqd;
extern unsigned long emdMETAR;
extern unsigned long emdOwm;
extern unsigned long emdThingSpeak;
extern unsigned long emdUpdateDisplay;
extern unsigned long emdReadSensors;
extern unsigned long emdUpTimeCheck;
extern unsigned long emdInsertSensorData;
extern String upTimeStr;
extern int reBoots;
extern String sysMessage;

extern String product;
extern String Platform;
extern float HWRevision;
extern String framework;
extern float version;
extern String vdated;

extern String serialNo;                             // Holds the unique unit serial number
extern String tempSymbol;//

extern float tempProbePOffset;
extern float tempProbeFOffset;
extern float tempProbeAOffset;

extern bool inSetup;                                // Are we in Setup.  Used to show failure/success initialisation messages
extern bool updateFirmware;

extern bool bmeT;
extern bool bmeH;
extern bool bmeP;
extern bool depthFail;
extern int wifiSig;

extern String owm_name;      
extern String owm_ctry;  
extern String owm_loc;                              // OWM User configured location i.e. Used to form the REST API request
extern String owm_country;                          // OWM User configured country i.e. Used to form the REST API request
extern String owm_units;

extern int depthAlarm;                              // Variable indicating the depth at which the alarm will sound
extern int alarmState;
extern String alarmMessage;

extern int errorCount;
extern bool errorFound;                             // High level identifying that there is an error somewhere
extern String errorCode;                            // Use the error codes below to populate.  High level capture of errors, use specific sub-codes to identify exact sensor/device


// Declare Function here

String convertEpoch (long epochTime, String formatType);
            //void readHistoryFile (void);
            //void updateJson(void);
            //void checkUpTime(void);

String readPondTemp(void);

void genTone(String toneType);

A Temperature.h file:

#ifndef TEMPERATURE_H
#define TEMPERATURE_H

#include <Arduino.h>

#define ONE_WIRE_BUS 04
#define TEMPERATURE_PRECISION 9

//Declare variables here
extern float tempProbeA;                             // DS18B20 Temperature variable for probe 1 (Upper)
extern float tempProbeP;                             // DS18B20 Temperature variable for probe 2 (Lower)
extern float tempProbeF;                             // DS18B20 Temperature variable for probe 3 (Filter Pack)  
extern float tempProbeACal;                        // Probe 1 Float value as integer for Google Charts
extern float tempProbePCal;                        // Probe 2 Float value as integer for Google Charts
extern float tempProbeFCal;                        // Probe 3 Float value as integer for Google Charts

//bmeTempOffSet makes up the last value we need for calibration


//Declare Functions here
int discoverOneWireDevices();
void readOneWireTemperatures(int type);
void checkTempRecords (void);
void resetTempRecords (String group);
//void updateHistory(String element, float value);
void tempCal (int n);                      // From the Nextion read, this takes the value 1 to 8 and adjusts the offset for that probe

#endif

and a temperature.cpp file:

#include "resources.h"

// Error Codes
#define DEVICE_DISCONNECTED_C -127
#define DEVICE_DISCONNECTED_F -196.6
#define DEVICE_DISCONNECTED_RAW -7040

int numberOfSensors = 0;                          // 1 Wire number of Sensors
float tempProbeA = 0;                             // DS18B20 Temperature variable for probe A (Spare)
float tempProbeP = 0;                             // DS18B20 Temperature variable for probe P (Pond)
float tempProbeF = 0;                             // DS18B20 Temperature variable for probe F (Filter Pack)  
float tempProbePCal = 0;
float tempProbeFCal = 0;
float tempProbeACal = 0;

extern OneWire oneWire(ONE_WIRE_BUS);

DallasTemperature sensors(&oneWire);              // Create an instance of DallasTemperatures called 'sensors'

int discoverOneWireDevices(void) {
    
  byte i;
  byte data[9];
  byte addr[8];
  int count = 0;
  sensors.begin(); 
  sensors.setResolution(9);
  Serial.print("Looking for 1-Wire devices...\n\r");
  while(oneWire.search(addr)) {
    Serial.print("\n\rFound \'1-Wire\' device with address:\n\r");
    for( i = 0; i < 8; i++) {
      Serial.print("0x");
      if (addr[i] < 16) {
        Serial.print('0');
      }
      Serial.print(addr[i], HEX);
      if (i < 7) {
        Serial.print(", ");
      }
    }
    if ( OneWire::crc8( addr, 7) != addr[7]) {
        Serial.print("CRC is not valid!\n");
        return 0;
    }
    count ++;
  }
  Serial.print("\n\r\n\rThat's it.\r\n");  
  Serial.print("Number of Sensors ");
  numberOfSensors = count;
  Serial.println(count);
  delay(1000);
  
  if(numberOfSensors == 0){
    Serial2.print(String("pgInitialise.t9.txt=\"Fail"));
    errorFound = true;
    errorCode = "DS18";
;  }else{
    Serial2.print(String("pgInitialise.t9.txt=\""));
    Serial2.print(String("OK * "));
    Serial2.print(numberOfSensors);    //Serial2.print(String("pgSplash.txtHWVerDate.txt=\"" + vdated + "\""));    
  }
  nexFinish();
  //delay(2000);
  sensors.requestTemperatures();
return numberOfSensors;
}

void readOneWireTemperatures(int type){                                   // Type: 1 = Poll sensors, 2 = Assign values, 0 = In Setup (so do both Poll and assign)
  errorCount = 0;                                                         // Ensure the error counter is zero'd
  if (type == 0 || type == 1){
      sensors.requestTemperatures();                                      // Global Poll of all sensors on teh bus
      Serial.println("Requesting temperatures:");    
      Serial.println("Done!");
  }
  if (type == 0 || type == 2){
      // Read each of our sensors and print the value
      Serial.println("I am assigning the temp values to the associated variables");
      for (int i = 0; i < numberOfSensors; i++) {                                           // Request temperatures from the number of sensor we discovered (See discoverOneWireDevices)
        Serial.print("Temperature for Device ");
        Serial.print( i );
        Serial.print(" is: ");
        Serial.println(sensors.getTempCByIndex(i) );                                        // Why "byIndex"? You can have more than one IC on the same bus. 0 refers to the first IC on the wire
        if (i == 0) {    
            if(sensors.getTempCByIndex(i) <= -55 || sensors.getTempCByIndex(i) >= 70 || sensors.getTempCByIndex(i) == DEVICE_DISCONNECTED_C) {   // If a reading was unsuccessful
              Serial.println("DS18B20 Probe 1 temperature is OUTSIDE of limits");
              errorCount = errorCount++;
              errorCode="TP1"; 
            }else{              
              tempProbeP = sensors.getTempCByIndex(i) ;
              tempProbePCal = tempProbeP + tempProbePOffset;                                // Accounts for the offset set by User - Default is 0.0
              delay (10);                                                                   // Small delay to give time for the result to be received
              Serial.print("DS18B20 Probe 1 temperature is in limits and reading: ");
              Serial.println(tempProbeP);
            }
        }
        else if (i == 1) {    
            if(sensors.getTempCByIndex(i) <= -55 || sensors.getTempCByIndex(i) >= 70 || sensors.getTempCByIndex(i) == DEVICE_DISCONNECTED_C) {   // If a reading was unsuccessful
              Serial.println("DS18B20 Probe 2 temperature is OUTSIDE of limits");
              errorCount = errorCount++;
              errorCode="TP2";
            }else{
              tempProbeF = sensors.getTempCByIndex(i) ;
              tempProbeFCal = tempProbeF + tempProbeFOffset;                                // Accounts for the offset set by User - Default is 0.0
              delay (10);                                                                   // Small delay to give time for the result to be received
              Serial.print("DS18B20 Probe 2 temperature is in limits and reading: ");   
              Serial.println(tempProbeF);       
            }
        }
        else if (i == 2) {    
            if(sensors.getTempCByIndex(i) <= -55 || sensors.getTempCByIndex(i) >= 70 || sensors.getTempCByIndex(i) == DEVICE_DISCONNECTED_C) {   // If a reading was unsuccessful
              Serial.println("DS18B20 Probe 3 temperature is OUTSIDE of limits");
              errorCount = errorCount++;
              errorCode="TP3";
            }else{
              tempProbeA = sensors.getTempCByIndex(i); 
              tempProbeACal = tempProbeA + tempProbeAOffset;                                // Accounts for the offset set by User - Default is 0.0
              delay (10);                                                                   // Small delay to give time for the result to be received
              Serial.print("DS18B20 Probe 3 temperature is in limits and reading: "); 
              Serial.println(tempProbeA);             
            }
        }
       } 
      checkTempRecords();                                                 // You may need this in each sub-section above??
  }
return;
}

I have rebuilt the platformio.ini file to the new libraries (required to repair the PlatformIO/VSCode installation, they are different and so I have tried to downgrade to the previous libraries but that hasn’t worked either.

platformio.ini is:

t[platformio]
default_envs = esp32dev-16Mb

[env]
monitor_speed = 9600
lib_deps = 
	robtillaart/ACS712@^0.3.1
	paulstoffregen/OneWire@^2.3.7
	bblanchon/ArduinoJson@^6.19.4
	teckel12/NewPing@^1.9.6
	milesburton/DallasTemperature@^3.11.0
	ropg/ezTime@^0.8.3
	pfeerick/elapsedMillis@^1.0.6
	adafruit/Adafruit Unified Sensor@^1.1.7
	adafruit/Adafruit BME280 Library@^2.2.2
	adafruit/Adafruit INA260 Library@^1.5.0
 	alanswx/ESPAsyncWiFiManager@ ^0.23
	ottowinter/ESPAsyncWebServer-esphome@ ^1.2.7
	rlogiacco/CircularBuffer@^1.3.3
	lbernstone/Tone32@^1.0.0
	ayushsharma82/AsyncElegantOTA@^2.2.7

[env:az-delivery-devkit-v4]
platform = espressif32
board = az-delivery-devkit-v4
framework = arduino

[env:esp32dev-16Mb]
platform = espressif32
board = esp32dev
framework = arduino
board_build.partitions = default_16MB.csv
board_upload.flash_size = 16MB
monitor_rts = 0
monitor_dtr = 0

Any help would be appreciated as I don’t want to have to re-write the functions in totality just because of an upgrade, it happens too often.

Here’s hoping for some help :slight_smile:

Take the simplest possible example OneWire/DS18x20_Temperature.ino at master · PaulStoffregen/OneWire · GitHub and the simplest possible platformio.ini for your target board. Does it see a sensor?

Yes it does, it sees all 3 attached and responds with their address and temperatures. I know I should rewrite from the example but it’s sole destroying to have working code stop working and compile issues taking a week to resolve.

I’m just blind as too why it’s stopped working

Usually the extern declaration only declares type and name, this looks like it’s calling a constructor? Which file has the OneWire oneWire(ONE_WIRE_BUS); line?

Careful with leading 0 in a numeric constant, they make C/C++ interprete it in octal (base 8). In this case octal 4 is decimal four though, so no problems.

Is it using the same pin between the previous example and you code?

Are there any pieces of code using GPIO4?

It’s weird seeing the higher-level objects (“sensors”) being initialized before the lower level ones (oneWire) to me. Especially since the DallasTemperature::begin() method has

So it already does a search, and before the search it does _wire->reset_search(); (with _wire being the onewire object given to it in the constructor). I however don’t see a call to

oneWire.reset_search();

between sensors.begin() and oneWire.search()…

1 Like

Apologies, away from the PC at the moment. Thanks for the 04 prompt, I’ll remove and remember for the future. The pin hasn’t changed for 3 years and there’s nothing else using it.

I forgot to add the main.cpp. it calls the discover function once in Setup, I always have 3 sensors and once in loop I only call for temperature readings. Because I don’t want to re-search I don’t call it again as I’ve assigned three previously found sensors in order against their physical placement and associated variables.

Looks like I need to have a good read of your response and pick the order of things apart