Help using ServoTimer2 (deegres to microseconds)

Well first of all, that's my first thread and I'm sorry if I posted in the wrong section.

My current project gets values from VirtualWire using of course VirtualWire.h which is incompatible with Servo.h because of TIMER1. The values I'm sending with VirtualWire are actually the angle the servo needs to rotate.

What I realised is that ServoTimer2 uses microseconds to control the servo (if someone can explain me this in deep I'll be very tahnkfull) and not with degrees, what I had programmed (and can't be changed at the moment).

What I've tried so far is to map() the value of the angle like this:

for (int i = 0; i < 5; i++) {
    angleServoTimer[i] = map(angleString[i].toInt(), 0, 180, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);

    servoMotor[dit].write(angleServoTimer[i]);
}

I've realised though, that sending a 180 it actually writes MAX_PULSE_WIDTH, but the servo does not move 180 degrees. Even hard-codding MAX_PULSE_WIDTH and MIN_PULSE_WIDTH to 755 and 2250 like the library suggests:

#define MIN_PULSE_WIDTH	 750	  // the shortest pulse sent to a servo  
#define MAX_PULSE_WIDTH	2250	  // the longest pulse sent to a servo

Although I'm feeling a bit confused on ServoTimer2.h when I read this:

 /* attach(pin, min, max  ) - Attaches to a pin setting min and max values in microseconds
   * default min is 544, max is 2400
   */

Is there a way to precise this? My project depends on the angles the servo should rotate.

Every help will be apracated, and a bit urgent, thanks!

I suggest you write a short sketch that controls your servo using ServoTimer2 and does nothing else. It will allow you to input the numbers of microseconds directly and see how your servo responds.

In theory 0 deg corresponds to 1000 microsecs and 180 deg corresponds to 2000 microsecs. But most servos don't exactly conform to the theory. Some can't move through a full 180 deg, others can move more than that. And for many 0 deg doesn't exactly correspond to 1000 microsecs.

...R

Robin2:
I suggest you write a short sketch that controls your servo using ServoTimer2 and does nothing else. It will allow you to input the numbers of microseconds directly and see how your servo responds.

In theory 0 deg corresponds to 1000 microsecs and 180 deg corresponds to 2000 microsecs. But most servos don't exactly conform to the theory. Some can't move through a full 180 deg, others can move more than that. And for many 0 deg doesn't exactly correspond to 1000 microsecs.

...R

Is there any way to know if my servo rotates from 0-180. My servo rotates with Servo.h from 0-180, can this be a clue to know if shall work too with ServoTimer2?

Is there any way to know if my servo rotates from 0-180

Put the output arm on, servo.write0); then servo.write(180);
How many degrees does the output arm rotate between the two ?

bieltv3:
Is there any way to know if my servo rotates from 0-180. My servo rotates with Servo.h from 0-180, can this be a clue to know if shall work too with ServoTimer2?

You can use servo.writeMicroseconds() with the regular servo library if you need to compare its behaviour with ServoTimer2.

Use servo.writeMicroseconds() to find out exactly what numbers represent the extreme ends of movement for your servo.

...R

UKHeliBob:

Is there any way to know if my servo rotates from 0-180

Put the output arm on, servo.write0); then servo.write(180);
How many degrees does the output arm rotate between the two ?

Yeah my servo TowerPro Mini sg-99 rotates 180 degrees (visually), maybe 170 or auch, but that is ok for my useage. - Using Servo.h
With code described above my servo.rotates like 90 deegres and that is not my purpose on the project.
Thanks for replying

Robin2:

bieltv3:
Is there any way to know if my servo rotates from 0-180. My servo rotates with Servo.h from 0-180, can this be a clue to know if shall work too with ServoTimer2?

You can use servo.writeMicroseconds() with the regular servo library if you need to compare its behaviour with ServoTimer2.

Use servo.writeMicroseconds() to find out exactly what numbers represent the extreme ends of movement for your servo.

...R

Hmm that sounds okey, but it is based on 'expierence' although it should be okey for my purpose.
Is there any documentation somewhere about microsecond as a variable of rotation (such as radiants or deegres), and what exactly does on the servo; it sets the time.it should rotate (which does not make sense, because then the servo won't go back) or if it is a variable you can calculate using the pair of a motor and such?
Thanks for replying!

Is there any documentation somewhere about microsecond as a variable of rotation (such as radiants or deegres),

There is no documentation as to the relationship between the number of microseconds and degrees of rotation because each type of servo will vary as to how far it can rotate, hence the suggestions to try the extremes of servo.write() and writeMicroseconds(). Specialist servos, such as sail winches, may turn through 360 degrees or more from one end of their travel to another whilst when using continuous rotation servos the parameters used in the functions control the speed and direction of rotation rather than the angle.

From what you say your servo rotates 180 degrees end to end between servo.write0); and servo.write(180); What does it do with writeMicroseconds(1000); and writeMicroseconds(2000); ?

I think you are missing the fact that "microseconds" is the natural value that is used by servos and "degrees" are just a convenience for users. All of the servo libraries that accept degrees will convert them into the appropriate number of microseconds. The microseconds number is the width of the pulse that is actually sent to the servo.

As has been said already, there is some variation between servos as to how they actually respond to pulses of a particular width. In the theory the range is from 1000 to 2000 but some servos work at lower and higher values. And there may be some differences between 2 otherwise identical servos.

...R

Robin2:
I think you are missing the fact that "microseconds" is the natural value that is used by servos and "degrees" are just a convenience for users. All of the servo libraries that accept degrees will convert them into the appropriate number of microseconds. The microseconds number is the width of the pulse that is actually sent to the servo.

As has been said already, there is some variation between servos as to how they actually respond to pulses of a particular width. In the theory the range is from 1000 to 2000 but some servos work at lower and higher values. And there may be some differences between 2 otherwise identical servos.

...R

Oh, no I didn't know that microseconds was the value used. Thanks for the tip! Now I searched into the Servo library, and I've come to the line I'm interested in:

void Servo::write(int value)
{  
  if(value < MIN_PULSE_WIDTH)
  {  // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds)
    if(value < 0) value = 0;
    if(value > 180) value = 180;
    value = map(value, 0, 180, SERVO_MIN(),  SERVO_MAX());
  }
  this->writeMicroseconds(value);
}

**value = map(value, 0, 180, SERVO_MIN(), SERVO_MAX()); **

This is what I need to achive into my code to make proces easier and cleaner, I searched function SERVO_MIN and SERVO_MAX into the code:

#define SERVO_MIN() (MIN_PULSE_WIDTH - this->min * 4)  // minimum value in uS for this servo
#define SERVO_MAX() (MAX_PULSE_WIDTH - this->max * 4)  // maximum value in uS for this servo

I've realised that MIN_PULSE_WIDTH is 544 and MAX_PULSE_WIDTH is 2400. What I need to know is wat this->min and this-> max means...

What I've searched so far is inside Servo.h, which includes a little information of those values:

/*
attach(pin, min, max  ) - Attaches to a pin setting min and max values in microseconds default min is 544, max is 2400  
*/

I'm not sure if it's taking this value, as if the funciton SERVO_MIN/MAX it will result into negatives numbers as MIN_PULSE_WIDTH will be the same as min, and MAX_PULSE_WIDTH will be the same as max...

I just need to know what does this->min and this->max refeer to to make my program! And then I can still keep my code as angles, and create a method to convert it to degrees and write it! Hope you could help me to know where this value come from :stuck_out_tongue: Thanks

Can we go back to basics and establish the angle that your servo moves through between writeMicroseconds(1000); and writeMicroseconds(2000); ?

I agree 100% with @UKheliBob.

The Min and Max in the servo library are intended to cover a huge range of servos and are there just as safeguards to ensure the library does not produce really silly outputs.

Just focus on finding, by trial and error, what are the maximum and minimum values for your particular servo.

Don't go looking for complexity.

...R

Robin2:
I agree 100% with @UKheliBob.

The Min and Max in the servo library are intended to cover a huge range of servos and are there just as safeguards to ensure the library does not produce really silly outputs.

Just focus on finding, by trial and error, what are the maximum and minimum values for your particular servo.

Don't go looking for complexity.

...R

Well after some expierence I found out that the values where 500 and 2400 more or less. Now I am having another issue, if you don't mind, please take a look here as it is very weird, thanks: Help using VirtualWire and Servo - Programming Questions - Arduino Forum

bieltv3:
Now I am having another issue, if you don't mind, please take a look here as it is very weird, thanks: Help using VirtualWire and Servo - Programming Questions - Arduino Forum

And I have an issue as well. If you had kept everything in this Thread I would not have wasted my time recommending ServoTimer2 in the other Thread.

...R

@Bieltv3: I suppose it will be quite simple to modify the servotimer2 library to accept both values in degrees and in milliseconds.
My mind is to add a check for write values, if they are less or equal to 180 300 then the value is in degrees, otherwise in milliseconds. As suggested, the conversion is easy with map() command.

I tried to make this modification, but unfortunately the servotimer2 library I found in Internet always returns a compilation error.

If you, or someone else, may link a working servotimer2 library, I can try to implement this mod.

Thanks

Luke

eBookLuke:
@Bieltv3: I suppose it will be quite simple to modify the servotimer2 library to accept both values in degrees and in milliseconds.

Microseconds are the natural currency of servo control. Wouldn't it be simpler to include a function in the user's code that converts degrees to microseconds?

...R

Yes, sure. But a servo usually has a range between 1000 and 2000 microsecond, sometimes you need as low as 500 microseconds, so in the write function values between 0 and 500 are useless. Why don't use them to pass degrees instead of micoseconds?

Luke

Microseconds are the natural currency of servo control. Wouldn't it be simpler to include a function in the user's code that converts degrees to microseconds?

Using ints that would only give a resolution of 1 in 180 whereas using microseconds give as resolution of 1 in 1000 assuming a range between 1000 and 2000. You could, of course use a float to hold the degrees but that sounds like too much of an overhead.