1

Topic: Control element switch does not work with element edit field.

Element "switch" with "edit field" doesn't work together.

Element switch returns itself back to position "ON", in this example.
In code there is only switch: switch_1, edit field:  edit_1 and text field: text_1.
Example is like the clock which increments 1s counter to text field and to edit field.
When switch is "ON" counter counts up.
When switch is "OFF" counter stops and gets new starting value from edit field edit_1.
Problem is: Switch doesn't want to stay in position "OFF". It magically, physically returns itself to position "ON".
If I put constant integer value, instead counter value seconds, to field edit_1, there is no problem with switch position.
What to do?

/*
   -- EditFieldTest --

   This source code of graphical user interface
   has been generated automatically by RemoteXY editor.
   To compile this code using RemoteXY library 3.1.6 or later version
   download by link http://remotexy.com/en/library/
   To connect using RemoteXY mobile app by link http://remotexy.com/en/download/
     - for ANDROID 4.8.01 or later version;
     - for iOS 1.5.1 or later version;

   This source code is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.
*/

//////////////////////////////////////////////
//        RemoteXY include library          //
//////////////////////////////////////////////

// RemoteXY select connection mode and include library
#define REMOTEXY_MODE__ESP8266WIFI_LIB_CLOUD
#include <ESP8266WiFi.h>
#include <RemoteXY.h>

// RemoteXY connection settings
#define REMOTEXY_WIFI_SSID "Your SSID"
#define REMOTEXY_WIFI_PASSWORD "Your password"
#define REMOTEXY_CLOUD_SERVER "cloud.remotexy.com"
#define REMOTEXY_CLOUD_PORT 6376
#define REMOTEXY_CLOUD_TOKEN "4d178e96e6d799971862231c2839c06f"

// RemoteXY configurate
#pragma pack(push, 1)
uint8_t RemoteXY_CONF[] =
{ 255, 3, 0, 11, 0, 38, 0, 13, 13, 1,
  2, 0, 19, 36, 28, 12, 2, 26, 31, 31,
  79, 78, 0, 79, 70, 70, 0, 7, 52, 23,
  17, 21, 7, 2, 26, 2, 67, 4, 23, 27,
  14, 6, 2, 26, 11
};

// this structure defines all the variables and events of your control interface
struct {

  // input variables
  uint8_t switch_1; // =1 if switch ON and =0 if OFF
  int16_t edit_1;  // 32767.. +32767

  // output variables
  char text_1[11];  // string UTF8 end zero

  // other variable
  uint8_t connect_flag;     // =1 if wire connected, else =0

} RemoteXY;
#pragma pack(pop)

bool sec;                   // one second status, 0 or 1
int16_t delay_time = 1000;  // delay [ms] for one second
unsigned long time_now;     // used for delay without delay();
int16_t seconds;            // clock counter for display

/////////////////////////////////////////////
//           END RemoteXY include          //
/////////////////////////////////////////////
//------------------------------------------------------------------------
void setup()
{
  RemoteXY_Init ();
}
//------------------------------------------------------------------------
void loop()
{
  RemoteXY_Handler ();
  Clock();      // 1s clock for counter display
  ShowClock();  // 1s increment counter display
}
//------------------------------------------------------------------------
void Clock()    // Delay 1s without "delay();"
{
  if (millis() > time_now + delay_time)
  {
    time_now = millis();
    sec = 1;    // flag for to check 1s counter
  }
}
//------------------------------------------------------------------------

void ShowClock()  // Show 1s counter to edit field and to text field
{
  if (RemoteXY.switch_1 == 1 && sec == 1) // Switch is "ON"
  {
    sec = 0;        // only one increment per second
    seconds += 1;   // increment 1s counter

    /*  PROBLEM: If row below is allowed (= not commented).
        OFF-state of the switch_1 automatically returns to ON-state.
        So, you can't set OFF-state at all.
        edit_1 has been set to use integer variables.
    */
    RemoteXY.edit_1 = seconds; // with this, switch_1 cannot be turned to OFF-state

    // This text field update works fine:
    sprintf (RemoteXY.text_1, "%d", seconds); // print seconds to field text_1
  }
  else if (RemoteXY.switch_1 == 0)  // Switch is "OFF"
  {
    seconds = RemoteXY.edit_1;  // get new start value for second counter
  }
}

