servo problem

Hello everyone, i want to controll a servo with my phone via bluetooth i’m using an HC-05 arduino uno a 5v regulator (i’m powering it with 6 AA batterys that supply 9v ) and an npn transistor and everything works but the problem is that the servo is making noise and i want to turn it off when i don’t wanna use it so i added a transistor to stop the power going to the servo and a servo detach command in the code

i think the problem is not from the wiring because when i remove this two lines it works :

digitalWrite(7,LOW);
myservo.detach();

so here’s the code and i hope you guys can help me

#include <Servo.h>

Servo myservo;

int pos = 0;

int state; 


void setup()

{

pinMode(13, OUTPUT);
pinMode(7,OUTPUT);


myservo.attach(9);

Serial.begin(9600);

myservo.write(60);

delay(1000); }

void loop()

{



if(Serial.available() > 0)

{

state = Serial.read();


} 



if (state == '1')

{
digitalWrite(7,HIGH);

myservo.write(55);

Serial.println("Mahloul");
digitalWrite(13, HIGH);

delay(5000);

myservo.write(8);
digitalWrite(13, LOW);

Serial.println("Msaker");

state=0;
digitalWrite(7,LOW);
myservo.detach(); 

}

}

What type of servo are you using and what voltage is it being supplied with ?

i'm using tower pro sg90 servo and it beeing supplied by 6v from the 5v regulator i don't know why 6 not 5

I'm assuming you have your transistor powering the servo on pin 7.

it looks like you are not waiting for the servo to get to position before you disconnect its power...

transistor powering the servo on pin 7 do you suggest adding a delay after digitalWrite(13, LOW);
because i did that but stll the same problem

omarbentaeb:
transistor powering the servo on pin 7 do you suggest adding a delay after digitalWrite(13, LOW);
because i did that but stll the same problem

Perhaps a simpler way to do this is to use the class I wrote as follows. It uses the detach() method, which you may find works as well as removing the power from the servo, but I included that in the example:

example.ino

#include "Sweep.h"

void startMoving(int value);
void stoppedMoving(int value);

const byte powerPin = 7;

Sweep servo1(startMoving, stoppedMoving);  //callback functions to execute when the servo starts or stops moving.

void setup() 
{
  Serial.begin(9600);
  pinMode(powerPin, HIGH);
  servo1.begin(4);
  pinMode(13, OUTPUT);
  Serial.print("Total Attached Servos:\t");
  Serial.println(Sweep::getServoCount());
}

void loop() 
{
  Sweep::update();  // this is necessary

  if (Serial.available())
  {
    int target = Serial.parseInt();
    Serial.print(F("Moving servo1 to:\t"));
    Serial.println(target);
    servo1.moveTo(target);
  }
}

void startMoving(int value)
{
  digitalWrite(powerPin, HIGH);
  Serial.print(F("servo1 motion started: "));
  Serial.println(value);
  digitalWrite(13, HIGH);
}

void stoppedMoving(int value)
{
  digitalWrite(13, LOW);
  digitalWrite(powerPin, LOW);
  Serial.print(F("servo1 motion completed: "));
  Serial.println(value);
}

Sweep.h

#ifndef SWEEP_H
#define SWEEP_H

#include <Servo.h>
#include "Arduino.h"

#define MOTION_SPEED_INTERVAL 20  // milliseconds
#define MAX_SERVO_INSTANCES 5

class Sweep : public Servo {

  public:
    Sweep(void(*_startCallback)(int), void(*_endCallback)(int));
    Sweep();
    void begin(int servo);
    void moveTo(uint32_t newPosition);
    static void moveAllTo(uint32_t angle);
    static void update();
    static void update(uint32_t now);
    static int getServoCount();
    int getPosition (void) const;
    
  private:
    enum MotionState{
      ARM_STANDBY,
      ARM_MOVING,
    };
    void(*startCallback)(int);
    void(*endCallback)(int);
    static Sweep* instanceAddress;
    static int instanceCount;
    int servoPin;
    MotionState motionState = ARM_MOVING;
    uint32_t lastMotionMillis = 0;
    int currentPosition;
    int targetPosition;
    uint32_t sensedChangedMillis;
    static void setTargetPosition(Sweep* instance, int position);
};

#endif

Sweep.cpp

#include "Sweep.h"
#include "Arduino.h"

int Sweep::instanceCount = 0;
Sweep* instances[MAX_SERVO_INSTANCES] = {nullptr};

Sweep::Sweep()
{
  instances[instanceCount++] = this;
}

Sweep::Sweep(void(*_startCallback)(int), void(*_endCallback)(int))
{
  instances[instanceCount++] = this;
  startCallback = _startCallback;
  endCallback = _endCallback;
}

int Sweep::getServoCount()
{
  return instanceCount;
}

void Sweep::begin(int servo)
{
  servoPin = servo;
  pinMode(servoPin, OUTPUT);
  attach(servoPin);
  moveTo(0);
  delay(1000);
  detach();
}

void Sweep::setTargetPosition(Sweep* instance, int position)  //flip-flop for the right vs. levt hands.
{
  instance->targetPosition = position;
}

void Sweep::moveTo(uint32_t newPosition)
{
  setTargetPosition(this, newPosition);
}

void Sweep::moveAllTo(uint32_t angle)
{
  for(auto i : instances)
  {
    setTargetPosition(i, angle);
  }
}

void Sweep::update()
{
  update(millis());
}

void Sweep::update(uint32_t now)
{
  for(auto srv : instances)
  {
    switch (srv->motionState)
    {
      case ARM_MOVING:
        if(now - srv->lastMotionMillis > MOTION_SPEED_INTERVAL)
        {
          if(srv->targetPosition == srv->currentPosition)
          {
            if(srv->attached())
            {
              srv->detach();
              srv->motionState = ARM_STANDBY;
              srv->endCallback(srv->getPosition());
            }
          }
          else
          {
            if(!srv->attached())
            {
              srv->attach(srv->servoPin);
            }
            if(srv->targetPosition > srv->currentPosition)
            {
              srv->currentPosition++;
              srv->write(srv->currentPosition);
            }
            else
            {
              srv->currentPosition--;
              srv->write(srv->currentPosition);
            }
          }
          srv->lastMotionMillis = now;
        }
        break;
      case ARM_STANDBY:
        if(srv->targetPosition != srv->currentPosition)    
        {
          srv->motionState = ARM_MOVING;
          srv->startCallback(srv->getPosition());
        }
      break;
    }
  }
}

int Sweep::getPosition(void) const
{
  return currentPosition;
}

just add the two files as tabs in your sketch like shown here:
Screen Shot 2017-12-01 at 06.25.12.png

i've compiled the code and uploaded it to the arduino but when i send number 1 with the phone i get
moving servo1 to : 1
servo1 motion completed : 1
bur the servo dosent move the transistor is connected to pin 7 and the servo to pin 9

t

omarbentaeb:
i've compiled the code and uploaded it to the arduino but when i send number 1 with the phone i get
moving servo1 to : 1
servo1 motion completed : 1
bur the servo dosent move the transistor is connected to pin 7 and the servo to pin 9

well, it starts at 0, so try moving to 90 or 180

use no line feed or carriage return in Serial Monitor, by the way, else you get a trailing zero, which will move it back to position zero.

ADDED:

if you want to just move from 0 to 180 by using a zero or one, modify the Serial parsing like this:

  if (Serial.available())
  {
    int target = Serial.parseInt();
    if (target != 0) target = 180;
    Serial.print(F("Moving servo1 to:\t"));
    Serial.println(target);
    servo1.moveTo(target);
  }

If a servo is being used it is presumably moving something. Removing power and/or detaching it is all very well but if that "something" is exerting a force on the servo output arm causing it to make a noise as it tries to maintain its position then, when powered down or detached the servo is likely to move under the influence of that force.

omarbentaeb:
bur the servo dosent move the transistor is connected to pin 7 and the servo to pin 9

did you chage this:

servo1.begin(4);

to:

servo1.begin(9);

?

yes now it works but as i can see you enter the desired angle and the servo move to it but how can i change it like my original code to move it to a certain angle display message wait 5 seconds then move the servo again and display message

omarbentaeb:
yes now it works but as i can see you enter the desired angle and the servo move to it but how can i change it like my original code to move it to a certain angle display message wait 5 seconds then move the servo again and display message

read #7 again...

then, add a timer to start the servo after it gets its instruction to move; something like this:

void loop() 
{
  static bool triggered = false;
  static uint32_t triggeredMillis = 0;
  Sweep::update();  // this is necessary
  if (Serial.available())
  {
    int target = Serial.parseInt();
    if (target ==1) 
    {
      target = 180;
      triggered = true;
      triggeredMillis = millis();
      servo1.moveTo(target);
    }
    Serial.print(F("Moving servo1 to:\t"));
    Serial.println(target);
  }
  
  if(triggered and millis() - triggeredMillis > 5000)
  {
    servo1.moveTo(0);
    triggered = false;
  }
}

so everything works now thank you for your help but i still have one last problem i want to add two more servos and two transistors but i having difficulties with the code can you please help

omarbentaeb:
so everything works now thank you for your help but i still have one last problem i want to add two more servos and two transistors but i having difficulties with the code can you please help

so just create an array of Sweep objects, define callbacks for each of them, put pin numbers into an array as well…

#include "Sweep.h"

void servoZeroStartMoving(int value);
void servoZeroStopMoving(int value);

void servoOneStartMoving(int value);
void servoOneStopMoving(int value);

void servoTwoStartMoving(int value);
void servoTwoStopMoving(int value);

const byte powerPin = 7;

Sweep servo[] = {
  {servoZeroStartMoving, servoZeroStopMoving},
  {servoOneStartMoving, servoOneStopMoving},
  {servoTwoStartMoving, servoTwoStopMoving},
};

byte servoPin[] = {
  9,  // ServoZero
  4,  // ServoOne
  5,  // ServoTwo
};

void setup() 
{
  Serial.begin(9600);
  pinMode(powerPin, HIGH);
  for (size_t i = 0; i < sizeof(servo)/sizeof(servo[0]); i++)
  {
    servo[i].begin(servoPin[i]);
  }
  pinMode(13, OUTPUT);
  Serial.print("Total Attached Servos:\t");
  Serial.println(Sweep::getServoCount());
}

void loop() 
{
  static bool triggered = false;
  static uint32_t triggeredMillis = 0;
  Sweep::update();  // this is necessary
  
  if (Serial.available())
  {
    int target = Serial.parseInt();
    if (target ==1) 
    {
      target = 180;
      triggered = true;
      triggeredMillis = millis();
      servo[0].moveTo(target);
    }
    Serial.print(F("Moving servo1 to:\t"));
    Serial.println(target);
  }
  
  if(triggered and millis() - triggeredMillis > 5000)
  {
    servo[0].moveTo(0);
  }
}

void servoZeroStartMoving(int value)
{
  digitalWrite(powerPin, HIGH);
  Serial.print(F("servo0 motion started: "));
  Serial.println(value);
  digitalWrite(13, HIGH);
}

void servoZeroStopMoving(int value)
{
  digitalWrite(13, LOW);
  digitalWrite(powerPin, LOW);
  Serial.print(F("servo0 motion completed: "));
  Serial.println(value);
}

void servoOneStartMoving(int value)
{
  Serial.print(F("servo1 motion started: "));
  Serial.println(value);
}

void servoOneStopMoving(int value)
{
  Serial.print(F("servo1 motion ended: "));
  Serial.println(value);
}

void servoTwoStartMoving(int value)
{
  Serial.print(F("servo2 motion started: "));
  Serial.println(value);
}

void servoTwoStopMoving(int value)
{
  Serial.print(F("servo2 motion ended: "));
  Serial.println(value);
}

omarbentaeb:
i did that but i still have no idea how to move the other two servos

well, what do you want to trigger their movement? By Serial also?

problem solved the problem was that i didn’t put any delay after or before opening the transistor here’s the code and BulldogLowell thank you for your help

#include <Servo.h>

Servo myservo;

int pos = 0;

int state; 


void setup()

{
pinMode(13, OUTPUT);
pinMode(7,OUTPUT);


myservo.attach(9);

Serial.begin(9600);

myservo.write(60);

delay(1000); }

void loop()

{

if(Serial.available() > 0)

{
state = Serial.read();

} 

if (state == '1')

{
digitalWrite(7,HIGH);
delay(250);

myservo.write(55);

Serial.println("Mahloul");
digitalWrite(13, HIGH);

delay(5000);

myservo.write(8);
digitalWrite(13, LOW);

Serial.println("Msaker");
state=0;
delay(250);
digitalWrite(7,LOW);

}

}