Photon not threading when using Blynk functions

Hello, I am new to this community so I don’t know if my problem has already been solved, but “Problems with particle photon and Blynk” under “Projects made with Blynk” seems to be having the same problem, and no one really addressed it :frowning:

I am making a device using Particle Photon and viewing/saving the data using Blynk. The device keeps counting “cycles” and if it hasn’t been used for quite sometime (20 sec) then it goes to sleep, and wakes up on an interrupt pin. Periodically, I log on to the interned and purge the data to Blynk. I am using SYSTEM_MODE(SEMI_AUTOMATIC); to control when I connect to the internet, and SYSTEM_THREAD(ENABLED); because it’s crucial for me to run processes in parallel and not lose data while trying to connect to WiFi/send data to Blynk…etc.

Unfortunately, when Blynk.begin(auth); is called without internet connection, the device stays offline (white LED breathing) and doesn’t proceed with setup()/void loop() {}; (I think this is what’s happening with the person I mentioned from the other post). In order to solve that problem I moved Blynk.Begin(); to a much later point in the code when an internet connection has been established.

However, when Blynk.begin(auth) is called it doesn’t allow threading to occur, void loop(){} isn’t running and the function doesn’t return until several seconds has passed that’s the time when I am currently loosing data and at this point the Photon is just trying to log on to the internet/establish a connection without using another thread to run void loop(){};

Any solutions for this? Is it possible to SYSTEM_THREAD(ENABLED) with Blynk? Any help would be highly appreciated, Thanks!

Here is my code:

#include <blynk.h>
#include "Particle.h"
#include "application.h"
#define Halleffect D1

SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(SEMI_AUTOMATIC);

char auth[] = "";
int WheelCount = 0;
int previous_state=1;
int current_state= 1;

unsigned int T1= 0;
unsigned int T2= 0;
unsigned int T_lapse_sleep= 0;
unsigned int T_lapse_data= 0;

int control = 1;

int t =0;
int h;int m=0;
int previous_h= 0;
int previous_m=0;
bool c = FALSE;

BlynkTimer timer;


void setup() {
    // SYSTEM_THREAD(ENABLED);
    // SYSTEM_MODE(SEMI_AUTOMATIC);
    
    Serial.begin(9600);
    delay (4000);Serial.println("starting at the beggining of setup");
    t = Time.now();
    timer.setInterval(1000L, WriteWheelData);
    pinMode(Halleffect,INPUT_PULLUP);
    pinMode(D7, OUTPUT);
    T1= millis();
}

void loop() {
    current_state = digitalRead(Halleffect);
    //Serial.println(current_state);
    
    if (current_state == 0){ //if a cycle is read
        if (previous_state != current_state){
            WheelCount += 1;
            Serial.print("Wheel count is: ");
            Serial.println(WheelCount);
            digitalWrite (D7, HIGH);
            delay (100);
            digitalWrite (D7, LOW);
            T2= millis();
            previous_state= current_state ;
            control = 1;
        }
    }
    
    else{ //a cycle isn't read
        previous_state= current_state;
        T_lapse_sleep = millis() - T2;
        if (T_lapse_sleep > 20000){ // sleep if wheel isn't used within 30 seconds

            // previous_h= Time.hour();
            // Serial.print("Previous hour is: ");Serial.print(previous_h);
            // previous_m= Time.minute();
            // Serial.print("Previous minute is: ");Serial.print(previous_m);
            Serial.println("Sleep");
            System.sleep(Halleffect,FALLING);
            
            Serial.begin(9600);
            SYSTEM_THREAD(ENABLED);
            SYSTEM_MODE(SEMI_AUTOMATIC);
            
            
            delay(100);
            
            //c= check_time();
            control = 0;
            T1= millis();
            T2= millis();
        }
    }
    
    Internet();
    
}

void Internet(){
    T_lapse_data = millis() - T1;
    if (T_lapse_data > 10000 & control == 1 ){
    //if (control == 1 & (c  || T_lapse_data > 10000) ){ // if it has been turned off for 10 mins or if it has been running for 1 min
        if (WiFi.ready() == FALSE) {
            WiFi.on();
            Serial.println ("WiFi On ");
            WiFi.connect();
            Serial.println ("WiFi Connecting");
        }
        
        Blynk.begin(auth);
        Serial.println ("Connected!");
        timer.run();
        Blynk.run();
        T1= millis();
    }
}


void WriteWheelData()
{
  Blynk.virtualWrite(V1, WheelCount);  
  WheelCount = 0;
}


bool check_time(){
    h= Time.hour();
    m= Time.minute();
    if (((h == previous_h) || (h > previous_h)) & (m >= previous_m + 1)){return TRUE;}
    else{ return FALSE;}
}

Look at using Blynk.config() instead:
http://docs.blynk.cc/#blynk-firmware-configuration-blynkconfig
http://docs.blynk.cc/#blynk-firmware-connection-management

And you have too much in your void loop()… break things out into timed routines:

http://docs.blynk.cc/#troubleshooting-flood-error
http://docs.blynk.cc/#blynk-firmware-blynktimer

But with the Photon equivalent that is called something like “Sparkcorepolledtimer”.

1 Like

Good point… I keep forgetting about some of the proprietary issues with Particle boards.

Thanks.

Thank you both for the prompt response. A combination of connecting to WiFi manually, Blynk.config, Blynk.connect and Blynk timer did the trick!!

Blynk Timer actually worked fine for me! How is Sparkcorepolledtimer different than using millis()? I am just curious.

Thanks,
Mohamed

1 Like

From what I can read on Google and https://community.particle.io/ it is a semi-proprietary timer library, using the internal clock of the Spark Core; similar to what SimplleTimer did for Arduino. i.e. it takes some of the coding intricacies out of using straight millis()