Go Down

Topic: Basic Servo Interfacing (Read 4207 times) previous topic - next topic

dsyed1

Folks I am a newbie to the arduino like mcu world... just getting started with all this...

i am having a lot of  trouble just getting one servo to work with arduino...  would really appreciate it if anyone can shed some light as to what i am doing wrong here... the servo seems to twitch once in a while ... when the code runs.. but nothing else.. i am using the servo library

my setup is the basic arduino USB board from sparkfun.com
JR Servo DS285

Connected to Pin 9 on arduino
Power source is from the +5 onboard arduino
the arduino is connected to my laptop via USB

#include <Servo.h>

Servo servo1;

void setup()
{
 
 pinMode(9,OUTPUT);
 Serial.begin(19200);
 servo1.attach(9);
 servo1.setMaximumPulse(2000);
 servo1.setMinimumPulse(700);
 Serial.print("Servo1 Ready\n");

}

void loop()
{
 
   Serial.print("Servo 1 position 70\n");
   servo1.write(70);
   delay(1500);
   
   Serial.print("Servo 1 position 100\n");
   servo1.write(100);
   delay(1500);
   
   Servo::refresh();
   
   Serial.print("\n");
   delay(3000);  
}

weirdo557

#1
Jul 26, 2008, 03:29 am Last Edit: Jul 26, 2008, 03:30 am by weirdo557 Reason: 1
try this

#include <Servo.h>

Servo servo1;

void setup()
{
 
 pinMode(9,OUTPUT);  
 Serial.begin(19200);
 servo1.attach(9);
 servo1.setMaximumPulse(2000);
 servo1.setMinimumPulse(700);
 Serial.print("Servo1 Ready\n");

}

void loop()
{
   
   Serial.print("Servo 1 position 70\n");
   servo1.write(70);
   Servo::refresh();
   delay(1500);
   
   Serial.print("Servo 1 position 100\n");
   servo1.write(100);
   Servo::refresh();
   delay(1500);
   
   Servo::refresh();  
   
   Serial.print("\n");
   delay(3000);  
}

dsyed1

thank you so much, that definitly did get it to start moving... i am trying to make it go from 0 degrees to 180 degrees.. or left to right so i can mount a sensor on it...

i tried updating the code as follows but seems to slow the movement down a lot... do you think it is some sort of a timing issue?

#include <Servo.h>
 
Servo servo1;
 
void setup()
{
 
 pinMode(9,OUTPUT);  
 Serial.begin(19200);
 servo1.attach(9);
 servo1.setMaximumPulse(2000);
 servo1.setMinimumPulse(700);
 Serial.print("Servo1 Ready\n");
 
}
 
void loop()
{
   
   Serial.print("Servo 1 position 0\n");
   servo1.write(0);
   Servo::refresh();
   delay(1500);
   
   Serial.print("Servo 1 position 180\n");
   servo1.write(180);
   Servo::refresh();
   delay(1500);
   
   Servo::refresh();  
   
   Serial.print("\n");
   delay(3000);  
}

weirdo557

perhaps your servo is just slow, can you post the model?

dsyed1

yes it is JR Servo DS 285... i have seen them used on align trex 450 rc helicopters

weirdo557

hmm, should take about half a second to swing 180 degrees. try commenting out the max and min pulse values just to see what it does. worked with my generic parralax servos.

mem

#6
Jul 26, 2008, 08:59 am Last Edit: Jul 26, 2008, 09:01 am by mem Reason: 1
The software servo library requires refresh() to be called at least once every 50ms (although most servos perform better with a 20ms refresh rate). In the sketch posted above each servo is only refreshed every six seconds. Here is on example of how you can code what you want:

void myRefresh(int delay){
  for(int i=0; i < delay/20; i++){ //delay is the total ms delay we want, 20 is the delay per iteration of the loop  
      Servo.refresh();  
      delay(20);
  }
}

void loop() {

  Serial.print("Servo 1 position 0\n");  
  servo1.write(0);
  myRefresh(1500);


  Serial.print("Servo 1 position 180\n");  
  servo1.write(180);
  myRefresh(1500);

 Serial.print("3 second delay\n");
 myRefresh(3000);   // refresh should be called even if the servo is not moving.
}

dsyed1

everyone thank you for your help... the following simple code seems to work just fine on an analog type servo... i am using an EFLRS60 from eflite... the other JR DS285 i beleive is a digital servo and only works if i use digitalwrite... not sure why that's the case though... any ways just thought i would share my findings..


#include <Servo.h>

Servo servo1;

void setup()
{
 
 Serial.begin(19200);
 servo1.attach(9);
 Serial.print("Servo1 Ready\n");

}

void loop()
{
 
   Serial.print("Servo 1 position 0\n");
   servo1.write(0);
   Servo::refresh();
   delay(1000);
   
   Serial.print("Servo 1 position 90\n");
   servo1.write(90);
   Servo::refresh();
   delay(1000);
   
   Serial.print("Servo 1 position 180\n");
   servo1.write(178);
   Servo::refresh();
   delay(1000);    
       
}


kBit

#8
Jul 27, 2008, 05:15 am Last Edit: Jul 27, 2008, 05:38 am by kBit Reason: 1
A working design is not always a good design.

Read and implement per Mem's suggestion. Using delay() in a servo program is playing with fire. You must keep refresh() called frequently. A servo normally has to compare its position with the commanded position. If you go away for a second, it has nothing to compare to and stops moving!

Analog servo? Digital servo? Smoke & mirrors!

mem

#9
Jul 27, 2008, 07:42 am Last Edit: Jul 27, 2008, 07:46 am by mem Reason: 1
Quote
... the following simple code seems to work just fine on an analog type servo...  any ways just thought i would share my findings..



dsyed1, I appreciate you trying to be helpful but your findings are a bad example of how to use the Software Servo library. As stated in the post above yours, the servo library you are using is designed to expect refresh to be called at least every 50ms and ideally at least every 20ms. Your code calls it once every second. So although you may observe the servos to move, they will not  perform within their specifications.  That may not matter in your application but for anyone coming to this thread for advice on basic servo interfacing, if you use the Software Servo library then your code should call refresh at least every 50ms. If you want your servo to operate at its rated speed and torque then call refresh  every 20ms or so.

If its inconvenient to call refresh at the recommended intervals then you may want to look at using one of the servo libraries that use a timer interrupt to do the refresh

dsyed1

Mem and Kbit you two are absolutely right, I am completely new to this world so just trying to find my way through things.. thanks again for your help!

Shepparton

just a thought..I'm new to this to. I have been using the ServoTimer1 lib with no problems. It carries out all timing in hardware so you don't have to worry about refresh. Only downside is you can only use two servos on pins 9 &10.

kBit

Quote
just a thought..I'm new to this to. I have been using the ServoTimer1 lib with no problems. It carries out all timing in hardware so you don't have to worry about refresh. Only downside is you can only use two servos on pins 9 &10.


Yeah, you pays your money and you takes your choice.
Servo1: 2 servos, less worries
Servo: many servos, more worries

mem

Quote
Quote
just a thought..I'm new to this to. I have been using the ServoTimer1 lib with no problems. It carries out all timing in hardware so you don't have to worry about refresh. Only downside is you can only use two servos on pins 9 &10.


Yeah, you pays your money and you takes your choice.
Servo1: 2 servos, less worries
Servo: many servos, more worries

Another option is to use the code posted here: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1204020386/74#74  for driving up to eight servos in background using timer2.

Go Up