Photon not entering void loop(), writing strange values to pins

Hi all,
This morning I got around to troubleshooting a particle project that’s been on the fritz for a while now. I opened my code, commented out a portion involving resetFunc(), and compiled it with no other changes.

It prompted me with a single error: my Adafruit_DHT library was missing. I re-downloaded it and recompiled.

However, upon compiling, my photon no longer enters the void loop() portion of my code. I can see this by the fact that it never reaches my Particle.publish statements, resulting in no webhook calls, as well as by the fact that nothing is coming through the serial monitor (even a simple “hello world” upon booting).
Also worth noting is that it seems to be randomly turning the digital pins off and on for random durations in random orders.

My setup code is below- I can post the rest if anyone deems useful, but it’s long messy code, and seeing as how my photon never gets there I thought it would be irrelevant. If I’m wrong, I’ll happily post the rest (1000+ lines) upon request.

//<editor-fold> HARDWARE- sensor setup and variables
SYSTEM_THREAD(ENABLED);

//Initialize humidity sensor
#include "Adafruit_DHT.h";                      //Include Adafruit humidity code
#define DHTPIN A4
#define DHTTYPE DHT11
DHT dht(DHTPIN,DHTTYPE);                        //Begin humidity sensor code (?)

//Initialize pressure sensor
#include "Adafruit_BMP085.h";                   //Include Adafruit pressure code
#include "Wire.h";
Adafruit_BMP085 bmp;                            //Begin pressure sensor code (?)

//Pins for interface with Arduinos
int board1_100 = 2;
int board1_10 = 3;
int board1_1 = 4;
int board2_100 = 5;
int board2_10 = 6;
int board2_1 = 7;
int condPin = A2;
int signaller = A3;

const int BUTTONPIN = A0;
const int RESETPIN = A1;

int condCounter(String string, String term);
void(*resetFunc) (void) = 0;

//<editor-fold> Variables
int i = 360;                                    //Starts i at 360, causing data
																								//publication at startup
int sinceReset = 0;
double humidRaw; double tempC; double tempF; double pressureRaw;
double pressurekPa; double elevation; double pressureOffset;
double pressureSeakPa; double buttonInput; double buttonReset;
uint32_t freemem; uint32_t usedmem;

//<editor-fold> Webhook parser variables
int weathercall = 1;	int forecastcall = 1;
//Variables for dataset 1 parser
float tempF1 = 0; float Pressure1 = 0; int Pcheck1 = 0; float Humidity1 = 0;
float temp1int; float Pressure1intin; float Humidity1int; int simplecast = 0;
//Variables for forecast parsers
double tempForecast1 = -100; String condForecast1 = "empty";
double tempForecast2 = -100; String condForecast2 = "empty";
double tempForecast3 = -100; String condForecast3 = "empty";
double tempForecast4 = -100; String condForecast4 = "empty";
double tempForecast5 = -100; String condForecast5 = "empty";
int condMaxIdx = 0;
//Variables for dataset 2 parser
float tempF2; float Pressure2; int Pcheck2 = 0; float Humidity2;
//Variables for dataset/forecast 3 parser
int tempBuffer = 0; float tempF3 = 0; int pressureBuffer3 = 0;
float Pressure3 = 0; int Pcheck3 = 0; float Humidity3 = 0;
int conditionBuffer3 = 0;
//Variables for dataset 4 parser
float tempF4 = 0; float Pressure4 = 0; float Humidity4 = 0;
int Pcheck4 = 0;
//Variables for dataset/forecast 5 parser
float tempF5 = 0; float Pressure5 = 0; float Humidity5 = 0;
int conditionBuffer5 = 0;
//Conditions
String conditionString = "empty";
//</editor-fold>

//<editor-fold> Display variables
double weightresid1;	double weightresid2; double weightresid3;
double weightresid4; double weightresid5;
int currentDisp_100 = 0; int currentDisp_10 = 0; int currentDisp_1 = 0;
int forecastDisp_100 = 0; int forecastDisp_10 = 0; int forecastDisp_1 = 0;
int conditionDisp = 0;
//</editor-fold>

