Slider Widget keeps resetting to 0 on Android only

it seems the screen isn’t my issue here - if I take the uno offline, the slider on the screen performs perfectyl. As soon as it is online it still likes to jump to zero when you slide it about - any ideas anyone ???

Cheers

kev

I can’t say that I have been following this in detail… so I am a bit unsure of how many devices you have control of via the app. But if taking one (or the only one) offline “solves” the issue, then that certainly sounds like a remaining code glitch… something is still feeding erroneous/conflicting data back to the slider in the app.

Hi @Gunner ,

Yes thats what I thought so I added another slider to the blynk app using a virtual pin that doesnt exist in my code at all and it does it as well. As soon as I take the uno offline all the sliders work spot on. So can it be my code if a dummy slider in the app connected to a dummy virtual pin is also going crazy ???

Forgot to say this only is an issue in the android app my ios blynk app works perfectly

Cheers

kev

When all the devices are offline, there is nothing to send or receive data to the vPin that the slider is attached too (I believe the server is relatively neutral in this case), so it does sound like code…

But one fairly solid way of testing that is download a basic simple sketch to the hardware with two sliders (one to move and the other to mimic that movement) and a display widget to show the slider value, and test that.

BLYNK_WRITE(Vx) // Slider Widget set to Vx
{
int SlideState = param.asInt();
Blynk.virtualWrite(Vy, SlideState); // Display Widget set to Vy
Blynk.virtualWrite(Vz, SlideState); // 2nd slider set to Vz to mimic 1st slider value
}
1 Like

ok @Gunner so it looks like its my code!!! bit I still don’t understand though is it works faultlessly on Iphone but not on android ???

Help!!!

Cheers

kev

Well as @Costas has mentioned, they are two completely different mobile OSs, with different Blynk App coding for each and thus may react differently to unique variances in the same device code.

I am afraid the you will have to take a systematic step by step crawl through your code, looking at every instance where any affected slider gets called BLYNK_WRITE() and modified Blynk.virtualWrite(), confirming syntax, looking for duplicate or conflicting commands, etc

Possibly even commenting all the slider related Blynk.virtualWrite() commands (as that should only affect the feedback, not operation, of your code) and, one by one, restoring them until you find the culprit.

Also look for all references to the virtual pins used by the slider, in case there is some other command that changes the values, even if only very temporarily.

This is where the find option in the IDE can be very useful… look for Vx (x = slider pin number)

Welcome to the world of digital bug hunting :stuck_out_tongue:

1 Like

Hi @Gunner,

The annoying thing is I have already done this as not new to arduino coding. The calls and writes toV29(slider) are very few and I have already isolated every single call to it and it still does it !!! I’m thinking its something to do with interaction from something else in the code ??? timer library calls or similar. Any pointers greatly appreciated.

cheers

kev

Well, dump your whole code here (in the forum) and we can all take a look… many eyes may spot something.

OK will do @Gunner

Thanks again

Kev

@Costas

I am beginning to think this is the issue I am having. I call the routine every 5 seconds shown below.

so are you saying because I am physically moving the slider and the 5 sec routine is called which is trying to do a write to V29 it screws up ??? Again if that’s the case how does it work fine in ios but not android ???

So how do you stop a timer and restart within loops etc
would it need to go in this bit of code and if so how ?

Cheers

kev

@Gunner see code above - do you think this could be my issue before I upload all of the code ?

@newdos as we have pointed out iOS and Android are written by different people and the iOS code might have “an error trapping routine” to cover simultaneous actions for the slider i.e. from a timer and from physically moving the slider.

If you think about it the system is going to get confused if the 5s action triggers at the same time as you are moving the slider. Which one should it action etc?

If you have checked for bugs in your code and if you don’t want to study the details of how SimpleTimer works one hack would be to break the link between the PIR and the slider. You could send SetPoint1 to a value display widget and then write some code to prioritise how the temperature setting should be set, probably with movement of the slider taking priority over your 5s PIR loop.

It wouldn’t fix the problem but does the 5s need to be so short?

OK @Costas thanks for this. I will read the info on how simple timer works and see if there is anyway round this. 5s is not critical and I have changed this to every minute but still the slider jumps to zero, so would you expect this to happen if I move the slider when the routine is NOT being called ??? I even commented out the call to the routine and it still does it ???

EDIT forgot to say I have written and compiled a much cut down version of the code to see if it still does it as I think this is relating to a timer library issue and I will upload the code later today after I have tested it and seen what the results are like.

All help appreciated.

Cheers

kev

@newdos I have moved relevant posts into your own topic for this unique issue. Please post the full code here when you are ready… otherwise it is hard to determine probable causes with only code segments and guesswork. Thanks.

Will done thanks again @Gunner

Cheers

Kev

Well guys the plot thickens!!! To test the cut down code I only had a Wemos d1 r1 at work so I modded the code and hooked it up to the wifi. Lo and behold the sliders on the android worked fine, so then I loaded mt full original code that I was running on an arduino to the wemos d1 r1 and again the sliders work perfectly!!!

so is this something to do with the arduino libraries ???

I have not tried the cutdown code on the arduino yet but will over the weekend.

Here is the cutdown code and the full code for you to take a look at if need be.

Over to you @Gunner @Costas

Cheers

Kev

CUTDOWN CODE

//#include<BlynkSimpleEthernet.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include<SimpleTimer.h>
SimpleTimer timer;

int SetPoint1;                        // Temp setting for room monitored by DHT22
int Away_Temp1;                       // Temp to set heating to if on but no occupance ie Away
int Occupied_Temp;                    // Copy of setpoint used in AWAY mode
int Activity = 0;                     // PIR occupancy counter
int PIR_pin = 4;                      // choose the input pin (for PIR occupancy sensor)

char auth[] = "xxx";
char ssid[] = "xxx";
char pass[] = "xxx";


void setup()
{
  Serial.begin(9600);
  //Blynk.begin(auth);
  Blynk.begin(auth, ssid, pass);
  
  pinMode(PIR_pin, INPUT);
  //Lets sync up all the store states for the V pins and load the appropriate variables listed below
  Blynk.syncVirtual(V28);            // Away_Temp1
  Blynk.syncVirtual(V29);            // SetPoint1
  timer.setInterval(5000, Occupancy);     // Check if the room is occupied via PIR sensor
  timer.setInterval(600000, Check_Away);  // Check if we need to go into AWAY mode every 10 mins
}

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

void Occupancy () // Is there anybody in there!!
{
  if (digitalRead(PIR_pin) == 1) {
    // Count movement activity every 5 seconds via PIR and maintain Setpoint1
    Activity = Activity + 1;
    SetPoint1 = Occupied_Temp;  // set setpoint1 back to what it was before away temp was instigated
    Blynk.virtualWrite(V29, SetPoint1);
  }
}

void Check_Away ()
{
  if (Activity == 0) {         // No one  present so drop setpoint temp to Away_temp1
    Occupied_Temp = SetPoint1; // store current setpoint1
    SetPoint1 = Away_Temp1;    // Set to Away_temp1
    Blynk.virtualWrite(V29, SetPoint1);
  }
  else {
    Activity = 0;              // presence has been detected so reset activity counter and and start again
  }
}

// Sync up all of the virtual pin data

BLYNK_WRITE(V28)  // Input from slider in app to set Away_Temp1
{
  Away_Temp1 = param.asInt();
}

BLYNK_WRITE(V29)  // Input from slider in app to set SetPoint1
{
  SetPoint1 = param.asInt();
  Serial.println(SetPoint1);
  Occupied_Temp = SetPoint1; // store this in a vrbl as used by Away_Temp1 setting
}



FULL CODE

