Problem with timer and disconnecting hardware

In my sketch I have in my setup

 timer.setInterval(1000L, LedWidget);

LedWidget is as follow:


void LedWidget()
{
  // lectureleds();

i=0;
  cdeLeds=digitalRead(LEDS);
  while (cdeLeds==1 && i<imax){cdeLeds=digitalRead(LEDS);i++;yield();}
  
    Serial.println("LED on V1: on");
   led4.on();
  }

Nothing is serial printed, and my hardware disconnects and connects again every 10 seconds
If I delete the line

while (cdeLeds==1 && i<imax){cdeLeds=digitalRead(LEDS);i++;yield();}

it works well.
Can anybody explain this?

09:16:30.952 INFO - EMAIL hardware joined.
09:16:41.208 INFO - EMAIL hardware joined.
09:16:51.798 INFO - EMAIL hardware joined.
09:17:02.113 INFO - EMAIL hardware joined.
09:17:12.379 INFO - EMAIL hardware joined.
09:17:22.671 INFO - EMAIL hardware joined.

Impossible to say based on that snippet of code, but my rule of thumb is never to use a while statement with Blynk, especially when a for loop can be used instead.

Pete,

I am trying to convert a remotexy sketch to blynk which is badly readable, so I didnt want to make it a hassle here on the board.

actually this is the code i need to convert:


/*//   -- Jacuzzi -- // version 6 avec 
                      gestion améliorée des états invalides des leds 
                      yield() function pour éviter les freeze (enfin je pense que cela y contribue)
                      Pour Jacuzzi SSP-H-20.1 Bubble only

                      R6.2.1 : avec fonction delay sur lecture segment et suppression clignotement
*/

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

// RemoteXY select connection mode and include library 
#define REMOTEXY_MODE__ESP8266_SOFTSERIAL_CLOUD
#include <SoftwareSerial.h>

// activate debug output on Serial 115200; ESP on SW Serial
#define REMOTEXY__DEBUGLOGS Serial 

#include <RemoteXY.h>

// RemoteXY connection settings 
 #define REMOTEXY_SERIAL_RX 3 
 #define REMOTEXY_SERIAL_TX 2 
 #define REMOTEXY_SERIAL_SPEED 9600 
 #define REMOTEXY_WIFI_SSID "<<SSID>>" 
 #define REMOTEXY_WIFI_PASSWORD "<<PASS>>"
 #define REMOTEXY_CLOUD_SERVER "cloud.remotexy.com" 
 #define REMOTEXY_CLOUD_PORT 6376 
 #define REMOTEXY_CLOUD_TOKEN "<<TOKEN>>"

// "THE REMOTE XY TOKEN See www.remotexy.com/en/account/tokens/"


// RemoteXY App configuration  
#pragma pack(push, 1)
uint8_t RemoteXY_CONF[] = 
   { 255,5,0,25,0,217,0,8,8,1,
  130,2,5,4,53,19,46,129,0,2,
  39,12,5,16,70,105,108,116,101,114,
  <DELETED SOME NUMBERS>
  194,176,99,0,129,0,54,99,6,3,
  17,82,54,46,50,0 };    
   
   
// this structure defines all the variables of the control interface for the RemoteXY App
struct {
     // input variable
   uint8_t bpPower; // =1 if button pressed, else =0 
   uint8_t bpFilter; // =1 if button pressed, else =0 
   uint8_t bpHeater; // =1 if button pressed, else =0 
   uint8_t bpUp; // =1 if button pressed, else =0 
   uint8_t bpDown; // =1 if button pressed, else =0  
   
     // output variable
   uint8_t ledPower_r; // =0..255 LED Red brightness 
   uint8_t ledPower_g; // =0..255 LED Green brightness 
   uint8_t ledFilter_r; // =0..255 LED Red brightness 
   uint8_t ledFilter_g; // =0..255 LED Green brightness 
   uint8_t ledHeater_r; // =0..255 LED Red brightness 
   uint8_t ledHeater_g; // =0..255 LED Green brightness 
   char digit1[2];  // string UTF8 end zero 
   char digit2[2];  // string UTF8 end zero 
   char digit3[2];  // string UTF8 end zero 
   char digit4[2];  // string UTF8 end zero 
   char waterTemp[11];  // string UTF8 end zero  
   
    // other variable
  uint8_t connect_flag;  // =1 if wire connected, else =0 
} 

RemoteXY;
#pragma pack(pop)

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

// define I/O

#define SEGA 8 // actif LOW : état segment a également jetLed
#define SEGB 16  // actif LOW : état segment b également heater2Led
#define SEGC 17  // actif LOW : état segment c également sunheatPos
#define SEGD 9  // actif LOW : état segment d également set1Led
#define SEGE 10  // actif LOW : état segment e également filterLed
#define SEGF 11  // actif LOW : état segment f également heater1Led
#define SEGG 7  // actif LOW : état segment g 
#define SEGDP 12  // actif LOW : état segment dp également set2Led  
#define AFF1 A4 // actif LOW : Données afficheur digit 1 disponibles
#define AFF2 A1 // actif LOW : Données afficheur digit 2 disponibles
#define AFF3 A0 // actif LOW : Données afficheur digit 3 disponibles
#define AFF4 A5 // actif LOW : Données afficheur digit 4 disponibles
#define LEDS 13 // actif LOW : Données des autres LED's disponibles 
#define LEDPOWER A7 // lecture d'un état on/off via Analog input car plus de digital input disponible
#define C4051 4 // D4 D5 et D6 utilisées en OUTPUT pour codage de 7 Commandes (+ 1 état neutre)... 
#define B4051 5 // ....via 3 sorties et multiplexeur-interrupteur analogique CD4051
#define A4051 6 // CD4051 : C = pin 9; B= pin 10; A = pin 11 

// déclaration des valeurs lues sur les I/O
boolean a,b,c,d,e,f,g,dp,h; // lecture de l'état des segments digits
boolean cdeAff1,cdeAff2,cdeAff3,cdeAff4,cdeLeds; // lecture du digit pour lequel les infos sont transmises
int powerLed; //lecture valeur analogique
boolean heater1Led,heater2Led,filterLed,jetLed; //bubbleLed non utilisée par manque d'entrées sur Nano


// déclaration et initialisation de variables

char digit[2];
int adigit=0,adigit1=0,adigit2=0,adigit3=0;
String digitseg="";
String digitsegled="11111111";
float tempWater=20.0;
int delayReadSeg=15;

// déclaration divers compteurs
int i=0;
int j=0;
int k1=0;
int k2=0;
int l=0;
int m=0;
int n=0;
int o=0;
int p=0;
int q=0;
int r=0;
int s=0;
int imax=1000; // nombre max d'itérations de lecture des bits de données afficheurs et états leds
int jmax=5; // autre compteur de base utilisé à divers endroits


// To replace the delay function (lets other routines working)
unsigned long currentMillis ;
unsigned long previousMillis1 = 0;         
unsigned long previousMillis2 = 0;
unsigned long previousMillis3 = 0; 
unsigned long previousMillis4 = 0; 

const long interval1 = 250;           // interval at which to repeat (delay in milliseconds)
const long interval2 = 5000; 
const long interval3 = 10000;
const long interval4 = 20000;

void setup() {

RemoteXY_Init (); 
// 115200 mendatory for debug
Serial.begin(115200);

analogReference(INTERNAL);

// affectation des modes aux I/O Arduino; (pas de déclaration pour les entrées analogiques car pas d'alternative)
pinMode(SEGA,INPUT); // voir également les autres affectations de ces entrées dans la fonction Void lecture digit ci-dessous
pinMode(SEGB,INPUT);
pinMode(SEGC,INPUT);
pinMode(SEGD,INPUT);
pinMode(SEGE,INPUT);
pinMode(SEGF,INPUT);
pinMode(SEGG,INPUT);
pinMode(SEGDP,INPUT);
pinMode(AFF1,INPUT);
pinMode(AFF2,INPUT);
pinMode(AFF3,INPUT);
pinMode(AFF4,INPUT);
pinMode(LEDS,INPUT);
// No need to define A7 (powerLed) because INPUT only
pinMode(C4051,OUTPUT); // 3 Sorties vers CD 4051 positionnées à 1 
pinMode(B4051,OUTPUT);
pinMode(A4051,OUTPUT);
digitalWrite(C4051,1);
digitalWrite(B4051,1);
digitalWrite(A4051,1);

// initialisation des variables à la valeur 1 car le circuit fonctionne en logique inversée
a=1,b=1,c=1,d=1,e=1,f=1,g=1,dp=1;
cdeAff1=1,cdeAff2=1,cdeAff3=1,cdeAff4=1,cdeLeds=1;
powerLed=1023;
heater1Led=1,heater2Led=1,filterLed=1;

// affichage par défaut au lancement
RemoteXY.ledPower_r=0;RemoteXY.ledPower_g=0;
RemoteXY.ledHeater_r=0;RemoteXY.ledHeater_g=0;
RemoteXY.ledFilter_r=0;RemoteXY.ledFilter_g=0;
digit[0]='0';
strcpy (RemoteXY.digit1, digit);
strcpy (RemoteXY.digit2, digit);
strcpy (RemoteXY.digit3, digit);
digit[0]='c';
strcpy (RemoteXY.digit4, digit);
dtostrf(tempWater, 0, 0, RemoteXY.waterTemp);

}

