Photon I2C Usage Fault SOS Error

I’m trying to run this on the Photon platform. I have 3 sensors: rain drop, soil moisture & temp+humidity. All three work fine when I wrote code for each one individually. I’m trying to combine the code now and run them all from the same Photon.

The rain drop & soil moisture code works fine when I comment out the I2C temp+humidity sensor. After commenting and testing, I get a Usage Fault SOS error when I uncomment the first read on the SHT31 sensor:

tc = sht31.readTemperature();

I’m certainly no expert with C. I’d love ideas on how to fix this or if you see any other glaring bloat or poor style.

Thanks!
David

Full code below:

    //
    //    Rain Drop Sensor + Capacitive Soil Moisture Sensor v1.2 + SHT31 Temperature & Humidity Sensor
    //    Purpose: Rain Drop Sensor - Analog sensor can detect how much rain is falling, digital sensor can be calibrated with pot to   trigger event at certain wetness level, also triggers led on device.
    //             Capacitive Soil Moisture Sensor v1.2 - Measures soil moisture
    //             SHT31 Temperature & Humidity Sensor - I2C sensor that measures both temperature in Celcius and humidity
    //    Author: David Cool
    //    Version: 1.0
    //
    
    STARTUP(System.enableFeature(FEATURE_RETAINED_MEMORY));
    
    #include <adafruit-sht31.h>
    
    // Setup SHT31 object
    Adafruit_SHT31 sht31 = Adafruit_SHT31();
    
    //#define RESOLUTION 1024 //Use for 10 bit resolution ADC (Arduino)
    #define RESOLUTION 4096 //Use for 12 bit resolution ADC (Particle Photon)
    
    // define rain drop sensor variables
    const int RAIN_DROP_ANALOG_PIN = A0;
    const int RAIN_DROP_DIGITAL_PIN = D2;
    int analogdropLevel;
    int digitaldropLevel;
    
    // define soil moisture sensor pin
    const int SOIL_SENSOR_PIN = A1;
    
    // define SHT31 temperature & humidity variables
    float tc;
    float tf;
    float h;
    
    // used to store device name
    char dev_name[32] = "";
    bool publishName = false;
    
    unsigned long firstAvailable = 0;
    int counter;
    retained int retainedCounter = 0;
    
    void handler(const char *topic, const char *data) {
      strncpy(dev_name, data, sizeof(dev_name)-1);
      Serial.printlnf("received %s: %s", topic, dev_name);
      publishName = true;
    }
    
    void setup()
    {
        // start serial monitor
        Serial.begin(9600);
        
        // setup A0 and D0 as input pins
        pinMode(RAIN_DROP_ANALOG_PIN,INPUT);
        pinMode(RAIN_DROP_DIGITAL_PIN,INPUT);
        pinMode(SOIL_SENSOR_PIN,INPUT);
        
        // get device name from cloud
        Particle.subscribe("particle/device/name", handler);
        Particle.publish("particle/device/name");  // <-- ask the cloud for the name to be sent to you
    }
    
    void loop()
    {
        
      bool wifiReady = WiFi.ready();
    	bool cloudReady = Particle.connected();
    
    	Serial.printlnf("wifi=%s cloud=%s counter=%d retainedCounter=%d", (wifiReady ? "on" : "off"), (cloudReady ? "on" : "off"),
    			counter++, retainedCounter++);
    			
        if (wifiReady && cloudReady) {
    		if (firstAvailable == 0) {
    			firstAvailable = millis();
    		}
    		if (millis() - firstAvailable > 60000) {
    			// After we've been up for 20 seconds, go to sleep. The delay is so the serial output gets written out before
    			// sleeping.
    			Serial.println("calling System.sleep(SLEEP_MODE_DEEP, 600)");
    			delay(2);
                
                // SLEEP_MODE_DEEP timinig is in SECONDS, NOT microseconds!!!
    			System.sleep(SLEEP_MODE_DEEP, 60);
    
    			// The rest of the code here is not reached. SLEEP_MODE_DEEP causes the code execution to stop,
    			// and when wake up occurs, it's like a reset where you start again with setup(), all variables are
    			// cleared, etc.
    			Serial.println("returned from sleep, should not occur");
    		}
    		
    		if (publishName) {
            // Publish an event every ? minutes. The event is JSON formatted and has a
        		// value "distance" that updates each time.
        		
            // rain drop sensor
            analogdropLevel = analogRead(RAIN_DROP_ANALOG_PIN);
            digitaldropLevel = digitalRead(RAIN_DROP_DIGITAL_PIN);
    
            // soil moisture sensor
            int soilMoisture = analogRead(SOIL_SENSOR_PIN);
    
            // SHT31 temp & humidity sensor
            tc = sht31.readTemperature();
            tf = (tc * 9/5) + 32;
            h = sht31.readHumidity();
            
        		char sensor_data[128];
        		snprintf(sensor_data, sizeof(sensor_data), "{\"analog_rain_drop_value\":\"%d\",\"digital_rain_drop_value\":\"%d\",\"soi   l_moisture\":\"%d\",\"C\":\"%.2f\",\"F\":\"%.2f\",\"Humidity\":\"%.2f\",\"name\":\"%s\"}", analogdropLevel,    digitaldropLevel, soilMoisture, tc, tf, h, dev_name);
        
        		Particle.publish("sensor_data", sensor_data, PRIVATE);
                delay(1000); // to ensure adhering to rate limit
                publishName = false;
            }
    		
    
    	}
    	else {
    		firstAvailable = 0;
    	}
    
    	delay(1000);
        
    }

I solved this one myself… I forgot this bit of code in setup:

    Serial.println("SHT31 Temperature & Humidity Sensor");
    if (! sht31.begin(0x44)) {   // Set to 0x45 for alternate i2c addr
        Serial.println("Couldn't find SHT31");
        while (1) delay(1);
    }
1 Like