//#include<BlynkSimpleEthernet.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

#include<SimpleTimer.h>
#include <TimeLib.h>            // Used by WidgetRTC.h
#include <WidgetRTC.h>          // Blynk's RTC
#include "DHT.h"
#define DHTPIN 5 // DHT signal in pin
#define DHTTYPE DHT22
SimpleTimer timer;
WidgetRTC rtc;

DHT dht(DHTPIN, DHTTYPE);
float t; //Temp variable
float h; //Humidity variable

bool resetFlag = true;    // TRUE when the hardware has been reset.


// Heating control pins and variables
int Heat1_pin = 9;                    // Pin for Heating rad 1 relay.
int PIR_pin = 4;                      // choose the input pin (for PIR occupancy sensor)
int Heat1_Status;                     // Status of relay1 at reset/startup etc also stored on V30
int SetPoint1;                      // Temp setting for room monitored by DHT22
int Away_Temp1;                     // Temp to set heating to if on but no occupance ie Away
int Hysteresis1_Val = 0.3;          // Allows for 0.3c above and below the setpoint1 to stop 'twitching' around the setpoint
int Activity = 0;                     // PIR occupancy counter
bool startFlag = false;               // TRUE when the heating is on
bool stopFlag = false;                // TRUE when the heating is off.
bool daySet = false;
int Occupied_Temp;                    // Copy of setpoint used in AWAY mode
long todaysAccumRuntimeSec;           // Today's accumulated runtime in seconds - displayed in app as minutes.
int currentCycleSec, currentCycleMin; // If Heating is running, the duration of the current cycle (non-accumulating).
int yesterdayRuntime;                 // Sum of yesterday's runtime in minutes - displays in app.
int yesterdayCount;                   // Sum of yesterday's cycle count to display in app.
int todaysDate;                       // Sets today's date related to things that reset at EOD.
int heatingTodaysStartCount;          // Today's number of heating cycles
String currentTimeDate;               // Time formatted as "0:00AM on 0/0"
String startTimeDate, stopTimeDate, resetTimeDate;
String currentStatus;                 // What displays in app. Used solely for sync and recover purposes.


// Lighting control pins and AC feedback
int RELAY1_PIN = 2;       // Relay 1 pin
int AC_Sens1_pin = 3;     // Relay 1 ac sens pin
int feedback1;            // AC feedback1 variable

//char auth[] = "xxx";
char auth[] = "xxx";
char ssid[] = "xxx";
char pass[] = "xxxx";

void setup()
{
  Serial.begin(9600);
  //Blynk.begin(auth);
 Blynk.begin(auth, ssid, pass);
  
  rtc.begin();
  // Setup all of the pins and default ALL relays to OFF before reinstating stored states
  pinMode(RELAY1_PIN, OUTPUT);
  pinMode(Heat1_pin, OUTPUT);
  pinMode(AC_Sens1_pin, INPUT);
  pinMode(PIR_pin, INPUT);
  digitalWrite(Heat1_pin, 0);
  digitalWrite(RELAY1_PIN, 0);

  //Lets sync up all the store states for the V pins and load the appropriate variables listed below
  Blynk.syncVirtual(V3);             // Light 1 Relay state
  Blynk.syncVirtual(V28);            // Away_Temp1
  Blynk.syncVirtual(V29);            // SetPoint1
  Blynk.syncVirtual(V30);            // Heat1_pin state
  Blynk.syncVirtual(V31);            // CurrentStatus
  Blynk.syncVirtual(V110);           // heatingTodaysStartCount
  Blynk.syncVirtual(V111);           // todaysAccumRuntimeSec
  Blynk.syncVirtual(V112);           // yesterdayRuntime
  Blynk.syncVirtual(V113);           // yesterdayCount

  timer.setInterval(200, AC_detect);      // Check AC_detect for AC presence every 50 milliseconds
  timer.setInterval(1000, setClockTime);  // Creates a current time with leading zeros.
  timer.setInterval(1000, countRuntime);  // Counts heating runtime for daily accumulation displays.
  timer.setInterval(1000, totalRuntime);  // Counts heating runtime.
  timer.setInterval(1500, sendStatus);    // update the app with all the data
  timer.setInterval(2000, TempControl);   // Check temp control and action
  timer.setInterval(5000, Occupancy);     // Check if the room is occupied via PIR sensor
  timer.setInterval(600000, Check_Away);  // Check if we need to go into AWAY mode every 10 mins
}

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

