Continuous servo rotation without for loop

Hello all,

I wanted to ask if there was a particular method/code I could use, instead of a for loop, to make my continuous servo rotate for a number of seconds, and then stop rotating. I need to be able to complete this process in both CW and ACW directions.

From my basic programming knowledge I understand that the for loop will only stop when a particular condition has been met, but this does not apply to my continuous servo as the potentiometer is in a constant position and hence receives no feedback on the motor position meaning the for loop found in most basic servo code doesn't really work for my purpose.

Thanks !

If you are asking if you can put your code in setup() which runs once at reset, then yes.

Right. Do you know any functions I can use which will let me control how long the servo rotates for, and then forces the servo to stop after a particular number of seconds ?

Are you saying the pot is not connected to the motor shaft as feedback but instead is like a position set dial where you select a pot position and that is supposed to represent a position (the pot controls the servo from Min to Max based on pot position) ?

Do you know any functions I can use which will let me control how long the servo rotates for, and then forces the servo to stop after a particular number of seconds ?

millis();

You can also use the TIMERs programmed as count-down or count up .

See the blink without delay example that comes with the IDE (File, Examples, Digital).

@raschemmel

Yes the pot has been disconnected from the servo gearing and hence feedback has been disabled. I've set it at a particular reference position where for example if one were to attempt to move the motor 90 degrees it would rotate in one direction, and in the opposite direction if attempted to move 180 degrees. Setting these positions allows for directional control.

I'm guessing that you want to use an external potentiometer to set the speed but you want separate control of how long the servo operates. (I'm assuming its a continuous rotation servo).

The usual way to do this is the technique in the Blink Without Delay sketch.

Save the value of millis() immediately before you start the servo and then stop the servo when the later value of millis() is (say) 5000 (for 5 seconds) later than the saved value. Something like this partial code

byte runServo = true;
int speedVal = 120; // for example
unsigned long startingMillis = 0;
unsigned long currentMillis;
unsigned long runMillis = 5000;

void loop() {
   currentMillis = millis();
   if (runServo == true) {
      if (currentMillis - startingMillis >= runMillis) { // time has expired
         myservo.write(90); // or whatever makes it stop
         runServo = false;
      }
      else { // time has not expired
         myservo.write(speedVal);
      }
   }
}

I hope that gives the idea. This will only run once unless you add other code to reset runServo to true. I assume the value from your pot will go into speedVal.

...R

I've set it at a particular reference position where for example if one were to attempt to move the motor 90 degrees it would rotate in one direction, and in the opposite direction if attempted to move 180 degrees.

What is the pot connected to ?

@Robin2

Thanks for the tip. Using the arduino timer looks useful. Is there a method of resetting the the arduino timer without actually turning the arduino off ? If not is there a method of resetting the arduino via code ?

I need the timer to reset as once the servo has completed its task, it will have to sit around for a finite number of seconds (minutes, hours...) until the user needs it to perform its a second and final task. This would be impossible to control using the timer, if the timer just carried on.

@raschemmel

Previously when the motor rotated the potentiometer would rotate in sync, hence allowing for position feedback/control. But in order to make the servo a continuous rotation servo i've disconnected the potentiometer from the servo gearing, as the potentiometer cannot rotate 360 degrees. When the motor rotates, the potentiometer does not move.

And what is your proposed function for the potentiometer now ? (what parameter do you want it to control ? (pos min -> max?)

AhmedemhA:
@Robin2

Thanks for the tip. Using the arduino timer looks useful. Is there a method of resetting the the arduino timer without actually turning the arduino off ? If not is there a method of resetting the arduino via code ?

I need the timer to reset as once the servo has completed its task, it will have to sit around for a finite number of seconds (minutes, hours…) until the user needs it to perform its a second and final task. This would be impossible to control using the timer, if the timer just carried on.

@raschemmel

Previously when the motor rotated the potentiometer would rotate in sync, hence allowing for position feedback/control. But in order to make the servo a continuous rotation servo i’ve disconnected the potentiometer from the servo gearing, as the potentiometer cannot rotate 360 degrees. When the motor rotates, the potentiometer does not move.

You don’t reset any timer, millis() returns a value that you use to implement a test for
a certain point in time being reached. Its like looking at a clock on the wall, not a
stopwatch.

In the hardware there are timers, and timer0 is used to implement millis(), micros(),
and delay(). All three timers are used to general PWM output on the PWM pins too,
so reseting a timer isn’t normally done.

Yes the pot has been disconnected from the servo gearing and hence feedback has been disabled. I've set it at a particular reference position where for example if one were to attempt to move the motor 90 degrees it would rotate in one direction, and in the opposite direction if attempted to move 180 degrees. Setting these positions allows for directional control.

Using writeMicroseconds() provides better speed control of continuous rotation servos. The typical continuous rotation servo calibration is to send 90 deg or 1500us command to the servo, then carefully adjust the servo pot until the servo stops rotating.

I've set it at a particular reference position where for example if one were to attempt to move the motor 90 degrees it would rotate in one direction, and in the opposite direction if attempted to move 180 degrees. Setting these positi

This is a little hard to follow but if I understand it correctly the pot is now a 90 deg/180 deg selector. Is the intent to allow selection of the positions between 90 & 180 degrees as well, so midpoint for the pot is (90+45)=135 degrees ?

but this does not apply to my continuous servo as the potentiometer is in a constant position

Need the value of the pot to calculate resolution.

int pot=A0;
value=analogRead(pot);
value=map(value, 0, 1023, 0, 90); 
value=map(value, 0, 1023, 90, 180);

Which one of these would work best for you ?
since the difference between 90 and 180 = 90, I don't see any real difference in the two statements above because the result can be modified by S/W after the Map is performed..

raschemmel:
This is a little hard to follow but if I understand it correctly the pot is now a 90 deg/180 deg selector.

I wonder if you are confusing the pot the OP is using to set speed with the pot that is normally inside a stepper motor. With a continuous rotation servo the pot inside the servo is usually removed and replaced by fixed resistors.

...R

@raschemmel

Referring to zoomkat's reply, this is what I have done. I have removed the physical connection between the pot and the servo, and calibrated the servo so that when 90 deg is sent to the servo it remains stationary (done by manually adjusting the pot until the servo stops moving).

@MarkT

By using the timer() code would I be able to start a timer, and then tell the servo to stop once a particular number of seconds has passed ? Would I then be able to stop the timer (assuming by stopping the timer it resets to 0) and then use the timer once more for a similar task, all within the same script ? Sorry for being vague, i'm essentially curious whether the timer resets to 0 once it is stopped so I can implement it again later on in my script.

I think so since I didn't know about the pot inside..