TCPClient + idDHT22 = Hard fault

Hi all, I’m trying to get my spark core to send temp/humidity to Xively.

The 2 parts in my loop separately run correctly but combined I see “Connecting to Xively…” in the serial monitor, a SOS Hard Fault (sos 1 sos) and the core restarting. (also sometimes blinking cyan or constant cyan and hard to reflash over wifi)

Does anybody have an idea what could be causing this?
Should I try something else to read my RHT03 data?
Is all this serial output causing problems? (also have crash without serial connection)

// This #include statement was automatically added by the Spark IDE.
#include "idDHT22.h"

//see http://docs.spark.io/examples/

#define FEED_ID "1234"
#define XIVELY_API_KEY "MYKEY"

// declaration for DHT11 handler
int idDHT22pin = D4; //Digital pin for comunications
void dht22_wrapper(); // must be declared before the lib initialization

// DHT instantiate
idDHT22 DHT22(idDHT22pin, dht22_wrapper);

TCPClient client;

const int xivelyInterval = 10000;
const int readInterval = 3000;

char message[50];
double Humidity =0;
double degF = 0;
double degC = 0;
double degK = 0;
double DewPoint = 0;
double DewPointSlow = 0;
int result;

int ledPin = D7;

bool serial = true;

void setup()
{
    pinMode(ledPin, OUTPUT);
    
    if(serial){
        Serial.begin(9600);
// 	while(!Serial.available()) {
// 	    Serial.println("hit a key");
// 	    delay(1000);
// 	}
        delay(1000);
    	Serial.println("idDHT22 Example program");
    	Serial.print("LIB version: ");
    	Serial.println(idDHT22LIB_VERSION);
    	Serial.println("---------------");
    }
    Spark.variable("message", &message, STRING);
	Spark.variable("Humidity", &Humidity, DOUBLE);
	Spark.variable("degF", &degF, DOUBLE);
	Spark.variable("degC", &degC, DOUBLE);
	Spark.variable("degK", &degK, DOUBLE);
	Spark.variable("DewPoint", &DewPoint, DOUBLE);
	Spark.variable("DewPointSlow", &DewPointSlow, DOUBLE);
    
}

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

unsigned long lastXively = millis();
unsigned long lastRead = millis();
void loop(){
    // only one of these can be enabled
    // if (millis() - lastRead > readInterval){
    //     lastRead = millis();
    //     readSensor();
    // }
    
    if (millis() - lastXively > xivelyInterval){
        delay(2000);
        lastXively = millis();
        sendResults();
    }
}

void sendResults(){
      Serial.println("Connecting to xively...");
        if (client.connect("api.xively.com", 8081)) 
        {
            Serial.println("...connected, sending data...");
            writeRequest(client);
            client.flush();
            Serial.println("...done, reading response...");
            // wait 5 seconds or less for the server to respond
            readResponse(client);
            client.stop();
            Serial.println("...disconnected");
            ledStatus(1, 250);        
        } 
        else 
        {
            // Connection failed
            Serial.println("...connection failed");
            client.stop();
            ledStatus(5, 100);
        }
}

void writeRequest(TCPClient client){
    writeHead(client);
    writeValue(client, "temperatureC", degC);
    writeComma(client);
    writeValue(client, "humidity", Humidity);
    writeTail(client);
}

void readResponse(TCPClient client){
            uint32_t startTime = millis();
            while(!client.available() && (millis() - startTime) < 5000){
                delay(100);   
            };
            if(client.available()){
                while(client.available()) 
                {
                    // Read response
                    char c = client.read();
                    Serial.print(c);
                }
            }else{
                Serial.println("...no response received");
            }
}

void writeHead(TCPClient client){
        // Connection succesful, update datastreams
        client.print("{");
        client.print("  \"method\" : \"put\",");
        client.print("  \"resource\" : \"/feeds/");
        client.print(FEED_ID);
        client.print("\",");
        client.print("  \"params\" : {},");
        client.print("  \"headers\" : {\"X-ApiKey\":\"");
        client.print(XIVELY_API_KEY);
        client.print("\"},");
        client.print("  \"body\" :");
        client.print("    {");
        client.print("      \"version\" : \"1.0.0\",");
        client.print("      \"datastreams\" : [");
}

void writeValue(TCPClient client, String name, double value){
        client.print("        {");
        client.print("          \"id\" : \"");
        client.print(name);
        client.print("\",");
        client.print("          \"current_value\" : \"");
        client.print(value);
        client.print("\"");
        client.print("        }");
}

void writeComma(TCPClient client){        
        client.print(",");
}

void writeTail(TCPClient client){
        client.print("      ]");
        client.print("    },");
        client.print("  \"token\" : \"0x12345\"");
        client.print("}");
        client.println();
}

void ledStatus(int count, int wait)
{
    for (int i = 0; i < count; i++)
    {
        digitalWrite(ledPin, HIGH);
        delay(wait);
        digitalWrite(ledPin, LOW);
        delay(wait); 
  }
}

void readSensor(){
    digitalWrite(ledPin, HIGH);   // turn the LED on (HIGH is the voltage level)
    if(serial){
        Serial.print("\nRetrieving information from sensor...");
    }
	DHT22.acquire();
	while (DHT22.acquiring()){
	  delay(100);   
	}
	if(serial){
	    Serial.print("done => ");
	    //delay(100);
    }
	int result = DHT22.getStatus();
	
	result = DHT22.getStatus();
	if(serial){
    	switch (result)
    	{
    		case IDDHTLIB_OK:
    			Serial.println("OK");
    			break;
    		case IDDHTLIB_ERROR_CHECKSUM:
    			Serial.println("Error\n\r\tChecksum error");
    			break;
    		case IDDHTLIB_ERROR_ISR_TIMEOUT:
    			Serial.println("Error\n\r\tISR Time out error");
    			break;
    		case IDDHTLIB_ERROR_RESPONSE_TIMEOUT:
    			Serial.println("Error\n\r\tResponse time out error");
    			break;
    		case IDDHTLIB_ERROR_DATA_TIMEOUT:
    			Serial.println("Error\n\r\tData time out error");
    			break;
    		case IDDHTLIB_ERROR_ACQUIRING:
    			Serial.println("Error\n\r\tAcquiring");
    			break;
    		case IDDHTLIB_ERROR_DELTA:
    			Serial.println("Error\n\r\tDelta time to small");
    			break;
    		case IDDHTLIB_ERROR_NOTSTARTED:
    			Serial.println("Error\n\r\tNot started");
    			break;
    		default:
    			Serial.println("Unknown error");
    			break;
    	}
	}
     
    Humidity = DHT22.getHumidity();
    degF = DHT22.getFahrenheit();
    degC = DHT22.getCelsius();
    degK = DHT22.getKelvin();
    DewPoint = DHT22.getDewPoint();
    DewPointSlow = DHT22.getDewPointSlow();
    
    if(serial){
        Serial.print("Humidity (%): ");
    	Serial.println(Humidity, 2);
    
    	Serial.print("Temperature (oC): ");
    	Serial.println(degC, 2);
    
    	Serial.print("Temperature (oF): ");
    	Serial.println(degF, 2);
    
    	Serial.print("Temperature (K): ");
    	Serial.println(degK, 2);
    
    	Serial.print("Dew Point (oC): ");
    	Serial.println(DewPoint);
    
    	Serial.print("Dew Point Slow (oC): ");
    	Serial.println(DewPointSlow);
        
        sprintf(message, "{\"Humidity\":%f,\"degF\":%f,\"degC\":%f,\"degK\":%f,\"DewPoint\":%f,\"DewPointSlow\":%f}", Humidity, degF, degC, degK, DewPoint, DewPointSlow);
    }
    digitalWrite(ledPin, LOW);    // turn the LED off by making the voltage LOW
}

You could try the same code but remove the DHT22 code, just use random numbers and see if the problem persists.
If not, it could be related to some of the issues in this thread :

1 Like

Thanks for the tip. With the readSensor() commented as in the code above everything works. I fear it’s going to be related to that idDHT22 lib.

Switched to this lib:

but did not help (though the lib works as expected)

Seems that my hard fault problem was related bad string (pointer) handling. I hope one day I will be able to program my spark core using http://www.rust-lang.org/ :smiley:

This was the fix:

char message[50] = "";
char *messagePtr = message;

setup

Spark.variable("message", messagePtr, STRING);

and in the loop

sprintf(messagePtr, "{\"Humidity\":%f,\"degF\":%f,\"degC\":%f,\"degK\":%f,\"DewPoint\":%f,\"DewPointSlow\":%f}", Humidity, degF, degC, degK, DewPoint, DewPointSlow);