Pages: 1 [2] 3 4   Go Down
Author Topic: VarSpeedServo - a modified Servo library with speed control  (Read 29113 times)
0 Members and 2 Guests are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Gday all


just a quick question, just recently started with arduino and i am having trouble woth the VarSpeedServo library and slowmove.

Is there anywhere where it has been incorporated with a sweeep sketch to provide sweep at various speeds?

Thanks for the time, I could not find anything anywhere else

Cheers

Rick
Logged

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

There might be one, you'd have to check. Here's the test-code I use for this library. It should be fairly simple to extend.

Code:
/*
ServoFollowPot
 
This little program controls a servo with a potentiometer.
The button moave the servo from one end to the other, the potentiometer
sets the speed. 0 = full speed, 1 slowest, 255 fastest.
When pressing the button, the led is turned on to exercise it a little.
Every few seconds the current postion of the servos is reported on the
serial line and whenever the button is pressed.
 
 The circuit:
* LED attached from pin 13 to ground: Button led
* Pushbutton attached to pin 2 from GND
* Linear Potentiometer attached to analog pin 2 from GND and +5V acting
  as a voltage splitter. Any value from 10 kOhm to 100 kOhm will work.
* Servo control line attached to pin 12.
 
 * Note: on most Arduinos there is already an LED on the board
 attached to pin 13.
 
*/

#include <VarSpeedServo.h>

const int buttonPin = 2; // the number of the pushbutton pin
const int ledPin =  13; // the number of the LED pin
const int potPin =  16; // the number of the potentiometer pin (Analog 0)
const int mainPin = 12; // Main servo control line
const int ServoMin = 1000; // Minimum pulse width for servos in ms.
const int ServoMax = 2000; // Maximum pulse width for servos in ms.
const int PotiMin = 0; // Minimum value read from potentiometer
const int PotiMax = 1023; // Maximum value read from potentiometer
const int ButtonDelay = 100; // Time in ms to press button to activate tuning mode


VarSpeedServo myServo; // Servo

void setup() {
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);     

// initialize the pot and button pin as an input:
pinMode(potPin, INPUT);
pinMode(buttonPin, INPUT);

// Activate internal pull up resistor for tuning button
digitalWrite(buttonPin, HIGH);

// Initialise Servos
myServo.attach (mainPin, ServoMin, ServoMax);

// Initialise Serial communication
Serial.begin (9600);
}

void loop() {
static unsigned long debounce = 0;         // variable for reading the pushbutton status
static int buttonstate = HIGH;         // variable for reading the pushbutton status
static unsigned long lasttick;

// Report position;
if (millis () - lasttick > 5000) {
lasttick = millis ();
Serial.print ("Position=");
Serial.println (myServo.readMicroseconds());
}

// Read button and debounce.
int buttonnow = digitalRead(buttonPin);
if (millis() - debounce >= ButtonDelay
&& buttonnow != buttonstate) {
buttonstate = buttonnow;
debounce = millis();
switch (buttonstate) {
case LOW:
// Button has just been pressed
digitalWrite(ledPin, HIGH);

// Set the servos
{
int potlast = analogRead (potPin); // Read potentiometer
int speed = map (potlast, PotiMin, PotiMax, 1, 256) & 0xff;
myServo.slowmove ((myServo.readMicroseconds() > ServoMin + 400
? ServoMin + 100 : ServoMax - 100), speed);
// Report pot position
Serial.print ("Speed=");
Serial.println (speed);
}

break;
case HIGH:
// Button has just been released
digitalWrite(ledPin, LOW);
break;
}
}

// Slow down
// delay (50);
}

Korman
Logged

Topsham, Vermont USA
Offline Offline
Edison Member
*
Karma: 33
Posts: 1906
... in The Woods In Vermont
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, Great work on this!

Question: would this work as acceleration control on continuous-rotation servos?? Newpos sets top speed, speed sets acceleration?

Logged

Regards, Terry King terry@yourduino.com  - Check great prices, devices and Arduino-related boards at http://YourDuino.com
HOW-TO: http://ArduinoInfo.Info

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

Question: would this work as acceleration control on continuous-rotation servos?? Newpos sets top speed, speed sets acceleration?

