[Solved] Red SOS flash using Blynk

I submitted this question over on the blynk forums but no response yet.

This has been a very strange issue. I am pushing data to 2 virtual pins, temperature and humidity from a DHT22 sensor. I am using the PietteTech_DHT library. However it seems if I push the temp and humidity values from the readings it causes my Photon to crash and do a red SOS blinking. If I hard code in say some int values like 5 and 6, it works just fine. But what is strange is that doing just one virtualWrite works just fine with the actual sensor values. Blynk Debug output has nothing that I can see of value. It just crashes and restarts.

Heres my stripped down code:

//#define BLYNK_DEBUG // Optional, this enables lots of prints
//#define BLYNK_PRINT Serial

#include "blynk/blynk.h"

char auth[] = "0123456789abcd";

#include <math.h>

// This #include statement was automatically added by the Particle IDE.
#include "PietteTech_DHT/PietteTech_DHT.h"

double temp                         = 0;
double humidity                     = 0;

#define DHTTYPE  DHT22       // Sensor type DHT11/21/22/AM2301/AM2302
#define DHTPIN   3           // Digital pin for communications

void dht_wrapper(); // must be declared before the lib initialization

PietteTech_DHT DHT(DHTPIN, DHTTYPE, dht_wrapper);

Timer blynk_timer(15000, blynkPublish);
Timer environment_timer(600000, environmentPublish);

void setup(){

    Particle.variable("g_temp", temp);
    Particle.variable("g_humidity", humidity);

	delay(1000);

    environmentPublish();

	delay(1000);

    blynk_timer.start();
    environment_timer.start();

    Particle.publish("End of setup");
    
    Blynk.begin(auth);

}

void dht_wrapper(){
    DHT.isrCallback();
}

void loop(){

    Blynk.run();

}

void blynkPublish(){

    if(Blynk.connected()){

       /* This failes */
        Blynk.virtualWrite(V0, temp);  // temp shows up like 70.2 when I view the variable
        Blynk.virtualWrite(V1, humidity); // humidity shows up like 50.4 when I view the variable

       /* 
       This is fine
        Blynk.virtualWrite(V0, 5);
        Blynk.virtualWrite(V1, 6);

        */


    }

}

void environmentPublish(){

    DHT.acquireAndWait();

    delay(500);

    temp = DHT.getFahrenheit();
    humidity = DHT.getHumidity();

    temp = round(temp*10)/10.0;
    humidity = round(humidity*10)/10.0;

    Particle.publish("temp", String(temp), 60, PRIVATE);
    Particle.publish("humidity", String(humidity), 60, PRIVATE);

}

How many red blinks do you see after the first SOS?
What does this (to be comparable to your other attempt with double vars)?

        Blynk.virtualWrite(V0, 5.5);
        Blynk.virtualWrite(V1, 6.6);
      // or
        double a = 5.5;
        double b = 6.6;

        Blynk.virtualWrite(V0, a);
        Blynk.virtualWrite(V1, b);

BTW, you can incorporate just one event to publish both values and don’t need to round(), since you can format the output (on Blynk too)

  Particle.publish("envData", String::format("%.1f°F %.1f%%", temp, humidity), PRIVATE);

I’d be not too keen on having DHT.acquireAndWait(), delay() or Particle.publish() inside a soft timer callback.

Success! I changed my temp and humidity datatypes to String and then just wrapped your cool String::format() around DHT.getFahrenheit() and bingo everything worked with no crashes. That is a much cleaner method to format sensor values that will be just sent back to a logging service.

Thanks for the advice!

I was thinking about your last statement. I know I do not have the level of expertise that you have but I’ve seen people, especially on the blynk side, say you shouldn’t have anything that will delay your code in the main loop and put them in timers. I’ve also have not had really any issues with having devices run for months if not over a year that way. If you are trying to avoid a 1 in a million chance of something getting hosed up is that worth less maintanable code?

If you look at example code showing how to use a DHT22 you’ll see people all over saying you need to “let it breath so add a delay”. Blynk says, no delays in main loop, use timers. You say no delays in timers. I guess this is the world we live in with examples taken from non-internet capable devices to different software vendors but my god it can be confusing to know what is the proper way to do things…especially if you are not a C wizard.

delay() is a nice and easy way in isolated environments with only one or a few tasks to perform, but it's best replaced with non-blocking alternatives (where possible).

While I agree with the first part (and suggest to go non-blocking), I'm a bit reluctant towards the second.
I'd say: "... and don't put delays in timers either".
It's OK to offload tasks to timers but keep the visits short, since the timers also need to share the µC and the time wasted in idle delays - even inside a timer callback - is still lost for other tasks.

Well planned async and non-blocking code doesn't have to be less maintainable.

This might me mixing pears and apples.
Tasks that would "delay" loop() don't necessarily mean using idle delay(). Time that needs to be spent doing stuff is time spent well, but just hanging around in an idle loop is not.
The former is required to achieve a goal but the latter should be avoided wherever possible.

1 Like

I think you are missing my point and validating it all in the same breath. I’m not debating if you are right or not. I’m explaining my experience/thought process. I’m saying people from lower levels of experience can easily be confused by conflicting information coming from all different resources on coding for arduino/microprocessors. To you, issues may seemed to be apples and pears but to others, it looks like apples and apples.

I had a college professor who was very smart and knew his subject material but good luck if you were not in the top 10% of the class. He can’t see things from other peoples prospectives and in my opinion is a poor teacher.

I had a similar experience on here maybe a year ago. I had a sketch on an Etherten and wanted to move it to the photon. It makes use of timers to send data out. I used a library called setInverval (http://playground.arduino.cc/Code/SimpleTimer#F_setInterval) to have something fire off every 10 minutes. So I searched for that in the packages and found one called exactly that. I used it but it wasn’t working right. I communicated with the author of it via this forum and found out that library wasn’t the best use case for my situation. The problem was when I called him out on lack of documentation or properly commented code made it seem like he expected that I would read through all of the source code and understand exactly how it works and how to use it. Hell, I didn’t even realize that I could click on the github icon and read more details there about it until the very end.

I don’t mean any offend anybody, but i’m trying to stick up for the less educated/experienced trying swim in this deep ocean.

I’ll get off my soap box now. Thanks for your time and willingness to help others! I’m sure I’ll need more in the future.

I see and agree - it’s not always easy to see a problem from the same perspective as someone else, no matter the skill level :wink:
Tuning in on someone else’s view is a skill by itself :blush:

But I hope my waffle about “delay” vs. delay() did contain some crumbs of useful information.

1 Like