Some trouble with STRING variable and DHT22 hanging [Solved]

Hi,

My Core consistently crashes on this code several minutes after initiating.

Only a power-off will reset the small app, but it fails consistently after some time. I’m guessing a memory leak, but I don’t know how to find this.

I read in some C++ sites that sprintf is good at creating memory leaks…

I assume the Arduino DHT22 library has been working OK.

 #include "idDHT22.h"

 int led2 = D7;
 char zTemp[40];

 int idDHT22pin = D4;    // digital pin for comunications
 void dht22_wrapper();   // must be declared before lib initialization
 idDHT22 DHT22(idDHT22pin, dht22_wrapper);   // DHT instantiate

 void setup() {
     Serial1.begin(9600);
     Spark.variable("resultX", &zTemp, STRING);
 }

 // wrapper -- must be defined for the lib work
 void dht22_wrapper() {
   DHT22.isrCallback();
 }

 void loop() {

     DHT22.acquire();
       while (DHT22.acquiring());
     double C_in = DHT22.getCelsius();
     double H_in = DHT22.getHumidity();

     sprintf(zTemp, "{'C_in':'%2.2f','H_in':'%2.2f'}", C_in, H_in );

     delay(2000);
 }

One problem lays in this code

Since you dropped the [] in your use of zTemp you don't need the & anymore, otherwise you actually write &&someVar which is not what you want here.

You could rather write

  Spark.variable("resultX", zTemp, STRING);
  // or
  Spark.variable("resultX", &zTemp[0], STRING);

Otherwise the string you put into zTemp[] will be used as a pointer, pointing who knows where, next time you want to retrieve the variable via the cloud.

1 Like

The fix was immediate. No more crashes. I took out the “&” and now my routine works !

Thank you :smile:

1 Like

Hi ScruffR,

I’m afraid I was rushed in concluding that the problem went away. Everything worked for a bit longer, but after 120 to 150 loops of generating the

Spark.variable("resultX", zTemp, STRING);

… the same crash locked up my Core.

I tried both zTemp and &zTemp[0] methods you suggested.

Not sure where else I’m going wrong…

Thanks,

Marcus

The next thing I'd suspect might be your

Since I've not looked into DHT22 I can't say if this does cause any harm, but I'd put a Spark.process(); into the loop to allow the Core to do the cloud "housekeeping".

Can you also give some more detail about the problem you are experiencing and put in some Serial.print() checkpoints to narrow down the location of the problem and the status of your variables?


Some unrelated hints:
You could use #define led2 D7 and #define idDHT22pin D4 instead of using int ... = ...; This would save some mem space and add speed (in small projects it wouldn't matter, but ...)
If you want someones direct attention in this forum, you could address (tag) them via (e.g.) @Marcus1 , then they will be notified to have a look at this thread.

@Marcus1, I have a lot of experience with the DHT22 lib (I ported it!) and it could be the cause if the sensor hangs, which is something I have found happens often with the library. I would highly recommend piettetech’s updated version of this library here.

Second, I am not sure why you have all the single quotes in the sprintf statement. These are not needed and I am not sure if they will cause problems. :smile:

That’s good advice…although I would say #defines are evil! ;-P:see_no_evil: If you use

const int led2 = D7;

The compiler will not allocate space for it and it will be inlined, just as if it was a #define. The benefit is that it preserves type-safety.

1 Like

To determine if it’s the sprintf or not, I would comment out that line and see if the app still crashes. (My feeling is that it’s not the sprintf…)

The single quotes have no special meaning within double quotes C-string generally and specifically no special meaning in a printf format string - they appear in the output.

@psb777, I believe the correct way to print a single quote is like a double quote, by using \'. :smile:

UDPATE: see here

1 Like

Fortunately, this is not a question that has to rely on faith alone. In a literal C string (a formal way of saying “within double-quotes”) a single quote never has a special meaning. In a printf format string it only has a special meaning within a conversion specification - between the ‘%’ character and the conversion specifier character e.g. "%'.2f"

The reference provided by @peekay123 says “Escape sequences are used to represent certain special characters within string literals and character literals.” Here we are talking about string literals.

