Average from virtual pins, possible?

I send temperature(V11) and humidity(V12) to Blynk, every ten seconds. There could be downtime of device where I’ll start losing the options of calculating average over a longer period of time. So, is there a way to calculate the following?

24 hours average
Today’s average
1 week’s average
1 month’s average
3 month’s average
6 month’s average
1 Year’s average

Your question is vauge.

You want to perform this on your hardware? or in the app?
What data are you using to calculate time from the temp and humidity data?
Are you logging the times on the hardware?

We would also need to see you code to be able to assist you further.

History Graph is able to show 3 month’s history. And History Graph does this with stored virtual pin data. Similarly, I want to retrieve values from virtual pin history, and use it to calculate the averages I mentioned earlier…

In short, Calculation can happen in hardware, but values has to be retrieved from cloud. I can’t store or maintain values locally for months…

Gotcha! Makes more sense now!

Its easy to do with global vars, a new virtual pin for each stored value (so a range of 7 in your case), and then a function the compiles/updates and renews the coutners. You will also need to log your own time with the RTC widget and some code.

Share your code and I can help you get started if you like.

Wow! Looks like it’s possible. Let me share the code :slight_smile:

1 Like
// This #include statement was automatically added by the Particle IDE.
#include <SparkCorePolledTimer.h>

// This #include statement was automatically added by the Particle IDE.
#include <blynk.h>

// This #include statement was automatically added by the Particle IDE.
#include <CE_BME280.h>

#define SEALEVELPRESSURE_HPA (1013.25)

char auth[] = "Blynk Auth Token";

SparkCorePolledTimer updateTimer2(2000);
void twoseconds(void);

CE_BME280 bme; // I2C

void setup() {
    Serial.begin(9600);
  
     // Set Timezone
    Time.zone(5.5);

    // Updating Timers To be Active
    updateTimer2.SetCallback(twoseconds);
  
    Blynk.begin(auth);
  
    Serial.println(F("BME280 test"));

    if (!bme.begin()) {
        Serial.println("Could not find a valid BME280 sensor, check wiring!");
        while (1);
    }
}

void twoseconds() {
    Serial.print("Temperature = ");
    Serial.print(bme.readTemperature());
    Serial.println(" *C");

    Serial.print("Pressure = ");

    Serial.print(bme.readPressure() / 100.0F);
    Serial.println(" hPa");

    Serial.print("Approx. Altitude = ");
    Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
    Serial.println(" m");

    Serial.print("Humidity = ");
    Serial.print(bme.readHumidity());
    Serial.println(" %");

    Serial.println();
    
    Blynk.virtualWrite(V11, bme.readTemperature());
    Blynk.virtualWrite(V12, bme.readHumidity());
}

void loop() {
    Particle.process();
    if (WiFi.ready()) {
        Blynk.run();
    }
    updateTimer2.Update();
}

Okay cool… give me a moment to process it and ill update this post.

You will actually need 12 vpins, 6 for temp and 6 for humidity (i ditched the 24 since its the same as day)
First thing you need to do is create some global floats to store the values to use outside of the scope
Put these with your auth token.

float temp_current, temp_24hr, temp_1w, temp_1m, temp_3m, temp_6m, temp_1y; 
float humidty_current, humidty_24hr, humidty_1w, humidty_1m, humidty_3m, humidty_6m, humidty_1y; 

Then you need to define the vpins you will be using. Defining will help you change the pins later easily if you need to (trust me its good practice!)
Put these at the top.

#define vPIN_TEMP_24HR V20
#define vPIN_TEMP_1W V21
#define vPIN_TEMP_1M V22
#define vPIN_TEMP_3M V23
#define vPIN_TEMP_6M V24
#define vPIN_TEMP_1Y V25

#define vPIN_HUMIDITY_24HR V26
#define vPIN_HUMIDITY_1W V27
#define vPIN_HUMIDITY_1M V28
#define vPIN_HUMIDITY_3M V29
#define vPIN_HUMIDITY_6M V30
#define vPIN_HUMIDITY_1Y V31

Then you need to create a BLYNK_WRITE for each pin so that you can pull the value from the cloud later.

