Pages: [1] 2 3 4   Go Down
Author Topic: VarSpeedServo - a modified Servo library with speed control  (Read 25713 times)
0 Members and 1 Guest are viewing this topic.
Central Europe
Offline Offline
Edison Member
*
Karma: 7
Posts: 1220
Use the Source, Luke.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Attached to this message is the library VarSpeedServo, a modified version of the Servo library with one additional function slowmove() which is a replacement of write with an additional speed parameter.

Speed=0: Write is used, full speed
Speed=1: Slowest
Speed=255: Fastest. With the servos I have, with values above 127 I couldn't see any difference to write because the mechanical speed of the servo was the limiting factor.

Everything that works with Servo works with VarSpeedServo too. Important: Don't use Servo.h and VarSpeedServo.h at the same time, it will create conflicts.

Example:
Code:
#include <VarSpeedServo.h>
VarSpeedServo myServo;
...
myServo.attach (mainPin, ServoMin, ServoMax);
...
myServo.slowmove (newpos, speed);
...

Have fun with it.

Korman

* VarSpeedServo.zip (7.91 KB - downloaded 952 times.)
« Last Edit: May 18, 2011, 02:52:02 pm by Korman » Logged

Copenhagen, Denmark
Offline Offline
Edison Member
*
Karma: 32
Posts: 1206
Have you testrun your INO file today?
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you. Saved me reinventing that particular wheel. Well, I already did it, but this is more elegant. To Be Tested   smiley-evil
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Very nice addition, good work!

Shouldn't it be just added to the servo lib? 
Or be a derived class from Servo?

Quote
Speed=0: Write is used, full speed
Speed=1: Slowest
Speed=255: Fastest. With the servos I have, with values above 127 I couldn't see any difference to write because the mechanical speed of the servo was the limiting factor.
Would it be more natural to let speed go from 1-100% ? Granularity is not as fine, but maybe fine enough?

just thinking out loud,
Rob
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Central Europe
Offline Offline
Edison Member
*
Karma: 7
Posts: 1220
Use the Source, Luke.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I thought about this, but in the end I didn't find any useful measure for the speed, as the actual movement speed of the servo is unknown.  50% or 1% wouldn't match the reality either, so I just went with one byte speed indicator as compromise between data overhead in the Servo-library, processing overhead in the interrupt function and granularity for the speed regulation. It was good enough for what I needed - lowering model aircraft landing gears in a realistic manner.

Korman
Logged

Netherlands
Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi there,

Looks like this library would be the solution to my problem.
So I downloaded the library, installed it and created the following code:
Code:
#include <VarSpeedServo.h>

VarSpeedServo servo1;
VarSpeedServo servo2;

void setup() {
  servo1.attach(9); 
  servo2.attach(10);

  Serial.begin(19200);
  Serial.println("Ready");
}

void loop() {

  static int v = 0;

  if ( Serial.available()) {
    char ch = Serial.read();

    switch(ch) {
case '0'...'9':
  v = v * 10 + ch - '0';
  break;
case 'R':
  servo1.slowmove(v,50);
  v = 0;
  break;
case 'L':
  servo2.write(v);
  v = 0;

  break;
        case 'Z':
          servo1.write(90);
          servo2.write(90);
          break;
       
    }
  }

But it gives the following error when compiling:
Code:
cameraCodeArduino.cpp.o: In function `__static_initialization_and_destruction_0':
C:\Users\s070099\AppData\Local\Temp\build7343566564887365634.tmp/cameraCodeArduino.cpp:6: undefined reference to `VarSpeedServo::VarSpeedServo()'
C:\Users\s070099\AppData\Local\Temp\build7343566564887365634.tmp/cameraCodeArduino.cpp:7: undefined reference to `VarSpeedServo::VarSpeedServo()'
cameraCodeArduino.cpp.o: In function `loop':
C:\Users\s070099\AppData\Local\Temp\build7343566564887365634.tmp/cameraCodeArduino.cpp:29: undefined reference to `VarSpeedServo::slowmove(int, unsigned char)'
C:\Users\s070099\AppData\Local\Temp\build7343566564887365634.tmp/cameraCodeArduino.cpp:33: undefined reference to `VarSpeedServo::write(int)'
C:\Users\s070099\AppData\Local\Temp\build7343566564887365634.tmp/cameraCodeArduino.cpp:38: undefined reference to `VarSpeedServo::write(int)'
C:\Users\s070099\AppData\Local\Temp\build7343566564887365634.tmp/cameraCodeArduino.cpp:39: undefined reference to `VarSpeedServo::write(int)'
cameraCodeArduino.cpp.o: In function `setup':
C:\Users\s070099\AppData\Local\Temp\build7343566564887365634.tmp/cameraCodeArduino.cpp:10: undefined reference to `VarSpeedServo::attach(int)'
C:\Users\s070099\AppData\Local\Temp\build7343566564887365634.tmp/cameraCodeArduino.cpp:11: undefined reference to `VarSpeedServo::attach(int)'

I have no idea how to solve this, do you have any idea what's going wrong here?

Thanks in advance
Logged

Central Europe
Offline Offline
Edison Member
*
Karma: 7
Posts: 1220
Use the Source, Luke.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I would have guessed the including didn't work properly. Did you place the library in the proper directory and import it as described here: http://www.arduino.cc/en/Reference/Libraries

Korman
Logged

Netherlands
Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Korman,

Yes, I have placed it correctly and it shows up in my Arduino, Sketch -> Import Library... -> VarServoSpeed. Imported it from there as well
Using Arduino 0022 btw, on Windows 7 computer.. maybe does that make any difference?
Logged

Netherlands
Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ah never mind
Typo somewhere. Testing it now and it works fine! Thanks so much!
Logged

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6252
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have just come across this, nice job Korman.

Do you think this is a capability I should add to the core Servo library?

BTW, I posted an example sketch using this library here: http://arduino.cc/forum/index.php/topic,68305.msg504226.html#msg504226


Logged

Central Europe
Offline Offline
Edison Member
*
Karma: 7
Posts: 1220
Use the Source, Luke.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Mem,

it's nice to know, that you like it. Whether to add it to the main Servo-library should be considered carefully. From my point of view, you're welcome to add the code or any modification from it. However, please consider a few things first:
  • The speed control adds more memory to the servo structure. It's just a few bytes, but in large setup with many servos, you should check if this causes problems
  • The speed parameter doesn't relate to any real time measure. It's just a number and you can set some speeds but others not. For many applications, like moving something at a pleasant speed to look at, this is good enough. If some specific speeds are necessary, the model I used might not offer enough granularity.
  • I didn't really check if the interaction of the position update and attach/detach works in a reasonable manner. What happens if one detaches the servo while on a slow move and then reattaches it?
  • The method-name slowMove is clumsy and not really in line with the rest of the rest of the methods
  • The spectrum of the available speeds isn't well used. Out of the speed byte, values above 128 are usually to fast to make visible differences because of the limits of the motor speed itself. I would like it improve this, but then I'd need more bits for the ticks parameter. If the memory isn't a problem, adding a byte to the tick counter will give more slower speeds. I think, it should also be considered what kind of speeds are going to be used most.
  • Some proper documentation and samples are also necessary.

In short, it was mostly a quick hack to get landing gears on model aircraft extend and retract at a more more realistic pace. Going by the general feedback, it seems to be of use for some applications. If you think part of my work is useful to be added to the main library, feel free to go ahead.

Korman
« Last Edit: August 04, 2011, 07:30:56 am by Korman » Logged

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6252
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Mem,

it's nice to know, that you like it. Whether to add it to the main Servo-library should be considered carefully. From my point of view, you're welcome to add the code or any modification from it. However, please consider a few things first:
  • The speed control adds more memory to the servo structure. It's just a few bytes, but in large setup with many servos, you should check if this causes problems
  • The speed parameter doesn't relate to any real time measure. It's just a number and you can set some speeds but others not. For many applications, like moving something at a pleasant speed to look at, this is good enough. If some specific speeds are necessary, the model I used might not offer enough granularity.
  • I didn't really check if the interaction of the position update and attach/detach works in a reasonable manner. What happens if one detaches the servo while on a slow move and then reattaches it?
  • The method-name slowMove is clumsy and not really in line with the rest of the rest of the methods
  • Some proper documentation and samples are also necessary.

In short, it was mostly a quick hack to get landing gears on model aircraft extend and retract at a more more realistic pace. Going by the general feedback, it seems to be of use for some applications. If you think part of my work is useful to be added to the main library, feel free to go ahead.

Korman

Hi Korman,

I agree with all your points. But this thread and the other one I linked below got me thinking about possibly adding a sweep function with user setable speed that I may be able to do using just one more byte of RAM per servo. I would be interested to hear if this is something that would be generally useful and will start a new thread to discuss this if enough people are interested.
Logged

Central Europe
Offline Offline
Edison Member
*
Karma: 7
Posts: 1220
Use the Source, Luke.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

To answer your question: I needed this kind of function, so I wrote the extension. From time to time, questions about moving things slowly come up, mostly for visual reasons. I think having such a function in the servo library would be a good idea if the library doesn't suffer from it.

NB: I added one more point about the speed control to my previous message.

Korman
« Last Edit: August 04, 2011, 07:36:59 am by Korman » Logged

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6252
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am interested to know if adding variable speed sweep would be good enough for most applications?  Most of the additional RAM needed in VarSpeedServo is for the target position, but this is not needed if the sweep is between the min and max positions set in the attach method because only the speed and current direction need to be stored and these can be held in a single byte if the max speed is limited to 127.

Would something like that be useful or will most people want the capability to control speed when moving the servo to any given?
Logged

Copenhagen, Denmark
Offline Offline
Edison Member
*
Karma: 32
Posts: 1206
Have you testrun your INO file today?
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Would something like that be useful or will most people want the capability
I am not "most people", despite my inflated ego smiley But as you see from my reply earlier, I would have found that usefull.

My sweep used a millis() timer construct. For me - not a big hassle to program, but I know from many of the threads here, that it will be too much for many people to "do more than one thing" (ie let the sweep progress without disturbing other processing.) As I do not (yet) have any experience in accessing the hardware timers I do not know how much hassle it is to add that in the timer/interrupt code - or if it would limit the max number of servos.

(My sweep code has an advantage that I can do something synchronized with two servos. In an built in function one would need to change the sweep rate for each "ratio".)

The alternative is to let the sweep be "blocking", ie calling servo.write with asweep value will take the time it takes. I would not like a servo.updatesweep() to be called "often" for the sweep to work.
Logged

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6252
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

(My sweep code has an advantage that I can do something synchronized with two servos. In an built in function one would need to change the sweep rate for each "ratio".)

What do you mean by the ratio? Perhaps you can say more about the functionality.

I don't want to hijack this thread so I have created a new thread here: http://arduino.cc/forum/index.php/topic,68474.0.html
Logged

Pages: [1] 2 3 4   Go Up
Jump to: