arduino-sps icon indicating copy to clipboard operation
arduino-sps copied to clipboard

sps30_sleep

Open ChrisKolan opened this issue 3 years ago • 4 comments

Could you provide a working example of using the sps30_sleep() function? Here is what I tried to do:

#include <Arduino.h>
#include <Wire.h>
#include <sps30.h>

void setup() 
{
  int16_t ret;
  uint8_t auto_clean_days = 4;
  uint32_t auto_clean;

  Serial.begin(9600);
  delay(2000);

  sensirion_i2c_init();

  while (sps30_probe() != 0) {
    Serial.print("SPS sensor probing failed\n");
    delay(500);
  }

#ifndef PLOTTER_FORMAT
  Serial.print("SPS sensor probing successful\n");
#endif /* PLOTTER_FORMAT */

  ret = sps30_set_fan_auto_cleaning_interval_days(auto_clean_days);
  if (ret) {
    Serial.print("error setting the auto-clean interval: ");
    Serial.println(ret);
  }

  // ret = sps30_start_measurement();
  // if (ret < 0) {
  //   Serial.print("error starting measurement\n");
  // }

#ifndef PLOTTER_FORMAT
  Serial.print("measurements started\n");
#endif /* PLOTTER_FORMAT */

#ifdef SPS30_LIMITED_I2C_BUFFER_SIZE
  Serial.print("Your Arduino hardware has a limitation that only\n");
  Serial.print("  allows reading the mass concentrations. For more\n");
  Serial.print("  information, please check\n");
  Serial.print("  https://github.com/Sensirion/arduino-sps#esp8266-partial-legacy-support\n");
  Serial.print("\n");
  delay(2000);
#endif

  delay(1000);
}

void loop() 
{
  struct sps30_measurement m;
  char serial[SPS30_MAX_SERIAL_LEN];
  uint16_t data_ready;
  int16_t ret;

  sps30_wake_up();
  sps30_start_measurement();
  delay(60000);
  do {
    ret = sps30_read_data_ready(&data_ready);
    if (ret < 0) {
      Serial.print("error reading data-ready flag: ");
      Serial.println(ret);
    } else if (!data_ready)
      Serial.print("data not ready, no new measurement available\n");
    else
      break;
    delay(100); /* retry in 100ms */
  } while (1);

  ret = sps30_read_measurement(&m);
  if (ret < 0) {
    Serial.print("error reading measurement\n");
  } else {

#ifndef PLOTTER_FORMAT
    Serial.print("PM  1.0: ");
    Serial.println(m.mc_1p0);
    Serial.print("PM  2.5: ");
    Serial.println(m.mc_2p5);
    Serial.print("PM  4.0: ");
    Serial.println(m.mc_4p0);
    Serial.print("PM 10.0: ");
    Serial.println(m.mc_10p0);

#ifndef SPS30_LIMITED_I2C_BUFFER_SIZE
    Serial.print("NC  0.5: ");
    Serial.println(m.nc_0p5);
    Serial.print("NC  1.0: ");
    Serial.println(m.nc_1p0);
    Serial.print("NC  2.5: ");
    Serial.println(m.nc_2p5);
    Serial.print("NC  4.0: ");
    Serial.println(m.nc_4p0);
    Serial.print("NC 10.0: ");
    Serial.println(m.nc_10p0);

    Serial.print("Typical particle size: ");
    Serial.println(m.typical_particle_size);
#endif

    Serial.println();

#else
    // since all values include particles smaller than X, if we want to create buckets we 
    // need to subtract the smaller particle count. 
    // This will create buckets (all values in micro meters):
    // - particles        <= 0,5
    // - particles > 0.5, <= 1
    // - particles > 1,   <= 2.5
    // - particles > 2.5, <= 4
    // - particles > 4,   <= 10

    Serial.print(m.nc_0p5);
    Serial.print(" ");
    Serial.print(m.nc_1p0  - m.nc_0p5);
    Serial.print(" ");
    Serial.print(m.nc_2p5  - m.nc_1p0);
    Serial.print(" ");
    Serial.print(m.nc_4p0  - m.nc_2p5);
    Serial.print(" ");
    Serial.print(m.nc_10p0 - m.nc_4p0);
    Serial.println();


#endif /* PLOTTER_FORMAT */

  }

  sps30_stop_measurement();
  sps30_sleep();
  delay(60000);
}

I can see the first measurement:

"SPS sensor probing successful measurements started PM 1.0: 2.62 PM 2.5: 2.77 PM 4.0: 2.77 PM 10.0: 2.77 NC 0.5: 17.90 NC 1.0: 20.88 NC 2.5: 20.92 NC 4.0: 20.92 NC 10.0: 20.93 Typical particle size: 0.48"

but after I only get: "error reading data-ready flag: -1" message.

ChrisKolan avatar Apr 21 '22 20:04 ChrisKolan

Just a quick thing to check (I don't have a sensor ready to test):

Could you check the return value of the sps30_start_measurement() after sps30_wake_up()? I'm not sure if there would need to be a short delay between those two calls, since wake-up takes a few milliseconds, and the start measurement might be too early... which would explain why there's no data ready.

winkj avatar Apr 21 '22 20:04 winkj

The return value of sps30_start_measurement() is 0. I also waited 1 second and also 10 seconds between sps30_wake_up() and sps30_start_measurement() but the problem remains.

ChrisKolan avatar Apr 22 '22 15:04 ChrisKolan

Thanks for checking, I'll escalate this internally

winkj avatar Apr 22 '22 15:04 winkj

Additionally sps30_probe() returns "SPS sensor probing failed". I also tried sps30_reset() but this does not help.

ChrisKolan avatar Apr 22 '22 15:04 ChrisKolan