String literals are delimited by double quotes. Character literals are delimited by single quotes. There is no need to escape a single quote within a string literal and there is no need to escape a double quote in a character literal.

char singlequote = '\'';
char doublequote = '"';
char somechars[] = "''''''\"\"\"\"\"";

The general rule is this: If an escaped character has no special meaning then the character escaped is the character itself.

I hope the original poster is reassured he can use his single quotes safely and correctly as he was doing.

I’d agree with @psb777 in this regard, but there is also an easy way to test and settle this.

As suggested above, try to Serial.print the string. If the char appears in the output as expected, escaping is not required, if it doesn’t or the string looks wrong, it’s likely to require escaping.


@mdma: I’ll try to bare the #define alternative in mind :wink:

You can verify it if you like, but remember the gcc compiler is being used. It’s standard C. It’s well understood or ought to be. It really is not helpful to make suggestions like this. There are a million things which could possibly be wrong, and I reckon we could come up with many other suggestions as to how the compiler might be broken. But it is not broken in this respect. And it isn’t helpful to suggest it is. Better than suggesting this it ought to have been tested beforehand.

But I want to reassure the OP again. There is no problem using single quotes as he does, and he would be wasting his time replacing the sprintf with serial.print except that sprintf takes lots of memory. Let’s be plain: If he sees a difference in behaviour it will be memory which is the issue.

In the interim we can each of us run this on every machine with every C compiler and report back :slight_smile:

main(){
printf("'\n");
printf("\'\n");
}

@psb777, I don't quite understand the undertone there. Could it be that you have actually misunderstood my post?
Actually I agreed with you and nothing else - but

You yourself suggested to check the output and since there is still an unresolved issue wit the OPs project my suggestion further up was to add checkpoints (e.g. Serial.print) to narrow down the cause of it - and hence these checkpoints could be put to further use to prove, what you and I already "know".
And I never suggested to replace sprintf() with Serial.print() but to check the sprintf()-output by Serial.print()ing it.

So what was actually "unhelpful" in that?

If you insist, you could maybe help @Marcus1 in a better way than I tried right from his first post on.


Don't confuse a friend for a foe, please - in this community we shouldn't expect a foe anyhow.

4 Likes

@Marcus1, I stand corrected on the use of the quote in a string literal. I sometimes have selective vision and oft-not-so-total recall :wink:

The one question no one asked so far is what you mean by “crashed”? Can you be more specific?

If what you mean by “crash” is actually “hang” then I highly suspect it is @ScruffR’s previous suggestion that the while (DHT22.acquiring()); is stuck (from my own experience) and though adding Spark.process() to the loop would prevent the cloud connection from dropping, it will not prevent it from running endlessly. Are you using piettetech’s updated DHT22 library?

This is what I actually wanted to find out, only less clear :wink:

Thanks @peekay123 for bringing the discussion back on track after some background noise hid it a bit :+1:

For the purpose of establishing if it's a crash or a hang, some Serial.print() - or any other means if someone does disagree with the use of this approach - would be helpful.

@ScruffR, all I was doing, however grumpily, was trying to avoid any misinformation being passed to the OP. I started off with a simple contradiction, an assertion there was no problem with the embedded single quotes. If there’s a problem with the brakes, being told to check the windscreen wipers, especially if they’re working fine, is a little annoying, especially if the suggestion is persisted with.

@psb777, I think you hit it! I think @Marcus1’s brakes have failed and that’s why he crashed! :wink: We are all on the same page now and @ScruffR latest suggestions are dead on. @Marcus1, just put a Serial.print() before and after the suspect while() loop and it should become very obvious if that is the problem. If that’s not the issue, then add more to follow the flow of the code.

3 Likes

Yes, but the single quotes were not the pivitol point here.

They were only one well meant (but not completely correct) “guess” of one of the biggest contributors in this community, to help the OP to narrow down all possible causes.
And actually we don’t know if it’s the brakes or something else.
And if the OP doesn’t want to rely on second hand insight but wants to actually learn and know how to nail down some unexpected behavior than even seemingly useless tests might help him to learn from them for the future.


If you hand someone in need a fish, you feed him for a day - If you teach him how to fish, you feed him for life.

2 Likes

And if you tell him fish aren’t good eating, to check he’s not eating fish, then …