//</editor-fold>

//</editor-fold> END HARDWARE

//<editor-fold> SETUP- mapping, start sensors, serial and I2C outputs
void setup()
{
	Particle.subscribe("hook-response/getWeather",gotWeather,MY_DEVICES);
	Particle.subscribe("hook-response/getForecast",gotForecast,MY_DEVICES);
	//Subscribe to webhook responses

	//<editor-fold> Expose Variables
	Particle.variable("%RH", humidRaw);         //Expose humidRaw as variable
																							//that can be requested via Wifi
	Particle.variable("Celcius", tempC);        //Expose temps as variables that
	Particle.variable("Fahrenheit", tempF);     //can be requested via Wifi
	Particle.variable("RawkPa", pressurekPa);   //Expose pressures as variables
	Particle.variable("SeakPa", pressureSeakPa);//that can be requested via Wifi

	Particle.variable("Current100s", currentDisp_100);
	Particle.variable("Current10s", currentDisp_10);
	Particle.variable("Current1s", currentDisp_1);
	Particle.variable("Forecast100s", forecastDisp_100);
	Particle.variable("Forecast10s", forecastDisp_10);
	Particle.variable("Forecast1s", forecastDisp_1);
	Particle.variable("Condition", conditionDisp);
	Particle.variable("Iteration", i);
	Particle.variable("Usedmemory", usedmem);
	Particle.variable("CondString", conditionString);
	Particle.variable("weight1", weightresid1);
	Particle.variable("weight2", weightresid2);
	Particle.variable("weight3", weightresid3);
	Particle.variable("weight4", weightresid4);
	Particle.variable("weight5", weightresid5);
	//</editor-fold>

	//<editor-fold> Pins
  pinMode(DHTPIN,INPUT);												//Mapping pins to hardware
	pinMode(BUTTONPIN,INPUT);
	pinMode(RESETPIN,INPUT);
	pinMode(board1_100,OUTPUT);
	pinMode(board1_10,OUTPUT);
	pinMode(board1_1,OUTPUT);
	pinMode(board2_100,OUTPUT);
	pinMode(board2_10,OUTPUT);
	pinMode(board2_1,OUTPUT);
	pinMode(condPin,OUTPUT);
	pinMode(signaller,OUTPUT);

	digitalWrite(board1_100,LOW);									//Make sure all pins are off
	digitalWrite(board1_10,LOW);									//at startup
	digitalWrite(board1_1,LOW);
	digitalWrite(board2_100,LOW);
	digitalWrite(board2_10,LOW);
	digitalWrite(board2_1,LOW);
	digitalWrite(condPin,LOW);
	digitalWrite(signaller,HIGH);
	//</editor-fold>

	dht.begin();																	//Begin sensor interfaces and
	bmp.begin();																	//serial interface
	Serial.begin(9600);
	waitUntil(Particle.connected);
}

There are three lines that may cause the issue you describe

  dht.begin();																		 
  bmp.begin();																		 
  waitUntil(Particle.connected);

either of these may be blocking indefinetly.
For the former two, you may need to look into the library implementation which may trap the code flow in some infinite loop.

1 Like

I’m looking into that now. Out of curiosity, since I am able to open a serial connection, is it fair to say that dht.begin and bmp.begin are not trapping the code flow (since my serial.begin is after those two)?

It is highly likely then that waitUntil(Particle.connected); is blocking.

Perhaps you could add afterSerial.begin(); while(!Serial.available()) Particle.process(); and after that Serial.println("call waitUntil(Particle.connected)"); Then Serial.println("Particle connected"); after it?

Better would be to use waitFor(Particle.connected, timeout); and timeout if after that period it still has not connected.

So, I commented those three lines out, thereby disabling subsequent parts of my code, but theoretically [?] allowing me to check if they are the issue.

I got the same result with them commented out. I’m honestly not familiar enough with how libraries work to be sure what to look for in their source code. I did however verify that my code uses those statements the same way the example codes within the libraries do.