BLYNK_WRITE(vPIN_TEMP_24HR){
  temp_24hr = param.asFloat();
}
BLYNK_WRITE(vPIN_TEMP_1W){
  temp_1w = param.asFloat();
}
BLYNK_WRITE(vPIN_TEMP_1M){
  temp_1m = param.asFloat();
}
BLYNK_WRITE(vPIN_TEMP_3M){
  temp_3m = param.asFloat();
}
BLYNK_WRITE(vPIN_TEMP_6M){
  temp_6m = param.asFloat();
}
BLYNK_WRITE(vPIN_TEMP_1Y){
  temp_1y = param.asFloat();
}
BLYNK_WRITE(vPIN_HUMIDITY_24HR){
  humidty_24hr = param.asFloat();
}
BLYNK_WRITE(vPIN_HUMIDITY_1W){
  humidty_1w = param.asFloat();
}
BLYNK_WRITE(vPIN_HUMIDITY_1M){
  humidty_1m = param.asFloat();
}
BLYNK_WRITE(vPIN_HUMIDITY_3M){
  humidty_2m = param.asFloat();
}
BLYNK_WRITE(vPIN_HUMIDITY_6M){
  humidty_6m = param.asFloat();
}
BLYNK_WRITE(vPIN_HUMIDITY_1Y){
  humidty_1y = param.asFloat();
}

Then you need to do a virtualSync in setup to call the values from the cloud.

void setup(){
// ...   
Blynk.syncVirtual(vPIN_TEMP_24HR, vPIN_TEMP_1W, vPIN_TEMP_1M, vPIN_TEMP_3M, vPIN_TEMP_6M, vPIN_TEMP_1Y);
Blynk.syncVirtual(vPIN_HUMIDITY_24HR, vPIN_HUMIDITY_1W, vPIN_HUMIDITY_1M, vPIN_HUMIDITY_3M, vPIN_HUMIDITY_6M, vPIN_HUMIDITY_1Y);
}

Then, at the time you store the values in to V11 and V12 you need to calcuate the averages then store them.

temp_current = bme.readTemperature();
humidity_current = bme.readHumidity();

Blynk.virtualWrite(V11, temp_current);
Blynk.virtualWrite(V12, humidity_current);

temp_24hr = (temp_24hr + temp_current) / 2;
Blynk.virtualWrite(vPIN_TEMP_24HR,temp_24hr);

temp_1w = (temp_1w + temp_current) / 2;
Blynk.virtualWrite(vPIN_TEMP_1W,temp_1w);

temp_1m = (temp_1m + temp_current) / 2;
Blynk.virtualWrite(vPIN_TEMP_1M,temp_1m);

// repeat the other 9 etc

Thne you need to reset them according to the RTC. So install the RTC library and learn how to use that in a difference project. Then you can use what you learnt to reset all the values to 0 as well as Blynk.virtualWrite() to each pin depending when you need to.
Here is some fake code for you to recreate as an example.

if current_day != new_day 
  then 
    temp_24hr = 0 AND virtualWrite(vPIN_TEMP_24HR,0) 
    humidity_24hr = 0 AND virtualWrite(vPIN_HUMIDITY_24HR,0) 

if current_month != new_month
  then 
    temp_1m = 0 AND virtualWrite(vPIN_TEMP_1M,0) 
    humidity_1M = 0 AND virtualWrite(vPIN_HUMIDITY_1M,0) 

// repeat for all

@ilak2k, another huge note is 2second polling is rediculous! Change that to poll for new temp/humidty every 5 or 10minutes. The changes you want to record will only be valid every 5mins at least.

2 Likes

Blynk.virtualWrite(V11, temp_current); already writes current temperature to Blynk Server.

So, shouldn’t we just retrieve values from where its stored based on time?
Retrieve values for last 1 week and average them
Retrieve values for last 1 month and average them
and so on…

It’s all there, right? We can see those average values in the History Graph already. Aren’t they retrievable?
Why use 6 virtual pins?

The history graph doesnt work like that. You need to think of it just visualising all the data you have sent over time. You cannot query a value from the history on demand.

If you are using a local server, you do have the ability to write some code to visualise the data because you will have access to the database.

Another user in this community has been building a web dash.