SGP30 doesn't work on Gen3 devices

To prevent an auto-upgrade you need to flash an application that is not targeted at a higher version than you are aiming for, otherwise this will always trigger the consolidation upgrade.

Typically we suggest particle flash --usb tinker -v for that as that version of Tinker is always targeted at the lowest stable device OS version possible.

Yea, I tired that, numerous times. Probably did about 10 attempts total including probably 30 usb flashes. I’m pretty sure I tried every possible suggestion in that downgrade thread in every conceivable order. That’s why I tried, successfully, other versions like 1.3.1 to confirm I wasn’t missing something fundamental.

Update all (zero thanks to Particle support btw). Got this working with some tweaking of the arduino library. Will get it tidied up and send link soon. Seems to be posting fine now via particle.publish so presume the rest is working.

3 Likes

@irwige What changes to code were needed?

Sorry for delay, no idea how to post a lib to github… ill get there.

The first thing (after cloning the adafruit library) was to move the .h and .cpp into src. then also created a properties file. Then, not 100% sure if needed, but added the Wire.h as that was in the example.


note: using udp as a workaround for posting my data to InfluxDB whilst Particle tech sort out my webhook issue. Not holding my breath on that though. So, you dont need to call UDP or TCPClient unless posting to web.

Then added the library to properties

Now into SGP30.h and changed it to Particle.h


I also had some issues with the default address on my sensor. I think this is the default, but some other makers use slightly different addresses such as 0x5A, 0x45, etc… look yours up, but the image worked for my adafruit branded one.

As for code, this is what is in my SGP30.ino

/*
 * Project SGP30
 * Description:
 * Author:
 * Date:
 */
#include "Particle.h"
#include "Wire.h"
#include "Adafruit_SGP30.h"

Adafruit_SGP30 sgp;


/* return absolute humidity [mg/m^3] with approximation formula
* @param temperature [°C]
* @param humidity [%RH]
*/
uint32_t getAbsoluteHumidity(float temperature, float humidity)
{
  // approximation formula from Sensirion SGP30 Driver Integration chapter 3.15
  const float absoluteHumidity = 216.7f * ((humidity / 100.0f) * 6.112f * exp((17.62f * temperature) / (243.12f + temperature)) / (273.15f + temperature)); // [g/m^3]
  const uint32_t absoluteHumidityScaled = static_cast<uint32_t>(1000.0f * absoluteHumidity);                                                                // [mg/m^3]
  return absoluteHumidityScaled;
}

void setup()
{
  Serial.begin(9600);
  Particle.publish("Argon_002", "SGP30 test", PRIVATE); // Argon_002 can be renamed to whatever you like.

  if (!sgp.begin())
  {
    Particle.publish("Argon_002", "SGP NOT FOUND", PRIVATE);
  }

  String serialString = "SGP30 Serial:";
  serialString += String(sgp.serialnumber[0], HEX);
  serialString += String(sgp.serialnumber[1], HEX);
  serialString += String(sgp.serialnumber[2], HEX);
  Particle.publish("Argon_002", serialString, PRIVATE);
  // If you have a baseline measurement from before you can assign it to start, to 'self-calibrate'
  //sgp.setIAQBaseline(0x8E68, 0x8F41);  // Will vary for each sensor!
}

int counter = 0;
void loop()
{

  /////// CO2 Sensor ///////
  // If you have a temperature / humidity sensor, you can set the absolute humidity to enable the humditiy compensation for the air quality signals
  float temperature = 22.1; // [°C]    <-- SET THESE FROM TEMP/HUMI SENSOR WHEN WORKING
  float humidity = 45.2;    // [%RH]   <-- SET THESE FROM TEMP/HUMI SENSOR WHEN WORKING
  sgp.setHumidity(getAbsoluteHumidity(temperature, humidity));

  if (!sgp.IAQmeasure())
  {
    Particle.publish("Argon_002", "Measurement Failed", PRIVATE);
    return;
  }

  if (!sgp.IAQmeasureRaw())
  {
    //Serial.println("Raw Measurement failed");
    Particle.publish("Argon_002", "Raw Measurement failed", PRIVATE);
    return;
  }
  Particle.publish("Argon_002",String(sgp.eCO2),PRIVATE); // <-- can also call tvoc here. but I'm only interested in co2
  delay(9000);

  counter++;
  if (counter == 30)
  {
    counter = 0;

    uint16_t TVOC_base, eCO2_base;
    if (!sgp.getIAQBaseline(&eCO2_base, &TVOC_base))
    {
      //Serial.println("Failed to get baseline readings");

      Particle.publish("Argon_002", "Failed to get baseline readings", PRIVATE);
      return;
    }
    String baselineString = "****Baseline values: eCO2: 0x";
    baselineString += String(eCO2_base, HEX);
    baselineString += " & TVOC: 0x";
    baselineString += String(TVOC_base, HEX);

    Particle.publish("Argon_002", baselineString, PRIVATE);
  }
  float voltage = analogRead(BATT) * 0.0011224;
}
2 Likes

Thanks for taking the time to post that.

1 Like

Thanks for posting about your success, I had all but given up but you gave me the motivation to try once more :wink:

I finally figured out my problem, a bad power wire. I have a Photon on one breadboard and an Argon on another and I was moving the SGP30 between them to test. Finally I decided to move the Argon to the Photon’s breadboard, adjusting the connections as appropriate, and then it started to work. Replacing the power wires on my Argon breadboard resolved my issue. It was a bit confusing because an SHT31 sensor plugged into the same power wires was working but I guess the SGP requires significantly more power and my faulty wire couldn’t supply that.

I then retried the half dozen SGP tests I had tried in the past and every single one of them worked. Including those that use the Adafruit and Sensirion Particle libraries. So if anyone else is still having issues, try swapping the power/ground wires.

2 Likes