2

Re: Control element switch does not work with element edit field.

We have reproduced this bug.
This works well on Arduino, but doesn't work on esp8266.

3

Re: Control element switch does not work with element edit field.

When you change RemoteXY.edit_1 field, the library fixes the value of ALL input variables, including the switch, which is "1". At this time, the controller tries to transfer all input variables to the smartphone. The controller will not receive input variables from the smartphone until the smartphone receives new values from the controller. Data exchange with the cloud server takes a long time 1-3 times per second. If you move the switch to the "0" position, then most likely it will change to "1" as soon as the new data of the stopwatch and switch comes from the controller. But the switch on the controller was "1" when the data was sent. In your case, the controller updates the input variables 1 time per second. Transmitting the input variables from the controller takes most of the connection time. In our test on arduino it worked well because bluetooth short-range communication works faster.
If possible, avoid situations of frequent changing input variables on the controller, only when it is really necessary.

4

Re: Control element switch does not work with element edit field.

@remotexy

Yes, if you change just one input in the app, every inputs are sent to the device, and similarly when one input is changed in code, everything is sent to the App.

You could make it so that only what was changed is sent (in both directions).

App -> Device : Instead of one command to send everything, use multiple commands, one for each input that was changed, to send the index (position in the struct) and the new byte value to store at this position.

Device -> App : Basically the same thing, compare old struct with new struct, and everytime a byte is different, send a command to App with the index and the new value of this byte.

It shouldn't be too hard to implement this! It would solve this problem and also reduce traffic.


But all this could be even better with an event system and object-oriented controls. Yes it would require a total rewrite, and it would use a lot more memory than an array and a struct, but it would be so much more powerful...

5

Re: Control element switch does not work with element edit field.

Guillaume wrote:

@remotexy

Yes, if you change just one input in the app, every inputs are sent to the device, and similarly when one input is changed in code, everything is sent to the App.

You could make it so that only what was changed is sent (in both directions).

App -> Device : Instead of one command to send everything, use multiple commands, one for each input that was changed, to send the index (position in the struct) and the new byte value to store at this position.

Device -> App : Basically the same thing, compare old struct with new struct, and everytime a byte is different, send a command to App with the index and the new value of this byte.

It shouldn't be too hard to implement this! It would solve this problem and also reduce traffic.


But all this could be even better with an event system and object-oriented controls. Yes it would require a total rewrite, and it would use a lot more memory than an array and a struct, but it would be so much more powerful...

Yes, we go to it.

6

Re: Control element switch does not work with element edit field.

You said "It shouldn't be too hard to implement this" but it is. I don't understand what to do.
There in my examble is only one change per 1s and another change, the switch 0 or 1.
The problem will stay even if the row where switch will be change to 0

from this:
else if (RemoteXY.switch_1 == 0)  // Switch is "OFF"

to this:
else if (RemoteXY.switch_1 == 0 && sec ==1)  // Switch is "OFF"

Can you give example how the switch update problem can be handled?
I think that many other simple stupid has same kind problem.

7

Re: Control element switch does not work with element edit field.

You should only change the position of the switch when it actually happened. For example, you control the turn on and turn off of the motor using a switch element, but the motor can be turned on not only from the switch element, any signal of you programm can turn on the motor. In this case, you do not have to update the position of the switch every "loop" cycle. You should only update it at the moment when the motor has changed its state.

// my motor control logic

if ("need to turn on the motor") {
  motorState = 1;
  motorStateHasChanged =1;
}
if ("need to turn off the motor") {
  motorState = 0;
  motorStateHasChanged =1;
}
// end my motor control logic

if (motorStateHasChanged == 1) {
  if (motorState != RemoteXY.switch) {
    RemoteXY.switch = motorState ;
  }
  motorStateHasChanged  = 0;
}
else {
  motorState = RemoteXY.switch;
}

digitalWrite(MOTOR_PIN, motorState);

