[HELP] function into function with Virtual button

Hello all !

for my first project, i have write a Dog Feeder, and i’ve write a function for reversing motor when the current is overload (in some case, the Wheel is blocking, to avoid this -> change rotation :wink:

but !

it work with a simple process into void section, and not working into BLYNK_WRITE section :frowning:

When i press V0 virtual button, it launch doFeed function, and into this function , testCourantMoteur check the current of motor and it change (or not) a flag.

into the serial monitor, i can’t the value of current, as if doesn’t launch the checkCurrentFunction !

I’ll rip my hair out! :wink:

i have extract some code from my project, if you have an idea, i take !

ps : if you think i must post all code, tell me.

#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#include <ESP8266WiFi.h>
#include <WiFiClient.h>  
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <ESP8266HTTPUpdateServer.h> 
#include <BlynkSimpleEsp8266.h>
#include <WidgetRTC.h>
#include <TimeLib.h>
#include <SimpleTimer.h>
ESP8266WebServer httpServer(80);
ESP8266HTTPUpdateServer httpUpdater;
SimpleTimer timer;
WidgetRTC rtc;
WidgetLCD lcd(V13);


int isFirstConnect = true;
boolean flag_arret = false;
boolean flag_running = false;
boolean flag_sens = false;
boolean flag_sens_canBeChanged = true;
bool flag_doManOK = false;
int courantMoteur1 = 0;
int courantMoteur2 = 0;
const int SeuilCourrant = 100;
int dureMoteur1 = 33000;

const byte buttonPin = D3;
const byte ledBP = D1;
const byte ENA = D5;
const byte IN1 = D6;
const byte IN2 = D7;
const int current = A0;


void setup()
{
  // Affichage version dans console
  Serial.begin(115200);
  Serial.println("V 3.2 Blynk version / OTA version");
  Serial.println();

  //connection au serveur Blynk
  Blynk.begin(auth, ssid, pass);

 // Begin synchronizing time
  rtc.begin();

 // Declaration PINS
 pinMode(buttonPin, INPUT_PULLUP); // start feeding
 pinMode(ledBP, OUTPUT);
 pinMode(buzzer, OUTPUT);
 pinMode(current, INPUT);
 //pinMode(CapteurIR, INPUT);

// Moteurs L298N
 pinMode(ENA,OUTPUT);
 pinMode(IN1,OUTPUT);
 pinMode(IN2,OUTPUT);


// Led OFF - Moteurs OFF
digitalWrite(ledBP,LOW);
digitalWrite(ENA,LOW);// Moteur A - Ne pas tourner (désactivation moteur)

}

// Current test for Motor A
void testCourantMoteur ()
{
  courantMoteur1 = analogRead(current);
  
  if(courantMoteur1 < SeuilCourrant)
  {
    Serial.println(courantMoteur1);
    flag_sens_canBeChanged = true;
    return;
  }

  if (flag_sens_canBeChanged && courantMoteur1 >= SeuilCourrant)
  {
    Serial.print("Moteur bloqué / changement sens : ");
    Serial.println(flag_sens);
    Serial.println(courantMoteur1);
    flag_sens = not(flag_sens);
    flag_sens_canBeChanged = false;
  }
}

BLYNK_WRITE(V0)
{
  if(param.asInt() == 1) {
    doFeed();
    Blynk.virtualWrite(V0, 0);
  }
}

void doFeed() 
 {

        Serial.println("Fonction Blynk Auto moteur");
        
        testCourantMoteur ();
        Serial.println("Courant : ");
        Serial.println(courantMoteur1);
        

        
        startOfMotor = millis();
        while(millis() != (startOfMotor+dureMoteur1))
        {
          
         if (flag_sens == false)
         {
         
            //Moteur A  : ON
            digitalWrite(ENA,HIGH);
            digitalWrite(IN1,LOW); 
            digitalWrite(IN2,HIGH);            
         }
         else
         {

            //Moteur A  : ON
            digitalWrite(ENA,HIGH);
            digitalWrite(IN1,HIGH); 
            digitalWrite(IN2,LOW);
           
         }
         yield();

        }
        digitalWrite(ledBP, LOW);
        digitalWrite(ENA,LOW);

        
        Serial.println("Fin de fonction auto blynk ");
        

 }

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

Does it compile? I didn’t see you declaring dureMoteur1

I belive the problem is in this if (flag_sens_canBeChanged && courantMoteur1 >= SeuilCourrant) as flag_sens_canBeChanged is a bool.

Why would that be a problem? It’s just shorthand for "if(flag_sen_canBeChanged == 1).

Personally I would add more () to keep things clear, e.g.

if( (flagSens) && (otherVar > thisValue) )

thanks for your reply !

yes, compilation works and dureMoteur is delcared, i have miss to add in my code extract :wink: my bad.

why do you think a boolean is an problem ? the same fonction into a loop void works fine.

your are right, my code is ugly !! i learn everyday the developpement but i have lot of works for write clean :wink: !

maybe change the test into the while ?

Capture

I would deffinitely avoid such a way of timing tasks. And what if device will be busy during this single, one millisecond?? You should use the ‘<’ instead of ‘!=’ Then the loop will be executed as long as the current time is less than the designated time, but will not have to point exactly that time.
In your code this shouldn’t be a problem, as loop is closed and has very little to do, but what if some more time demanding task would step in?

good point ! i change that !

thanks.

Why is there a space between testCourantMoteur and ():? That should give a nice error…

Anyway, another hint. If you turn everything into English it’s much more understandable for everyone here to see what your program is doing. It’s not a very big thing, but it could lead to better solutions :slight_smile:

Just though flag_sens_canBeChanged && courantMoteur1 would be compared before the next statement

it seems to be compile with or without space, but i change it. :wink:

you are right for language… the next projet will be in English (i’m french)

thanks for your help :wink:

Mmmmm what do you meen exaclty ? inverse void testCourantMoteur () and BLYNK_WRITE(V0) maybe ?

What you mean by this? Can you clarify?

sure !

i have try with this code

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

 if (digitalRead(buttonPin) == LOW)
    {
      
      while(((millis()-tempo) < dureMoteur1) 
      {

        testCourantMoteur();

		if (flag_sens == false)
  		{
   		// Moteur ON / sens 1
   		digitalWrite(ENA,HIGH);
   		digitalWrite(IN1,LOW); 
   		digitalWrite(IN2,HIGH);
  		}
  		else
  		{
   		// Moteur ON / sens 2
   		digitalWrite(ENA,HIGH);
  		digitalWrite(IN1,HIGH); 
   		digitalWrite(IN2,LOW);
   		 } 

  digitalWrite(ENA,LOW);

  	}

}

and it works !
before writing this post,
I thought it was a blynk limitation, but apparently not;)

maybe there’s some meaning in the code?

ideally?
1- DEFINE (include… pinout)
2 - setup ()
3 - BLYNK WRITE
4 - functions
5 - loop()

my final code is like this:
1- DEFINE (include… pinou)
2 - setup ()
3 - functions
4 - BLYNK WRITE
5 - loop()

Then, if it works then just slightly modify it, for example:

boolean FeedEnable;
BLYNK_WRITE(V0)  //<-- make sure switch is defined as PUSH not SWITCH
{
  if(param.asInt() == 1) {
    tempo = millis();
    FeedEnable = true;
  }
}

and in loop:

if (FeedEnable)
    {
      if((millis()-tempo) < dureMoteur1) // <--we don't want and don't need to block the loop() with while()
      {
        testCourantMoteur();

		if (flag_sens == false)
  		{
   		// Moteur ON / sens 1
   		digitalWrite(ENA,HIGH);
   		digitalWrite(IN1,LOW); 
   		digitalWrite(IN2,HIGH);
  		}
  		else
  		{
   		// Moteur ON / sens 2
   		digitalWrite(ENA,HIGH);
  		digitalWrite(IN1,HIGH); 
   		digitalWrite(IN2,LOW);
   		 } 
	}
	else
	{
		digitalWrite(ENA,LOW);
	    FeedEnable=False;
	}
}

I have not checked it in compiler, so feel free to fix/modify it, but I do hope you got the sense of it.

great idea! i test that !

One more note: Your testCourantMoteur () will not work properly - probably will not unblock motor due to rapidly changing current flow (back and forth) and you will see (probably) a flood of serial outputs and feel motor vibrating but not moving. It’s just my quick guess based on quick analysis, so we will see

@marvin7 i have try with your method, it works !!
i’m happy !

big thanks to all !