@armor, I will try that momentarily. However, I did at one point comment that line out, and I encountered the same problem regardless.

@armor adding the timeout did not help.

Suggest you go back to basics and build out one thing at a time. For DHTxx devices you should not have to look in the libraries but have you got the devices wired up correctly? Also, you should not do a pinMode(DHTPIN, INPUT); as this is done within the library. I know that this code works:

#include "Adafruit_DHT/Adafruit_DHT.h"

// Example testing sketch for various DHT humidity/temperature sensors
// Written by ladyada, public domain

#define DHTPIN D7     // what pin we're connected to

// Uncomment whatever type you're using!
#define DHTTYPE DHT11		// DHT 11 
//#define DHTTYPE DHT22		// DHT 22 (AM2302)
//#define DHTTYPE DHT21		// DHT 21 (AM2301)

// Connect pin 1 (on the left) of the sensor to +5V
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

DHT dht(DHTPIN, DHTTYPE);

void setup() {
	Serial.begin(9600); 
	Serial.println("DHTxx test!");

	dht.begin();
}

void loop() {
// Wait a few seconds between measurements.
	delay(2000);

// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
	float h = dht.getHumidity();
// Read temperature as Celsius
	float t = dht.getTempCelcius();
// Read temperature as Farenheit
	float f = dht.getTempFarenheit();
  
// Check if any reads failed and exit early (to try again).
	if (isnan(h) || isnan(t) || isnan(f)) {
		Serial.println("Failed to read from DHT sensor!");
		return;
	}

// Compute heat index
// Must send in temp in Fahrenheit!
	float hi = dht.getHeatIndex();
	float dp = dht.getDewPoint();
	float k = dht.getTempKelvin();

	Serial.print("Humid: "); 
	Serial.print(h);
	Serial.print("% - ");
	Serial.print("Temp: "); 
	Serial.print(t);
	Serial.print("*C ");
	Serial.print(f);
	Serial.print("*F ");
	Serial.print(k);
	Serial.print("*K - ");
	Serial.print("DewP: ");
	Serial.print(dp);
	Serial.print("*C - ");
	Serial.print("HeatI: ");
	Serial.print(hi);
	Serial.println("*C");
	Serial.println(Time.timeStr());
}

@armor Yeah, I’ve got the device wired correctly; I’ve been using it for 6 months straight without issue, so I’m good on that end.

I seem to be following your example code exactly, except for different pin mapping. (After making your recommended modification to pinMode).
To what extent are you suggesting that I rebuild my code?

Is there a particular led pattern I should see right now? If, as has been suggested, it is hanging on waitUntil(Particle.connected), would that not imply that I have no connection? It’s breathing cyan, so theoretically it’s got that connection…

You could just comment out using /* */ everything that isn’t to do with DHT setup and use. It sounds like the issue is not with that.

What Device OS are you using? I somehow remember that waitUntil() was blocking on older versions. Really I would use waitFor() OR just do not check since you are using SYSTEM_MODE(AUTOMATIC) the device will try to connect automatically and keep trying.

@armor, I just stripped it all the way down to this:

SYSTEM_THREAD(ENABLED);

#include "Adafruit_DHT.h"
#define DHTPIN A4
#define DHTTYPE DHT11
DHT dht(DHTPIN,DHTTYPE);

double humidRaw;


//<editor-fold> SETUP- mapping, start sensors, serial and I2C outputs
void setup()
{
		dht.begin();
		Serial.begin(9600);
		Particle.variable('Humidity',humidRaw);
}
//</editor-fold> END SETUP

//<editor-fold> MAIN CODE- measurements, serial output, publishing, webhooks
void loop()
{
		delay(2000);
		Serial.println('Hello World');

    //<editor-fold> Humidity Sensor
    humidRaw = dht.getHumidity();               //Pull RH% from humidity sensor
                                                //using Adafruit code
		Serial.println(humidRaw);

    if (isnan(humidRaw))
    {
      Serial.println("Failed to read from DHT sensor!");
		  return;
    }                                           //^Warning for NaN data
		//</editor-fold>
}

