Sensirion / embedded-sps

Embedded i2c Driver for Sensirion Particulate Matter Sensors - Download the Zip Package from the Release Page
https://github.com/Sensirion/embedded-sps/releases
BSD 3-Clause "New" or "Revised" License
45 stars 15 forks source link

Arduino platform errors - please use https://github.com/sensirion/arduino-sps / 'sensirion-sps' from Library Manager #14

Closed SmartTVVN closed 4 years ago

SmartTVVN commented 5 years ago

Hi I am trying to read values of the sps30 via I2C with esp8266 and the arduino IDE. i used library embedded-sps and embedded-common to programing, but when my code run at function

while (sps30_probe() != 0) { Serial.print("probe failed\n"); delay(1000); } then serial shows this message: "probe failed"

I found the problem and i saw, inside function:

`int16_t sensirion_i2c_read_bytes(uint8_t address, uint8_t data, int64_t num_words) { int16_t ret; int64_t i, j; int64_t size = num_words (SENSIRION_WORD_SIZE + CRC8_LEN); int64_t word_buf[SENSIRION_MAX_BUFFER_WORDS]; uint8_t const buf8 = (uint8_t )word_buf;

ret = sensirion_i2c_read(address, buf8, size);
if (ret != STATUS_OK)
    return ret;
/* check the CRC for each word */
for (i = 0, j = 0; i < size; i += SENSIRION_WORD_SIZE + CRC8_LEN) {

    ret = sensirion_common_check_crc(&buf8[i], SENSIRION_WORD_SIZE,
                                     buf8[i + SENSIRION_WORD_SIZE]);
    if (ret != STATUS_OK)
        return ret;

    data[j++] = buf8[i];
    data[j++] = buf8[i + 1];
}
return STATUS_OK;

}`

`uint8_t sensirion_common_generate_crc(uint8_t *data, int64_t count) { int64_t current_byte; uint8_t crc = CRC8_INIT; uint8_t crc_bit;

/* calculates 8-Bit checksum with given polynomial */
for (current_byte = 0; current_byte < count; ++current_byte) {
    crc ^= (data[current_byte]);
    for (crc_bit = 8; crc_bit > 0; --crc_bit) {
        if (crc & 0x80)
            crc = (crc << 1) ^ CRC8_POLYNOMIAL;
        else
            crc = (crc << 1);
    }
}
return crc;

}` with buf8[30],buf8[31] and buf8[32] checksum value not corect when use buf8[30] ,buf8[31] to calculate checksum value, the result don't match with buf8[32], program cannot break out while loop. I tried with 3 board: arduino, esp32, esp8266 inside arduino IDE but error still same. I don't know how can i fix Can i remove checksum function ? Plz help me, thanks

abrauchli commented 5 years ago

Hi @khongco44

Did you make sure that the sensors starts in i2c mode and not in UART mode (pin4 pulled to ground)?

Could you print the content of the buffer (I'm assuming that it fails to retrieve the serial number)? Do you have a logic analyzer (e.g. from salae) that you could debug the i2c communication with?

If you have a CRC error it's unlikely that it consistently appears at the same buffer index but are there other devices on the i2c bus that could cause crosstalk?

abrauchli commented 5 years ago

Oh wait, are you running into Arduino's maximal buffer size issue discussed in #7? If so, try using the UART driver (https://github.com/Sensirion/embedded-uart-sps) or the software-i2c library which doesn't suffer from the limited buffer.

SmartTVVN commented 5 years ago

i know what is uart mode or i2c mode, i know if i use i2c, i will connect pin 4 to ground. You mean i cannot use arduino, esp32, esp8266 and arduino ide to programing. I want to use i2c because my board only have 2mode uart, not enough for programing. can you help me Thanks bro

michapr commented 5 years ago

@khongco44 : if you use ESP you can modify the wire.h lib.

change: #define BUFFER_LENGTH 64 (was 32)

Please remember that this will take more RAM from your device and can be overwritten after Arduino update.

SmartTVVN commented 5 years ago

@michapr thanks bro, I will try it

SmartTVVN commented 5 years ago

Hi @michapr i changed #define BUFFER_LENGTH 64, but still same, cannot read i2c

paultanner commented 5 years ago

My SPS-30 works OK when I talk to it in async serial and I am in the process of testing it via I2C. I had the same checksum failure problem and saw that Wire.h specified BUFFER_LENGTH 32. This is happening on Arduino 1.6.12. On a Mac this library is at /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/libraries/Wire I altered Wire.h to BUFFER_LENGTH 64 and recompiled. No errors shown. Also checked that Wire.cpp.o had really been updated. The example now ran but the SPS-30 was no longer responding to the read_serial command. Just to check I put Wire.h back as it was. Now I see the proper response on my Salae. However, we are back to failed checksums. I went hunting and found this post https://forum.arduino.cc/index.php?topic=54439.0 Looks like you also need to change Java/libraries/Wire/utility/twi.h to #16 #define TWI_BUFFER_LENGTH 64 However, I can't locate that file. Any suggestions pls?

michapr commented 5 years ago

I have checked it with Arduino 1.8.7 - here it is working as I wrote, editing only Wirhe.h My small program is working now, and the provided sample too.

What happen if you will initialize the SPS only and ask for the ready data flag? Is it working? I think you have checked the device with i2c scanner ? ;)

Best regards Michael

michapr commented 5 years ago

Good news - will work for ESP8266 in future release The request to increase size in library was merged (after I have requested again ;) ) https://github.com/esp8266/Arduino/pull/3576#pullrequestreview-194377996

paultanner commented 5 years ago

Unfortunately with Arduino 1.8.8 on Leonardo (and the mod toWire.h) it's still not working. The problem is the same as above: no response from the SPS-30 seen on Salae. The command looks the same so, given that it works on other chips, I'm probably looking at something like a memory overflow. There may also be an issue with signal levels as moving it to an Arduino Mega did not make it any better.

michapr commented 5 years ago

@paultanner You can try my simple sketch - maybe it will help. https://smarthome-work.com/blog/?particulate-matter-sensor-sps30-and-arduino

It is working with small buffer too - but then only for the first 5 values.

paultanner commented 5 years ago

Many thanks @michapr This worked with 32 byte buffer but broke when I changed Wire.h to 64 byte buffer. I looked again for twi.h and found it this time in /utility in the Wire folder (Arduino 1.6.12). I changed it as follows and your mini example now works.

define TWI_BUFFER_LENGTH 64

So evidently we were dealing with an overrun issue. The original code from this repo is now working :-) Thanks again.

justb4 commented 5 years ago

Also struggled to get SPS30 working with a ThingsNetwork UNO Node (which is a Leonardo in fact).

Found this repo: https://github.com/paulvha/sps30 . Well-documented (read also the sps30.odt doc!) . According to the author reading more than 5 values via I2C is never possible "... as the amount of data that is sent by the SPS30 in I2C is always 32 bytes.".

Got SPS30 with Leonardo via I2C (according to the author UART is not possible with UNO R3), with the following config:

Ran the example Example1_sps30_BasicReadings.ino ok! See output below:

image

Credits and kudos to @paulvha , as he did a very nice job, making a compact driver lib with ample examples and documentation!

paulvha commented 5 years ago

Thanks Just

Looking to the results, you have the debug level set to 3 in the sketch. Remove that and you will get a nicer output.

The 32 bit issue withI2C I discoverd by scoping the SDA/SCL signals and running special code. I have reported to Sensirion as the datasheeet indicates different. Waiting on the outcome.

I found the embedded-sps and UART to difficult and not complete (only implementing a VERY modular communication layer without examples). In the many reactions I got sofar I understand that others around the world run into this as well.

My implementation has been tested to work (without buffer changes) on UNO, MEGA2560, ESP32, ESP8266, Particle Photon and others.

Indeed as Just did, you can configure for flexibility. I will add the line 55 checks as well to the next version of the code. (learning every day 😊)

Today run a test with on an ESP32 with the SPS30 + SCD30 + BME280 and SDS011 on Ubuntu. Still analysing the results. It looks that the PM2.5 mass reading for the SPS30 and SDS011 are very much the same… not so much for PM10…

Regards, Paul

Verzonden vanuit Mailhttps://go.microsoft.com/fwlink/?LinkId=550986 voor Windows 10

Van: Just van den Broeckemailto:notifications@github.com Verzonden: zondag 3 februari 2019 17:55.Aan: Sensirion/embedded-spsmailto:embedded-sps@noreply.github.com CC: paulvhamailto:paulvha@outlook.com; Mentionmailto:mention@noreply.github.com Onderwerp: Re: [Sensirion/embedded-sps] checksum error (#14)

Also struggled to get SPS30 working with a ThingsNetwork UNO Node https://nam01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.thethingsnetwork.org%2Fdocs%2Fdevices%2Funo%2F&data=02%7C01%7C%7Ce34956f2b3b442c92e1508d689f877cc%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636848097579321237&sdata=oxyLorOw%2BdNaBW30xSAGcruKzPo0OSPyLMQ3EJMr6%2FE%3D&reserved=0 (which is a Leonardo in fact).

Found this repo: https://github.com/paulvha/sps30https://nam01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fpaulvha%2Fsps30&data=02%7C01%7C%7Ce34956f2b3b442c92e1508d689f877cc%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636848097579331236&sdata=6CG4BmxPE7mw0iSq%2BEd4FcKdNjS63q7zZTgAhmxeZhg%3D&reserved=0 . Well-documented (read also the sps30.odt https://nam01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fpaulvha%2Fsps30%2Fblob%2Fmaster%2Fsps30.odt&data=02%7C01%7C%7Ce34956f2b3b442c92e1508d689f877cc%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636848097579351257&sdata=cJ117kx0MjBrPtFmuhRSaa3%2FnoL6rNOrJ%2FwMSgHs1YA%3D&reserved=0 doc!) . According to the author reading more than 5 values via I2C is never possible "... as the amount of data that is sent by the SPS30 in I2C is always 32 bytes.".

Got SPS30 with Leonardo via I2C (according to the author UART is not possible with UNO R3), with the following config:

Ran the example Example1_sps30_BasicReadings.inohttps://nam01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fpaulvha%2Fsps30%2Fblob%2Fmaster%2Fexamples%2FExample1_sps30_BasicReadings%2FExample1_sps30_BasicReadings.ino&data=02%7C01%7C%7Ce34956f2b3b442c92e1508d689f877cc%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636848097579361268&sdata=jcvOZptjeIyNT6OMen1TQivjBdrV%2BzdwkkjgUEI7aXQ%3D&reserved=0 ok! See output below:

[image]https://nam01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fuser-images.githubusercontent.com%2F582630%2F52179597-d1f08500-27dc-11e9-92dd-50f1e417b505.png&data=02%7C01%7C%7Ce34956f2b3b442c92e1508d689f877cc%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636848097579371279&sdata=W%2BPL8EvWPZ9MONwcn7uahXgZ99Nj4cBaWJ3A5effl%2Bc%3D&reserved=0

Credits and kudos to @paulvhahttps://nam01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fpaulvha&data=02%7C01%7C%7Ce34956f2b3b442c92e1508d689f877cc%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636848097579371279&sdata=P4vaJfLDDMJL1CM%2BvC0v6jZOypQLkzn%2FkxgVAU8XO1o%3D&reserved=0 , as he did a very nice job, making a compact driver lib with ample examples and documentation!

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://nam01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FSensirion%2Fembedded-sps%2Fissues%2F14%23issuecomment-460068271&data=02%7C01%7C%7Ce34956f2b3b442c92e1508d689f877cc%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636848097579381284&sdata=xh9KSk71DxdojF%2FN5k%2FHRY1o0ofCLKDv6K6LH3lA1c0%3D&reserved=0, or mute the threadhttps://nam01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAPRgvCE8oXeNgbRV5IegyN5_NLqco3CNks5vJxSdgaJpZM4Z-E-i&data=02%7C01%7C%7Ce34956f2b3b442c92e1508d689f877cc%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636848097579391295&sdata=KSU4IrDTBKqdGhGrpJd9ADRx4bTnom9t2mITGC44Jlk%3D&reserved=0.

justb4 commented 5 years ago

@paulvha yes, much nicer output with DEBUG 0. Was dealing with many issues at the same time, including the wiring/pins/pull-up resistors, so had full debugging on. Eventually targeting to connect SPS30 to PyCom LoPy4, which will be even more of a challenge as I found no drivers nor folks using that combo.

paulvha commented 5 years ago

Thanks

Just to make clear and good news !!! : I stand corrected !

With I2C communication you CAN get all the information. The issue is indeed the 32 bytes I2C buffer length on Arduino and ESP8266 (maybe others). If the length send is more than this buffer size it will send will send a NACK, thus stopping the SDS30 from sending more.

I have adjusted my library that it will check and whether the I2C buffer size is at least 64. It will request and display the full amount else it will stick to the MASS values only. My beta test version worked as expected.

Now need to update my documentation, examples and test. Expect the new version to be available tomorrow.

regards, Paul


Van: Just van den Broecke notifications@github.com Verzonden: zondag 3 februari 2019 21:07 Aan: Sensirion/embedded-sps CC: paulvha; Mention Onderwerp: Re: [Sensirion/embedded-sps] checksum error (#14)

@paulvhahttps://nam03.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fpaulvha&data=02%7C01%7C%7Cfac5aeb8c55d4391754308d68a132fc1%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636848212335488176&sdata=PAJY2cGCft64iWr1ARRI0kuXevZrzn8VBn4noLSIA6E%3D&reserved=0 yes, much nicer output with DEBUG 0. Was dealing with many issues at the same time, including the wiring/pins/pull-up resistors, so had full debugging on. Eventually targeting to connect SPS30 to PyCom LoPy4https://nam03.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpycom.io%2Fproduct%2Flopy4%2F&data=02%7C01%7C%7Cfac5aeb8c55d4391754308d68a132fc1%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636848212335498181&sdata=QQRxSk5HJ1AVj%2BCUvUx3xAS%2BgKMdqTyzNEE7dDLzHvU%3D&reserved=0, which will be even more of a challenge as I found no drivers nor folks using that combo.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://nam03.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FSensirion%2Fembedded-sps%2Fissues%2F14%23issuecomment-460083675&data=02%7C01%7C%7Cfac5aeb8c55d4391754308d68a132fc1%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636848212335508180&sdata=CYbVuDfStN%2B%2FPOp6v7sX91Ytdga2P1NKVkE6mL4Wbhg%3D&reserved=0, or mute the threadhttps://nam03.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAPRgvNGHyrOBcLAjq9AS7k2NRqEK4lgvks5vJ0FwgaJpZM4Z-E-i&data=02%7C01%7C%7Cfac5aeb8c55d4391754308d68a132fc1%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636848212335518202&sdata=zmXNG9eJN%2BZS%2FVg0tcDHk4GxubHQzvDbiZDRITAEAuE%3D&reserved=0.

justb4 commented 5 years ago

@paulvha yes, I was not clear: the I2C limitation is indeed only for certain boards (Arduino (UNO, Leonardo), ESP8266,...). If that is really the case, and possible workarounds then that should be documented in the Sensirion SPS30 docs/specs. We can take issues specific to your driver to your repo, https://github.com/paulvha/sps30. And don't feel rushed :-), you already did an excellent job!

Hopefully Sensirion folks follow this discussion and your repo, so eventually all efforts find their way to usable drivers for our AQ-communities. That would be also be beneficial to Sensirion as AQ communities like LuftDaten are constantly on the lookout for better/more accurate PM measurements.

paulvha commented 5 years ago

Just posted the updated driver on the github

Based on some observations, feedback and learning I have made changes to the driver. The most important one is around I2C You can get all the SPS30 data in I2C communication, but you need to extend the I2C receive buffer in Wire.h. The driver will now check whether that buffer is at least 64 bytes and then provide all the values, else it will only provide the 4 MASS values. A new call has been added (I2c_expect()) which will return the expected number of valid values to receive from the SPS30 (either 4 or 10).

If have updated the samples, documentation and added new example as indicated in the readme file


Van: Just van den Broecke notifications@github.com Verzonden: maandag 4 februari 2019 09:57 Aan: Sensirion/embedded-sps CC: paulvha; Mention Onderwerp: Re: [Sensirion/embedded-sps] checksum error (#14)

@paulvhahttps://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fpaulvha&data=02%7C01%7C%7C9851a86383134b9540a108d68a7ed53b%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636848674679229939&sdata=Wn5zFpJbf%2BlB1wC6Hz%2FPDi%2FUN2SxntpLSZNb0pNfZEk%3D&reserved=0 yes, I was not clear: the I2C limitation is indeed only for certain boards (Arduino (UNO, Leonardo), ESP8266,...). If that is really the case, and possible workarounds then that should be documented in the Sensirion SPS30 docs/specs. We can take issues specific to your driver to your repo, https://github.com/paulvha/sps30https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fpaulvha%2Fsps30&data=02%7C01%7C%7C9851a86383134b9540a108d68a7ed53b%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636848674679239944&sdata=l3mDxysCfpcQNPPYpGMrR3aunCSu4tNlshJcMBuSPCc%3D&reserved=0. And don't feel rushed :-), you already did an excellent job!

Hopefully Sensirion folks follow this discussion and your repo, so eventually all efforts find their way to usable drivers for our AQ-communities. That would be also be beneficial to Sensirion as AQ communities like LuftDatenhttps://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fluftdaten.info%2F&data=02%7C01%7C%7C9851a86383134b9540a108d68a7ed53b%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636848674679249949&sdata=maGfOHm25PeOrRtpWilqCEa0hecgZc%2BpAaXDBmG9QRY%3D&reserved=0 are constantly on the lookout for better/more accurate PM measurements.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FSensirion%2Fembedded-sps%2Fissues%2F14%23issuecomment-460172445&data=02%7C01%7C%7C9851a86383134b9540a108d68a7ed53b%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636848674679259960&sdata=BC8YSFLMJ8KeuWH3FVU%2BvIK2b%2BsMbBPmX5ZtK%2FCZMVM%3D&reserved=0, or mute the threadhttps://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAPRgvLLw3OFupZMNKLcdtbqyM-vRv43iks5vJ_YKgaJpZM4Z-E-i&data=02%7C01%7C%7C9851a86383134b9540a108d68a7ed53b%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636848674679269965&sdata=YBGiyfZBmK%2BsuIZ5nlKOrkRz7tRgGA%2FJu1F5R0D8pNc%3D&reserved=0.

justb4 commented 5 years ago

@paulvha the above version works for me (Leonardo, I2C). To get full readings I had to change in both Wire/src/Wire.h and Wire/src/utility/twi.h the (TWI_)BUFFER_LENGTH 64 .

image

paulvha commented 5 years ago

great ! Indeed for Arduino & variants you have to change both. It is documented in the .odt file. On ESP8266 there is only one change needed and not needed on ESP32 (already 128). Still working to understand the full results and that is next point of focus. Hoping to learn from others here as well.

paulvha commented 5 years ago

I have posted version 1.3.1 which fixes the issue that PM10 number is always showing zero's.

winkj commented 5 years ago

@paulvha thanks for the work on the library. We've looked into providing an Arduino library, and have a version ready for AVR based Arduino's that supports reading both mass and counts. Currently, the ESP8266 is not supported yet, so I hope your library can help with that.

winkj commented 5 years ago

@khongco44 there will be a fix for the ESP8266 in the next release of the ESP8266 Arduino libraries (version 2.5.0). For now, it is not officially supported yet. In the meantime, there exist third party solutions like @paulvha's that may be able to address your concerns.

I renamed this to be a bit more descriptive, and will update once the fix is in place.

systembolaget commented 4 years ago

That would be also be beneficial to Sensirion as AQ communities like LuftDaten are constantly on the lookout for better/more accurate PM measurements.

That really is the issue. I would like to use a large number of these sensors in a citizen's science air monitoring project in Sweden, but to get citizens excited and to participate without code worries, a working I2C driver is necessary, because not every citizen can delve into the depths of the great work you guys are accomplishing here.

paulvha commented 4 years ago

@systembolaget : if you are looking for a working I2C implementation for the SPS30, please check my library https://github.com/paulvha/sps30.

winkj commented 4 years ago

@systembolaget, Sensirion provides a dedicated Arduino driver, which is available through the Arduino IDE Library Manager (library name is 'sensirion-sps') or for manual installation from https://github.com/Sensirion/arduino-sps

winkj commented 4 years ago

@abrauchli we should probably add a note to the README and close this

abrauchli commented 4 years ago

ESP8266 should be fixed as of https://github.com/esp8266/Arduino/pull/3576 merged as part of 2.5.0. Link to the arduino repo from the README is up for review.

bonamibond commented 3 years ago

Hi , I am trying to make SPS30 work with ESP8266. I got it working for Arduino Uno but it is not working on ESP8266 as it has only 3.3v output. Can you please tell me how to fix the issue?

rnestler commented 3 years ago

@bonamibond As mentioned here several time: Please use https://github.com/sensirion/arduino-sps if you work with an Arduino.