I’m collecting measurement samples from my SPS30 (FW: 2.1 HW: 7, SHDLC: 2.0) in an ordinary household room and I appear to be getting consistently bad data. Typical mass concentrations of PM1, PM2.5, PM4, and PM10 will be in the ~3500 to ~6000 ug/m^3 range, and typical number concentrations are ~28000 to ~45000/cm^3 (PM0.5 number count low end of the range is ~24000). Typical particle size has been ~0.28 to ~0.34 um. I have two other particle sensors in the room which both show mass concentrations near 0, so it seems that the Sensirion is not reporting accurate data.
I have a protocol analyzer attached to the TX/RX lines on the sensor and it is displaying correctly formatted SHDLC frames. The first 13 bytes of most frames sent by the SPS30 look like:
where xx/yy/zz/pp/qq/rr are all changing (slightly), while the 0x45 remains the same. It is interesting to observe that the PM2.5, PM4, and PM10 values are virtually identical to one another in every frame. The number concentrations also change very little from frame to frame.
This looks like some internal offset is incorrect; the position of the 0x45 within its IEEE-754 representation is what is contributing the massive increase to the concentration data. I have already done many power cycles, sent device reset commands (0xd3), triggered manual fan cleanings (0x56), and tried gently blowing into the air inlets/outlet. Nothing has changed the behavior after thousands of samples.
Has anyone encountered similar behavior? Are there undocumented commands that will allow me to reset the offset or force an internal recalibration?
Thanks for the suggestion, Paul. The sensor is attached to an NXP LPC812 chip so unfortunately your driver cannot be used here, but I did look through your code in detail to make sure that I’m following the same decoding algorithm. The driver is not the issue in any case. I’m using the Sensirion sample code and I’m getting fully valid measurement packets coming in over the wire. I have evidence of this because my protocol analyzer is showing me the TX and RX packets and, after decoding that data according to the protocol outlined in the SPS30 datasheet, the raw packets shown by my analyzer decode identically to the values printed by my code.
The problem lies with the actual values generated by the SPS30 itself: When collecting measurements in IEEE754 format (cmd 0x0, subcommand 0x0103) the most significant byte of each of the first four measured fields (mass concentrations) is in the range 0x45-0x47, which according to the IEEE754 format represents a decimal range of 2048-65535. (https://www.h-schmidt.net/FloatConverter/IEEE754.html) This range is clearly far too high to represent the PM1/2.5/4/10 concentration of a room with clean air in ug/m^3. If I switch the measurement format to unsigned 16-bit ints (cmd 0x0, subcommand 0x0105) then the most significant byte is in the range 0x35-0x38, which is a decimal range of 13568-14591.
Note that these values are coming directly out of the SPS30 as seen by my protocol analyzer - they have not yet reached any firmware!
There is clearly bad data coming out of the module. This is most evident in measurement fields 5-9 (the number concentrations) when collected in uint16 format: All five of these fields are 0xFFFF! These values must be off-scale high. Again, I’m in a clean room with two other brands of sensors reading clean air.
The only sane number that I’ve seen in either measurement format is the last field, Typical Particle Size. In float format I see a range of 280-340 nm and in integer format I see 289-296 nm. I can’t make an educated guess about the internal workings of the SPS30 to understand why this value seems to be reasonable while the rest of the measurements are way too high.
The evidence clearly points to an issue with my particular module. Before I request a product exchange from SparkFun I was hoping to see if there was someone else who might have encountered similar bad data and had found a workaround.
Weird indeed. Looks to me this is problem with the product as these values come directly from the SPS30 and do not make sense to me either. But just to be sure :