void AC_detect()
{
  feedback1 = digitalRead(AC_Sens1_pin);
  Blynk.virtualWrite(V2, feedback1); // update SWITCH widget state from AC input only if it has changed
}

void TempControl()
{
  //Read temp and humidity from DHT22
  h = dht.readHumidity();
  t = dht.readTemperature();
  // write values to V5 and V6
  Blynk.virtualWrite(V5, h);  // Update widgets with temp & humidity data
  Blynk.virtualWrite(V6, t);

  //OK lets action if heating needs to be turned ON or OFF
  // ON first
  if (t < (SetPoint1 - Hysteresis1_Val)) // Only turn ON when below setpoint1 minus Hysteresis1_Val
  {
    digitalWrite(Heat1_pin, 0);  // Turn rad 1 ON
    Blynk.virtualWrite(V30, 0);  // update V30 with Heat1_pin current status
  }
  // Turn OFF then
  else if (t > (SetPoint1 + Hysteresis1_Val)) // Only turn OFF when above setpoint1 plus Hysteresis1_Val
  {
    digitalWrite(Heat1_pin, 1); // Turn rad 1 OFF
    Blynk.virtualWrite(V30, 1); // update V30 with current status
  }
}

void Occupancy () // Is there anybody in there!!
{
  if (digitalRead(PIR_pin) == 1) {
    // Count movement activity every 5 seconds via PIR and maintain Setpoint1
    Activity = Activity + 1;
    SetPoint1 = Occupied_Temp;  // set setpoint1 back to what it was before away temp was instigated
    Blynk.virtualWrite(V29, SetPoint1);
  }
}

void Check_Away ()
{
  if (Activity == 0) {         // No one  present so drop setpoint temp to Away_temp1
    Occupied_Temp = SetPoint1; // store current setpoint1
    SetPoint1 = Away_Temp1;    // Set to Away_temp1
    Blynk.virtualWrite(V29, SetPoint1);
  }
  else {
    Activity = 0;              // presence has been detected so reset activity counter and and start again
  }
}

void setClockTime()
{

  //if (year() != 1970) // Doesn't start until RTC is set correctly.

  // Below gives me leading zeros on minutes and AM/PM.
  if (minute() > 9 && hour() > 11) {
    currentTimeDate = String(hourFormat12()) + ":" + minute() + "PM on " + day() + "/" + month();
  }
  else if (minute() < 10 && hour() > 11) {
    currentTimeDate = String(hourFormat12()) + ":0" + minute() + "PM on " + day() + "/" + month();
  }
  else if (minute() > 9 && hour() < 12) {
    currentTimeDate = String(hourFormat12()) + ":" + minute() + "AM on " + day() + "/" + month();
  }
  else if (minute() < 10 && hour() < 12) {
    currentTimeDate = String(hourFormat12()) + ":0" + minute() + "AM on " + day() + "/" + month();
  }
}

