-
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
Fixing 1 in 256 edge-case that can lead to continuous no-output. #10
base: master
Are you sure you want to change the base?
Conversation
…cksum mismatch and therefore no output. If the last byte of the checksum is 0x42 it can be mistaken for the first start-byte, therefore checking the secondy start-byte is neccessary. The probability of this happening is 1 in 256 and in addition it has 100% probability if testing hepa-filtered air with 0 particels. Reason: All non-zero bytes remaining are: Decimal: 66 + 77 + 28 + 151 checksum: 256 + 66 Hex: 0x42 0x4d 0x00 0x1c ... 0x97 checksum: 0x01 0x42 It is not possible for byte 31 (second checksum-byte) to be 0x42 too, as the sum of the first 30 bytes is at most 30*255 which is less than 66 * 256 which is the smallest checksum that would cause byte 31 to be 0x42 (=66). The sequence 0x42 0x42 0x42 0x4d with the last two being the start bytes is therefore impossible. Though it is not impossible for the sequence 0x42 0x42 0x4d or 0x42 0x4d to appear at another position in the sequence it can only happen with particle count above 16896 = 66*256 and then this event is extremely unlikely itself and will extremely likely lead to a checksum mismatch therefore be discarded.
fixed formatting
this time using clang-format
@dherrada wanna test? |
@caternuson Hi - we are looking at an issue with this driver on WipperSnapper. It's been a few years since you proposed this fix. Do you still think that switching the read to "passive mode" would resolve this issue? |
@brentru I think it's at least worth investigating. Just checked and I do not currently have a PID 3686 to try it out though. I'll order one up to have since it looks like the general issue this PR was fixing still exists. |
@caternuson Thanks! |
@brentru OK, got a PID 3686 and played around with it a bit. It looks like all the current guides and examples are based on this "active mode" which does have the benefit of only needing to connect to the TX pin. My suggestion would require more than a simple code update, since connecting to RX would then be needed. So, no longer suggesting "passive mode". At least not now - maybe for a future major revision. The general idea for the fix seems simple - just need to check for both start bytes: This PR has merge conflicts now though. :( What are the two sensors being supported now? Adafruit_PM25AQI/Adafruit_PM25AQI.cpp Lines 105 to 109 in 37060f9
What has the |
The 0x16 start byte may be the for the Cubic PM1006 air quality sensor present on the IKEA VINDSTYRKA |
Yah, looks like. It was added with #13. And it looks like it does have more than Adafruit_PM25AQI/Adafruit_PM25AQI.cpp Lines 134 to 138 in 37060f9
but with 3 bytes less likely to be false detected. I agree with the general intent of what this PR is attempting. Stick with "active mode" for the sensor and improve the start sequence detection logic. But now there are two sensors in play. It may be easier to break things out in subclasses and override |
Yeah, Cubic has more than just the start byte to detect. I think that is a good plan, |
@caternuson Aren't we detecting both start bytes for active mode within the existing driver, though: https://github.com/adafruit/Adafruit_PM25AQI/blob/master/Adafruit_PM25AQI.cpp#L130 |
Hmmm. Maybe? This issue/PR is 4 years old now. And that looks like an update to the logic since then. The code at the point of time of this PR was much simpler and just checked for the first byte: Adafruit_PM25AQI/Adafruit_PM25AQI.cpp Lines 94 to 100 in 10fdb52
Can also see that in the code diff for this PR. So maybe those updates fixed this issue? But you are currently seeing an issue with Wippersnapper? |
@caternuson Yep, I understand. It appears that we are checking for both start bytes (
@tyeth raised the issue in WipperSnapper in September and I believe he tested it recently. He was able to "patch" it by adding a retry around reading the data, but long-term that's a patch around a driver-specific issue. |
If the last byte of the checksum is 0x42 it can be mistaken for the first start-byte, causing a byte-shift which leads to checksum mismatch followed by no ouput (continuously in the HEPA edge-case).
Therefore checking the secondy start-byte is necessary.
The probability of this happening is 1 in 256 and in addition it has 100% probability if testing HEPA-filtered air with 0 particles.
Reason: With HEPA-filtered air all bytes are zero except:
start 1 + start 2 + frame-length + reserved
Decimal: 66 + 77 + 28 + 151 checksum: 256 + 66
Hex: 0x42 0x4d 0x00 0x1c ... 0x97 checksum: 0x01 0x42
Testing with hepa-filtered air, an arduino nano, software serial (2,3) the byte-shift with continuous no-output happened repeatedly after less than 10 measurement cycles. With disabled checksum-check the 15 uint16_t components of data then look like this:
Byte-shift.txt
---- considering & disregarding further edge-cases ----
It is not possible for byte 31 (second checksum-byte) to be 0x42 too, as the sum of the first 30 bytes is at most 30*255 which is less than 66 * 256 which is the smallest checksum that would cause byte 31 to be 0x42 (=66).
The sequence 0x42 0x42 0x42 0x4d with the last two being the start bytes is therefore impossible.
Though it is not impossible for the sequence 0x42 0x42 0x4d or 0x42 0x4d to appear at another position in the sequence it can only happen with:
which is both really unlikely and very likely not a stable condition with a low chance of multiple byte-shift leading to checksum-mismatch and continuous no-output.