control of multiple servos with input though serial multitasking.

I'm trying to do a basic project servos controlled by keyboard at different timing and speed.

the idea is control different behavior of servos trough the key board.
my only correct approximation is these sketch that runs with delays. (attached at the end)

the big problem here is: If I send a new input before one of the tasks is finish. The new task don't would start until the end of the previous task.

I know that use delays is not the correct way to do this, maybe use millis and put the things in a class.

but when I follow some tutorials neither of them work for me. When I try to initialize the action with the signal from the serial in this case the keyboard. everything is a mess.

I already tried to modify my sketch based on this examples but without success:

Thanks for any advice this is my forth day in the research

//control multiple servos using keyboard keys (1,2 for servo1 atached to pin 15
and key 5,6, for servo atached to pin 13) servos could be continous rotation o standard servo, speed of rotation could be diferent
/

#include <Servo.h>

Servo servo1; //regular servo
Servo servo2; // continous rotation
Servo servo3;
Servo servo4;

int val = 0; //Variable input serial

void setup() {

Serial.begin(115200); //serial

servo1.attach(15); //regular servo
servo2.attach(13); //continous rotation servo
//servo3.attach(12); //optional servos
//servo4.attach(16); // optional servos

servo1.write (90); //position 90 degrees
servo2.write (90); // initial speed = 0
//servo3.write (90); // optional servos
//servo4.write (90); // optionalservos
}

void loop() {
//////////serial configuration///////
if(Serial.available() >= 1) //Detect input serial
{
val = Serial.parseInt(); //save as int
//////////serial configuration///////

//////////Main Functions///////

if(val == 1)
{
int pos = 0;
int dtwait = 3; // control servo speed

for (pos= 90; pos > 0; pos-=1){ // control servo position from 90 degrees to 0 degrees
servo1.write(pos);
delay(dtwait);
}
Serial.println("servo1: up");
}

else if(val == 2)
{
int pos = 0; //control servo continuos rotation////////
int dtwait = 3; // control servo time

for (pos= 90; pos > 0; pos-=1){ // control servo speed stop to 180 speed
servo2.write(pos);
delay(dtwait);}
servo2. write(90); // control servo position speed stop=90
Serial.println("servo2: up");
}

else if(val == 5)

{
int pos = 0;
int dtwait = 10; // control servo speed

for (pos= 0; pos < 180; pos +=1){ // control servo position from 0 degrees to 180 degrees
servo1.write(pos);
delay(dtwait);}

for (pos= 180; pos >= 90; pos -=1){ // control servo position from 180 degrees to 90 degrees and stop
servo1.write(pos);
delay(5); // control servo speed
}
Serial.println("servo 1 neutral");
}
else if(val == 6)
{
int pos = 0;
int dtwait = 10; // control servo time
for (pos= 0; pos < 180; pos +=1){ // control servo speed stop to 180 speed clockwise
servo2.write(pos);
delay(dtwait);} //time active
for (pos= 180; pos >= 90; pos -=1){ // control servo speed stop to 180 speed unclockwise
servo2.write(pos);
delay(5); // time active
}
Serial.println("servo 2 neutral");
}
}
}

here is my basic code, hopefully somebody can help me :wink:

/*/control multiple servos  using keyboard keys (1,2 for servo1 atached to pin 15 
and key 5,6, for servo atached to pin 13) servos could be continous rotation o standard servo, speed of rotation could be diferent*/

#include <Servo.h>

Servo servo1;  //regular servo
Servo servo2;  // continous rotation 
Servo servo3;
Servo servo4;

int val = 0; //Variable input serial

void setup() {
  
  Serial.begin(115200); //serial 

  servo1.attach(15); //regular servo 
  servo2.attach(13); //continous rotation servo
  //servo3.attach(12); //optional servos
  //servo4.attach(16); // optional servos

  servo1.write (90); //position 90 degrees 
  servo2.write (90); // initial speed = 0
  //servo3.write (90); // optional servos
  //servo4.write (90); // optionalservos
}

void loop() {
  //////////serial configuration///////  
  if(Serial.available() >= 1) //Detect input serial
  {
    val = Serial.parseInt(); //save as int
  //////////serial configuration///////  

  //////////Main Functions/////// 
      
if(val == 1)
       {
        int pos = 0;      
        int dtwait = 3;    // control servo speed
        
        for (pos= 90; pos > 0; pos-=1){   // control servo position from 90 degrees to 0 degrees
          servo1.write(pos);
          delay(dtwait);
        }
        Serial.println("servo1: up");
      }      
      
      
else if(val == 2)
       {
        int pos = 0;    //control servo continuos rotation////////
        int dtwait = 3; // control servo time
        
        for (pos= 90; pos > 0; pos-=1){  // control servo speed  stop to 180 speed
            servo2.write(pos);
            delay(dtwait);}
         servo2. write(90);  // control servo position speed stop=90
         Serial.println("servo2: up");
        }

else  if(val == 5)

       {
        int pos = 0;
        int dtwait = 10;  // control servo speed
        
        for (pos= 0; pos < 180; pos +=1){    // control servo position from 0 degrees to 180 degrees
          servo1.write(pos);
          delay(dtwait);}
        
         for (pos= 180; pos >= 90; pos -=1){ // control servo position from 180 degrees to 90 degrees  and stop
          servo1.write(pos);
          delay(5);                          // control servo speed
        }
          Serial.println("servo 1 neutral");
       }
    else  if(val == 6)
       {
        int pos = 0;
        int dtwait = 10;     // control servo time
        for (pos= 0; pos < 180; pos +=1){     // control servo speed  stop to 180 speed clockwise
          servo2.write(pos);
          delay(dtwait);}                     //time active
         for (pos= 180; pos >= 90; pos -=1){    // control servo speed  stop to 180 speed unclockwise
          servo2.write(pos);
          delay(5);                           // time active
          }
         Serial.println("servo 2 neutral");
      }
}
}

Other post/duplicate DELETED
Please do NOT cross post / duplicate as it wastes peoples time and efforts to have more than one post for a single topic.

Continued cross posting could result in a time out from the forum.

Could you take a few moments to Learn How To Use The Forum.
It will help you get the best out of the forum in the future.
Other general help and troubleshooting advice can be found here.

Difficult to work out what exactly you're trying to do because your description and the comments often don't match what the code is doing. From what I can see nothing is timed except the speed of servo "moves" and the speed isn't controlled directly from Serial. You just have a few routines that do slightly different things.

Anyway I think the first thing I'd try is to use VarSpeedServo.h instead of Servo.h. That will let you get rid of all those (blocking) for loops. Just use the (non-blocking) speed parameter in the write command instead. That should at least help.

Steve

These links may help

Serial Input Basics - simple reliable non-blocking ways to receive data.

Several Things at a Time which inludes a servo
Note how each function runs very briefly and returns to loop() so the next one can be called. None of the functions tries to complete a task in one call. And there may be dozens of calls to a function before it is actually time for it to do anything.

...R

Thanks for the help, but I continue without success,

I'm attaching a sketch of what I am expecting for when I press the keys on the serial port. my sketch do the basic. But with the problem of the (blocking) with the (delay) function.

I tried to use VarSpeedServo.h but this library use interrupts, and looks that this is not compatible with Blynk.

I dont know if the problem is the "delay" in all that parts of the code. Somebody know a way to change this "Delay" for another thing but keeping my condiition : if (val==1) that represents the keyboard "1"?

if(val == 1)
       {
        int pos = 0;      
        int dtwait = 5;    // control servo speed
        
        for (pos= 90; pos > 0; pos-=1){   // control servo position from 90 degrees to 0 degrees
          servo1.write(pos);
          delay(dtwait);
        }
        Serial.println("servo1: up");
      }

Thanks for any help!!!!!

ivanoff2019:
I tried to use VarSpeedServo.h but this library use interrupts, and looks that this is not compatible with Blynk.

Why is that a problem? The code you have shown us does not use Blynk.

Steve

The reason is that I'll need merge this sequence later into a blynk project based in a board esp8266 that don't admit interrupts for the correct functionality.

but more that the blynk reason is that right now each sequence is blocking any answer of a new input. For example if I press 5 the servo will run, but I'll need wait until the first sequence ends to see the response of another command sent previously by the keyboard.

