-
Notifications
You must be signed in to change notification settings - Fork 106
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
Added reset() function #78
Conversation
Thank you for contributing. A couple items:
|
Thanks for your answer.
Actually, I don't seem to have those problems, at the time of writing the PR it took something between 20 minutes and about 5 or 6 hours to crash. |
I correlate this issue with this failure: esp8266/Arduino#1025. the wire library for esp32 use a fix: espressif/arduino-esp32#678 to make the library more failsafe, we should check the Wire.requestFrom return value. |
I mean the addition of "WriteRegister(RESET_ADDR, RESET_VALUE);" into Initialize() before ReadChipID() is the best solution. However, there is a more serious problem with a temporary failure or sensor power drop-out, or even by replacing the BME280 sensor. Actually for example after sensor power dropout (after NAN values ended) some constant unrealistic values are read forever. These phenomena need to be detected and begin() must be called repeatedly (possibly with a hidden reset) automatically. ReadTrim() could usually be omitted. |
@coelner, is there ever a situation when you would not immediately call bme.begin() after calling reset? Can you give me a use case of something you might want to do in between reset and begin? |
@jirkaptr the problem with this is the reset requires a wait time, which limits how the user can use the sensor. Is it the libraries responsibility to detect this, or is it the users responsibility? What if the user wants to handle it a certain way, the library shouldn't dictate the recovery steps. |
@finitespace resetting other devices without starting this one. Especially if we reset all devices because there was a hickup at the bus. IMHO the library should be user-friendly, there-fore integrate a failover procedure. But this should be defined at the begin() call as opt-out. But I can understand the easyness of jirkaptr recommendation. |
@coelner, you would want to call reset on other devices before calling begin on the bme? What purpose would that serve? |
@jirkaptr, I didn't quite follow the second part of your post. I don't think it is within the scope of the library to detect a replacement of the sensor. If you are replacing the sensor, you should probably be resetting your controller and everything should be initialized from scratch. Temperature failure and power dropout I can get on board with. I am not seeing these failure states in the datasheet. @coelner if we check the return from requestFrom and it returns false, you think the library should automatically reset the device? |
@yanbec Do you have the possibilities to use a logic analyzer with the i2c bus? I'm not sure about this bug A generic reset call within the begin() seems to be a good idea and leads to a defined starting point. |
Hey! In my opinion, a sensor library should enable the user to communicate with a device in an easy way. If a problem with the communication or the device itself occurs, this should not be masked or handled (automagically) by the library. That way, it gets way harder for the user to find the root cause of the problem. Same applies for error handling, replacing sensors or power dropouts. If you don't know about it, you can't solve it. By the way, thanks for the vivid discussion, I wasn't really expecting this much interest in a single line of code ;) |
Probably I'm involved by many years of work in the industrial area, with huge systems usually running continuously. The need to push RESET is there one of the most horrible things. However so strict requirements may not be applied for Arduino. I like the saying "In simplicity is power and beauty". It is nice to have a small but widely usable SW modules. Here the matter is (only) about the library, over which has to be built application (7 layers ISO model...). The library cannot be designed to cover the needs or wishes of a wide spectrum of applications and applicators. It should only provide the tools for creating higher layers of SW. Cannot be used to interfering with outside of its own device (e.g. in a crash on the I2C bus). Why to have or not to have a alone-standing function or automatic reset()?
In any case, the library has to detect and report the problem with the sensor and it must be easy to use it. In that I agree fully with @coelner. In other words, it is necessary to generate a STATUS that shall be published. How to deal with this status? Either human or machine operator processes it, as shown above. Error detection is already possible, and it is easily reached via the function(s) returned value. Primitive error detection plus an automatic solution represents the loop while( !bme.begin()){ Record it! + Do something! } located in the setup(). A somewhat drastic example of the status is the measured value equal to NAN. I like the idea of checking the return value of the Wire.requestFrom() or so. @finitespace, maybe replacing of BME280 on the fly is not on the agenda, but (repeated) calls bme.begin() allows you to change the sensor because it calls ReadTrim() and sets all registers. @finitespace, @coelner, @yanbec, automatic immediate reset is dangerous due to likely cycling while an error continues. In any case, it is necessary to provide the error report to a higher layer of the program! Brief conclusion:Detection of errors should be implemented in the library. How the higher SW layer (or human user) treats the detected error is its/his thing and responsibility (logger, visualized/sent message or lamp, manual or automatic attempt to recover). To call bme.begin() is usually necessary because the considered reset() is not powerful enough. If someone wishes to have special features that go beyond the usual features of the library, he/she should create them individually on his/her repository. |
Alright, so I think it is on the user to handle the error, but the library can detect it. In this regard it looks like the function returns NaN on read error. To remedy having to check for NaN, I am gathering that an interface change is necessary to have readData return a boolean. Are any of the other functions used (hum, press, temp)? Should the interface be changed for them with a reference to the value and a boolean return? Or should they just be removed? I don't see any reason for begin not to be called on reset, so I will add it to the reset function. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add the begin call after the delay and submit again?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the most effective will be, when @yanbec makes changes in his repository. No additional forking and pull requests will be needed. (I have not write access permissions to his repository)
Reset() should return a bool, received from begin() respectively from Initialize(). (Initialize() is the only effective content of the begin()).
Begin() becomes a subset of reset().
Hi! //edit: @finitespace |
Related issue # and issue behavior
I didn't create a related issue, because my problem has probably it's root cause not with this library, but is in fact an electronic problem. I have one of the BME280 chips in combination with an CCS881 connected to a NodeMCU-Board. While developing a working library for the CCS chip (the existing ones just don't work for me), the BME sometimes just kind of crashed and returned one or more values as "nan". Rebooting the ESP didn't help.
Description of changes/fixes
To overcome this issue I looked up the documentation and found that the possibility of to reset the chip isn't currently implemented in this lib. So I took care of it ;)
@mention a person to review
Maybe @finitespace wants to take a look? Of course, I appreciate every comment.
Steps to test
(Alternative: begin(), reset(), begin(), see if it's still running)
Any outstanding TODOs or known issues
I don't know, maybe you prefer to put the necessary begin()-call into the reset()-function, I just implemented what the function name says it does. In my opinion that's a matter of taste.
Best regards,
Yannick