8

Re: Control element switch does not work with element edit field.

Now I think I know where is the main problem as you noticed me before.
The switch is not mainly problem to update but Control "Edit field" is.
In my very simple example there is used only one switch and one edit field symbol.
The switch will be set only manually using phone app, no any other function can't control it.
When switch is in position ON, "Edit Field" will be updated by counter.
If switch is in position OFF, Edit Field will be not updated.
Now, if counter sequency is too fast, obout 1000ms in my network, Edit Field updating will disturbs switch control.
If the delay time is about 2000ms ore more there is no switch position problem.
If Edit Field row is commented, there is no problem iven if delay in counter is much lower.
So, the problem is in Edit Field timing. Text field updating has no problem at all. So use it if you can.

//////////////////////////////////////////////
//        RemoteXY include library          //
//////////////////////////////////////////////

// RemoteXY select connection mode and include library
#define REMOTEXY_MODE__ESP8266WIFI_LIB_CLOUD
#include <ESP8266WiFi.h>
#include <RemoteXY.h>

// RemoteXY connection settings
//#define REMOTEXY_WIFI_SSID "Your SSID"
//#define REMOTEXY_WIFI_PASSWORD "Your password"

#define REMOTEXY_CLOUD_SERVER "cloud.remotexy.com"
#define REMOTEXY_CLOUD_PORT 6376
#define REMOTEXY_CLOUD_TOKEN "4d178e96e6d799971862231c2839c06f"

// RemoteXY configurate
#pragma pack(push, 1)
uint8_t RemoteXY_CONF[] =
{ 255, 3, 0, 0, 0, 59, 0, 14, 13, 1,
  2, 0, 13, 52, 28, 12, 2, 26, 31, 31,
  79, 78, 0, 79, 70, 70, 0, 7, 52, 14,
  35, 26, 7, 2, 26, 2, 129, 0, 22, 44,
  9, 3, 17, 101, 100, 105, 116, 95, 49, 0,
  129, 0, 20, 67, 13, 3, 17, 115, 119, 105,
  116, 99, 104, 95, 49, 0
};

// this structure defines all the variables and events of your control interface
struct {

  // input variables
  uint8_t switch_1; // =1 if switch ON and =0 if OFF
  int16_t edit_1;  // 32767.. +32767

  // other variable
  uint8_t connect_flag;  // =1 if wire connected, else =0

} RemoteXY;
#pragma pack(pop)

bool timeStep;            // one (some) second status, 0 or 1
int16_t delay_time = 1000; // delay [ms] for one timeStep. MUST BE >1000ms
unsigned long time_now;   // used for delay without delay();
int16_t stepCount;        // counter for mobile display

/////////////////////////////////////////////
//           END RemoteXY include          //
/////////////////////////////////////////////
//------------------------------------------------------------------------

void setup()
{
  RemoteXY_Init ();
}
//------------------------------------------------------------------------
void loop()
{
  RemoteXY_Handler ();
  Clock();          // timeStep for stepCounter display
  Switch();         // only manually switch setting
}
//------------------------------------------------------------------------
void Clock()        // Delay 1s without "delay();"
{
  if (millis() > time_now + delay_time)
  {
    time_now = millis();
    timeStep = 1;   // flag, one delay_time has been reached
    stepCount += 1; // increment stepCount counter
  }
}
//------------------------------------------------------------------------
void Switch()
{
  if (timeStep == 1)                // flag, one delay_time has been reached
  {
    timeStep = 0;                   // reset counter to zero
    if (RemoteXY.switch_1 == 1)     // if turned to ON position
    {
      RemoteXY.edit_1 = stepCount;  // show stepCount only if ON position is active
      //                            // delay_time has to be more than 1000ms (in my network)
      //                            // if not, switch goes sometimes back to position ON
    }
  }
}
//------------------------------------------------------------------------

9

Re: Control element switch does not work with element edit field.

Yes, we understand that this is so, this is due to the peculiarities of the data exchange protocol. But now it works like this. We plan to change this in the future.
Now the best solution would be to use a Text string to display the counter. Do not update the Edit field every increment of the counter.