Pages: [1] 2   Go Down
Author Topic: Servo winch always initializes by turning  (Read 2677 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 9
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

I'm using the servo library that comes with arduino. I have a setup with a servo winch that is capable of turning <360°. Attaching the servo (on pin 9) is no problem. But as soon as I send the first "write" command, my servo does what appears to me are ~2,5 rotations.
Since my setup would mangle all the parts installed, I cannot have this happening. What could be the reason for this strange behaviour?

This is my code-I'm sorry, I prefer you can see everything rather than wasting everyone's time with snippets that tell only half the truth ...

btw: I am using a modelcraft SW 1200 from the German Conrad- online-Store thingy. Unfortunately, there is no documentation available for this online that could be of any value ...

[glow]
#include <Servo.h>

Servo myservo;
int pos = 0;    // variable to store the servo position
const int maxServoPos = 45;

boolean gbFirstrun = true;
boolean gbObjectApproached = false;
const int ciIRPin = 4;

const int ciRedPin = 12;
const int ciGreenPin = 7;
const int ciButtonPin = 5;
int iButtonState = 0;

unsigned long ulStartTime = 0;

void setup()
{
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  pinMode(ciRedPin,OUTPUT);
  pinMode(ciGreenPin,OUTPUT);
  pinMode(ciButtonPin,INPUT);
  Serial.begin(9600);
  ulStartTime = millis();
  Serial.println("servo attached");
}


void loop()
{

  int iIRVal = 0;

  unsigned long ulCurrentTime = 0;
  const int ciTolerance = 50;
  const int ciLowThreshold = 70;



  // start by evaluating the values of the IR-Sensor
  // if something approaches, recoil the mat


  if (gbFirstrun)
  {
    ulCurrentTime = millis();
    if(ulCurrentTime>=(ulStartTime+12000))
    {
      // discard all values that are junk data produced by the arduino initializing
      gbFirstrun = false;
      blink(ciGreenPin,3);
      Serial.println("Arduino initialized, proceeding with evaluation of values");
    }
  }
  else
  {
    iIRVal = analogRead(ciIRPin);
    Serial.print("iIRVal ");
    Serial.println(iIRVal);


    if(iIRVal>= ciTolerance + ciLowThreshold)  //smooth low values, ignore artifacts
    {
      gbObjectApproached = true;   // set the flag for evaluation during each loop
      blink(ciRedPin,1);
      Serial.print("iIRVal within tolerance :");
      Serial.println(iIRVal);
    }

    iButtonState = digitalRead(ciButtonPin);
    if(iButtonState == HIGH)
    {
      Serial.print("SIG HUP received, setting servo to zero");
      for(pos; pos >=1; pos -= 1)  // goes from 0 degrees to 180 degrees
      {                                  // in steps of 1 degree
        myservo.write(pos);              // tell servo to go to position in variable 'pos'
        delay(15);               // waits for servo to reach position &/or delays pulses        
      }
    }
    else
    {
      if(gbObjectApproached)
      {  
        Serial.println("starting servo: fast");
        for(pos = 0; pos < maxServoPos; pos += 1)  // goes from 0 degrees to 180 degrees
        {

          // in steps of 1 degree
          myservo.write(pos);              // tell servo to go to position in variable 'pos'
          delay(15);               // waits for servo to reach position &/or delays pulses        
        }

        for(pos = maxServoPos; pos>=1; pos-=1)    
        {                      
          if(pos == maxServoPos)
          {
            Serial.println("starting servo: slow");
          }
          myservo.write(pos);
          delay(100+pos*10);                      
        }
      }
    }
  }
}



void blink(int iPin, int iRepeats)
{
  for(int i=0;i<=iRepeats;i++)
  {
    digitalWrite(iPin,HIGH);
    delay(250);
    digitalWrite(iPin,LOW);
    delay(250);
  }
}
[/glow]



Many thanks for your help.

bastian
Logged

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

Snippets are better.

If you remove everything in your sketch except the servo positioning code and try that you will have a better idea of what is happening. In fact, try a very simple sketch that just slowly pans the servo from 0 to 180 degrees and see what happens.

You can experiment with a range of angle values to find out what it takes to move your servo. When you know that, you can add back in all the other code and modify it to get the desired angle values. I hope that helps
« Last Edit: January 26, 2009, 11:30:48 am by mem » Logged

Bristol, UK
Offline Offline
Edison Member
*
Karma: 1
Posts: 1197
Exhibitor at UK Maker Faire
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Snippets are better.

I disagree!  I'd prefer to see the whole of the code, because it's usually the bits that the poster has left out that are the cause of the trouble.
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 59
he's not a real doctor
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am not familiare with the way servo winches are supposed to work, but are you sure it isnt just moving to the correct "pos" position.   Are you physically moving the servo to a particular position before starting your program.   If so normal behaviour would be to move to "pos" as soon as the servo code starts.  this should be an absolute position, not relative to where you started.

You could test this by starting your code, let the servo move to where it jumps to.  Next power everything down.  Finally start your code again.  See if the servo moves to a "new" position.
Logged

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

Quote
I disagree!  I'd prefer to see the whole of the code, because it's usually the bits that the poster has left out that are the cause of the trouble.

I was suggesting that the poster remove everything but the servo code to see if he could get the servo working. If he still had a problem then post the simplified code. Are you really disagreeing with that approach?

Its really hard to see the wood from the trees with all the irrelevant logic in the sketch.
« Last Edit: January 26, 2009, 11:41:21 pm by mem » Logged

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

Hi,

thanks for the input so far. I have substantially reduced the code:

[glow]#include <Servo.h>

Servo myservo;
const int ciRedPin = 12;

void setup()
{
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  pinMode(ciRedPin,OUTPUT);
  Serial.begin(9600);
  Serial.println("servo attached");
}


void loop()
{
  blink(ciRedPin,5);
  delay(10000);
  Serial.println("starting loop");
  myservo.write(9);
}


void blink(int iPin, int iRepeats)
{
  for(int i=0;i<=iRepeats;i++)
  {
    digitalWrite(iPin,HIGH);
    delay(250);
    digitalWrite(iPin,LOW);
    delay(250);
  }
}

[/glow]


The behaviour of the servo is as follows:

when I send arduino the upload code-command, the servo already starts turning, doing it's 2,5 revs-already very annoying for my setup, but I would figure that this is an issue with the servo itself(any hints on that are welcome ...->I'll try and get the power supply of the servo modified so that it is only connected to +5V once the arduino is set up)