void sendStatus()
{
  // has Arduino been reset or just started.
  if (resetFlag == true && year() != 1970)
  {
    resetTimeDate = currentTimeDate;
    Blynk.virtualWrite(V31, currentStatus);
    Blynk.setProperty(V31, "label", String("Current Status:                    SYSTEM RESET at ") + resetTimeDate);
  }

  if (Heat1_Status == 1 && resetFlag == true)   // Runs once following reset/start if Heat is ON.
  {
    startFlag = true;
    resetFlag = false;
  }
  else if (Heat1_Status == 0 && resetFlag == true) // Runs once following Arduino reset/start if heat is OFF.
  {
    stopFlag = true;
    resetFlag = false;
  }

  // Display all the data on the app
  // Have we passed threshold of heat limit? if so turn it off
  if (digitalRead(Heat1_pin) == 1 && startFlag == true) // now OFF, but was on
  {
    // Purpose: To swap between ON and OFF display once heating state change.
    stopTimeDate = currentTimeDate;                                   // Set off time.
    Blynk.setProperty(V31, "color", "#23C48E");   // Green
    Blynk.virtualWrite(V31, String("Heat OFF since ") + stopTimeDate); // Write to app.
    currentStatus = String("Heat OFF since ") + stopTimeDate;
    stopFlag = true;   // Ready flag when heat turns on.
    startFlag = false;// Keep everything locked out until the next cycle.
  }
  else if (digitalRead(Heat1_pin) == 0 && stopFlag == true) // ON, but was off
  {
    startTimeDate = currentTimeDate;
    Blynk.setProperty(V31, "color", "#D3435C");   // Red
    Blynk.virtualWrite(V31, String("Heat ON since ") + startTimeDate);
    currentStatus = String("Heat ON since ") + startTimeDate;
    startFlag = true;
    stopFlag = false;
  }
  Blynk.virtualWrite(V25, Activity);
}

void countRuntime()
{
  if (year() != 1970) // Doesn't start until RTC is set correctly.
  {
    if (daySet == false) {      // Sets the date (once per hardware restart) now that RTC is correct.
      todaysDate = day();
      daySet = true;
    }
    if (digitalRead(Heat1_pin) == 0 && todaysDate == day()) // Accumulates seconds unit is running today.
    {
      ++todaysAccumRuntimeSec;                              // Counts today's Heat1 on time in seconds.
      Blynk.virtualWrite(111, todaysAccumRuntimeSec);
    }
    else if (todaysDate != day()) // day changed so do the business
    {
      yesterdayRuntime = (todaysAccumRuntimeSec / 60);  // Moves today's runtime to yesterday for the app display.
      Blynk.virtualWrite(112, yesterdayRuntime);        // Record yesterday's runtime to V112
      todaysAccumRuntimeSec = 0;                        // Reset today's sec timer.
      Blynk.virtualWrite(111, todaysAccumRuntimeSec);
      yesterdayCount = heatingTodaysStartCount;         // set yesterdays runtime cycles variable for display
      Blynk.virtualWrite(113, yesterdayCount);          // Record yesterday's no of cycles to V113
      heatingTodaysStartCount = 0;                      // Reset how many times heating cycle has started today.
      todaysDate = day();
    }
    if (yesterdayRuntime < 1)     // Displays yesterday's runtime in app, or 'None' is there's none.
    {
      Blynk.virtualWrite(14, "None");
    }
    else
    {
      Blynk.virtualWrite(14, String(yesterdayRuntime) + " mins (" + (yesterdayCount) + " runs)");
    }

    if (todaysAccumRuntimeSec == 0)   // Displays today's runtime in app, or 'None' if there's none.
    {
      Blynk.virtualWrite(15, "None");
    }
    else if (todaysAccumRuntimeSec > 0 && heatingTodaysStartCount == 0)
    {
      Blynk.virtualWrite(15, String(todaysAccumRuntimeSec / 60) + " minutes");
    }
    else if (todaysAccumRuntimeSec > 0 && heatingTodaysStartCount > 0)
    {
      Blynk.virtualWrite(15, String(todaysAccumRuntimeSec / 60) + " mins (" + (heatingTodaysStartCount) + " runs)");
    }
  }
}

