issues with winch Servo, continuously rotating

Hello,

i have wired up a Hitec HS-785HB Winch Servo Motor to an arduino.

I am attempting to get it so the servo is triggered by a motion sensor. The arduino will activate the servo to move to a number of positions and then return to its position, delay and then get triggered again when motion is sensed.

I have wired this up and have it running on several normal servos, but when i turn on the circuit the servo continuously rotates rather than heading to its starting position of 1500.

Here is the schematic (the only difference between the schematic and the actual circuit is that i have the PIR wired up to pin 8, not pin 12 as stated):

and here is the code:

#include <Servo.h>


#define S_IDLE 1
#define S_MAXA 2
#define S_MID 3
#define S_MAXB 4
#define S_WAITING 5
#define S_FINISH 6

Servo myservo;
int PIR_SensorPin = 8;
unsigned long duration;
unsigned long lastMillis;
int calibrationTime = 30;
int state = S_IDLE;

void setup()
{
  Serial.begin(9600);
  pinMode (PIR_SensorPin, INPUT);   // Set pinMode
  digitalWrite(PIR_SensorPin, LOW);
  myservo.attach(9, 700, 2300);  // servo.attach(pin, min, max)
  myservo.writeMicroseconds(1500);  // set servo to mid-point

  Serial.print("calibrating sensor ");
  for (int i = 0; i < calibrationTime; i++) {
    Serial.print(".");
    delay(1000);
  }
}

void loop() {

  if (millis() - lastMillis > duration) { // Step in sequence finished - time to take action!
    lastMillis = millis();
    switch (state) {
      case S_MAXA:
        myservo.writeMicroseconds(2100); // turn servo to new position
        duration = 200; // Duration of this position
        state = S_MID; // Next step of the sequence - runs when duration has passed.
        break;

      case S_MID:
        myservo.writeMicroseconds(800); // turn servo to new position
        duration = 200; // Duration of this position
        state = S_MAXB;  // Move to the next state
        break;

      case S_MAXB:
        myservo.writeMicroseconds(2100); // turn servo to new position
        duration = 200; // Duration of this position;
        state = S_WAITING; // Move to the next state
        break;

      case S_WAITING:
        myservo.writeMicroseconds(1500); // return servo to netural position
        duration = 5000; // Wait for moving on.
        state = S_FINISH;  // Move to the next state
        break;

      case S_FINISH:
        state = S_IDLE; // Done - time to look at the PIR sensor again.
        break;
    }

    // General state: only look at the sensor when IDLE.
    if (state == S_IDLE) {
      if (digitalRead(PIR_SensorPin) == HIGH) {
        state = S_MAXA;
        duration = 0;
        lastMillis = millis();
      }
    }
  }
}

Can anyone see why it might be continuously rotating when the circuit is powered up?

Thaks in advance

3201_0_HS-785HB.pdf (572 KB)

You have a huge loop antenna there.

The ground wire from the Arduino needs to run alongside the pin 9 signal to the servo directly, so its
not a big loop antenna for noise. You can run the Vin wire alongside them too, but what you mustn't do
is have a signal wire going off on its own like the drawing.

How do you suggest i can do this? I have attached a photo of the actual circuit so yu can get an idea of what i have made.

Try doing the writeMicroseconds(1500) immediately BEFORE the attach(). That does at least make sure the servo has a fixed position on start up

Have you tested that servo with something like the Knob example program to see what range of pulse lengths it is actually willing to respond to correctly?

Or of course it could always be broken.

Steve

I can't help thinking that there should be a ground connection. between the servo and the arduino.

It might be that the power supply passes the same ground through. But I would still try.

Hi,

I have wired this up and have it running on several normal servos, but when i turn on the circuit the servo continuously rotates rather than heading to its starting position of 1500.

What do you expect the continuous servo to do when you send 1500, return to centre position?
You cannot control the position of a continuous servo like a 0 to 180 servo.

A continuous servo response with speed and direction, not position to servo commands.
Unless it is a winch servo for RC yachts.

Typically 90deg is stop, 0 is full speed in one direction, 180 is full speed in the other.

Tom... :slight_smile:

But the OP did say it was an HS785HB which isn't a continuous servo. It is a winch servo and should be fully controllable over about 8 turns. It shouldn't be possible for it to turn continuously...unless it's broken or a fake (it is a bit suspicious that it doesn't have it's normal winch drum fitted).

Steve

I have just tried the knob test, heres the code:

/*
 Controlling a servo position using a potentiometer (variable resistor)
 by Michal Rinott <http://people.interaction-ivrea.it/m.rinott>

 modified on 8 Nov 2013
 by Scott Fitzgerald
 http://www.arduino.cc/en/Tutorial/Knob
*/

#include <Servo.h>

Servo myservo;  // create servo object to control a servo

int potpin = 0;  // analog pin used to connect the potentiometer
int val;    // variable to read the value from the analog pin

void setup() {
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
}

void loop() {
  val = analogRead(potpin);            // reads the value of the potentiometer (value between 0 and 1023)
  val = map(val, 0, 1023, 0, 180);     // scale it to use it with the servo (value between 0 and 180)
  myservo.write(val);                  // sets the servo position according to the scaled value
  delay(15);                           // waits for the servo to get there
}

when i power up the servo spins, and it does not change direction or come to a stop when i turn the pot, turning the pot has no effect on the servo.

As a note, i have two identical servos and it happens to them both, also, i didn't put the standard winch drum on it.

You say turning the pot has no effect? The servo rotates continuously in on direction and at the same speed? Do they rotate even if the signal wire is disconnected? It certainly sounds like the servos are bad.

Can you test them with anything else like maybe an RC receiver or basic servo tester? Or just get them replaced.

Steve

I have just tested the circuit with the servo signal wire disconnected and it doesn't rotate at all on start up.

I have set up the original circuit that i made and altered the code:

#include <Servo.h>


#define S_IDLE 1
#define S_MAXA 2
#define S_MID 3
#define S_MAXB 4
#define S_WAITING 5
#define S_FINISH 6

Servo myservo;
int PIR_SensorPin = 8;
unsigned long duration;
unsigned long lastMillis;
int calibrationTime = 30;
int state = S_IDLE;

void setup()
{
  Serial.begin(9600);
  pinMode (PIR_SensorPin, INPUT);   // Set pinMode
  digitalWrite(PIR_SensorPin, LOW);
  myservo.writeMicroseconds(1000);  // set servo to mid-point
  myservo.attach(9, 1000, 1000);  // servo.attach(pin, min, max)
  

  Serial.print("calibrating sensor ");
  for (int i = 0; i < calibrationTime; i++) {
    Serial.print(".");
    delay(1000);
  }
}

void loop() {

  if (millis() - lastMillis > duration) { // Step in sequence finished - time to take action!
    lastMillis = millis();
    switch (state) {
      case S_MAXA:
        myservo.writeMicroseconds(1000); // turn servo to new position
        duration = 200; // Duration of this position
        state = S_MID; // Next step of the sequence - runs when duration has passed.
        break;

      case S_MID:
        myservo.writeMicroseconds(1000); // turn servo to new position
        duration = 200; // Duration of this position
        state = S_MAXB;  // Move to the next state
        break;

      case S_MAXB:
        myservo.writeMicroseconds(1000); // turn servo to new position
        duration = 200; // Duration of this position;
        state = S_WAITING; // Move to the next state
        break;

      case S_WAITING:
        myservo.writeMicroseconds(1000); // return servo to netural position
        duration = 5000; // Wait for moving on.
        state = S_FINISH;  // Move to the next state
        break;

      case S_FINISH:
        state = S_IDLE; // Done - time to look at the PIR sensor again.
        break;
    }

    // General state: only look at the sensor when IDLE.
    if (state == S_IDLE) {
      if (digitalRead(PIR_SensorPin) == HIGH) {
        state = S_MAXA;
        duration = 0;
        lastMillis = millis();
      }
    }
  }
}

When the code is as seen above, on power up the servo turns about 90 degrees clockwise then continuously rotates anti clockwise. Do you think the centre point is not 1500?

Hi,
As noted in post#4, there is no connection between the servo gnd and the UNO gnd.

It looks like it should be okay because of the power supply loop, BUT can you also connect the servo gnd to the UNO gnd, please?

What is the DC-DC converter?
What is the 9V power supply?
Have you measured the 5V and 9V supplies while the servo is malfuctioning?

Thanks.. Tom.. :slight_smile:

Hi,

i connected the gnd between the servo and Arduino, but it makes no difference.

The step down convertor im using is this.

The power supply to the convertor is this.

Hi,
Is that the power supply 24Vdc?


Tom... :o

yes thats the one.

Hi,
But it is 24Vdc output?
You said you had a 9Vdc supply, your circuit shows 9Vdc power input.

Are you supplying 24Vdc to the DC-DC converter AND the UNO?
If so STOP.....

Tom.... :slight_smile:

Looks as though i have mixed some of my power supplies up. I am normally using a 36W 9V 4A Switch Mode AC/DC Power Supply Do you think this might be the cause of the problems?

Hi,
Can you try this code with this circuit please, open the monitor in the Arduino IDE and set it to 9600 baud.
As you turn the pot you should see the "Pot Values" change and the "Servo Values" change, tell us what the servo does as you slowly turn the pot from end to end.
Then leave the pot in about mid position and see what the servo does.

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
int potpin = A0;  // analog pin used to connect the potentiometer
int val;    // variable to read the value from the analog pin
int sval;

void setup()
{
  Serial.begin(9600);
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
}

void loop()
{
  val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
  Serial.print("Pot Value :");
  Serial.print(val);

  sval = map(val, 0, 1023, 0, 180);     // scale it to use it with the servo (value between 0 and 180)
  myservo.write(sval);                  // sets the servo position according to the scaled value
  Serial.print("  Servo Value :");
  Serial.println(sval);

  delay(15);                           // waits for the servo to get there
}

Thanks..Tom.. :slight_smile:

I made the circuit;

As i turned the pot, the Pot and Servo Values both changed in relation to each other in the Serial Monitor. The servo started rotating as soon as i powered up. Turning the pot from 0 to 180 (Servo Value reading) made the servo turn faster, in the direction it was already turning at. It never stopped rotating or came to a stop.