Core locks up / cycles after power-up (DHT22 & SSD1306, I2C mode)

Hi! I have “successfully” combined

(thanks to @peekay123 and @mtnscott for the above!)

The resulting Spark Core firmware works just fine (displaying humidity and temp on the OLED etc.) except when I completely power-up the core from scratch. In these situations, the core seems to enter an endless restart cycle sometime after calling display.begin(SSD1306_SWITCHCAPVCC, 0x3D). (I get multiple, identical Serial.println() outputs when I keep reconnecting the serial monitor.)

However, the above

  • does not happen after reflashing the firmware (no power cycle)
  • can be mitigated by pressing the reset button on the Spark (after power-up).

In both cases, the device resets just fine and works like a charm.

I am currently at a loss when it comes to understanding the fine differences of power-up vs. reset and would appreciate helpful pointers. Similarly, if you have hints on how to help the analysis of the above behavior, I’ll be happy to try. Thanks!

What colors do you see on the RGB LED?
Can you try a power source that delivers more power (higher current)?

Thanks for helping!

  • tried a 2A power supply, didn’t change behavior
  • colors: breathing white, flashing green, flashing cyan, off – repeat – if at any point, I press ‘reset’, it starts working with no other change

Can you post your code?
I’ve got these devices, so I could check if mine do the same.

Just to ensure, you are using a Spark Core not a Particle Photon?

What would be a good place to post the code (apologies for asking, first time around for me)? It’s about 120 lines not including the lib code. Mostly a combination of sample code from the libs I’m using, so nothing special as far as I can tell.

More importantly, I took a shortcut and flashed a second one (yes, I’m using Spark Cores) myself, same result. Works after reset, but not after power-up.

You could post your code right here. Just make sure you place three backticks on the line before and after the code

```
code here
```

Okay, here we go with the code…

#include "Adafruit_SSD1306.h"
#include "PietteTech_DHT.h"

//
// Don't require cloud connection / wifi
//
// SYSTEM_MODE(SEMI_AUTOMATIC);


//
// OLED DEFINES
//
#define OLED_RESET D4
Adafruit_SSD1306 display(OLED_RESET);

#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

//
// DHT22 LIB DEFINES
//
#define DHTTYPE  DHT22
#define DHTPIN   2
#define DHT_SAMPLE_INTERVAL   60000  // Sample every minute

//declaration
void dht_wrapper(); // must be declared before the lib initialization
PietteTech_DHT DHT(DHTPIN, DHTTYPE, dht_wrapper);
// globals
unsigned int DHTnextSampleTime;	    // Next time we want to start sample
bool bDHTstarted;		    // flag to indicate we started acquisition
int n;                              // counter

double humid;
double temp;

void setup()   {

  // initialize with the I2C addr 0x3D (for the 128x64)
  display.begin(SSD1306_SWITCHCAPVCC, 0x3D);

  // init done
  display.setTextSize(1);
  display.setTextColor(WHITE);

  // set the time for next sample
  DHTnextSampleTime = 0;

  // Publish some variables
  Particle.variable("h", humid);
  Particle.variable("t", temp);

}

// This wrapper is in charge of calling
// must be defined like this for the lib work
void dht_wrapper() {
    DHT.isrCallback();
}


void loop() {

  // Check if we need to start the next sample
  if (millis() > DHTnextSampleTime) {
  	if (!bDHTstarted) {		// start the sample
  	    DHT.acquire();
  	    bDHTstarted = true;
  	}

  	if (!DHT.acquiring()) {		// has sample completed?

  	    // get DHT status
  	    int result = DHT.getStatus();

  	    switch (result) {
    		case DHTLIB_OK:
    		case DHTLIB_ERROR_CHECKSUM:
    		case DHTLIB_ERROR_ISR_TIMEOUT:
    		case DHTLIB_ERROR_RESPONSE_TIMEOUT:
    		case DHTLIB_ERROR_DATA_TIMEOUT:
    		case DHTLIB_ERROR_ACQUIRING:
    		case DHTLIB_ERROR_DELTA:
    		case DHTLIB_ERROR_NOTSTARTED:
    		default:
  		    Particle.publish("err", "Unknown error");
  		    break;
  	    }

        display.clearDisplay();
        display.setCursor(0,0);

        humid = DHT.getHumidity();
        temp = DHT.getCelsius();

        display.print("Humidity:    ");
        display.println(humid, 2);

        display.print("Temperature: ");
  	    display.println(temp, 2);

        display.println();

        display.print("Connected:   ");
        if (Particle.connected()) {
          display.println("yes");
        } else {
          display.println("no");
        }

        display.display();

  	    n++;  // increment counter
  	    bDHTstarted = false;  // reset the sample flag so we can take another
  	    DHTnextSampleTime = millis() + DHT_SAMPLE_INTERVAL;  // set the time for next sample
  	}
  }

}

I have had issues with the piette library on the Spark Core, not soo on the Photon. I did find the Adafruit_DHT library seemed more stable. I didnt spend anytime getting to the bottom of the issue.

Actually, the piettetech one is considered to be the most stable one. It has been running flawlessly for almost two years on one of my cores.

Hmm, I’ve tried your code in Web IDE and I can’t reproduce your issue.

I’ll have to reread your post to copy your steps to try triggering it.

I only changed this in your code, to make it work with the jumpers I already had in place on my board :wink:

//
// OLED DEFINES
//
#define OLED_DC     A0
#define OLED_CS     A1
#define OLED_RESET  D6
Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS);

You’d need to add a break; after case DHTLIB_OK: otherwise you’ll always get an “Unknown error” event published.

Do you by any chance remember if you ever applied a bootloader patch?
If not, you can download the patch and flash it via CLI particle flash --usb core-firmware.bin.

Thanks! That’s interesting. Ok, here’s to your points:

  • I’m using Particle Dev and / or CLI, not Web
  • thanks for the hint on the break (I scrubbed the code a bit before I posted it and overdid that)!
  • not sure where I2C vs. SPI makes a difference but worth a try, as indicated by your experience and … (see below)
  • yes, I applied a bootloader patch just yesterday because it was mentioned as a potential solution in a hang situation that seemed similar to mine (though using different sensors etc.) but it did not change the result.

EDIT

Grand reveal: maybe I should have thought of it before, but I finally tried to power the OLED and the DHT using Vin as opposed to 3.3V and that helped. This said, I modified the code to look like this […]

My apologies, but I need to retract my earlier statement and code, as I had wrongly wired the OLED - funny though because it actually worked :flushed:

I went back to testing the DHT and SSD1306 libs separately and tracked the lock up situations down to my use of the SSD1306 lib. I’ll investigate further and also try the SPI route later and report back.

@ScruffR, thanks for your help + suggestions, I got it to work using SPI, and for now, I won’t shed a tear over I2C.

I didn’t realize you tried I2C (since the display is set for SPI by default and you didn’t mention any HW adaptions).
For I2C you’d need to solder a jumper on the flip side if the display.

My bad, I should have mentioned that (I’ll update the topic to reflect it).

Anyway, I had the jumpers soldered (remember, it worked except for the “cold” start scenario) for I2C and I now ‘opened’ them in order to facilitate the SPI variant.

To provide the background story on why I2C - originally, I worked with the display using Johnny Five (http://johnny-five.io) and OLED-JS (https://github.com/noopkat/oled-js). It did what it should, but just as the OLED-JS github page says, it is really slow with SPI… Hence I decided to switch to I2C.
When I then took the step to integrate the DHT22 and to use the two libs I mentioned in my first post, I did not reverse that decision.

Anyway, it’s working like a charm now with SPI, and since I finally had the opportunity for a chat with a friend I now believe to understand why I2C sometimes worked and sometimes not. Maybe I’ll give it another try some other time, but for now, all is well and I can continue with other parts of the project.

1 Like