No luck. Nothing coming through the serial monitor, nothing coming up on the app from the particle.variable.
I’m using 0.7.0, if that’s what you are referring to by OS.

One good thing: I think we can safely say that the DHT portion is the bit causing the trouble.

Not clear what you mean by no serial output - do you mean Serial.println(humidRaw); does not output

  1. Declaring Cloud variable should always be done as early as possible in setup().
  2. Cloud variable types are int, double and String - however,
  3. The return type from dht.getHumidity(); is a float not a double - so try typecasting humidRaw = (double) dht.getHumidity();

In the previous iteration you should have used waitFor(Particle.connected, 10000); not waitFor(Particle.connected);

In the serial monitor, there is no text displayed by Serial.println(‘Hello World’); or Serial.println(humidRaw);.

Alright, here’s another look at that code. Changed data type to double, moved the particle variable up further in setup.

SYSTEM_THREAD(ENABLED);

#include "Adafruit_DHT.h"
#define DHTPIN A4
#define DHTTYPE DHT11
DHT dht(DHTPIN,DHTTYPE);

double humidRaw;



void setup()
{
		Particle.variable('Humidity',humidRaw);
		dht.begin();
		Serial.begin(9600);
}


void loop()
{
		delay(2000);
		Serial.println('Hello World');


    humidRaw = dht.getHumidity();

		Serial.println(humidRaw);

    if (isnan(humidRaw))
    {
      Serial.println("Failed to read from DHT sensor!");
		  return;
    }                                           
}

@bjjesteadt, instead of:

DHT dht(DHTPIN,DHTTYPE);

Try this:

DHT dht(DHTPIN, DHTTYPE, 6);

You can experiment with the “6”. Try 6 first, then bump up by 1.

@syrinxtech trying that now. you mean 6, then 7, etc.? What does that do?

It doesn’t seem to be doing anything.

I can’t remember the precise reason, but I believe it helped when using faster processors. I use that same code in all of my DHT11’s with Arduino, Moteino, Photon and ESP32.

I found this:

// Initialize DHT sensor.
// Note that older versions of this library took an optional third parameter to
// tweak the timings for faster processors. This parameter is no longer needed
// as the current DHT reading algorithm adjusts itself to work on faster procs.

I’m not using the exact header that you’re using. Mine is simply <DHT.h>. It’s an older Adafruit adaptation of an MIT library.

So, this suggestion probably won’t work for you according to the comments I found.

I also found this, suggesting a value of 30:

// Initialize DHT sensor for normal 16mhz Arduino
DHT dht(DHTPIN, DHTTYPE, 15);
// NOTE: For working with a faster chip, like an Arduino Due or Teensy, you
// might need to increase the threshold for cycle counts considered a 1 or 0.
// You can do this by passing a 3rd parameter for this threshold.  It's a bit
// of fiddling to find the right value, but in general the faster the CPU the
// higher the value.  The default for a 16mhz AVR is a value of 6.  For an
// Arduino Due that runs at 84mhz a value of 30 works.
// Example to initialize DHT sensor for Arduino Due:
//DHT dht(DHTPIN, DHTTYPE, 30);

@bjjesteadt Actually the issue here is the library being used is the old type. Try including ADAFRUIT_DHT_PARTICLE instead. You can open the .cpp and .h files and see that the value @syrinxtech refers to is actually set to 6 by default - no need to include.

Also, when I said the code worked - I haven’t tried it since the library changes.

Hey guys,
Thanks for your help. I tried switching the library, but that didn’t work. It now tells me my compiler encountered an error or timed out.
I don’t honestly have a lot of time to work this out, but thank you all for trying.

Nope, the system already activates the USB Serial connection, so that's not an indicator

@armor, waitUntil() is blocking in all versions - that's the whole purpose of it: Blocking further code execution of the respective thread till the condition is satisfied, in worst case indefinetly.

The explicit type cast is not required since the compiler knows how to implicitly fit a float into a double.