-
Notifications
You must be signed in to change notification settings - Fork 26
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
Ensure calibration registers loaded before read #5
base: master
Are you sure you want to change the base?
Conversation
The calibration data is not calculated on startup but burnt to memory at the factory. I think. So it's unique per chip and always present. It's the raw values from measuring that's sometimes missing during reading. I think compensating for sensor warm up is best handled outside the lib. It depends on your settings, specially oversampling. Also the potentially infinite loop is a bit of a high risk. Might lock the SoC totally on boot if chip is bad. So I'm a little hesitant to this change. |
Good point re infinite loop, that could be an even more obscure rabbit hole than the issue with the calibration data itself. The problem though is that reading the calibration data in the BMP280 initialization method, if it does so before the data is moved from non-volatile memory to the image registers will mean the instance never gets the correct values. It may be better to separate the reading of the calibration data to another method that can be called again should it fail to get the correct values during the initialization. The datasheet specification has a max startup time of 2ms, from section 1:
But given my test communicates with the chip and reads
An example method for reading the calibration data: def __init__(self, *):
# ...setup i2c
# init calibration data attributes
self._T1 = self._T2 = ... = self._P9 = 0
self.calibrate() # will refuse to update if not ready
# ...setup other attributes
def calibrate(self):
if self._T1 != 0: # may need to be more thorough, but this is the first register that wouldn't have data
return True
if self.is_updating:
return False
# read calibration data
# < little-endian
# H unsigned short
# h signed short
self._T1, self._T2, self._T3, \
self._P1, self._P2, self._P3, \
self._P4, self._P5, self._P6, \
self._P7, self._P8, self._P9 = unpack('<HhhHhhhhhhhh', self._read(0x88, 24))
return True And usage: bmp = BMP280(I2C())
if not bmp.calibrate():
print('Calibration data not yet available.') |
Add confirmation that calibration data is read. Refuse to read calibration data while registers are written from NVM.
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 like the idea to be able to "recalibrate". I was unaware of the registers sometimes having the wrong data. However I think the logic at lines 135-138 belongs outside of this function. Timings for the register data is too complicated to be asumed inside the functions. The application needs to check is_updating and the register values itself during runtime. The calibrate-function should only to just that and not handle too much logic for the user.
Do you mean that Really the only cases that need to be handled is on power-on-reset which occurs at power on, and immediately after receiving a reset register value (soft power on), with the latter case being initiated by the user. The chip does set the registers before a measurement so |
one remark. this should be covered in use case "normal mode" by shadowing the data registers. RFC |
The calibration registers are read immediately on initialization of a BMP280 instance, however if the device itself has not completed power-on-reset these registers may not contain valid data. We should wait until the
im_update
bit from thestatus
register is off before continuing (see section 4.3.3 of bst-bmp280-ds001.pdf for details).I've tested the changes by forcing a reset (section 4.3.2) immediately before initializing BMP280 and found it takes between 1 and 3 passes through the loop before the update is complete. The following code was used in testing: