I’m trying to communicate with DS18B20 sensors. I get completely unreliable results.
sensors.getDeviceCount() returns 0 or 1, never more, regardless of how many sensors I have attached.
sensors.getAddress(device0, 0); returns correct addresses maybe 25% of the time. Otherwise the addresses are usually partial or zero.
Calls to sensors.getTempCByIndex(0) work, regardless of the result of the getDeviceCount() call, and return non “-127” values about 10% of the time.
Note: I have tried this with several sensors, both alone and with multiple sensors on the bus. Other than attempting to capture the actual line level signals, I am not sure what the problem is.
Attaches is a pic from my scope. The signal looks pretty good.
I have the argon on a breadboard, plugged into my PC (the power line looks stable, compared to a wall wort power signal).
I have VUSB and GND connected to the red/back lines on the breadboard, and a pull up resistor from the red to D0 (I have also used D7 to see the light blink).
I then use BB patch cables to connect to DIN mount temrinal blocks, and I have the sensors leads tied appropriately together to all the leads (5VDC in parallel, GND in parallel, DATA in parallel).
Code:
// This #include statement was automatically added by the Particle IDE.
#include <OneWire.h>
// This #include statement was automatically added by the Particle IDE.
#include "DallasTemperature.h"
// Setup a oneWire instance to communicate with a OneWire device
//#define ONE_WIRE_BUS D2 //GPIO 15 for bus
OneWire oneWire(D0);
// Pass our oneWire reference to Dallas Temperature sensor
DallasTemperature sensors(&oneWire);
// This #include statement was automatically added by the Particle IDE.
//#include <DS18B20.h>
// using Dallas Temperature instead
int numSensors = 0; //Number of found sensors
//int intSensors = 0;
DeviceAddress deviceList[10]; //Array of found device addresses
DeviceAddress device0, device1;
String DeviceString = "INIT"; //Formatted String of devices
String buffer = "";
double temp1=0;
double temp2=0;
double temp=0;
SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(SEMI_AUTOMATIC);
void setup(){
Particle.variable("DeviceString", buffer);
Particle.variable("numSensors", numSensors);
Particle.variable("temp1", temp1);
Particle.variable("temp2", temp2);
Particle.connect();
delay(1000);
sensors.begin();
numSensors = (int)sensors.getDeviceCount();
// for (int i=0; i<10;i++){
// sensors.getAddress(deviceList[i], i);
// buffer = buffer + "0x"+formatDeviceAddress(deviceList[i])+"; ";
// }
sensors.getAddress(device0, 0);
sensors.getAddress(device1, 1);
buffer = "NumSensors: " + String(sensors.getDeviceCount()) + "; ";
buffer = buffer + "0x"+formatDeviceAddress(device0);
buffer = buffer + ";\n0x"+formatDeviceAddress(device1);
}
void loop() {
//sensors.requestTemperatures();
//Added for debugging, to try and trigger resets in the loop; didn't help, didn't make it worse
//sensors.begin();
//sensors.getAddress(device0, 0);
//sensors.getAddress(device1, 1);
//buffer = "NumSensors: " + String(sensors.getDeviceCount()) + "; ";
//buffer = buffer + "0x"+formatDeviceAddress(device0);
//buffer = buffer + ";\n0x"+formatDeviceAddress(device1);
temp = sensors.getTempCByIndex(0);
if (temp != -127) {temp1 = temp;}
temp = sensors.getTempCByIndex(1);
if (temp != -127) {temp2 = temp;}
//delay(1000);
delay(5000);
}
String formatDeviceAddress(DeviceAddress deviceAddress){
String tempString = "";
for (int j=0; j<8;j++){
if (deviceAddress[j] < 0x10) {
tempString = tempString + "0" + String(deviceAddress[j], HEX).toUpperCase();
} else {
tempString = tempString + String(deviceAddress[j], HEX).toUpperCase();
}
}
return tempString;
}
Seems like the pin is still OK, as I am still sending receiving good data. But just in case, I moved to a totally different pin, and moved Vcc to 3.3V.
Still very unreliable. This code never sees more than one serial number, and it’s inconsistent as to which one shows up. For testing, I also cut down the lead on two of the sensors, from 3m down to 0.5m. No change. I also tried different resistors, from 300Ohm (too small) to 100kOhm (too large). No change.
(Scope sill looks good)
Next I am gonna rewrite the code to specify the serial numbers. But I’ll still have to have some search routine just to find them. Grrr.
I have now tried the multidrop example with two sensors and a 2k2 pull-up resistor on D2 and I do get some good readings.
Not nearly as reliable as on a Photon but still some valid readings (once the ROM ID was obtained correctly - which is a bit tricky )
You should read the Dallas/Maxim app note in this earlier posting. In particular I recommend using the resistors shown and something like the FET pull-down in Appendix A. You are asking for a lot of capacitance to be driven by that IO pin.
You may also want to try slowing down the software side to give more time since a few of the pulses in your scope picture are pretty short.
Just for completeness, I think you might want to pick up a Maxim DS18b20 from DigiKey or Mouser, just to be sure you have an authentic part to test with.
The last time I hooked an Adafruit DS18B20 waterproof sensor to a Photon, I saw some similar behavior, where I would get random, totally wrong temperature results maybe 25% of the time. I seem to recall seeing something about this “somewhere” a while back. That project ended up getting shelved because the fish tank I was going to use it with no longer has any fish, but I was going add range checking to my code and just throw out stuff that was way out of bounds.
Quick note: DS18B20 lib is unreliable, at least in the SingleDrop (One sensor on the signal line) mode.
IT has some defects that return invalid results in some-to-many power-on results.
Absolutely. Not here to complain, but rather to help improve.
I’ll report back the results. Do you have a link to the new lib I can perhaps view on GitHub? Away from my Particle devices.
That was my take as well on my several-year old Electron 3G – all worked well there.
0.1.0 didn’t seem to make much difference, sadly.
I do see some difference between individual 18B20’s: Fresh out of the bag, some work really well (1 CRC error on 20 reads), others seem to have The Plague (1 good read out of 10 or so CRC’s).
As @Jeppedy said, want to help diagnose / be part of the solution rather than loudly complain.
I don’t see any mention of good supply bypassing on the 18B20. That would be good to try to clean up the device output. Using a moderate electrolytic along with a good mylar.
Saying “BYPASS” I was referring to the VCC or VDD, not a data or signal pin.
I played around, and could not get reliable readings at all. Maybe what looked like accurate readings 1/25.
The routines to search for serials only returned two correct serials ONCE over an hour of playing. Mostly it returned nothing, about 10% of the time it returned one of the two.
Once I had the serials, I used getTemperature(SERIAL) to return data. I didn’t dig into the code, but it returned an error most of the time, BAD data some of the time, and good data maybe 10% of the time. BUT when I disconnedted one of the sensors, BOTH calls to different serials would return data from the single sensor on the bus- that is, the disconnected sensor call did not return an error if the good one returned data. It actually returned GOOD DATA that appeared to be from the remaining sensor.
So this is unreliable.
Also, I get that there may be some issues with just using a single pull–up… however I read through the discussion, and all the signals on the scope look good. None of the issues they discuss, and the signal appears to mimic what looks like a good signal, even with 2 sensors on the bus… and if I can’t get this working with just one…?
So maybe it’s my sensors. These are a batch of cheap ones off amazon. I may buy a couple of the IC packs and try again.
Hi,
I had a similar problem with an older Photon device and fixed it by putting a SINGLE_THREADED_BLOCK() { sensor request code goes here } around the sensor read requests. This seems to stop interrupts during the sensor request code.