void totalRuntime()
{
  if (digitalRead(Heat1_pin) == 0) // If Heating 1 is on running...
  {
    ++currentCycleSec;               // accumulate the running time, however...
    currentCycleMin = (currentCycleSec / 60);
  }
  else if (digitalRead(Heat1_pin) == 1 && currentCycleSec > 0) // if Heating 1 is off but recorded some runtime...
  {
    Blynk.virtualWrite(110, ++heatingTodaysStartCount);  // Stores how many times the unit has started today... adds one start.
    currentCycleSec = 0;                                 // Reset the current cycle clocks
    currentCycleMin = 0;
  }
}

// Sync up all of the virtual pin data

BLYNK_WRITE(V2)  // Runs every-time switch widget is toggled - For Light 1
{
  digitalWrite(RELAY1_PIN, !digitalRead(RELAY1_PIN)); // Toggle relay1
  Blynk.virtualWrite(V3, digitalRead(RELAY1_PIN));    // Store Light 1 relay state in V3
}

BLYNK_WRITE(V3)
{
  int pinData = param.asInt();
  digitalWrite(RELAY1_PIN, pinData); // and reinstate relay state
}

BLYNK_WRITE(V28)  // Input from slider in app to set Away_Temp1
{
  Away_Temp1 = param.asInt();
}

BLYNK_WRITE(V29)  // Input from slider in app to set SetPoint1
{
  SetPoint1 = param.asInt();
  Occupied_Temp = SetPoint1; // store this in a vrbl as used by Away_Temp1 setting
  Serial.println(SetPoint1);
}


BLYNK_WRITE(V30)
{
  Heat1_Status = param.asInt();
  digitalWrite(Heat1_pin, Heat1_Status); // and reinstate heat 1 condition
}

BLYNK_WRITE(V31)
{
  currentStatus = param.asStr();
}


BLYNK_WRITE(V110)
{
  heatingTodaysStartCount = param.asInt();
}

BLYNK_WRITE(V111)
{
  todaysAccumRuntimeSec = param.asLong();
}

BLYNK_WRITE(V112)
{
  yesterdayRuntime = param.asInt();
}

BLYNK_WRITE(V113)
{
  yesterdayCount = param.asInt();
}

@newdos which Arduino are you using?

Hi @Costas

I am breadboarding this with a UNO but will be using a Mega when the project is debugged and build.

Cheers

kev

@newdos you say you modified your Arduino code for ESP but you have some serious bugs.

We have previously discussed int and float with you regarding the Slider widget.

What do you think the following lines will do:

int Hysteresis1_Val = 0.3; // Allows for 0.3c above and below the setpoint1 to stop 'twitching' around the setpoint

  //OK lets action if heating needs to be turned ON or OFF
  // ON first
  if (t < (SetPoint1 - Hysteresis1_Val)) // Only turn ON when below setpoint1 minus Hysteresis1_Val
  {
    digitalWrite(Heat1_pin, 0);  // Turn rad 1 ON
    Blynk.virtualWrite(V30, 0);  // update V30 with Heat1_pin current status
  }
  // Turn OFF then
  else if (t > (SetPoint1 + Hysteresis1_Val)) // Only turn OFF when above setpoint1 plus Hysteresis1_Val
  {
    digitalWrite(Heat1_pin, 1); // Turn rad 1 OFF
    Blynk.virtualWrite(V30, 1); // update V30 with current status
  }

We tried to flash your sketch to some of our WeMos’ and we noticed they are getting too hot to touch and will not run the firmware.
Might have something to do with things like this line:

int AC_Sens1_pin = 3; // Relay 1 ac sens pin

There is no official pin 3 on an ESP.

Hi @Costas,

Not sure what you mean about the code bugs ? V30 is just a variable storage and not associated with a slider ?

So can you tell me what is wrong with the code here as I am missing it??

And apols I didn’t explain really I just uploaded the long code as a quick test(didnt change pins or anything like that) and it worked fine for me on the wemos???

Cheers

kev