-
Notifications
You must be signed in to change notification settings - Fork 18
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
Issue with DS18B20 on D1 Mini not found, dependent on trivial changes to flow #93
Comments
I have done some more testing, and determined that the symptom remains absolutely consistent.
I can see that it is getting to this code, but the search is not finding any sensors.
then the search does correctly find the sensors. Moving that line up to before the for loop causes it to fail again and it shows the length as zero. Is anyone able to confirm what I am seeing? |
Surely mysterious. I did a bunch of work recently with the DS18X20 on ESP32 without a problem. The I/O is completely different on ESP8266, and much more sensitive to timing variations. But that doesn't explain your observations. Stupid questions:
|
I only have one sensor connected at the moment, it always returns 1 when it is working and 0 when it isn't. I think I have another sensor somewhere I will dig it out and wire it up. Disabling Wi-Fi does not appear to make any difference either way. |
Thanks for trying.
I wasn't clear. I was suggesting to try something like this: trace(`search: ${this.#bus.search().length\n`);
trace(`search: ${this.#bus.search().length\n`);
trace(`search: ${this.#bus.search().length\n`);
trace(`search: ${this.#bus.search().length\n`);
trace(`search: ${this.#bus.search().length\n`); |
Bingo!
Then if I remove all the wires in the flow I get, consistently
or if I add back the first wire I get all 1s
and if put all the wires back then
So it is looking as if maybe there is a time window during which it works, and small changes move the window about. One thing I have just realised is that, since the ds18b20 node is not the first one started, parts of the flow are already running while this code is running, so that may be part of the reason for the variation in the symptom. |
Wild. I guess the question is, "what closes the window?" |
When the stuff going on in the background in the other nodes finishes? Or starts? No idea really. |
ESP8266 is cooperatively multitasked -- there's really just one thing running at a time and it cannot be swapped out. And there are just two tasks -- the project and Wi-Fi. An interrupt can take time, of course, but there's not much running there either (Wi-Fi is the main one, but you said turning that off didn't make a difference). |
This is just ridiculous. I went back to the situation with just the first two wires in the flow connected, and I get (as I did yesterday)
If I comment out the last two
So commenting out the last two lines affects what the earlier lines do. There needs to be some understanding of how that can be. |
Could this be something to do with
and now I get 100% success, whatever I do with the flow (so far anyway). I don't understand how though, the trace calls will affect the timing of the second and later searches, but I don't see how it could affect the result of the first search. Also I think that takes us back to the unmodified file (except for the forEach line) which itself did fail consistently on the first (and only) search. |
Hi @colinl ! |
Hi @ralphwetzel |
'been using low resistor values with DS18B20's for over a decade, however, always with 5V. They certainly work down to 2.7K or even 2.2K pull-up resistors IIRC and the low values are beneficial for long lines. The 3.3V could produce issues, though, because that means the internal capacitors that power the chips don't get nearly as much charge. The issue this causes could also very well be 100% repeatable because certain bus transactions require more power for the DS18B20 to send its data to the bus master. So it could run out of power consistently when it reaches a specific transaction. |
[quote] Are you sure about that? Opinion appears to be divided over the issue. I don't want to blow the chip up. I am having great difficulty seeing how that could give the sort of issues I am seeing here, where changing the code in the lines following the bus access changes the result of the search. |
I'm sure the Moddable folks would be happy to send you a couple of spare esp8266's, that's less money than about 1-2 minutes of their troubleshooting time in salary ;-). Using a 3.3K pull-up you're only putting 0.5mA into the pad, that's pretty much in the noise. WRT how later lines could influence earlier ones... The code gets executed from flash, which comes in pages/lines that get cached. The processor only really executes from cache. So changes in code size can cause "distant" code to be split across cache lines where they formerly fit into a cache line. That can cause bus transactions to have delays introduced, or timings to be missed. The one-wire bus distinguishes 1's and 0's using the timing of an edge, that timing generation/measurement could be off due to cache misses depending on how it's implemented in the SDK. I'm not saying that any of this is the real reason for what you observe, I'm just providing some ideas for how changes in later code can affect earlier code... Happy troubleshooting ;-) |
OK, I have tried it with 5V and it doesn't appear to have made any difference. |
I have updated node-red-mcu and Moddable to pick up stack handling improvements as described in #90 and the symptoms have changed somewhat. Now not only does the search succeed or not dependant on unrelated changes to the flow or code, but also whether the temperature read succeeds or not depends on the flow configuration. Again it is repeatable, a flow that works always seems to work, and one that doesn't work, always does not work. |
Thanks for trying the latest. I didn't expect it would help here, but this problem is mysterious enough that nothing would surprise me. My best guess at the moment is that this is a timing related bug. The OneWire stuff is very timing sensitive. On ESP32, the driver uses the RMT hardware block to achieve very precise timing. That block doesn't exist on ESP8266, so it uses synchronous GPIO with delays. The implementation is disables interrupts while doing that to avoid interference. But, there could be a bug or some timing that's just enough on the edge that some subtle environmental factor is tipping it. Comparing successful and unsuccessful transitions with an oscilloscope, as you propose, would confirm that. I didn't write the OneWire stuff, so I'm not familiar with the details. I can take a look. My DS18B20 hardware is at the office (and connected to an ESP32 from our FOSDEM demos!), It'll be a day or so before I can get that to try. FWIW – I'm assuming that this isn't a consequence of some bug in the XS JavaScript engine. I can understand why you might draw that conclusion from some of the evidence. My experience is that XS is (very) deterministic and conformant. There's a lot of testing and real-world experience to back that up. There could always be an undiscovered bug, of course, but it feels unlikely here to me. |
I am inclined to agree with you. The fact that it is manifesting itself in several different ways makes it much more likely it is a bus timing issue as you suggest. |
When you find time to look at this, could you check it with more than one sensor too please? I find that when I add a second sensor it only finds one of them. They both work individually. |
That's an interesting addition. Good to know that it is 99.99% reliable with one sensor. I only have one sensor connected in my set-up at the moment, so I'll probably start there. But, understood. I have a couple ideas about what might not be optimal based on reading some other 1 Wire implementations (most relevant is the Arduino implementation). Even with a single sensor, I can try to more closely match their behavior and confirm it still works. |
I finally had a chance to look into this. You'll be pleased to know it failed for me even with a single sensor. ;) I believe the reason for your intermittent failures was a good, old-fashioned uninitialized variable. That said, the DS18B20 sensors I ordered recently didn't work without some other changes. They do work on ESP32, which is where I tested this originally. I made changes to our ESP8266 implementation to match the Arduino OneWire library more closely and everything is working smoothly for me with two sensors connected. All the changes are local to owb_gpio.c. I don't have a clean solution yet to commit, but if you'd be willing to give it a try to see if it is in the right direction, I'll post it. |
Yes, please post the file and I will give it a try. |
At my first attempt it isn't working, but I have had a busy day and brain fade has set in, so I may well have messed it up. I will have another go tomorrow. |
Sure, thanks. Long week here too. There is something different between our set-ups. Based on what I saw, I'm a little surprised it ever works for you. There are some parameters we can adjust if it doesn't work for you as-is. |
FWIW – I updated the gist to revert to using the original timings. They are what Maxim recommends and are notably different from the Arduino implementation. No idea why. Since the Maxim values worked for you, maybe that will help. With the Maxim values, my two sensor set-up still works. |
Bad news I am afraid. I went back to the latest moddable checkout ( Fri Mar 3 14:31, 746d1378311d), rebuilt moddable, did a mcconfig clean make and rebuild and with just one sensor confirmed that I have a working flow that finds the sensor. I then replaced owb_gpio.c with the version from the gist, rebuilt moddable (though in fact I don't think that is necessary for changes to this file is it?), mcconfig clean and rebuild and it doesn't find the sensor. I even removed everything else from the flow except the ds18 node,, including the mqtt config node and built it without without wifi and it still doesn't find anything. I have about a metre of cable on my sensor, but that should be nothing for a ds18b20. |
@colinl – that is vey mysterious. It is extremely reliable in finding both sensors here. Let us simplify a bit. Would you try running the OneWire example outside of Node-RED? That would make experimenting a little easier.
You main need to change the pin number in the manifest to match your set-up: "config": {
"onewire": {
"pin": "4"
}
},
Correct. You should only need to replace owb_gpio.c and build with mcconfig (no clean needed before). I expect that the example will give the same OneWire result as running the flow. I updated the gist to add a few traces (using Once you have that result, try changing the call to modGPIOInit(driver_info->bus.config , NULL, pin, kModGPIOInput) ...and re-running. Does that change the traces? Thank you. |
With the new gist it says Changing the Init line to an Input appears to fix the problem, it works both with one and two sensors. |
Excellent! Thanks for running those tests. We're circling in on a solution. I'll probably have a change or two more to ask you to try in coming days to try to wrap this up. |
I modified modules/pins/digital/esp/modGPIO.c to more closely match the Arduino ESP8266 settings. The main difference is the initializing of the open drain flag on inputs, which is noteworthy because 1Wire requires open drain. So.... the owb_gpio.c stays as you have it -- initializing the pin to kModGPIOInput. Try the modGPIO.c, please. In theory everything should just work the same for you. It works reliably here. But... there's clearly something different about our set-ups so anything is possible. Thank you. |
Working well still with new modGPIO.c |
OK! One last change to try. This backs out the direct register modifications in owb_gpio.c. While slightly more efficient and precise on timing, it is also not at all portable. If this still works for you (fingers crossed), I'll clear out the commented-out code and commit. Thanks again. |
I am confused. The gist linked to appears to be modGPIO.c, not owb_gpio.c. |
Apologies. owb_gpio.c is further down the page. Here's the direct link for that. |
Oh yes, I didn't look down there. |
Actually I think we have gone backwards with this one. I am seeing regular mis-reads of the sensor - the family and id are correct coming out of the node but the temperature is null. Also one of my D1 Minis, with its own sensor, appears to be intermittent finding the sensors. Can you put back the previous version of that file (sorry, I should have kept a copy) so I can check that it really is that file causing the problem, and not the phase of the moon or something similar. |
The Gist maintains all the old versions. Just click "revisions" in the top-left corner to see them. Use the "..." menu on the right of each file to select "View File" to get the full copy. |
Sorry about the delay, I have had to do some lengthy testing to try to work out what is going on. |
Scrub my previous comment, I think the latest gist is ok, at least at the moment. I had a screw loose, literally, though at some points I was beginning to wonder whether it was metaphorically. |
Aargh! Perhaps I have got a metaphorical screw loose. It is failing again. There must be a pattern here, but I haven't convinced myself what it is yet. |
An update before I give up for the night. I don't think there is any noticeable difference in performance between the previous owb_gpio.c (with the modified line at the end - output to input) and the latest gist. Two of my sensors work perfectly as far as I can tell. The third one seems to have marginal timing when measuring. It is always found okin the initial search, but sometimes the read returns It could be a dodgy sensor, there are apparently a lot of clone devices out there, but it has been working for years, in parasitic mode, attached to a 1-wire dongle with several other sensors. |
The drama! One question (you may have answered already, apologies). You mention parasitic power. I don't believe I'm doing that. Would you share your wiring diagram so I can try to reproduce that? Regarding xsbug, if anything I would expect the environment to be more friendly without xsbug as it eliminates serial traffic. |
I haven't been trying to use parasitic mode on the ESP device, I don't know whether one would expect to be able to use parasitic on 3.3V, I suspect not. I use it in a system where I have a 1-Wire dongle, which has a 1-wire chip in it. I didn't have much choice but to use parasitic as I wanted to re-use existing tv aerial co-ax distributed through the house, as a 1-wire bus. I was amazed when it all worked perfectly. With parasitic one has a pullup from the signal to Vcc as normal, but only the signal and 0v are fed to the sensors. At the sensor, the 0v and Vcc connections are both connected to ground, which tells the device to power itself from the signal lead when it is quiescent, I think. |
Probably I should try and build an arduino sketch reading the sensors and see how well that works. I haven't done that before though, so will need to do some research first. |
I found an old sketch I had used with the sensors, I had forgotten that I had done that. I ran it all night and it did not fail once! So there must be a difference still. |
OK! Let's try to close the loop on some of this. I've committed the GPIO and 1-Wire changes. While perhaps imperfect, they are an overall improvement. This will propagate out to the Moddable SDK on GitHub in the next day. Having read several 1-Wire implementations, including the Arduino code, and the Maxim app note, I think the updated implementation is consistent with the requirements there. Regarding the failures when not using xsbug, I would like to understand that scenario more completely. There should be no physical coupling between the serial pins and the 1-Wire pin. When you say you run without xsbug, could you explain the differences between the two runs? For example, is it still a debug build or is it an instrumented or release build? What is connected to the serial TX and RX pins? Is the device powered in a different way? Thank you. |
I have two sensors connected to the D1 Mini, connected to a USB port on the laptop, running the flow below. I built and ran it with -d so that it opens xsbug and the debug is shown there, and I can see that sometimes one of the sensors returns an object with temp set to null. During the time of the chart the laptop was not being used for anything else, in fact there was no-one in the room except when I went in to shut down xsbug.
|
In addition there is the fact that it runs 100% solid using the arduino codeon the same hardware, so presumably there must be a timing diffference there, or an issue with pin mode or something similar. |
Well, that is interesting. I have updated to the latest moddable code and also node-red-mcu and it has been running for a couple of hours without a glitch. I will leave it running and see what happens, but it is looking hopeful. Why my previous build showed the problem I don't know, I had checked several times that I was using what I thought was the latest version of the files from the gist. |
Having just checked, I see that the new version of $MODDABLE/modules/drivers/onewire/esp/owb_gpio.c is not the same as the version in the gist, so perhaps that is the explanation. |
I am happy it is solid now, I haven't had any reading failures in 24 hours so I will close this. |
@colinl - I'm only just getting back to this thread. I was traveling and my DS18B280 hardware was a few hundred miles away. I'm happy to see things are working well for you! In staring at the code for the 37th time, I noticed a potential issue in how the GPIO driver (modGPIO) transitions to output. Normally it wouldn't matter, but for a 1-wire protocol it could look like noise. There's some more work to solve the that correctly in all cases, related to this issue EcmaTC53/spec#35. I'll get to that in time. Once I do, it will allow the GPIO 1-wire implementation in owb_gpio to work on hardware beyond ESP8266 (like Raspberry Pi Pico and another port we have brewing). Anyway... many thanks for your help in tracking this one down. Great to have this level of reliability now. |
OK. Let me know when the changes are done and I will check it out with my hardware. |
Have you had a chance to look at this yet? I am again seeing issues on some sensors, that come and go with apparently unrelated changes to the flow, such as adding a debug node. |
The work I mentioned above shouldn't have a visible impact. It is architectural. At the moment, the code in owb_gpio.c bypasses the code that would generate the noise by using I believe the only significant difference from the Arduino implementation at the moment is the timings for some of the 1-wire states. The values use match the recommendations from Maxim for broadest compatibility. We had tried the Arduino implementation's numbers at one point, but that didn't seem to make a difference. I'm happy to put that back as an option, if you'd like to give it a try. |
The attached simple flow, with an inject node driving a DS18B20 node and on to a function node and MQTT Out, works correctly. The Wemos D1 Mini has a DS18B20 connected in the normal manner, 0V, 3,3V and GPIO4, with a 3k3 pullup resistor.
However, if I delete the wire to the MQTT node then the sensor is not detected. Using xsbug I can see that the bus search in rpi-ds18b20.js does not find anything. With the wire connected I can see that it does find the device, so I am looking at the right code. Making other trivial changes to the flow can also change whether it is found or not. I have done enough experimenting to be confident that it is not an intermittent hardware problem. The attached flow works every time and with a flow that does not work then it never works.
This makes absolutely no sense to me, and it has taken a lot of playing to convince myself that it is really happening, but I am convinced.
The text was updated successfully, but these errors were encountered: