I am doing a project where I query data from two sensors using a Particle Photon. The device is offline (no internet connection) most of the time, but I log in once every 10 mins to send data to Blynk. To further save on power, the device goes to sleep if it isn’t being used (no sensor data) for 10 seconds. From my understanding, Blynk only works off of Blynk. timer() and Blynk.run(). Is there anyway I can use VirtualWrite or use some other function to send data on my command, instead of using the Blynk timer routine?
Note: I have basically coded my own “timer” using the on board RTC, by using Time.hour() and Time.minute(), this is because the on board RTC is still on when the device is in sleep mode.
The community’s help is highly appreciated!! Please let me know if anything isn’t clear.
First, Blynk does need Blynk.run() and a network connection to a server to run, but BlynkTimer is all internal to the library, so all timers will keep working even if you are not connected to a server… that said, without connection, Blynk.virtualWrite() will have no server to send the data too, thus it will be “lost”.
@Gunner, Thank you for the prompt and elaborate explanation for timers. In this post I am including my “Internet” function (I changed it a little bit to hide auth…etc.), and as of now it doesn’t send data to my phone app. I believe the main problem is with Blynk.run(), since this is the only place it is being called (not called in void loop)! I am not calling it anywhere else because this function is the only place in the code where I have internet and Blynk connection established. However, when I run Blynk.run and Blynk.Timer in the void loop, it sends data just fine. Go ahead and take a look:
void Internet(){
if (checktime() == 1){ // if X amount of time has passed
Serial.println("Signing into the internet");
WiFi.on(); Serial.println ("WiFi On ");
while (WiFi.ready() == FALSE) {
WiFi.connect(); Serial.println ("WiFi Connecting");
delay(100);
}
Blynk.config("auth");
if (!Blynk.connected() & (WiFi.ready() == TRUE)){
Blynk.connect(30); // time out set to 30 seconds
Serial.println("Blynk connection occured");
}
Blynk.virtualWrite(V1, PIRCount);
Blynk.virtualWrite(V2, WheelCount);
Blynk.virtualWrite(V3, soc);
Blynk.run();
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);
soc= lipo.getSOC();Serial.print("State of charge is: ");Serial.println(soc);
WheelCount = 0;
PIRCount = 0;
}
else{
WiFi.off();
}
}
Is there anyway I can perhaps have Blynk.run() return a bool when it is done sending data, in this case I can do something like this:
bool x = 0;
while (x==0){
x= Blynk.run();
delay (100);
}
Also if I do something with a ‘for’ loop, will this send the data several times:
Is there anyway I can have Blynk.run return a bool when it is done sending data, in the case I can do something like this:
for(i=0; i< 10; i++){
Blynk.run();
delay (100);
}
To clarify: I am trying to find a way to send the data when I am commanding it to or when I call Blynk.run() once or in a loop without writing the data twice and without calling Blynk.run() ubiquitously in my code’s void loop() .
@wanek Sure, I am basically trying to use Blynk.run() without having it in a void loop. I guess you’ve posed my question in a different way you would like to know for how long to keep device "on" to make sure all the data is sent, or what?
I thought of it based on the number of times I call the function Blynk.run(), and not necessarily the “time/duration” that the device & WiFi need to be ‘on.’
yes, i understand now what you want to do.
but i do not understand why?
i think there should be a better solution than “managing” how many time to run blynk.run…
if you give more detail what is the main objective, i’m sure we could find a better / simpler way.
you could simply send a bool value to a display widget or button to the phone as the last blynk.write command, after all your other blynk.write commands.
then check with a blynk.read if the respective widget has the correct value. it means the transfer was finished, and you can put to sleep the wifi / mcu.
edit:
or, the technically more advanced solution to send the values directly to the blynk api, then look for the http response. if 200, than should be ok.
Ok, so I am making a device that quantifies motion data and wheel cycles using two sensors, a PIR and a hall effect. The device is in sleep mode unless someone is running on the wheel or moving in front of the device in which case an interrupt on a digital pin wakes the device up. I quarry the data offline without logging to the internet, and once every 10 mins I would like to log on the internet and send data to Blynk.
The device is battery powered it uses a 3.7 volt LiPo, so it needs to be power efficient. The most power hungry aspect of a Particle photon is logging to the internet, sending data and maintaining internet connection. That’s why when I am querying data from the sensors, I am doing it offline (not connected to the internet). So the purpose of the function I shared earlier on ^^ is to log on to the internet, log on to Blynk servers and send the data using Blynk.run(). Once the data is sent, I’d like to log off the internet and quarry the sensors offline again.
relax, it is not too complicated. i do not use it actually, but tested a long time before, and made it to work quite easy.
basically when you want to send the string of data from mcu, you just make a http get request and thats all. afaik it should be much more faster than via the blynk.run, this is why i think it is more energy saving.
please try it, and report back how it works. this function you can call from anywhere, you do not need blynk.run, neither blynk.begin. the only requirement is to have wifi internet connected. you can also send multiple values in the url string.
/*
by wanek t, 2017.
send data from esp8266 to blynk, using the blynk api. for more details, see:
http://docs.blynkapi.apiary.io/#reference/0/write-pin-value-via-put/write-pin-value-via-get
https://techtutorialsx.com/2016/07/17/esp8266-http-get-requests/
include these 2 libs:
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
*/
void APIget()
{
HTTPClient http; // create http object
String url = "http://blynk-cloud.com/"; // url
url += "blynk token here"; // your project token
url += "/update/";
url += "V14"; // pin to update
url += "?value=";
url += "HAHA"; // value to send
http.begin(url);
http.GET();
delay(10);
http.end();
}
#include <HttpClient.h>
/**
* Declaring the variables.
*/
unsigned int nextTime = 0; // Next time to contact the server
HttpClient http;
// Headers currently need to be set at init, useful for API keys etc.
http_header_t headers[] = {
// { "Content-Type", "application/json" },
// { "Accept" , "application/json" },
{ "Content-Type", "plain/text"},
{ "Accept" , "*/*"},
{ NULL, NULL } // NOTE: Always terminate headers will NULL
};
http_request_t request;
http_response_t response;
void setup() {
Serial.begin(9600);
}
void loop() {
if (nextTime > millis()) {
return;
}
Serial.println();
Serial.println("Application>\tStart of Loop.");
// Request path and body can be set at runtime or at setup.
request.hostname = "http://blynk-cloud.com/"; //blynk-cloud.com
request.port = 80;
request.path = "authtocken/update/V1?value=12";
// The library also supports sending a body with your request:
//request.body = "{\"key\":\"value\"}";
// Get request
http.get(request, response, headers);
Serial.print("Application>\tResponse status: ");
Serial.println(response.status);
Serial.print("Application>\tHTTP Response Body: ");
Serial.println(response.body);
nextTime = millis() + 10000;
}
just turn on the wifi in your sketch (without blynk)
and try the function. you do not need any port numbers, header formats etc for this to work.
please, first just try with a very basic sketch, and see if it works. i use the above method in one of my current projects, and it works 24h, sending some values every minute, without blynk.run, so it works 100% sure!
i’m not at my pc, but tomorrow i can send you more details, if you don’t succeed.
Thank you for the prompt response, I wasn’t at my desk either. I am using a Particle Photon, that’s why I automatically started searching for http libraries that would be equivalent to ESP8266HTTPClient.h. I am sure the code you sent earlier would work great for an ESP8266! This is why I am #including HTTPclient.h I think it essentially does the same thing in Particle Photons that #include ESP8266HTTPClient.h does in ESP8266. Let me know what you think!! Particle build doesn’t have the two libraries that you included.