when the servo gets it's write command, it will once again turn 2,5 (or so) revolutions. It will do so, even if the last command it received was a write to the same position...
I'll try writing to 0, see where that leads me.

Keep you posted.

Cheers,b.
Logged

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

The behaviour for write(0) is the same as with the write(9) I posted previously. Since there is no block/arrester for the winch servo, I would not really know where to zero the servo manually, either.

I'll give the power on/arduino-setup a shot. If I'm not mistaken, the servo shouldn't budge if my last write was to 0 ...
Logged

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

so now, I give the servo its 5V only after the servo.attach(9) command has been executed. When the power is up, the servo starts it's revolutions again.

I'll try what happens disconnecting the signal as opposed to the 5V, maybe that will get me somewhere...
Logged

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

Well. The behaviour of the servo looks the same to me if I leave 5V & GND connected and only connect the SIG-cable after the Servo.attach command has been exec'd.

I'm completely puzzled. The servo is new, I don't think it fell down or anything. Should be working fine.
I'll try a different servo if I get one.

regards,
b.
Logged

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

It sounds like the servo is faulty What exactly does the servo do when you run the code posted in #5?  It does seem like it moves even with no signal.
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 59
he's not a real doctor
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

My understanding is that winch servos are suposed to turn appx 1.75 revoloutions in each direction.  I would expect it to have a hard stop at that point.

Do you think you got a servo with a continuous rotation mod or perhaps a "gearmotor in a servo case" like solarbotics sells.  You might even open it up and look and see whether it has a pot on the output shaft. (with the obvious disclamer about taking it apart..)

Also check your voltagt to the servo.  I have gotten screwy behavior when my voltage dropped too low.  Some servos worked down to 4 volts, but others didnt.  
Logged

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

Hi,

there was one obvious error in my script: I did not call the Servo::refresh() command.
But now that I'm trying to remedy this, the compiler keeps telling me:

In function 'void loop()':
error: 'refresh' is not a member of 'Servo'

strangely, I tried all variations of calling the refresh command, with "myServo" being the name of the instance of the class 'Servo'.


myServo.refresh();
myServo::refresh();

anyone have any idea how to correctly call this function?!! The documentation only states the examples I have tried.

thx.
Logged

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

The voltage on the servo should be 5V directly from the arduino/breadboard. I measure ~5V directly on the connector to the Servo (which is in actual fact a winch-meaning, that it covers more than the 180° of "normal" servos. I wouldn't know of any hardware restrictions regarding the number of degrees it covers. As long as the servo seems to be working, I prefer not opening it-it was a little too expensive for experiments in that direction ...
smiley
Logged

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

just checked the specs on the servo-it needs 6V. So I'll check it's behaviour with 6V and update what's happening.

regards and thanks for your input so far ...
Logged

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

The servo library that is distributed with Arduino version 0012 does not have or need a refresh method.

Try this code, it should move the servo in steps every ten seconds.

Code:
#include <Servo.h>

Servo myservo;
int position = 0;

void setup()
{
 myservo.attach(9);  // attaches the servo on pin 9 to the servo object
 Serial.begin(9600);
 Serial.println("servo attached");
 myservo.write(position);
 delay(10000);
}


void loop()
{
 position += 10;  
 if(position > 180)
      position = 0;
 Serial.print("changing position to ");
 Serial.println (position);
 myservo.write(position);
 delay(10000);
}
Logged

Pages: [1] 2   Go Up
Jump to: