Multiple DS18B20 Zero Reading Error

Hi
I have a Raspberry Pi with four DS18B20 sensors, using an rpi-ds18b20 node triggered at one minute intervals. The sensors are wired in parallel and use one 4K7 pull up on the data line. Their cable lengths are all less then 2m.

All is fine for some hours but then one, sometimes two of the sensors start displaying zero temperature either permanently or intermittently (not possible given where they are mounted). Re-starting the flow restores "normal" operation.


The same four sensors have worked reliably, monitoring the same physical entities, via an Arduino for some years.

I've tried changing the 3V3 for sensor power and data pull up for 5V power, 3V3 pull up.
I have tried swapping the rpi-ds18b20 node for the ds18b20 node.
Using 'cat /sys/bus/w1/devices/xyz/w1_slave' shows the correct sensor temperatures, a debug node shows the ds18b20 node outputting zeros.
Neither 'cat /var/log/syslog' nor 'node-red-log' show anything untoward.

Any suggestions would be much appreciated!
Thanks
Derek

Welcome to the forum.

Tell us which ds18b20 node you are using, node-red-contrib-something probably and show us how you have configured it. Is the debug node right on it's output?

Hi Colin
Thanks for your reply.

The current node is 'node-red-contrib-ds18b20-sensor' (1.3.6) - it is labelled rpi-ds18b20.
The debug node is connected directly to the output of the rpi-ds18b20 node in parallel with a function node which processes the payload.
I'm using the default configuration of rpi-ds18b20 (topic = ""; array = true).

Screenshot 2020-11-20 162735
(If you would like so see the full node code, please let me know)

Also, if it helps-
Hardware: Raspberry Pi 3 Model B Rev 1.2
OS: PRETTY_NAME="Raspbian GNU/Linux 10 (buster)"
node -v: v12.19.0
npm -v: 6.14.8
-and attached is a debug capture of the node ds18b20 payload along with the command line output for 'cat /sys/bus/w1/devices/ xyz /w1_slave' taken (just about) simultaneously.
Capture.txt (1.1 KB)

Correction: If you would like so see the full flow code, please let me know

I can't quite parse that line, but don't put 5.5v anywhere near it when connected to a pi, you are likely to blow the input pin, or worse. If the cat command works at the same time as the node isn't then I don't know what is going on, particularly if two nodes are showing the same problem. Are you sure the cat is absolutely reliable and never shows 0? Perhaps it is some sort of timing issue.

I don't use either of those nodes as I use owserver for my 1-wire stuff, which sits between the kernel and node-red.

Looking at the code for node-red-contrib-ds18b20-sensor it is particularly odd as that node appears to just read the w1_slave file.
All I can suggest is that you edit the file ds18b20-node.js which you will find under .node-red/node_modules/node-red-contrib-ds18b20-sensor/ds18b20-node and sprinkle some log messages about. You can use this.warn("Some text"); to display variable contents in the debug pane. First convince yourself that the cat command never shows zero though.

Do you have any relay boards also connected/controlled with that PI?
DS18B20 sensors tend to turn themselves off when voltage spikes occur or something like that. And the wake up can only be done via power reset.
Switching relays may introduce such spikes. So if you do, that is one thing to investigate.

No relays...
Screenshot 2020-11-20 183403
Also tried moving Vdd line to 5V leaving pull up on 3V3.

