DC Motor Control Issue

Hello everyone. I try to control a dc motor with blynk app. I create a button in the app and set to virtual pin. What I want to do is, when I press the button (logic 1) the motor rotates 90°, when I press the button again (logic 0) the motor returns to its starting position. I use rotary sensor for angle control. I can find the angle of rotation of the motor by doing analog reading. I can’t read analog inside the loop function. Because I’m disconnected from blynk server. I did analog reading within the BLYNK_WRITE(V5) function. This time, the problem is that it only read analog when I press the button. So the function only works when I press the button. Therefore, although the sensor 90°, the microprocessor can’t give a stop command to the motor. How can I continuously read the data from the sensor without writing it to the loop function. I would be very greatful if you could support me with the issue. I am sharing the code I prepared below for you to review.

#define BLYNK_PRINT Serial
#define motorSpeed D5
#define motorDir D6
#define encoderPin A0
//#define BLYNK_TEMPLATE_ID   "YourTemplateID"

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




char auth[] = "***********************************";
char ssid[] = "VsFuar";
char pass[] = "***************";
int motorAngle;
int eMin=510;
int eMax=1023;
int count=0;

void setup()
{
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  pinMode(motorSpeed,OUTPUT);
  pinMode(motorDir, OUTPUT);
  pinMode(encoderPin, INPUT);
}

BLYNK_WRITE(V5)
{
  int pinValue=param.asInt();
  Serial.println(pinValue);
  motorAngle=analogRead(encoderPin);
  motorAngle=map(motorAngle, eMin, eMax, 0, 180);
  if(pinValue==1)
  {
    motorAngle=analogRead(encoderPin);
    motorAngle=map(motorAngle, eMin, eMax, 0, 180);
    if((pinValue==1) && (motorAngle<=20))
    {
      motorAngle=analogRead(encoderPin);
      motorAngle=map(motorAngle, eMin, eMax, 0, 180);
      digitalWrite(motorSpeed,HIGH);
      digitalWrite(motorDir, LOW);
      if(motorAngle>=90)
      {
        digitalWrite(motorSpeed,LOW);
      }
    }
  }
  if(pinValue==0)
  {
    motorAngle=analogRead(encoderPin);
    motorAngle=map(motorAngle, eMin, eMax, 0, 180);
    if((pinValue==0) && (motorAngle>=90))
    {
      motorAngle=analogRead(encoderPin);
      motorAngle=map(motorAngle, eMin, eMax, 0, 180);
      digitalWrite(motorSpeed,HIGH);
      digitalWrite(motorDir, HIGH);
      if(motorAngle<=1)
      {
        digitalWrite(motorSpeed,LOW);
      }
    }
  }
}

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

What kind of dc motors you’re using ?
Most dc motors doesn’t have a feedback system, I recommend servo motors instead.

motor
rotary sensor

I use brushed DC motor. I’m mounting a rotary sensor on the output shaft of the motor. Thus, when the output shaft rotates, I can get information about the angle since the rotary sensor also rotates.

BLYNK _WRITE is a function called every time device gets an update of Virtual Pin value from the server or app.
You can use blynk timer to call your function, just create a void function like this

Void readsensor()

and in the void setup add this line

timer.setInterval(5000L, readsensor);

and in the void loop add

timer.run

More details here

Thank you for your advice. I try this solution asap. I want to ask one more thing.

timer.setInterval(5000L, readsensor);

The value of 5000L in above code means that the sensor is reading at intervals of 5 seconds. If I write 250 L instead of this value, can I read with 250ms intervals? So I mean is there a minimum limit for this value or can I use milliseconds?

I don’t understand the “can I use milliseconds” part of this question at all. The value is the frequency in milliseconds that the timer is called.

If you reduce this value too low (lest say to single digits) then you’ll likely run into problems for two reasons…

  1. it depends on how long it takes the function being called to execute. If the code in that function takes 12ms to execute and you’re calling it every 10ms then you’re going to have problems.

  2. The reason why you use a timer instead of a blocking delay is to allow the void loop to continue to operate, and the Bynk.run() command within the void loop - which is responsible for making the Blynk magic happen - has its own processing overhead to take into account.

Pete.