Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

getDeviceCount() returns 0 #257

Open
vatsake opened this issue Nov 29, 2024 · 7 comments
Open

getDeviceCount() returns 0 #257

vatsake opened this issue Nov 29, 2024 · 7 comments

Comments

@vatsake
Copy link

vatsake commented Nov 29, 2024

Sometimes getDeviceCount() method returns 0 sensors.
If I use the method by parsdc, it gets correct count.

deviceCount=0;
sensors.requestTemperatures();
while (tempC[0] > (-127) ){
  tempC[0] = sensors.getTempCByIndex(deviceCount);
  deviceCount++;
}
deviceCount--;
@PhySix66
Copy link

My Solution to the Problem was to rename getDeviceCount(void) to getValidDeviceCount(void) and implement a new getDeviceCount(void) . I've done this simply for tracing down the original problem to the while (_wire->search(deviceAddress)) in begin(void) function. For some reason it simply doesn't work in the begin(void), but outside of it it's OK.
This is not a good(elegant) workaround, but as the meme goes: If it works -> DO NOT TOUCH!

// returns the number of devices found on the bus
uint8_t DallasTemperature::getDeviceCount(void) {
	
	uint8_t dev_cnt = 0;
	DeviceAddress deviceAddress;
	
	while (_wire->search(deviceAddress)) {
		dev_cnt++;
	}
	return dev_cnt;
}

// returns the number of devices found on the bus that are validated via CRC
uint8_t DallasTemperature::getValidDeviceCount(void) {
	return devices;
}

@tdwilson
Copy link

tdwilson commented Dec 30, 2024

I've been having trouble with getDS18count() on NodeMCU returning 0 when called in setup().

I have found five ways to make getDS18count() return the correct number instead of zero (see commented-out lines in code snippet below):

  1. The duplicated call to begin() recommended in getDeviceCount still doesn't work with ESP32s (ie, Issue 85 is not really closed) #168 (comment).
  2. Adding delay(0) (or any other number I tried) after (!) the call to getDS18count().
  3. Changing the printf to use Serial rather than lcd.
  4. Turning off optimisation just for the setup() function.
  5. In the loop() function of my sketch, when I use getDS18count() to display the temperature of however many of my three (genuine) DS18B20s I have connected, it always gives the correct result.

Hopefully this information will provide some clues, as I'm puzzled about what kind of issue could have such a variety of workarounds, and especially perplexed how changing code after the call to getDS18count() could affect its result! I'm also surprised that changing the optimisation level helps: I looked at the assembly output and the main difference seemed to be whether the n_devices variable was written back to memory or held in a register between the call to getDS18count() and the printf().

// Change to ("O0") [that's a capital letter O followed by zero] to fix getDS18Count()
#pragma GCC optimize ("Os") 
void setup() {
  Serial.begin(74880); // Default for NodeMCU
  delay(100);
  
  lcd.init();
  lcd.clear();         // Sets cursor to 0, 0
  lcd.backlight();     // Make sure backlight is on
  lcd.print("Starting");
  
  sensors.begin();     // Re-enumerates the bus.       
  // sensors.begin();  // Fixes getDS18Count()     
  uint8_t n_devices = sensors.getDS18Count();
  // delay(0);         // Fixes getDS18Count()
  lcd.setCursor(0, 1);
  lcd.printf("%hhu/%d devs", n_devices, MAX_SENSORS);
  // Serial.printf("%hhu/%d devs", n_devices, MAX_SENSORS);  // Fixes getDS18Count()
  delay(1000);
}
#pragma GCC optimize ("Os") 

@milesburton
Copy link
Owner

Thanks chaps. Let me investigate

milesburton pushed a commit that referenced this issue Jan 4, 2025
@PhySix66
Copy link

PhySix66 commented Jan 4, 2025

Adding delay(0) (or any other number I tried) after (!) the call to getDS18count().

This is most bizzar... getDS18count() is basicly a return(value) and it needs a call for delay() to work? (Not tested my self)
Just a thought: Can it be, that it has to do with the dual-core nature of the ESP32-S3?
Like Core 0 starts (or is in the process) of getting the data, while Core 1 already starts to do stuff with the unobtained data?
(Like drinking a glass of water, before puring it in the glass)

@milesburton
Copy link
Owner

My friend believes it could be a memory consistency issue. Hopefully he doesn't mind me sharing this email:

  1. Adding delay(0) (or any other number I tried) after (!) the call to getDS18count().
  2. Changing the printf to use Serial rather than lcd.

make it sound like memory consistency issues, which doesn't make sense for such a microcontroller. I don't have access to an lx106 compiler to check the assembly.

I thought it was a race condition but I don't have an IC to test at the moment. PR #259 could be our answer but could someone test it out for us?

@tdwilson
Copy link

tdwilson commented Jan 4, 2025 via email

@milesburton
Copy link
Owner

Hi Miles, If there is any way I can help (eg send you the complete code I am using with my ESP8266 / NodeMCU 1.0), please let me know. Kind regards, Tim

On Sat, 4 Jan 2025 at 12:10, Miles Burton @.***> wrote: Thanks chaps. Let me investigate — Reply to this email directly, view it on GitHub <#257 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABE6CIHPNCL2CJWMABRUV432I7FS5AVCNFSM6AAAAABSWQ7AYKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKNZRGI3DSNZXGA . You are receiving this because you commented.Message ID: </issues/257/2571269770@ github.com>

Hey Tim, that's very kind of you. Let me get PR #259 passing and if you could run that on your device and give it a sanity check that'd be awesome.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants