rwaldron / johnny-five

JavaScript Robotics and IoT programming framework, developed at Bocoup.
http://johnny-five.io
Other
13.27k stars 1.76k forks source link

Reading more than two DS18B20 - 1-Wire device read timeout #1665

Open saksholm opened 4 years ago

saksholm commented 4 years ago

Board: Arduino Mega 2560 R3 (original) J5 version: 1.4.0 Node.js version: 12.16.1

In my project, I need a lot of thermometers and facing an issue when trying to read more than two sensors. It does not matter if I try to read sensors from one pin (with addresses) or one pin per sensor. Tried couple of weeks now to investigate this issue, read almost every single thread that I found. Tried at least tens of different ConfigurableFirmata versions and scenarios.

Basic tests are done by writing the app directly to the board and everything works. So hardware (board and sensors) works.

Error what I got is:

events.js:200
      throw er; // Unhandled 'error' event
      ^

Error: 1-Wire device read timeout - are you running ConfigurableFirmata?
    at Timeout._onTimeout (/Users/Saksi/work/saksi/heatpump-node/node_modules/firmata-io/lib/firmata.js:1632:16)
    at listOnTimeout (internal/timers.js:531:17)
    at processTimers (internal/timers.js:475:7)
Emitted 'error' event at:
    at EventEmitter.<anonymous> (/Users/Saksi/work/saksi/heatpump-node/node_modules/johnny-five/lib/thermometer.js:237:24)
    at Timeout._onTimeout (/Users/Saksi/work/saksi/heatpump-node/node_modules/firmata-io/lib/firmata.js:1632:7)
    at listOnTimeout (internal/timers.js:531:17)
    at processTimers (internal/timers.js:475:7)

I have no more ideas about how to resolve this issue.

dtex commented 4 years ago

This has come up before. Here is a long thread that discusses possible culprits and solutions. It doesn't look like it was ever resolved. It could be anything in the stack (Johnny-Five, firmata.js, or configurableFirmata). I don' thave any DS18B20's (or even any other one-wire devices) to try this with. Could you post a minimal example that recreates the bug in case we can get someone to give it another shot?

saksholm commented 4 years ago

@dtex here is repro: https://github.com/saksholm/1wire-j5-problem-repro just npm install && node index.js ofc you have to change pins to match yours. version is one sensor per pin.

If you comment out these lines, you won't get an error: https://github.com/saksholm/1wire-j5-problem-repro/blob/master/repro.js#L14 https://github.com/saksholm/1wire-j5-problem-repro/blob/master/repro.js#L35-L43

I also read that #1115 issue and didn't get any clues. Maybe I have read it again if I find something that I don't already test.

this problem prevents me from continuing the heat pump controller project: https://github.com/saksholm/heatpump-node

dtex commented 4 years ago

Thanks. I've got some DS18B20's on the way. Hopefully, somebody else will be able to try this out before I can get to it.

dtex commented 4 years ago

My sensors arrived today. I'll try and reproduce tonight. Any updated information?

saksholm commented 4 years ago

@dtex nothing new. I hope you find something that helps

dtex commented 4 years ago

Hi @saksholm

I've got good news, bad news and then a little more good news...

Good news part 1: I was able to recreate the issue immediately. This is good news because we avoid the whole "works on my computer" scenario and it helps me with debugging.

Bad news: I think this is an issue with Firmata or Arduino's utlity/onewire running on the Arduino, not Johnny-Five, which means we may have to enlist others to get it fixed. I'll recreate a test case that uses just firmata.js and create an issue over there.

Good news part 2: I've got a workaround. If you wait just a bit (100ms for me) between the initialization of the different onewire components, everything works fine.

saksholm commented 4 years ago

Hi @dtex

Firstly, I want to thank you for your effort on this issue. I don't see any bad news in this case right now because there is a workaround to get this all work.

I tested mine setup with 6pcs DS18B20's successfully. Just added timeouts between initials as you mentioned in your workaround.

I'm not sure is there something to really need to be changed in J5 or firmata.js. Ofc maybe some easy improvement is to use buffer/array when adding more sensors at a time and it's automatically handling delays/sync in the initial phase. Or if not any changes... maybe some instructions to docs how this kind problem can be avoided.

Super excited that I can continue my project :)

saksholm commented 4 years ago

One side effect is still appearing. I have a 2004 LCD with a PCF8574 controller.

It works well if I write some initial text only. If I add some 10-sec interval it works 1-10 times totally random time very well and then the screen is full of random characters :D Program keeps running and I think everything else is ok, but there is still some I2C/OneWire related issue.

Initialising like that:

new five.LCD({controller: "PCF8574", rows: 4, cols: 20});

Not sure if there are some options to test.

dtex commented 4 years ago

Does the screen work fine if you don't have your OneWire stuff running? Is there anything else besides the DS18B20's and the PCF8574?

saksholm commented 4 years ago

@dtex The screen seems to work if I disable OneWires. I put some 200ms interval run counter and screen not "crash". The refresh rate is not perfect but it still works.

After that test, I enabled only one DS18B20 sensor and screen crashes immediately.

saksholm commented 4 years ago

And yes, only DS18B20 and PCF8574. Nothing else.

dtex commented 4 years ago

I have a PCF8574AT, but need to dig up a Mega to try it all out on. Not enough RAM on an Uno to use I2C and OneWire side-by-side.

dtex commented 4 years ago

Well, I have one at home but it's cooked. The rest are at my local hackerspace which I can't get into until this Covid-19 mess blows over. I'll see if I can't order one and have it delivered.

dtex commented 4 years ago

I've ordered a Mega, not sure how long it will take but hopefully, it will be here soon.

saksholm commented 4 years ago

The saga goes on, 17 hours and 14pcs OneWire DS18B20 and total 54 crashes :/ So the issue is not gone totally away. The average time between those crashes is ~18mins.

So, that is the result of running my larger app. Next, I'm going to run again with a simpler repro app but the same amount of sensors.

Is there any simple way to inspect how much board has free memory?

Here is some logged data from one of sensors:

Screenshot 2020-03-31 at 18 29 41

Drops is crashes

saksholm commented 4 years ago

a simpler version also crashes after ~16-23mins constantly.

saksholm commented 4 years ago

I tested this.

Board reporting: available memory: 4718. It does not vary, so I guess that is not a memory issue on board.

saksholm commented 4 years ago

Tried to extend timeout times from 5000ms to 10000ms on firmata.js... same results. It would be nice to help to debug this issue more. Any tips to try?

dtex commented 4 years ago

Wow, that's a lot of DS18B20's! I have two thoughts:

1) This almost certainly has something to do with the oneWire implementation in configurableFirmata or the Arduino libraries which means this issue should probably move to that repo. To test this, the smart (but somewhat tedious) thing to do would be to recreate a minimal test case that does not use Johnny-Five or firmata.js but not many people are going to have enough oneWire devices or the free time to recreate this problem which means you're kinda on your own here. It may even turn out that firmata just can't handle this many oneWire devices and this is an impractical approach (see thought 2)

2) That is a lot of DS18B20's, and maybe trying to attach them all to one Mega running firmata isn't the way to go. I'd explore creating a DS18B20 I2C backpack, then you could just use standardFirmataPlus and you won't have to worry about running firmata and the oneWire code on the same microcontroller.

mariusnorheim commented 3 years ago

Just wanted to give some input on this as I'm getting a similar error on my project; The issue seems to relate to DS18B20 and all sensors using the SCL/SDA port. I only have one DS18B20 but also a SHT31D temp/humidity sensor running and i initially thought the SHT31D was causing the issues as it would sometimes become unresponsive before throwing this error.

Could it be related to system architecture or drivers? I've run tests spanning over a week continuously on my Win10 development machine and it has never thrown this error. As soon as the project was transferred to my Raspberry Pi with ubuntu 64bit arm running the code this error is frequent.

My bachelor thesis is riding on this project and delivery is in less than two weeks, might have to skip out on using the DS18B20 sensor to save it but that would be less than ideal.

dtex commented 3 years ago

@mariusnorheim Are you using an Arduino connected to your Pi, or are you using the Pi's GPIO via raspi-io?

mariusnorheim commented 3 years ago

@dtex I'm using Arduino with ConfigurableFirmata. When browsing I came across this and tried to separate my single sensor variable for temp/rh that was using the Multi API into two separate using Thermometer and Hygrometer APIs with seemingly favorable results.

The system has been up and running for a few hours now, whereas it would crash fairly frequently before. I probably misattributed this to account for all SCL/SDA sensors when it seems to have been the Multi API causing issues in my case.

dtex commented 3 years ago

I'm glad things are running better, and thanks for isolating this. That should make it easier for someone to solve.