void loop() { 

RemoteXY_Handler();

// acquisition des valeurs introduites via l'app : delais de lecture des segments après flanc descendant 
// du bit de données afficheurs ou led's et nombre max d'itérations de lecture de ces bits

// gestion des commandes en provenance RemoteXY via BCD vers 1 de 10 (en réalité 1 de 8) (Mux analogique CD4051)
// gestion de la durée de l'impulsion de commande

currentMillis = millis();
if (currentMillis - previousMillis1 >= interval1) {
  previousMillis1 = currentMillis;

  digitalWrite(C4051,1);
  digitalWrite(B4051,1);
  digitalWrite(A4051,1);

  if(RemoteXY.bpFilter!=0) {
    digitalWrite(C4051,0);
    digitalWrite(B4051,0);
    digitalWrite(A4051,0); }

  if(RemoteXY.bpUp!=0) {
    previousMillis4 = millis(); // to freeze the update of tempWater when pushed
    digitalWrite(C4051,0);
    digitalWrite(B4051,0);
    digitalWrite(A4051,1); }

  if(RemoteXY.bpDown!=0) {
    previousMillis4 = millis(); // to freeze the update of tempWater when pushed
    digitalWrite(C4051,0);
    digitalWrite(B4051,1);
    digitalWrite(A4051,0); }
  
  if(RemoteXY.bpPower!=0) {
    digitalWrite(C4051,1);
    digitalWrite(B4051,0);
    digitalWrite(A4051,0); }
  
  if(RemoteXY.bpHeater!=0) {
    digitalWrite(C4051,1);
    digitalWrite(B4051,0);
    digitalWrite(A4051,1); }
}


lectureleds();

// lecture et décodage des digits
i=0;
cdeAff1=digitalRead(AFF1);
while (cdeAff1==1 && i<imax) {cdeAff1=digitalRead(AFF1);i++;yield();}
if (cdeAff1==0 && i<imax) {
  delayMicroseconds(delayReadSeg);
  lecturedigit();
  decodage();
  if (digit[0] != 'x' && digit[0] != 'c' && digit[0] != ' ') { 
  adigit1=adigit;
  strcpy (RemoteXY.digit1, digit);}
  }

i=0;
cdeAff2=digitalRead(AFF2);
while (cdeAff2==1 && i<imax) {cdeAff2=digitalRead(AFF2);i++;yield();}
if (cdeAff2==0 && i<imax) {
  delayMicroseconds(delayReadSeg);
  lecturedigit();
  decodage();
  if (digit[0] != 'x' && digit[0] != 'c' && ((millis() - previousMillis4) <= (interval4/4)) ) { // ' ' value authorized when modifying temp instruction
  adigit2=adigit;
  strcpy (RemoteXY.digit2, digit);}
  if (digit[0] != 'x' && digit[0] != 'c' && digit[0] != ' ') { 
  adigit2=adigit;
  strcpy (RemoteXY.digit2, digit);}
  }


i=0;
cdeAff3=digitalRead(AFF3);
while (cdeAff3==1 && i<imax) {cdeAff3=digitalRead(AFF3);i++;yield();}
if (cdeAff3==0 && i<imax) {
  delayMicroseconds(delayReadSeg);
  lecturedigit();
  decodage();
  if (digit[0] != 'x' && digit[0] != 'c' && ((millis() - previousMillis4) <= (interval4/4)) ) { // ' ' value authorized when modifying temp instruction
  adigit3=adigit;
  strcpy (RemoteXY.digit3, digit);}
  if (digit[0] != 'x' && digit[0] != 'c' && digit[0] != ' ') { 
  adigit3=adigit;
  strcpy (RemoteXY.digit3, digit);}
  }


i=0;
cdeAff4=digitalRead(AFF4);
while (cdeAff4==1 && i<imax ) {cdeAff4=digitalRead(AFF4);i++;yield();}
if (cdeAff4==0 && i<imax) {
  delayMicroseconds(delayReadSeg);
  lecturedigit();
  decodage();
  if (digit[0] != 'x' && digit[0] != ' ') { 
  strcpy (RemoteXY.digit4, digit);}
  }

// affichage température de l'eau jacuzzi moyennant respect des conditions
currentMillis = millis();
if (digit[0]=='c' && adigit1==0 && (currentMillis - previousMillis4) >= interval4) {
  // previousMillis4=currentMillis;
  tempWater=(adigit3+(10*adigit2));
  dtostrf(tempWater, 0, 0, RemoteXY.waterTemp);
}
// si l'afficheur sur SPA est en °F, conversion en °c (tempSun et tempWater tjrs en °c)
if (digit[0]=='F' && (currentMillis - previousMillis4) >= interval4) {
  // previousMillis4=currentMillis;
  tempWater=((adigit3+(10*adigit2)+(100*adigit1)-32)/1.8);
  dtostrf(tempWater, 0, 0, RemoteXY.waterTemp);
}

}

void lectureleds(){

  // tests delay usec: de 10 à 200: c'est 15 usec qui donne mes meilleurs résultats (99% de réussite)
  // détection platine sous tension (=> Led Rouge allumée)  + lecture et décodage des led's d'état
  // jmax changements consécutifs pour être pris en compte 

  i=0;
  cdeLeds=digitalRead(LEDS);
  while (cdeLeds==1 && i<imax){cdeLeds=digitalRead(LEDS);i++;yield();} // détection présence de bits états LED
  if (cdeLeds==0 && i<imax){
    delayMicroseconds(delayReadSeg);
    powerLed=analogRead(LEDPOWER); // utilisation d'une entrée analogique pour lecture d'une valeur digitale suite manque d'entrées digitales
    lecturedigit();
    if(powerLed<=900){a=0;}
    else{a=1;}
    digitseg=String(String(a)+String(f)+String(b)+String(d)+String(dp)+String(e)+String(c));
    s=0;
    while(digitsegled!=digitseg && s<jmax){
      i=0;s++;yield();
      cdeLeds=digitalRead(LEDS);
      while (cdeLeds==1 && i<imax){cdeLeds=digitalRead(LEDS);i++;yield();}
      if (cdeLeds==0 && i<imax){
        delayMicroseconds(delayReadSeg);
        powerLed=analogRead(LEDPOWER);
        lecturedigit();
        if(powerLed<=900){a=0;}
        else{a=1;}
        digitseg=String(String(a)+String(f)+String(b)+String(d)+String(dp)+String(e)+String(c));
      }
    } 
    
    if(digitsegled!=digitseg){

      digitsegled=digitseg;
      heater1Led=f;heater2Led=b;filterLed=e;

      if(powerLed<=900){RemoteXY.ledPower_r=255;RemoteXY.ledPower_g=0;}
      else{RemoteXY.ledPower_r=0;RemoteXY.ledPower_g=0;}
      
      if(heater2Led==0 && heater1Led==1){RemoteXY.ledHeater_r=255;RemoteXY.ledHeater_g=0;}  // led rouge
      if(heater2Led==1 && heater1Led==0){RemoteXY.ledHeater_r=0;RemoteXY.ledHeater_g=255;}  // led verte
      if(heater2Led==1 && heater1Led==1){RemoteXY.ledHeater_r=0;RemoteXY.ledHeater_g=0;} // led éteinte
      
      if(filterLed==0){RemoteXY.ledFilter_r=0;RemoteXY.ledFilter_g=255;} // led verte
      else{RemoteXY.ledFilter_r=0;RemoteXY.ledFilter_g=0;}  // led éteinte
      
      }        
  }
}


void decodage(){
// Actif LOW

digitseg=String(String(a)+String(b)+String(c)+String(d)+String(e)+String(f)+String(g));
digit[0]='x';

if (digitseg == "1111111") {digit[0]=' ';adigit=0;}
if (digitseg == "0000001") {digit[0]='0';adigit=0;}
if (digitseg == "1111001") {digit[0]='1';adigit=1;}
if (digitseg == "0010010") {digit[0]='2';adigit=2;}
if (digitseg == "0110000") {digit[0]='3';adigit=3;}
if (digitseg == "1101000") {digit[0]='4';adigit=4;}
if (digitseg == "0100100") {digit[0]='5';adigit=5;}
if (digitseg == "0000100") {digit[0]='6';adigit=6;}
if (digitseg == "1110001") {digit[0]='7';adigit=7;}
if (digitseg == "0000000") {digit[0]='8';adigit=8;}  
if (digitseg == "0100000") {digit[0]='9';adigit=9;}
if (digitseg == "0000111") {digit[0]='c';adigit=10;}
if (digitseg == "1001000") {digit[0]='H';adigit=11;}
if (digitseg == "0000110") {digit[0]='E';adigit=12;}
if (digitseg == "1000110") {digit[0]='F';adigit=13;}
if (digitseg == "1011100") {digit[0]='n';adigit=14;}
if (digitseg == "0011000") {digit[0]='d';adigit=13;}

// Serial.print(digit[0]);
}

void lecturedigit(){
a=digitalRead(SEGA); // également jetLed
b=digitalRead(SEGB); // également heater2Led
c=digitalRead(SEGC); 
d=digitalRead(SEGD); 
e=digitalRead(SEGE); // également filterLed
f=digitalRead(SEGF); // également heater1Led
g=digitalRead(SEGG);
dp=digitalRead(SEGDP); 
}

I guess the real question is what changes you’ve made to this sketch to make it Blynk friendly?

Pete.

1 Like