So if I press 5 and 6. 5 is executed immediately (servo 1 moves), but the inside of the command 6 will be execute until 5 (servo1) ends.
I'm expecting a behavior that each motor could respond independent with out wait another motor to ends.

I saw that change delay by mills could be the correct way to aproach the project, only that my attempts have been unsuccesful

"I saw that change delay by mills could be the correct way to aproach the project, only that my attempts have been unsuccesful"

So where is the code where you tried to implement the use of millis()?

At least the servos are moving but the rest is Just a frustrating bunch of code: no control of speed, and looks like the millis are a mess.

#include <Servo.h>

Servo servo1;  //regular servo
Servo servo2;  // continous rotation 
Servo servo3;
Servo servo4;

int val = 0; //Variable input serial

unsigned long previusMillis1 = 0;
unsigned long previusMillis2 = 0;
unsigned long previusMillis3 = 0;
unsigned long previusMillis4 = 0;

unsigned long currentmillis1 = millis();
unsigned long currentmillis2 = millis();
unsigned long currentmillis3 = millis();
unsigned long currentmillis4 = millis();

int pos;              // current servo position 

void setup() {
  servo1.attach(15); //regular servo 
  servo2.attach(13); //continous rotation servo
  //servo3.attach(12); //optional servos
  //servo4.attach(16); // optional servos

  servo1.write (90); //position 90 degrees 
  servo2.write (90); // initial speed = 0
  //servo3.write (90); // optional servos
  //servo4.write (90); // optionalservos
    Serial.begin(115200);


}

void loop() {
 //////////serial configuration///////  
  if(Serial.available() >= 1) //Detect input serialpre
  {
    val = Serial.parseInt(); //save as int
  //////////serial configuration///////  

  //////////Main Functions/////// 
      
if(val == 1)
{
  servo1routine ();
 
  }
else if (val ==2)
  {
     servo1routineB ();
  }
else if (val ==5)
  {
     servo2routine ();
  }
else if (val ==6)
  {
      servo2routineB ();
  }
 }
}
/////////////////////////////////////
/////////servo 1/////////////////
/////////////////////////////////////
void servo1routine ()
{
  const long  interval  =5000; 
 Serial.println("working1");


  if (currentmillis1 - previusMillis1 >= interval)
  {
     previusMillis1 = currentmillis1;
    pos += interval;
 for (pos= 90; pos >= 90; pos-=1){
   servo1.write (pos);}
    Serial.println(previusMillis1);
  }
}
  
void servo1routineB ()
{
 const long  moveservo1at  =5; 
 
  if (millis() - previusMillis2 >= moveservo1at)
  {
      previusMillis2 = currentmillis2;
    //pos += 1;
    for (pos= 0; pos < 180; pos +=1){
   servo1.write (pos);
   }
    Serial.println(pos);
    }
}

/////////////////////////////////////
/////////servo 2/////////////////
/////////////////////////////////////
void servo2routine ()
{
  const long  moveservo2at  =10; 
  if (millis() - previusMillis3 >= moveservo2at)
  {
    pos += moveservo2at;
    for (pos= 90; pos > 0; pos-=1){
   servo2.write (pos);}
   }
  previusMillis3 = currentmillis3;
}


void servo2routineB ()
{
  const long  moveservo2at  =599; 
 Serial.println("working1");
{
  if (millis() - previusMillis4 >= moveservo2at)
  {
    pos += moveservo2at;
    for (pos= 0; pos < 180; pos +=1){
   servo2.write (pos);}
  }
  previusMillis4 = currentmillis4;
}
}

ivanoff2019:
but more that the blynk reason is that right now each sequence is blocking any answer of a new input. For example if I press 5 the servo will run, but I'll need wait until the first sequence ends to see the response of another command sent previously by the keyboard.

Then you weren't using VarSpeedServo correctly. I bet you added the 'wait' parameter which turns each write into a blocking version.

Your latest code is full of for loops which are also blocking constructs. Nothing else runs until the full 0-180 move is complete. If you want non-blocking speed control you need to use millis() for the actual servo move. You can't use for loops.

Steve

Learn about state-machines perhaps?