virtualWrite multiple value then display


...

BLYNK_CONNECTED() {
  Blynk.virtualWrite(127, "ab", "cd");
}

...

If I use “Value Display” widget to show it then I get “abcd”.
Could it show “ab, cd” (I don’t want to send “ab, cd”)?

No, unless you send “ab, cd”.

Without more information about exactly what you’re trying to do, and why you can’t/won’t send “ab, cd”, it’s difficult to suggest a solution.
If you’re trying to construct a string of data from a number of string variables (as opposed to string literals as you’re showing in your example) then you could use the sprintf() function to construct the data to be sent to Blynk.

Pete.

yes you can use a string with concatenated values.

char comma= ',';
String StringValue;

StringValue=(String(value1)+ comma + String (value2));

BLYNK_CONNECTED() {
  Blynk.virtualWrite(127, StringValue);
}

Hello everyone,
I resuscitate this topic to avoid opening another one for the (about) same question.

I’m trying to send to Blynk app datas from wind sensors (windSpeed and windDirection) through Arduino MKR1010 WIFI (up to date Blynk library).
I initialize both variables as String and create another
String Wind = (windDirection + " " + windSpeed + "km/h");
I then send to Blynk once per second
Blynk.virtualWrite(V102, Wind);
but the value display displays only km/h.

here is the whole code

#include <SPI.h>
#include <WiFiNINA.h>
#include <BlynkSimpleWiFiNINA.h>
BlynkTimer timer;
char auth[] = "xxx";
char ssid[] = "xxx";
char pass[] = "xxx";

int dirPin = A1;
int speedPin = 0;

unsigned long lastMillis = millis();
int digitalCount = 0;
unsigned long durata = millis();
unsigned long startime = millis();
String windSpeed;
bool stato;
String windDirection;
int windAngle;
int adc;
//String wind = String(windDirection + windSpeed + "km/h");
String Wind = (windDirection + " " + windSpeed + "km/h");

void setup() {
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);

  pinMode(speedPin, INPUT);
  //timer.setInterval(1L, speedCalc);
  timer.setInterval(1L, windCalc);
}

void loop() {
  Blynk.run();
  timer.run();
  //speedCalc();
}

void windCalc() {
  digitalCount = digitalRead(speedPin);   // legge il pin del sensore

  if ((stato == 0) & (digitalCount == 1)) {    // punto di transizione
    durata = millis() - startime;        // calcola la durata della pulsazione
    startime = millis();            // setta il nuovo tempo di partenza
    windSpeed = 2500.0 / durata;  // calcola la velocità in Km/h
  }

  /*timer.setTimeout(10000L, []() {
    Serial.print(windSpeed);
    Serial.println(" km/h");
    });*/

  stato = digitalCount;

  adc = analogRead(A1);
  if (adc < 870 && adc >= 750) {
    windAngle = 0;
    windDirection = 'N';
  }
  if (adc < 440 && adc >= 380) {
    windAngle = 23;
    windDirection = "NNE";
  }
  if (adc < 500 && adc >= 440) {
    windAngle = 45;
    windDirection = "NE";
  }
  if (adc < 90 && adc >= 80) {
    windAngle = 68;
    windDirection = "ENE";
  }
  if (adc < 120 && adc >= 90) {
    windAngle = 90;
    windDirection = 'E';
  }
  if (adc < 80) {
    windAngle = 113;
    windDirection = "ESE";
  }
  if (adc < 220 && adc >= 150) {
    windAngle = 135;
    windDirection = "SE";
  }
  if (adc < 150 && adc >= 120) {
    windAngle = 158;
    windDirection = "SSE";
  }
  if (adc < 380 && adc >= 270) {
    windAngle = 180;
    windDirection = 'S';
  }
  if (adc < 270 && adc >= 220) {
    windAngle = 203;
    windDirection = "SSW";
  }
  if (adc < 680 && adc >= 615) {
    windAngle = 225;
    windDirection = "SW";
  }
  if (adc < 615 && adc >= 570) {
    windAngle = 248;
    windDirection = "WSW";
  }
  if (adc >= 920) {
    windAngle = 270;
    windDirection = 'W';
  }
  if (adc < 870 && adc >= 810) {
    windAngle = 293;
    windDirection = "WNW";
  }
  if (adc < 920 && adc >= 870) {
    windAngle = 315;
    windDirection = "NW";
  }
  if (adc < 750 && adc >= 680) {
    windAngle = 338;
    windDirection = "NNW";
  }

  timer.setTimeout(2000L, [] () {
    //    Serial.print (adc);
    Serial.print ("\t");
    Serial.println (windSpeed);
    Serial.println(windDirection);
    Blynk.virtualWrite(V100, windDirection);
    Blynk.virtualWrite(V101, windSpeed);
    Blynk.virtualWrite(V102, Wind);

  });
}

And what do you see in your serial monitor?

What type of widget are you sending this data to?

Pete.

Hi Pete.
I trying with a simple Value Display.
This is the serial monitor window. “NW” is the windDirection variable


I also cannot understand why the monitor is printing once in 30-40ms instead o 2s as stated here

timer.setTimeout(2000L, [] () {
    //    Serial.print (adc);
    Serial.print ("\t");
    Serial.println (windSpeed);
    Serial.println(windDirection);
    Blynk.virtualWrite(V100, windDirection);
    Blynk.virtualWrite(V101, windSpeed);
    Blynk.virtualWrite(V102, Wind);

  });

probably I did not understand fully how to use the Lambda Timer…

P.S. I can’t set a longer interval in the setup for this function because this causes bad data from windSpeed

Correct. You should remove the lambda time altogether, and change the frequency of this timer from once every millisecond to a more appropriate interval, say once every 5 seconds.

Also, your approach of attempting to poll the anemometer every 1ms and hoping to calculate the wind speed from this won’t work. You need to attach an interrupt to the anemometer pin and use that to calculate the windspeed…

Back to the original problem, you should try sending the value of Wind to the serial monitor to visualise your concatenated string.

Pete.

:flushed:
I’m sorry, I forgot to update the serial.print code part…
I did it and now I see exactly what I see in the Widget: “km/h” with a couple of blank space before and nothing elseSchermata 2021-01-10 alle 14.38.02

the code it is actually working. I set the Interval to 1ms just to use timer and do not call the function directly in the loop. I don’t know what’s the accuracy of the measurement, but it is coherent (faster rotation = higher speed, anemometer almost stopped = speed approx. 0). With the same code, I tried to use longer Interval in timer setup but values were totally incoherent.
I will give a try to interrupt implementing your code (in effect I already saw that someone use interrupts, but I don’t want a blocking code because I need the rain sensors to interrupt. I will try to understand how to set interrupts priorities.)

Okay, I see what’s happening - you are constructing your Wind variable at the top of the code, when windDirection and winsSpeed" are null, rather than in your windCalc` function.

Maybe, but not in the way you think, and it isn’t a sustainable approach if you want to measure rainfall too.

Did you read and understand what I wrote in the post that I linked you to?

I don’t think there is such a thing in C++, but if you read through what I wrote you’ll understand my approach - which works very successfully.

Pete.