Understanding Step Widget

Particle Boron via cellular
iOS running 12.4.1
Blynk Server
Blynk 0.6.3 in Particle IDE and latest version of app

I am trying to learn how to use the step widget. I set out to build a simple thermostat. If the user adjusts the step widget and it is >= to the temp value, write some digital pins HIGH. If the step is < the temp value the write those digital pins LOW.

The code I am using

BLYNK_WRITE(V2) {
  stepWidget = param.asInt();
  Blynk.virtualWrite(V1, stepWidget); //
  Serial.printf("Step");
  Serial.println(stepWidget);
 if(stepWidget >= sensors.fahrenheit()){
  digitalWrite(D7, HIGH);
  digitalWrite(D0, HIGH);
  Serial.println ("ON");
 }
 else if (stepWidget < sensors.fahrenheit()){
     digitalWrite(D7, LOW);
     digitalWrite(D0, LOW);
     Serial.println("OFF");
 }
 
}

The step widget values are set from 60 to 85 with a step of 1.0, send step OFF and loop values OFF. While the >= argument seems to work, I get random HIGH/LOW results for the < portion of the code.

Temperature  F 70.81
Temperature  F 70.81
Temperature  F 70.81
Temperature  F 70.81
Temperature  F 70.81
Temperature  F 70.81
Temperature  F 70.81
Temperature  F 70.81
Temperature  F 70.81
Temperature  F 70.81
Temperature  F 70.93
Step61
ON
Temperature  F 70.93
Temperature  F 70.93
Temperature  F 70.81
Temperature  F 70.93
Step62
OFF
Temperature  F 70.93
Temperature  F 70.93
Step63
OFF
Temperature  F 70.93
Step64
OFF
Temperature  F 70.93
Step65
ON
Temperature  F 70.93
Temperature  F 70.93
Temperature  F 70.93
Step66
OFF
Temperature  F 70.93
Step67
OFF
Temperature  F 70.93
Step68
OFF
Temperature  F 70.93
Step69
OFF
Temperature  F 70.93
Step70
ON
Temperature  F 70.93
Temperature  F 70.93
Step69
OFF
Temperature  F 70.93
Temperature  F 70.93
Temperature  F 70.93
Temperature  F 70.93
Step68
OFF
Temperature  F 70.93
Step67
OFF
Temperature  F 70.93
Step66
OFF
Temperature  F 70.93
Step65
OFF
Temperature  F 70.93
Step64
OFF
Temperature  F 70.93
Step63
OFF
Temperature  F 70.93
Step62
OFF
Temperature  F 70.93
Step61
OFF
Temperature  F 70.93
Step60
OFF
Temperature  F 70.93
Temperature  F 70.93
Temperature  F 70.93
Temperature  F 70.93
Temperature  F 70.93
Step61
ON
Temperature  F 70.93
Step62
ON
Temperature  F 70.93
Temperature  F 70.93
Step63
OFF
Temperature  F 70.93
Step64
OFF
Step65
ON
Temperature  F 70.93
Step66
ON
Temperature  F 70.93
Temperature  F 70.93
Step67
OFF
Temperature  F 70.93
Step68
OFF
Step69
ON
Temperature  F 70.93
Step70
OFF
Temperature  F 70.93
Step71
ON
Temperature  F 70.93
Temperature  F 70.93
Step72
ON
Temperature  F 70.93
Temperature  F 70.93
Temperature  F 70.93
Step71
ON
Temperature  F 70.93
Step70
OFF
Step69
OFF
Step68
OFF
Temperature  F 70.93
Step67
OFF
Step66
OFF
Step65
OFF
Step64
OFF
Temperature  F 70.93
Step63
OFF
Step62
OFF
Step61
OFF
Step60
OFF
Temperature  F 70.93
Temperature  F 70.93
Temperature  F 70.93
Temperature  F 70.93
Temperature  F 70.93
Temperature  F 70.93
Temperature  F 70.93

What have I missed in my understanding of the widget or my code? I have searched the community and while I found other step widget issues, I failed to locate an answer that I could apply to my situation. Any help is appreciated.

It’s possible that you’re comparing int to float and the compiler is not smart enough

Test this code to see if it’s OK

BLYNK_WRITE(V2) {
  stepWidget = param.asInt();
  Blynk.virtualWrite(V1, stepWidget); 
  Serial.printf("Step");
  Serial.println(stepWidget);
  Serial.printf("Temp");
  Serial.println(sensors.fahrenheit());
  Serial.printf("(int) Temp");
  Serial.println((int) sensors.fahrenheit());

  if (stepWidget >= (int) sensors.fahrenheit())
  {
    digitalWrite(D7, HIGH);
    digitalWrite(D0, HIGH);
    Serial.println ("ON");
   }
   else
   {
     digitalWrite(D7, LOW);
     digitalWrite(D0, LOW);
     Serial.println("OFF");
   }
}

@khoih, thank you very much for the reply and the code. I do have this at the beginning of my code

 int stepWidget;

I will try as you suggest and let you know how it goes.
Thanks again!

Still getting random results

Temperature  F 66.54
Temperature  F 66.54
Temperature  F 66.54
Temperature  F 66.54
Temperature  F 66.54
Step61
Temp66.54
(int) Temp66
OFF
Temperature  F 66.54
Temperature  F 66.54
Temperature  F 66.54
Step62
Temp66.54
(int) Temp66
OFF
Temperature  F 66.54
Temperature  F 66.54
Step63
Temp66.54
(int) Temp66
OFF
Temperature  F 66.54
Step64
Temp66.54
(int) Temp66
OFF
Temperature  F 66.54
Temperature  F 66.54
Step65
Temp66.54
(int) Temp66
OFF
Step66
Temp32.00
(int) Temp32
ON
Temperature  F 66.54
Temperature  F 66.54
Temperature  F 66.54
Step67
Temp66.54
(int) Temp66
ON
Temperature  F 66.54
Step68
Temp66.54
(int) Temp66
ON
Temperature  F 66.54
Step69
Temp32.00
(int) Temp32
ON
Temperature  F 66.54
Step68
Temp32.00
(int) Temp32
ON
Temperature  F 66.54
Step67
Temp66.54
(int) Temp66
ON
Step66
Temp66.54
(int) Temp66
ON
Temperature  F 66.54
Step65
Temp66.54
(int) Temp66
OFF
Temperature  F 66.54
Step64
Temp32.00
(int) Temp32
ON
Temperature  F 66.54
Step63
Temp66.54
(int) Temp66
OFF
Temperature  F 66.54
Temperature  F 66.54
Temperature  F 66.54
Temperature  F 66.54
Temperature  F 66.54
Temperature  F 66.54
Temperature  F 66.54
Temperature  F 66.54
Temperature  F 66.54
Temperature  F 66.54
Step62
Temp32.00
(int) Temp32
ON
Temperature  F 66.54
Step61
Temp66.54
(int) Temp66
OFF
Step60
Temp66.54
(int) Temp66
OFF
Temperature  F 66.54
Temperature  F 66.54
Temperature  F 66.54
Temperature  F 66.54
Step61
Temp66.54
(int) Temp66
OFF
Step62
Temp66.54
(int) Temp66
OFF
Temperature  F 66.54
Step63
Temp66.54
(int) Temp66
OFF
Temperature  F 66.54
Step64
Temp66.54
(int) Temp66
OFF
Temperature  F 66.54
Step65
Temp66.54
(int) Temp66
OFF
Step66
Temp32.00
(int) Temp32
ON
Temperature  F 66.54
Step65
Temp32.00
(int) Temp32
ON
Temperature  F 66.54
Temperature  F 66.54
Temperature  F 66.54
Step64
Temp66.54
(int) Temp66
OFF
Temperature  F 66.54
Step63
Temp66.54
(int) Temp66
OFF
Temperature  F 66.54
Step62
Temp66.54
(int) Temp66
OFF
Temperature  F 66.54
Temperature  F 66.54
Step61
Temp66.54
(int) Temp66
OFF
Temperature  F 66.54
Temperature  F 66.54
Step60
Temp32.00
(int) Temp32
ON
Temperature  F 66.54
Temperature  F 66.54
Temperature  F 66.54
Temperature  F 66.54
Temperature  F 66.54
Temperature  F 66.54
Temperature  F 66.54
Temperature  F 66.54
Temperature  F 66.54
Temperature  F 66.54
Temperature  F 66.54
Temperature  F 66.54

The comparison is working correctly now.
The issue is your sensor sending random results and you have to check why. There is nothing wrong with the step widget.

1 Like

Seems odd that the “error” is only present <sensors.fahrenheit(). It works flawlessly if(stepWidget >= sensors.fahrenheit())

EDIT
Also of interest, if DO, D7 are HIGH in error, such as they are HIGH when the step is at 60 while the DS18B20 reports 67, if I continually tap the - button on the widget, D0, D7 will go LOW after a few taps.

I think the root cause is that you call sensors.fahrenheit() repetitively and unnecessarily. This will create erratic behaviour.

It’s better to do like this

float temp;

void Read_Temp()
{
  ...  
  // Read temp directly here to global var temp, then use everywhere
  temp = sensors.fahrenheit();
  Serial.printf("Temp = ");
  Serial.println(temp);
  ....      
}

BLYNK_WRITE(V2) {
  stepWidget = param.asInt();
  Blynk.virtualWrite(V1, stepWidget); 
  Serial.printf("Step");
  Serial.println(stepWidget);
  Serial.printf("Temp : ");
  Serial.println(temp);
  Serial.printf("(int) Temp = ");
  Serial.println((int) temp);

  if (stepWidget >= (int) temp)
  {
    digitalWrite(D7, HIGH);
    digitalWrite(D0, HIGH);
    Serial.println ("ON");
   }
   else
   {
     digitalWrite(D7, LOW);
     digitalWrite(D0, LOW);
     Serial.println("OFF");
   }
}
1 Like

That makes sense. Ill give it a whirl. I appreciate your continued help

@khoih Well, I found out what is going on, but I must admit I have no idea how to fix it, yet. Every other push of the step widget causes the (int) temp to change from the actual temp to 32.00. This is why once I reach the >= it never is an issue because both variables are now true. Check it out.

Step  60
Temp  71.49
(int) Temp  71
OFF
Step  61
Temp  32.00
(int) Temp  32
ON
Step  62
Temp  71.49
(int) Temp  71
OFF
Step  63
Temp  32.00
(int) Temp  32
ON
Step  64
Temp  71.49
(int) Temp  71
OFF
Step  65
Temp  32.00
(int) Temp  32
ON
Step  66
Temp  71.49
(int) Temp  71
OFF
Step  67
Temp  32.00
(int) Temp  32
ON
Step  68
Temp  32.00
(int) Temp  32
ON
Step  69
Temp  32.00
(int) Temp  32
ON
Step  70
Temp  32.00
(int) Temp  32
ON
Step  71
Temp  71.49
(int) Temp  71
ON
Step  72
Temp  32.00
(int) Temp  32
ON
Step  73
Temp  71.49
(int) Temp  71
ON
Step  74
Temp  32.00
(int) Temp  32
ON
Step  75
Temp  71.49
(int) Temp  71
ON
Step  74
Temp  32.00
(int) Temp  32
ON
Step  73
Temp  32.00
(int) Temp  32
ON
Step  72
Temp  71.49
(int) Temp  71
ON
Step  71
Temp  32.00
(int) Temp  32
ON
Step  70
Temp  71.49
(int) Temp  71
OFF
Step  69
Temp  32.00
(int) Temp  32
ON
Step  68
Temp  32.00
(int) Temp  32
ON
Step  67
Temp  32.00
(int) Temp  32
ON
Step  66
Temp  71.49
(int) Temp  71
OFF
Step  65
Temp  32.00
(int) Temp  32
ON
Step  64
Temp  32.00
(int) Temp  32
ON
Step  63
Temp  32.00
(int) Temp  32
ON
Step  62
Temp  71.49
(int) Temp  71
OFF
Step  61
Temp  32.00
(int) Temp  32
ON
Step  60
Temp  71.49
(int) Temp  71
OFF
Step  60
Temp  32.00
(int) Temp  32
ON

Edit BTW, this is using the code from your first suggestion. I never got the second one to work at all

There must be something wrong in the other part of your code so that the second suggestion didn’t work.
The widget has no power to change anything.
You have to post the whole code so we know where the problem is.

Here it is

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

DS18 sensors(D1);

float stepWidget;

char auth[] = "auth token";


BLYNK_CONNECTED() {
  
    Blynk.syncAll();
    Blynk.notify("CONNECTED");
   Blynk.syncVirtual(V1);
  
}



BLYNK_WRITE(V2) {
    if (sensors.read())
  stepWidget = param.asInt();
  Blynk.virtualWrite(V1, stepWidget); 
  Serial.printf("Step  ");
  Serial.println(stepWidget);
  Serial.printf("Temp  ");
  Serial.println(sensors.fahrenheit());
  Serial.printf("(int) Temp  ");
  Serial.println((int) sensors.fahrenheit());
 

if (stepWidget >= (int) sensors.fahrenheit())
  {
    digitalWrite(D7, HIGH);
    digitalWrite(D0, HIGH);
    Serial.println ("ON");
   }
   else
   {
     digitalWrite(D7, LOW);
     digitalWrite(D0, LOW);
     Serial.println("OFF");
   }
}

void setup() {
  Serial.begin(9600);
  Blynk.begin(auth);
  Blynk.syncVirtual(V1);
  
  pinMode(D0, OUTPUT);
  pinMode(D7, OUTPUT);

}

void loop() {
  Blynk.run();
}

Found it

void setup() {
  Serial.begin(115200);
  Blynk.begin(auth);
  Blynk.syncVirtual(V10);
  sensors.read(); //ADD THIS HERE
  
  pinMode(D0, OUTPUT);
  pinMode(D7, OUTPUT);

}

Instead of

BLYNK_WRITE(V2) {
    if (sensors.read()) //INSTEAD OF HAVING THIS HERE

That fixed it!
Thanks very much for your help

You have to move sensor.read() outside BLYNK_WRITE(V2), and use timer to call it.
For example (to modify according to Particle syntax)

float temp;
void readSensor()
{
   sensors.read();
   temp = sensors.fahrenheit();
   Serial.printf("readSensor: (int) Temp = ");
   Serial.println((int) temp);
}

BLYNK_WRITE(V2) {
  stepWidget = param.asInt();
  Blynk.virtualWrite(V1, stepWidget); 

  Serial.printf("Step = ");
  Serial.println(stepWidget);
  Serial.printf("(int) Temp = ");
  Serial.println((int) temp);

  if (stepWidget >= (int) temp)
  {
    digitalWrite(D7, HIGH);
    digitalWrite(D0, HIGH);
    Serial.println ("ON");
  }
  else
  {
     digitalWrite(D7, LOW);
     digitalWrite(D0, LOW);
     Serial.println("OFF");
  }
}

void setup() {
  Serial.begin(9600);
  Blynk.begin(auth);
  Blynk.syncVirtual(V1);
  
  pinMode(D0, OUTPUT);
  pinMode(D7, OUTPUT);

  timer.setInterval(5000,  readSensor);
}

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

1 Like

Noted. Thanks for cleaning it up for me and again, Thank you very much for your help

@khoih one more question. As I worked back through this today, I am apparently still missing something. The example you provided does not return any data in the serial print? Here is one of the many examples I tried to get simply the global var to print.

 #include <blynk.h>
#include "DS18.h"

float temp;

DS18 sensors(D5);

char auth[] =

void Read_Temp()
{
  // Read temp directly here to global var temp, then use everywhere
  temp = sensors.fahrenheit();
  Serial.printf("Temp = ");
  Serial.println(temp);
       
}


void setup() {
  Serial.begin(115200);
  Blynk.begin(auth);
(sensors.read());
}

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

}

Thanks again

I wonder how the code can display anything when the Read_Temp() hasn’t been called anywhere.
You can use millis() to call it periodically as follows:

#include <blynk.h>
#include "DS18.h"

float temp;

DS18 sensors(D5);

char auth[] =

// How often we update the temperature
#define INTERVAL_MS   10000

// Global variable to track time (used for temp sensor readings)
system_tick_t time_millis;

void Read_Temp()
{
 (sensor.read());
  // Read temp directly here to global var temp, then use everywhere
  temp = sensors.fahrenheit();
  Serial.printf("Temp = ");
  Serial.println(temp);  
}

void setup() 
{
  Serial.begin(115200);
  Blynk.begin(auth);

 // Set time to 0
  time_millis = 0;
}

void loop() 
{
  Blynk.run();

  // Check if our interval > 10s
  if( millis() - time_millis > INTERVAL_MS ) 
  {
     //Set time to the 'current time' in millis
     time_millis = millis();
     Read_Temp();
   }
}

But I’m suggesting that you’d better go the Particle Forum to search for help because different syntax, hardware and libraries are used

1 Like

Good advice and this is what I have been doing. Taking your suggestions, reading on Blynk and Particle. Thank you once again

@mpo881 Please don’t pm general questions, posting to public topic gives much better chances to get help.

I don’t see any issues with the step widget.

The sensors.fahrenheit() returns those odd values, so search for a proper way to read the temperature values from your sensor. I’m guessing you have to do the reading only upon successful sensors.read() call.

So, you probably should take the advice given by @khoih and move sensor reading to a separate timer-based routine, which would run sensors.read() and, if successful, store the sensors.fahrenheit() into a global variable. And then, in the BLYNK_WRITE function just use that variable.

I did that. The timer creates the same issue.
Thanks

I’d suggest that you post your revised code and results.

Pete.