arduino-libraries / Servo

Servo Library for Arduino
http://arduino.cc/
GNU Lesser General Public License v2.1
252 stars 262 forks source link

Servo write() vs writeMicroseconds() #73

Open per1234 opened 3 years ago

per1234 commented 3 years ago

Moved from https://github.com/arduino/Arduino/issues/10160 by @kreinkens

Both write() and writeMicroseconds() commands should be able to control both position and continuous rotation servos, given appropriate inputs.

I discovered that they are unable to act equally in controlling the continuous rotation servos. I was working in MATLAB which apparently used only the write() command as the basis for servo control. Returning to Arduino environment, I configured the servo, attach(12,1400,1600). I measured the delivered signals. Although the midpoint pulse width of 1500 was valid, the min/max values were closer to 375 and 2620 respectively. The result is that it is not possible to vary the speed of the continuous rotation servo using the write() command.

Not a problem in Arduino, since writeMicroseconds() is available to create variable speed control. However, MATLAB has not included a similar command in the support for Arduino Hardware. I have made this request, but thought that addressing this in the Arduino write() command might be another strategy to solve this.

per1234 commented 3 years ago

From PaulinaQuintero on 2020-06-07:

Hello! Can I work on this feature? Or is already taken by someone else?

per1234 commented 3 years ago

From kreinkens on 2020-06-08:

Hello Paulina, I would love the help. This is not my expertise, I'm just identifying the need. I'll help if I can, but that seems unlikely. I'm hoping to have a MATLAB solution for next January so I can have my students use it in their introductory activities for robot speed control. The Arduino solution might make the MATLAB solution easier. Please let me know if I can support you in any way.

per1234 commented 3 years ago

From PaulinaQuintero on 2020-06-08:

Hello kreinkens! I've been researching, an this is what I can say: The function writeMicrosecods() writes a value in microseconds (uS) to the servo, controlling the the angle of the shaft. Continuous-rotation servos will respond to the writeMicrosecond function in arduino software but not in matlab that only keep the function write(). So a solution will be to put two variables in a while sentence to define in the Servo object like this s = servo(a, 'pin', 'MinPulseDuration', range_value_min_servo_angle, 'MaxPulseDuration', range_value_max_servo_angle), where a = arduino('COM#', 'Type_arduino', 'Libraries', 'Servo'); and MaxPulseDuration, MinPulseDuration will be set in microseconds acording to your datasheet of your servo and do a fake continues servo with matlab and you may skip this issue

per1234 commented 3 years ago

From kreinkens on 2020-06-08:

Hello Paulina, I believe I may not have described the situation clearly. I have tried to 'trick' MATLAB into running the continuous rotation servos using the appropriate pulse width values, which I expected to work. In my efforts with MATLAB support, they admitted that the it would not be possible and have created an enhancement request for that purpose (the timeline for that solution is not clear).

The Arduino write() and writeMicroseconds() commands do not send the same signals to the servos as expected. There seems to be a clear limitation to the write() command regarding the min/max pulse width levels.

To add some details... In Arduino, I completed the following:

  1. I configured both types of servos using their defined pulse width characteristics, 1 position servo, 1 continuous rotation servo.
  2. I used both the write() and writeMicroseconds() commands to drive them as follows to confirm the minimum and center pulse widths at the servos: a. Using write(90) for center/stop and write(0) for full right/speed.
    • Position servo received the expected midpoint 1450ms and min 500ms pulses respectively as defined in the attach(8, 500, 2400) command.
    • Continuous rotation servos received signals that did not match those provided in the attach(12, 1400, 1600) command. Although the midpoint value of 1450ms is correct the min and max were again 375ms and 2620ms respectively. b. Using writeMicroseconds() both types of servos received the expected values scaled between the min and max values for each.
    • Position servo driven using writeMicroseconds(1450) for center and writeMicroseconds(500) for full right.
    • Continuous rotation servos driven using writeMicroseconds(1500) for stop and writeMicroseconds(1400/1600) for full speed.
per1234 commented 3 years ago

From per1234 on 2021-03-28:

I'm hoping to have a MATLAB solution for next January

Hi @kreinkens. Has this been resolved?

per1234 commented 3 years ago

From kreinkens on 2021-03-28:

Hello there per1234, Thank you for your interest in this. I do not believe that MATLAB has addressed this. And I'm not sure if the Arduino community has addressed this. I am not programming in Arduino regularly at this point. I switched to regular motors for motion in my course, but they are less precise for students, but cheaper :).

I'm still hoping to use continuous rotation servos in MATLAB in the future. Addressing the difference between write() and writeMicroseconds() might help in transferring solution to MATLAB.

Again, I'm not an experienced programmer, just enough to help our freshmen get started.

Thank you, Kirk