Ok so in response to Colin, I have never seen a zero value returned from the cat command. Consequently, I created a function which exactly emulates the 'node-red-contrib-ds18b20-sensor'. It uses 'fs' (specifically 'fs.readdirSync' and ('fs.readFileSync') hoping that this might be more successful than using the DS18B20 node. Here is the function:

/* 
	DS18B20 function uses fs.readdirSync() method to get device list from system folders
	then reads 'devices' files using 'fs.readFileSync'

	REQUIRES the following to be added to 'settings.js':
	var fs = require("fs");
	functionGlobalContext: {
		fs   : require('fs')
	},
*/
const SensorFamily = '28';
const RootFolder = '/sys/bus/w1/devices';   // location of DS18B20 FolderList folders
var SensorReadings = [];
var FolderName;
var fs=global.get("fs");                    		// import the filesystem module
var FolderList = fs.readdirSync(RootFolder);		// get files / folders in RootFolder
//console.log('DS18B20 root folder contents: ' + FolderList);                               // DEBUG

// loop incoming folder array to get foldername beginning 'w1_' (used later as 'dir' in output array)
for (i = 0; i < FolderList.length; i++) {
	if (FolderList[i].substring(0, 3) == 'w1_') {
		FolderName = FolderList[i];
    	//console.log('DS18B20 foldername: ' + FolderName);                                   // DEBUG
		{ break; }
	}
}

// loop incoming folder array and process sensor folders
for (i = 0; i < FolderList.length; i++) {
	if (FolderList[i].substring(0, 3) == (SensorFamily +'-')) {
		// compile and read sensor file
		var FileName = '/sys/bus/w1/devices/' + FolderList[i] + '/w1_slave';
		try {
			//console.log('DS18B20 reading file: ' + FileName);                      // DEBUG
			var FileContents
			FileContents = fs.readFileSync(FileName, 'utf8');
			// console.log('DS18B20 FileContents length:' + FileContents.length);    // DEBUG
			if (FileContents.length !==0) {
				var TempPos = FileContents.search("t=");
				if (TempPos !== -1) {
					var SensorTemp = FileContents.substring(FileContents.search("t=") + 2) / 1000;
					// add new object to SensorReadings
					SensorReadings.push({
						family : '28', 
						id : FormatId(FolderList[i]),
						dir : FolderName,
						file : FolderList[i],
						temp : SensorTemp,
					})
				} else {
					// cannot find temperature string in file content
					console.log('DS18B20 temperature not present in file: ' + FileName);
					console.log(FileContents);
				}
			} else {
				// zero length file read!
				console.log('DS18B20 zero length sensor file returned: ' + FileName);
			}
		}
		catch (ex)
		{
			console.log('DS18B20 read function error for: ' + FileName);
			console.log(ex);
		}
	}
}
if(SensorReadings.length !== 0) {
	msg.payload = SensorReadings;
	return(msg);
}

return;

function FormatId(file) {
	var id = '';
	for (k = 0; k <= 6; k++){
		//var Byte = file.substring((file.length) - (2 * k), 2);
		var Byte = file.substr(file.length - (2 * k), 2);
		id = id + Byte;
	}
	return id.toUpperCase();
}

I dropped it into my flow and it worked fine for some hours, then I started seeing zero length files returned by 'fs.readFileSync'. When it failed, of the four sensor files read ('/sys/bus/w1/devices/' + + '/w1_slave'), the first permanently returned zero length, the second intermittently and the other two were fine - just like the 'node-red-contrib-ds18b20-sensor' that the function replaced! albeit the DS18B20 node returned a perfectly formatted object but with zero for the temperature value.

I then replaced the function with three nodes. The first is a function which uses 'fs.readdirSync' to build a list of sensor filenames and send them to a standard 'file in' node (Node Red in the 'storage' category). The 'file in' node reads the file (in place of the 'fs.readFileSync' function) and passes it to another function which outputs a single message for each file read in a 'node-red-contrib-ds18b20-sensor' like format. In short, three nodes replacing the original DS18B20 node.

[{"id":"35647b33.319794","type":"inject","z":"8369f339.da573","name":"1 Minute","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"60","crontab":"","once":true,"onceDelay":"10","topic":"","payload":"","payloadType":"date","x":120,"y":400,"wires":[["6d36625a.5e26fc"]]},{"id":"6d36625a.5e26fc","type":"function","z":"8369f339.da573","name":"Get Files to Read","func":"/* \n\tFunction uses fs.readdirSync() method to get device list from system folders\n\n\tREQUIRES the following to be added to 'settings.js':\n\tvar fs = require(\"fs\");\n\tfunctionGlobalContext: {\n\t\tfs   : require('fs')\n\t},\n*/\n\nconst SensorFamily = '28';\nconst RootFolder = '/sys/bus/w1/devices';   // location of DS18B20 FolderList folders\nvar FolderName;\nvar fs=global.get(\"fs\");                    \t\t// import the filesystem module\nvar FolderList = fs.readdirSync(RootFolder);\t\t// get files / folders in RootFolder\n//console.log('DS18B20 root folder contents: ' + FolderList);                               // DEBUG\n\n// loop incoming folder array to get foldername beginning 'w1_' (used later as 'dir' in output array)\nfor (i = 0; i < FolderList.length; i++) {\n\tif (FolderList[i].substring(0, 3) == 'w1_') {\n\t\tFolderName = FolderList[i];\n//    \tconsole.log('DS18B20 foldername: ' + FolderName);                                   // DEBUG\n\t\t{ break; }\n\t}\n}\n\n// loop incoming folder array and send sensor filenames\nfor (i = 0; i < FolderList.length; i++) {\n\tif (FolderList[i].substring(0, 3) == (SensorFamily +'-')) {\n\t\t// compile sensor filename\n\t    msg.filename = '/sys/bus/w1/devices/' + FolderList[i] + '/w1_slave';\n\t    msg.dir = 'FolderName';\n\t    node.send(msg);\n\t}\n}\n\nreturn;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":310,"y":400,"wires":[["c135d16a.8536e"]]},{"id":"c135d16a.8536e","type":"file in","z":"8369f339.da573","name":"Get Sensor File","filename":"","format":"utf8","chunk":false,"sendError":false,"encoding":"none","x":520,"y":400,"wires":[["8bf460c1.0a4c6","9db96fa3.6246e","eed5b91.6a1b248"]]},{"id":"9db96fa3.6246e","type":"function","z":"8369f339.da573","name":"Convert to Array","func":"\nvar SensorReadings = [];\nvar FileName = msg.filename.substr(20,15);\nvar FileContents = msg.payload\nif (FileContents.length !==0) {\n\tvar TempPos = FileContents.search(\"t=\");\n\tif (TempPos !== -1) {\n\t\tvar SensorTemp = FileContents.substring(FileContents.search(\"t=\") + 2) / 1000;\n\t\t// add new object to SensorReadings\n\t\tSensorReadings.push({\n\t\t\tfamily : '28', \n\t\t\tid : FormatId(FileName),\n\t\t\tdir : msg.dir,\n\t\t\tfile : FileName,\n\t\t\ttemp : SensorTemp,\n\t\t})\n\t} else {\n\t\t// cannot find temperature string in file content\n\t\tconsole.log('DS18B20 temperature not present in file: ' + FileName);\n\t\tconsole.log(FileContents);\n\t}\n} else {\n\t// zero length file read!\n\tconsole.log('DS18B20 zero length sensor file returned: ' + FileName);\n}\n\nif(SensorReadings.length !== 0) {\n\tmsg.payload = SensorReadings;\n\treturn(msg);\n}\n\nreturn;\n\nfunction FormatId(file) {\n\tvar id = '';\n\tfor (k = 0; k <= 6; k++){\n\t\t//var Byte = file.substring((file.length) - (2 * k), 2);\n\t\tvar Byte = file.substr(file.length - (2 * k), 2);\n\t\tid = id + Byte;\n\t}\n\treturn id.toUpperCase();\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","x":720,"y":400,"wires":[["7ed1a82f.831608","c8f8fdbf.89d52"]]}]

This seems to work just fine - I haven't had any reading errors for many days now! The downside is that it returns an object for each file rather than a single object for all sensors read, meaning more messages to send.

I don't know whether the problem is my implementation of 'fs.readFileSync', whether there is a problem with 'fs.readFileSync' or if the issue is something completely different. In any case, my problem is solved.

Apologies for the long ramble; apologies for the code quality (my skill level is 'Dangerous Amateur') and thanks to Colin and hotNipi for your replies.

I think that means that the files did not exist for the sensors. It might be interesting to put a check in your node to notify if there are not three files there (or something similar).

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.