sweeping a servo motor for specific time duration

Hi all,

I am Jatin Goyal, newbie on this forum. I am working upon a project wherein i need to make a servo motor sweep for a specific time interval.

Time interval will be received from serial communication.

I have made a sketch for sweeping servo using millis(), It works well without using serial communication

CODE 1:

#include <Servo.h>
Servo myservo;
int pos = 0; 

void setup() {
  myservo.attach(9);
 Serial.begin(9600);

}
int jatin=2000;   // interval for which servo will sweep
unsigned long cm;   // current miliseconds
void loop() {
  myservo.write(0);     // setting servo pos at default
  cm=millis();          // starting measuring miliseconds
  if(cm<jatin)          // comparing elapsed miliseconds to interval
  {
  // servo sweep program start 
    for (pos = 0; pos <= 30; pos += 10) {
     myservo.write(pos);           
    delay(15);  
  }
  for (pos = 30; pos >= 0; pos -= 10) { 
    myservo.write(pos);              
    delay(15);                 
  }   // servo sweep program ends
  Serial.println(cm);     // println elapsed miliseconds
  }  
}

Next on adding serial communication function sketch became

CODE : 2

#include <Servo.h>

Servo myservo;
int pos = 0; 

void setup() {
  myservo.attach(9);
  Serial.begin(9600);
  sweep(500);
}

unsigned long cm;

void loop(){}
 
void serialEvent() {
  int channel;
 if (Serial.available() >0){
  channel = Serial.parseInt();
  //pos = Serial.readStringUntil('*').toInt();
  //pos = Serial.readString().toInt();
  //sweep(channel);
  Serial.println(channel);} }


  int jatink;
void  sweep(int jatink){
  myservo.write(0);
  cm=millis();
  if(cm < jatink){
    for (pos = 0; pos <= 30; pos += 10) {
     myservo.write(pos);           
    delay(15);  
  }
  for (pos = 30; pos >= 0; pos -= 10) { 
    myservo.write(pos);              
    delay(15);                 
  }// Serial.println(cm);
  }}

--Code 1 works fine.

ERRORS

--when I pass interval duration in code 2 by using serial monitor, servo doesn't perform sweeping action for that duration

-- in code 2 when I pass the interval duration like " sweep(10), sweep(100), sweep(1000) " servo sweeps for that time interval.

---CODE 2 doesn't work when interval time is passed via serial monitor

Please help me in troubleshooting the code in the attached file.

I would be highly grateful to you all.

serial_servo-millis.ino (781 Bytes)

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data. There is also a parse example to illustrate how to extract numbers from the received text.

...R

I have edited my thread. please have a look at it

Your loop() function is empty. So the other functions are never called except sweep() is called just once in setup().

Steve

Hi steve ,
Thanx for replying.

I tried working in loop too. i added if (serial.availabe>0) {......}

but it didnt worked out too

slipstick:
Your loop() function is empty. So the other functions are never called except sweep() is called just once in setup().

Steve

Hi steve ,
Thanx for replying.

I tried working in loop too. i added if (serial.availabe>0) {......}

but it didnt worked out too

Jatin1o1:
I tried working in loop too. i added if (serial.availabe>0) {......}

but it didnt worked out too

You need to post the latest version of your program so we can see exactly what you tried.

Also "didn't work" provides no useful information from which to help you. Please give as much detail as you can about what happens when you run the program.

...R

Robin2:
You need to post the latest version of your program so we can see exactly what you tried.

Also "didn't work" provides no useful information from which to help you. Please give as much detail as you can about what happens when you run the program.

...R

Code 1 and code 2 both are latest version of the codes.
you can please Trying running it on your arduino while attaching a servo on pin 9

Jatin1o1:
Code 1 and code 2 both are latest version of the codes.

I find that hard to believe considering what you said in Reply #4 which was written after you posted the code in your Original Post. And if you have another version please put it in your next Post so we can compare it with the version in the Original Post.

you can please Trying running it on your arduino while attaching a servo on pin 9

That's your job.

...R

If the version of "Code 2" in the first post is really your latest version then you have completely ignored all advice given to you.

loop() is still empty. So serialEvent() is never called. So it's hardly surprising that the program doesn't use any values from the serial monitor. And sweep() is never called in loop() so obviously the servo is never going to move.

Steve

slipstick:
If the version of "Code 2" in the first post is really your latest version then you have completely ignored all advice given to you.

loop() is still empty. So serialEvent() is never called. So it's hardly surprising that the program doesn't use any values from the serial monitor. And sweep() is never called in loop() so obviously the servo is never going to move.

Steve

Pardon me for not getting with latest post.
I got quite busy because of my semester examinations.

I had tried with putting my code in loop too.

I had experience successfully controlling servo motors using void serialEvent(){} and not entering a thing in void loop{}, see code at " Controlling multiple servo motors using serial monitor without using void loop in arduino. · GitHub "

After a lot of experimentation , removing #include<Servo.h> servo library and putting things in loop my code finally look like this

int pos = 0; 
int servopin= 9;

void setup() {
pinMode(servopin,OUTPUT);
  Serial.begin(9600);
}

unsigned long cm;

void loop(){
  int channel;
 if (Serial.available() >0){
  channel = Serial.parseInt();
  //pos = Serial.readStringUntil('*').toInt();
  //pos = Serial.readString().toInt();
  Serial.print(" value enters if : ");
  Serial.println(channel);
  sweep(channel);}
  }


  int jatink;
void  sweep(int jatink){

  Serial.print("inside sweep fucntion  and value of jatin k is : ");
  Serial.print(jatink);
  cm=millis();
  if(cm/1000 < jatink){
     for (pos = 1500; pos <= 1750; pos += 10) {
                digitalWrite(servopin,HIGH);          
                 delayMicroseconds(pos);
                 digitalWrite(servopin,LOW); 
                 delay(1);
                  
              }
         for (pos = 1750; pos >= 1500; pos -= 10) { 
                 digitalWrite(servopin,HIGH);          
                 delayMicroseconds(pos);
                 digitalWrite(servopin,LOW); 
                 delay(1);              
              }               
  }// Serial.println(cm);
  }

I apologies for not commenting the above code at this time.

The problem with the above code is that the servo doesn't sweep continuously until the enter value of time duration.

It just make a sweep if the entered value is greater than current values of millis().

I almost made the servo run up to the desired interval.

Last thing which is troubling me is to reset the value of cm=millis() in this for loop " for (cm-pm;cm/1000 < jatink;cm=millis()) " in " void sweep "

int pos = 0; 
int servopin= 9;

void setup() {
pinMode(servopin,OUTPUT);
  Serial.begin(9600);
}

unsigned long cm;
unsigned long pm;
void loop(){
  int channel;
 if (Serial.available() >0){
  channel = Serial.parseInt();
  //pos = Serial.readStringUntil('*').toInt();
  //pos = Serial.readString().toInt();
  Serial.print(" value enters if : ");
  Serial.println(channel);
  sweep(channel);}
  }


  int jatink=0;
void  sweep(int jatink){

  Serial.print("inside sweep fucntion  and value of jatin k is : ");
  Serial.print(jatink);

 for (cm-pm;cm/1000 < jatink;cm=millis()){
     for (pos = 1500; pos <= 1750; pos += 10) {
                digitalWrite(servopin,HIGH);          
                 delayMicroseconds(pos);
                 digitalWrite(servopin,LOW); 
                 delay(1);
                  
              }
         for (pos = 1750; pos >= 1500; pos -= 10) { 
                 digitalWrite(servopin,HIGH);          
                 delayMicroseconds(pos);
                 digitalWrite(servopin,LOW); 
                 delay(1);              
              }      
              Serial.println(cm);         
  }cm =0;// Serial.println(cm);
  }

I have never seen a FOR loop like this before

for (cm-pm;cm/1000 < jatink;cm=millis()){

I think that would be interpreted first time around as

for (0 - 0;  0/1000 < 0; cm = millis()) {

and next time round it might be (if millis() happened to be 750)

for (750 - 0;  750/1000 < 0; cm = millis()) {

However I cannot see any situation in which cm/1000 could be a negative number so the test cm/1000 < 0 will always fail.

Of course I might misunderstand.

My suggestion is to make a much simpler FOR loop. Or maybe change it to a WHILE loop and do the time checking within the WHILE. But that brings me right around to using a simple IF and allowing loop() to do the iteration - for example

if (millis() - prevTime >= desiredInterval) {
   prevTime = millis();
   // do whatever needs to be done
}

which is how things are done in the demo Several Things at a Time

...R

Robin2:
I have never seen a FOR loop like this before

for (cm-pm;cm/1000 < jatink;cm=millis()){

I think that would be interpreted first time around as

for (0 - 0;  0/1000 < 0; cm = millis()) {

and next time round it might be (if millis() happened to be 750)

for (750 - 0;  750/1000 < 0; cm = millis()) {

However I cannot see any situation in which cm/1000 could be a negative number so the test cm/1000 < 0 will always fail.

Of course I might misunderstand.

My suggestion is to make a much simpler FOR loop. Or maybe change it to a WHILE loop and do the time checking within the WHILE. But that brings me right around to using a simple IF and allowing loop() to do the iteration - for example

if (millis() - prevTime >= desiredInterval) {

prevTime = millis();
  // do whatever needs to be done
}



which is how things are done in the demo [Several Things at a Time](http://forum.arduino.cc/index.php?topic=223286.0)

...R

I can understand i am such a bad coder.

yeah I have finally solved the problem.

I am Highly Thankful and grateful of everyone commenting on this thread and helping me solve the problem :smiley: