Move motor every 6.5 seconds to different positions

Start by editing your post (using the pencil icon at the bottom of your post) to format the code correctly:
Blynk - FTFC

I’d also reccomend that you search for examples of how to use the Blynk Timer, it’s a much better and simpler solution than the system you’re currently using.

Pete.

Hi Pete,

I have tried the blynk timer, its not working with me, i think might not be writing the code properly.
I would appreciate it if someone could help me with this.

Thanks & Regards,
Noor

We’ll help you to help yourself.
Post your Blynk Timer code (correctly formatted) and explain what ‘not working’ actually means in practice - does it compile properly? Does it work to a degree, or not at all?

Pete.

That’s great,
This is what I did …
to introduce the Blynk Timer, I modified the code to the following:


#define BLYNK_PRINT DebugSerial

#include <SoftwareSerial.h>

SoftwareSerial DebugSerial(2, 3); // RX, TX

#include <BlynkSimpleStream.h>
#include <Servo.h>
BlynkTimer timer;
Servo myServo;


int Stretch_end_Position=75;
int Stretch_start_Position=120;
int Switch_button;

char auth[] = "cc07a569b5xxxxxxbe57decc";

BLYNK_WRITE(V3)
{
  Switch_button=param.asInt();
      if (Switch_button==1);{
      Cyclic();
      }
      if (Switch_button==0);{
      Pause_pos();
      }

  }
  

void Cyclic()
{
  int timeCount= millis();
 
     do { 
         timer.setInterval(6500, Stretch);  
         timer.setInterval(13000, Release); 
        }while (timeCount<300000);

     if (timeCount==300000);
     {
      Pause_pos();
    
        }
}

void Stretch()
{
 myServo.write(Stretch_end_Position); 
}

void Release()
{
 myServo.write(Stretch_start_Position); 
}

void Pause_pos ()
{
  myServo.write(Stretch_start_Position);
  Blynk.virtualWrite(V3, 0);
}

void setup()
{
  // Debug console
  DebugSerial.begin(9600);
  myServo.attach(9);

  // Blynk will work through Serial
  // Do not read or write this serial manually in your sketch
  Serial.begin(9600);
  Blynk.begin(Serial, auth);
}

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

The code uploads fine, it complies and connects to the server.
When I press the switch button, nothing happens, the motor does not move in any direction.
Then the application disconnects from the server.
I thought the problem was timer.setInterval(6500, Stretch); as at the beginning I had both (Stretch and Release) at 6500 I thought a clash is happening as the motor is receiving 2 values at the same time, so I changed the release to 13000.
I think the clash is still happening as its going to the program every 6500 and 13000 is just the double of 6500. There is no motor movement with this change as well.
I am not sure what to do.

This lead me to avoid the Blynk Timer, and back to the old code and use an if statement with a normal millis() count.
Which is the code below:
This code is running however it is disconnecting as well, I am not sure what is the reason.
It goes to each position once and then disconnects.


#define BLYNK_PRINT DebugSerial

#include <SoftwareSerial.h>

SoftwareSerial DebugSerial(2, 3); // RX, TX

#include <BlynkSimpleStream.h>
#include <Servo.h>
BlynkTimer timer;
Servo myServo;

int Stretch_end_Position=75;
int Stretch_start_Position=120;
int Switch_button;



char auth[] = "cc07a569xxxxxxx62be57decc";

BLYNK_WRITE(V3)
{
  Switch_button=param.asInt();
      if (Switch_button==1);{
      Cyclic();
      }
      if (Switch_button==0);{
      Start_pos();
      }

  }
 

void Cyclic()
{
  int timeCount= millis();
  
     do { 
        if (int timeCount1=millis()==6500)
        {myServo.write(Stretch_end_Position);
        timeCount1=0;}
        if (int timeCount2=millis()==13000)
        {myServo.write(Stretch_start_Position);
        timeCount2=0;}
        }while (timeCount<300000);

     if (timeCount==300000);
     {
      Start_pos();
    
        }
}
void Start_pos ()
{
  myServo.write(Stretch_start_Position);
  Blynk.virtualWrite(V3, 0);
}

void setup()
{

  DebugSerial.begin(9600);
  myServo.attach(9);

  Serial.begin(9600);
  Blynk.begin(Serial, auth);

}

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

I am not sure what I am doing wrong, or how to correct it, I have been slamming into walls with this.

I think your do loop is acting as a blocking function, which is causing your disconnects.
I’d scrap all the millis() stuff and the do loop. I’d start the stretch process and use a timer.setTimeout command to trigger the end of the stretch after your 6500 millis period has ended.

Pete.

Dear Pete,

Thanks I have tried what you have suggested.
Removed the do loop my program no longer disconnects.
However, now it simply moves once.

The reason I have the millis() is to run the program for a couple of min / hrs.


void Cyclic()
{

           Stretch();  
           timer.setTimeout(6500, Release); 
           
}

@Noor, post your full code.

Pete.


#define BLYNK_PRINT DebugSerial

#include <SoftwareSerial.h>

SoftwareSerial DebugSerial(2, 3); // RX, TX

#include <BlynkSimpleStream.h>
#include <Servo.h>
BlynkTimer timer;
Servo myServo;

int Stretch_end_Position=75;
int Stretch_start_Position=120;
int Switch_button;


char auth[] = "cc07a569xxxxxx4062be57decc";

BLYNK_WRITE(V3)
{
  Switch_button=param.asInt();
      if (Switch_button==1);{
      Cyclic();
      }
      if (Switch_button==0);{
      Release();
      }

void Cyclic()
{

           Stretch();  
           timer.setTimeout(6500, Release); 
           
}

void Stretch()
{
 myServo.write(Stretch_end_Position); 
}

void Release()
{
 myServo.write(Stretch_start_Position); 
}

void Pause_pos ()
{
  myServo.write(Stretch_start_Position);
  Blynk.virtualWrite(V3, 0);
}

void setup()
{

  DebugSerial.begin(9600);
  myServo.attach(9);


  Serial.begin(9600);
  Blynk.begin(Serial, auth);
}

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

This is running the process once, then calling your Release() function which returns the servo to the start.
I’d have thought that your Release() function then needs to check the state of the Switch_button and if it’s equal to 1 then call the Cyclic() function again, so you go around in a loop:

void Cyclic()
{
  Stretch();  
  timer.setTimeout(6500, Release); 

  if (Switch_button==1);
  {
    Cyclic();
  }
}

Pete.

Hi there Pete,

This change caused the application to disconnect from the server -_- and the motor only moved to one position.

I guess it could be that the MyServo library calls are blocking functions, in which case you wont have nay joy using it with Blynk.
Have you tried searching the forum for other examples of sever code, that maybe use different libraries?

Also, it seems that you’ve set-up a debug serial connection, but you aren’t really using it. If you added some meaningful DebugSerial.print statements then you’d have more understanding of your program flow as it moved from one function to another.

Pete.

Maybe try something like this

BLYNK_WRITE(V3)
{
  Switch_button=param.asInt();
      if (Switch_button==1);{
      myServo.write(Stretch_end_Position); 
      timer.setTimeout(6500, Release); // Run once after 6.5 seconds
      }
      else if (Switch_button==0);{
      myServo.write(Stretch_start_Position);
      }
}

void Release()
{
 myServo.write(Stretch_start_Position); 
  timer.setTimeout(6500L, []() {  // Run once after 6.5 seconds
     Blynk.syncVirtual(V3);  });  // END Timer Function
}

Although I don’t really use servos, and if the MyServo library is blocking you may still have issues as @PeteKnight mentioned .

1 Like

Hi there Toro,

Well I have changed the code as you noted, I have also changed to a standalone ESP8266 instead of the Mega2560 via USB, thinking it might be better supported.

The good thing after the code modifications you have suggested the application no longer disconnects.
However, it only goes to one position.

make sure you button is set to switch, and add i some serial.prints to see if the portions of the code are executing. This should help you determine what may be causing the issue.

Also there was a typo in my above code, which I have now fixed.

@Noor I am not really following what you are tying to do… but here is some random servo code that I had running on my Mega2650 test-bench.

//===== Servo Sweep =====
BLYNK_WRITE(V0) // Switch Widget
{
  SrvoButtonState = param.asInt();
  if (SrvoButtonState == 1) {
    //Serial.println("Servo Sweep");
    timer.setTimeout(900L, ServoCW);  // Run Servo1 loop every 900ms
    myservo.attach(servoPin);
  } else {
    myservo.detach();
  }
} // END Blynk Function

void ServoCW() {
  timer.setTimeout(900L, ServoCCW);  // Run Servo2 loop every 900ms
  Blynk.virtualWrite(V10, 160);
  myservo.write(160);
  //Blynk.run();
}  // END Servo1 Loop

void ServoCCW() {
  Blynk.syncVirtual(V0);  // Check if switch still activated
  myservo.write(0);
  Blynk.virtualWrite(V10, 0);
}  // END Servo2 Loop
//===== END Servo Sweep =====



//===== Slow Servo Sweep =====
BLYNK_WRITE(V32) {
  int SlowServo = param.asInt();
  if (SlowServo == 1) {
    //Serial.println("SLOW Servo Sweep");
    myservo.attach(servoPin);
    SrvoPos = 1;
    timer.setTimer(15, moveServoUP, 160);
  } else {
    myservo.detach();
  }
}

void moveServoUP()
{
  myservo.write(SrvoPos);  // tell servo to go to position in variable 'pos'
  SrvoPos++;
  if (SrvoPos == 161) {
    timer.setTimer(15, moveServoDOWN, 160);
  }
}

void moveServoDOWN()
{
  myservo.write(SrvoPos);  // tell servo to go to position in variable 'pos'
  SrvoPos--;
  if (SrvoPos == 1) {
    Blynk.syncVirtual(V32);
  }
}
//===== END Slow Servo Sweep =====



//===== Servo Slider =====
BLYNK_WRITE(V10) // Servo Slider Function
{
  myservo.attach(servoPin);
  SrvoPos = param.asInt();
  myservo.write(SrvoPos);
  timer.setTimeout(1000L, ServoDetach);
} // END Blynk Function

void ServoDetach() {
  myservo.detach();
}
//===== END Servo Slider =====
1 Like

OK, I took another look… seems like you are tying to make a camera slider for Hyperlapse photography? BTW, A stepper motor will give you a more precise control of the movement than a servo.

EDIT - OK, forget all my ramblings… I missed a line in your OP about the repetitive nature of the back and forth moment… rubber band tester perhaps :stuck_out_tongue: One of my timer controlled servo loops above might be suitable for what you are doing.

Hi there Gunner,

Thanks for your feedback.
:grin:
Yes I am trying to stretch between two positions.
I did try your code, interestingly, the motor moved to two positions only once 0 and 160. It doesn’t loop between these two positions. However, the values 0 and 160 are displayed on the app and are continuously looping on the app display once I turn the switch button on.

Note: I am using switch mode on the application and not push.
I am not sure where or what is the reason behind the motor only going to these two positions once.
What I have noticed:
if I define the motor attachment in the setup, the motor only moves to one position.
If I define the motor attachment, as you did within the Bylnk Write (V0) it moves to 2 positions (0 and 160) only once.

I am starting to think the motor attachment gets detached, but I am not sure why.

#define BLYNK_PRINT Serial

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <Servo.h>
BlynkTimer timer;
Servo myServo;

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "78ab486d9960xxxxxx5b82edb3a09";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "TxxDY";
char pass[] = "2xxxxx84";


int Switch_button;
int servoPin=15;


void ServoCCW() {
  Blynk.syncVirtual(V0);  // Check if switch still activated

  myServo.write(0);
  Blynk.virtualWrite(V10, 0);
} 

void ServoCW() {
  timer.setTimeout(6500, ServoCCW);  // Run Servo2 loop every 900ms

  Blynk.virtualWrite(V10, 160);
  myServo.write(160);
 
}  // END Servo1 Loop

void ServoDetach() {
  myServo.detach();
}

BLYNK_WRITE(V0) // Switch Widget
{
  Switch_button = param.asInt();
  if (Switch_button == 1) {
    //Serial.println("Servo Sweep");
    myServo.attach(servoPin);
    timer.setTimeout(6500, ServoCW);  // Run Servo1 loop every 900ms
    
  } else {
    myServo.detach();
  }
} // END Blynk Function


void setup()
{
  // Debug console
  Serial.begin(9600);
 
  pinMode(LED_BUILTIN, OUTPUT);
  
  Blynk.begin(auth, ssid, pass);
 
}

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

I use the myServo.attach() & myServo.detatch() commands because otherwise the servo with twitch when sitting idle… probably due to a shared internal processor timer between libraries?

To make your test less complicated, you can comment out all of those references for your testing… besides, you may not see the same twitching I did unless you also have dozens of other timers running in the background like I did.

1 Like

Yes, I did face the motor vibrations while its idle.
The good news is: I just changed the motor values, and the program worked fine.
Seems like the motor I am using doesn’t support the values, works on a different range of values.

Now I just modified the the program to run for a period of time through the timer widget, however the timer widget is not user inputted. I guess its mostly used for a specific daily timed task (ie the time is fixed)

My preference is for the user to have the flexibility to input the time (start & stop) ie use the time input widget, and the program should run according to those inputted timings. I haven’t found much details about using this timer, I am not sure if it will give me HIGH on start time and LOW on end time or even
HIGH on Start time and HIGH on stop time.

Is there anywhere I can find more details on the time input widget.

Thanks

Great… considering this topic solved then?

Both questions for a different topic… but in short, both are unique in how they are used…

Timer Widget, WILL give you a user settable start/stop time (typically for simple daily repeating) with a vPin 0/1 result

Time Input Widget - Is basically a simple user interface to supply your sketch with detailed start, stop, days, etc information… but it requires you to create code to interpret and utilize the results, and trigger the actions - See here for more…