Terry, it well could be, but to be honest I don't know. The library just increases continuously the position of the target until the set target value is reached. The consequence is that the PWM pulse increases or decreases in length over time. If the speed on continuous rotation servos is the same as the position for  a regular servo, the speed parameter would be the acceleration.

Perhaps someone with access to such a servo could try that out?

Korman
Logged

Topsham, Vermont USA
Offline Offline
Edison Member
*
Karma: 33
Posts: 1906
... in The Woods In Vermont
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Korman,

I have a small 2-wheel robot that I will try it on.  Maybe be a day+ as I'm busy with The Work Thing..

If it's dynamically changing the POS value, that should work. Within a reasonable range, Continuous-Rotation servos speed is proportional to the POS offset from 90 in both directions...

Logged

Regards, Terry King terry@yourduino.com  - Check great prices, devices and Arduino-related boards at http://YourDuino.com
HOW-TO: http://ArduinoInfo.Info

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

Thanks Terry, that'll be interesting to know. If I understand it right, if you use slowmove with different speed parameters but the same position for each wheel, the robot should accelerate in a spiral.

Korman
Logged

Topsham, Vermont USA
Offline Offline
Edison Member
*
Karma: 33
Posts: 1906
... in The Woods In Vermont
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
the robot should accelerate in a spiral.

Cool! Gotta try that....
Logged

Regards, Terry King terry@yourduino.com  - Check great prices, devices and Arduino-related boards at http://YourDuino.com
HOW-TO: http://ArduinoInfo.Info

Brisbane AUST
Offline Offline
Newbie
*
Karma: 0
Posts: 41
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Korman, great work!
Im going to give it a go over thru my ECU code.
one advantage I love is the easy way I can slowly raise the speed the motor for my gas turbine starter.
One question I have as you seem the guru in all things servoish....

what happens in situations when there is alot of other code processing going on, and the servo gets "noisy".
I used a simple for command to slowly raise the servo output.
to test it, I plug in a standard hobby servo, but my intended use is for a brushless motor controller.
I have a project that has an interupt watching a input, measuring RPM.
also a large LCD display and several other things going on, temperature measurment, button menu inputs, etc etc goes on and on (using a Mega 2560 and a 240x320 LCD).
Im using the Servo output to feed a Brushless motor controller input drive to slowly increase the speed of the motor to start a gas turbine.
but the servo output im getting is jittery, noisy. Is this because the processor isnt fast enough to keep up with the PWM pulses the motor requires?
On the oscilliscope, i see alot of "topping off" between the pulses. is there any practices I can apply to my code that will help avoid this?
I stripped away bits of my code untill the LCD touchscreen code was removed before the servo drive got clean, but it was still not perfect.
I did try to break up my code into sections so it always goes back to the servo drive command without too much delay.

What I am guessing, is maybe this is an application where an arduino such as a standalone arduino needs to be setup as a dedicated controller?

keen to hear your thoughts.
cheers.
Logged

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

One question I have as you seem the guru in all things servoish....

Sorry to disappoint you here, we have no guru here. The last thing that made guru-guru ended after a short sting in the oven on the table at thanksgiving.

what happens in situations when there is alot of other code processing going on, and the servo gets "noisy".
I used a simple for command to slowly raise the servo output.

Hi John,

as long as you have just one single interrupt going on the the servo is pretty stable, no matter what you do in your main loop.  To test that out, create a program that leaves the servo in a fixed position and does other processing meanwhile. The servo should only have occasional minimal movements. Check that out with various servo positions, not only the extremes.

In my experience, the servos start to get jittery once you have multiple interrupt functions or you have functions that disable interrupts periodically. Then the pulse length isn't constant in the situations where another interrupt (or cli / sei instructions) are delaying the servo interrupt and thus lengthening the PWM impulse. This can be a hairy problem.

If the rpm-counter is bothering your servo, you might want to look into using your rpm-signal as an external clock reference so that you can use timer2 as a counter. (This is all from memory, I don't have the Atmel datasheet on me at the moment). For very high frequencies, consider adding an external counter chip you then can read at your leisure. As usual, the problem lies in the details.

 When I'm back at home, I will have a closer look at the matter.

Korman
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 4
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello, I was trying to make the servo go back and fourth 180 degrees with speed at 1 but it doesn't work, it just goes to one direction and is stuck there, what is wrong in the code?

Code:
#include <VarSpeedServo.h>

// Sweep
// by BARRAGAN <http://barraganstudio.com>
// This example code is in the public domain.



 
int pos = 0;    // variable to store the servo position
VarSpeedServo myServo;
void setup()
{
myServo.attach (9);
}
 
 
void loop()
{
  for(pos = 0; pos < 180; pos += 180)  // goes from 0 degrees to 180 degrees
  {                                  // in steps of 1 degree
  myServo.slowmove (pos,1);             // tell servo to go to position in variable 'pos'
   
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for(pos = 180; pos>=1; pos-=180)     // goes from 180 degrees to 0 degrees
  {                               
    myServo.slowmove (pos,1);
 
    delay(15);                       // waits 15ms for the servo to reach the position
  }
}
Logged

New Jersey
Online Online
Faraday Member
**
Karma: 67
Posts: 3693
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Looks like you're not giving the servo enough time to reach 180 at the slow pace before you order it back. Put a substantial delay between the two for loops. Why you're using those loops at all given the 180 degree increments is a bit of a mystery too.
Logged

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

I just installed the library and referenced it. Upon build I get the following compile error. I use the latest Arduino 1.0 compiler running on Windows 2008 server with Arduino MEGA2560. Any thoughts?

Code:
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp:56:23: error: WProgram.h: No such file or directory
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp: In function 'void handle_interrupts(timer16_Sequence_t, volatile uint16_t*, volatile uint16_t*)':
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp:91: error: 'LOW' was not declared in this scope
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp:91: error: 'digitalWrite' was not declared in this scope
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp:122: error: 'HIGH' was not declared in this scope
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp:122: error: 'digitalWrite' was not declared in this scope
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp:126: error: 'clockCyclesPerMicrosecond' was not declared in this scope
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp: At global scope:
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp:266: error: 'boolean' does not name a type
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp: In constructor 'VarSpeedServo::VarSpeedServo()':
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp:283: error: 'clockCyclesPerMicrosecond' was not declared in this scope
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp: In member function 'uint8_t VarSpeedServo::attach(int, int, int)':
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp:297: error: 'OUTPUT' was not declared in this scope
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp:297: error: 'pinMode' was not declared in this scope
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp:304: error: 'isTimerActive' was not declared in this scope
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp: In member function 'void VarSpeedServo::detach()':
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp:315: error: 'isTimerActive' was not declared in this scope
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp: In member function 'void VarSpeedServo::write(int)':
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp:326: error: 'map' was not declared in this scope
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp: In member function 'void VarSpeedServo::writeMicroseconds(int)':
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp:334: error: 'byte' was not declared in this scope
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp:334: error: expected `;' before 'channel'
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp:335: error: 'channel' was not declared in this scope
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp:343: error: 'clockCyclesPerMicrosecond' was not declared in this scope
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp: In member function 'void VarSpeedServo::slowmove(int, uint8_t)':
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp:377: error: 'map' was not declared in this scope
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp:380: error: 'byte' was not declared in this scope
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp:380: error: expected `;' before 'channel'
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp:381: error: 'channel' was not declared in this scope
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp:388: error: 'clockCyclesPerMicrosecond' was not declared in this scope
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp: In member function 'int VarSpeedServo::read()':
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp:407: error: 'map' was not declared in this scope
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp: In member function 'int VarSpeedServo::readMicroseconds()':
C:\Program Files (x86)\arduino-1.0\libraries\VarSpeedServo\VarSpeedServo.cpp:414: error: 'clockCyclesPerMicrosecond' was not declared in this scope
Logged

Gosport, UK
Offline Offline
Faraday Member
**
Karma: 21
Posts: 3113
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes. That library has not been updated for IDE 1.0. Read the IDE release notes for the solution.

http://arduino.cc/en/Main/ReleaseNotes
Logged

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

Thanks for the pointer. I'll produce an updated version in a few days.

Korman
Logged

Belgium
Offline Offline
Sr. Member
****
Karma: 1
Posts: 281
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I've used the varspeedservo library in Arduino 1.0. I just changed WProgram.h to Arduino.h in one of the library files.
Logged


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