Matha Goram
Published © GPL3+

Serve by Rotation

This note illustrates the introductory use of a servo motor directly from an Arduino microcontroller. See video!

BeginnerFull instructions provided30 minutes1,327
Serve by Rotation

Things used in this project

Hardware components

Elegoo Arduino UNO R3
×1
SG90 Micro-servo motor
SG90 Micro-servo motor
×1
Elegoo DuPont connection wires
×1
Elegoo Breadboard, any size
×1
Baseplate
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Custom parts and enclosures

Simplest assembly

Basic layout to connect servo motor to the Arduino board

Autonomous power

Isolate the power to the servo motor from the Arduino board

Stabilize the potential spike

Improve the servo motor performance by using a capacitor to protect the current spike on startup

Schematics

Autonomous power

Power the servo motor separately from the Arduino board

Simplest schematic to drive servo motor

Connect servo motor directly to Arduino board.

Stabilize the potential spike

A simple surge protection for the servo motor current drain

Code

ElegooMotorServo-01.ino

C/C++
Test basic functions of Arduino Servo library using a popular micro servo motor - SG90.
/*
 * ElegooMotorServo-01.ino
 * A basic set of tests to drive a servo motor directly
 * 2018-10-12
 * armw
 * v0.1
 * © 2018 <reza@parkcircus.org> All Rights Reserved
 *  
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA.  
 * 
 * Reference:
 * https://playground.arduino.cc/ComponentLib/Servo
 * attach(int)  - set pin to servo driver
 * detach()     - release pin from servo driver
 * write(int)   - set angle for servo position, degrees
 * read()       - obtain last value used by write method
 * attached()   - check attach status of servo
 * https://www.arduino.cc/en/Reference/Servo
 * attach(int, int, int)  - attach the Servo variable to pins 9 or 10 only
 * write(int)             - write angle value to control the shaft orientation
 * map(int, int, int, int, int) - maps a number from one range to another
 * writeMicroseconds()    - write value (uS) to servo; 1000 full counter-clockwise, 2000 full clockwise
 * read()                 - read current angle of servo (value passed during last call to write())
 * attached()             - boolean flag returned on servo attach status
 * detach()               - detach servo from attached pin
 * http://www.towerpro.co:
 * Color          Purpose
 * red            VDC
 * black, brown   GND
 * yellow, orange signal
 * Three use cases:
 * Use direct power from board to servo motor
 * Use 470 uF capacitor between VDC and GND to stabilize power from board to servo motor
 * Use separate power supply to servo motor but use common ground for board and motor power supplies
 */

#include <Servo.h>                      // Arduino Software Servo Library https://playground.arduino.cc/ComponentLib/Servo

#
#define PIN_SERVO 9                     // board pin number attached to servo signal pin
#define MAX_ANGLE 180                   // maximum angle for servo position
#define PULSEWIDTH_SG90_MAX 2000        // max pulse width for SG90 servo motor (per datasheet)
#define PULSEWIDTH_SG90_MIN 1000        // min pulse width for SG90 servo motor
#define SG90_CENTER_ANGLE 90            // if Servo library range is from 0 to 180 then mid-point is 90
#define SG90_CENTER_WIDTH 1500          // pulse width range is from 1000 to 2000 then mid-point is 1500

Servo myServo;                          // instantiate a Servo entity
int currentPosition = 90;               // initialize (i.e. center) position variable for SG90 servo motor

void centerServo()
{
  myServo.write(SG90_CENTER_ANGLE);     // 90 is mid-point between 0 and 180
                                        // 1 ms to position to extreme left, -90 degrees
                                        // 40 ms delay
                                        // 2 ms to position to extreme right, +90 degrees
                                        // 40 ms delay
  myServo.writeMicroseconds(SG90_CENTER_WIDTH);// 1.5 ms to center, 0 degrees
                                        // 40 ms delay
  currentPosition = myServo.read();   // update the current angle of servo (for global use)
}

void setup()                            // initialization section
{
                                        // https://www.arduino.cc/en/Reference/ServoAttach
  myServo.attach(PIN_SERVO, PULSEWIDTH_SG90_MIN, PULSEWIDTH_SG90_MAX); // attach pin to servo entity
  delay(100);                           // 100 milliseconds
  centerServo();                        // standard operating practice to initialize servo motor
  delay(100);                           // 100 milliseconds
  myServo.detach();                     // test the detach command in the library ;)
  delay(100);                           // 100 milliseconds
  myServo.attach(PIN_SERVO, PULSEWIDTH_SG90_MIN, PULSEWIDTH_SG90_MAX); // resume the show!
  delay(1000);                          // 1 second
}

// the direction of rotation predicted by Fleming's rule
void panRightAngular()
{
  for (int i = 0; i <= MAX_ANGLE; i += 1)  // iterate through all positions from 0 to 180 degrees
  {
    myServo.write(i);                   // set the angle and rotate shaft to corresponding orientation
    delay(100);                         // 100 milliseconds hold
    currentPosition = myServo.read();   // update the current angle of servo (for global use)
  }
}

// the direction of rotation depends by Fleming's rule
void panLeftAngular()
{
  for (int i = MAX_ANGLE; i >= 0; i -= 1)  // iterate through all positions from 0 to 180 degrees
  {
    myServo.write(i);                   // set the angle and rotate shaft to corresponding orientation
    delay(100);                         // 100 milliseconds hold
    currentPosition = myServo.read();   // update the current angle of servo (for global use)
  }
}
// the direction of rotation predicted by Fleming's rule
void panRightPulseWidth()
{
  for (int i = PULSEWIDTH_SG90_MIN; i <= PULSEWIDTH_SG90_MAX; i += 1)  // iterate through all pulse width values from MIN to MAX
  {
    myServo.writeMicroseconds(i);       // set pulse width for desired angle and rotate shaft to corresponding position
    delay(5);                           // 100 milliseconds hold
    currentPosition = myServo.read();   // update the current angle of servo (for global use)
  }
}

// the direction of rotation depends by Fleming's rule
void panLeftPulseWidth()
{
  for (int i = PULSEWIDTH_SG90_MAX; i >= PULSEWIDTH_SG90_MIN; i -= 1)  // iterate through all pulse width values from MIN to MAX
  {
    myServo.writeMicroseconds(i);       // set the angle and rotate shaft to corresponding orientation
    delay(5);                           // 100 milliseconds hold
    currentPosition = myServo.read();   // update the current angle of servo (for global use)
  }
}

void loop()                             // repetitive section
{
  panRightAngular();                    // clockwise rotation from 0 to 180 degrees
  delay(1000);                          // 1,000 milliseconds
  centerServo();                        // return servo to mid-point angle
  delay(1000);                          // let us catch our breath
  panLeftAngular();                     // counter-clockwise rotation from 180 to 0 degrees
  delay(1000);                          // 1,000 milliseconds
  centerServo();                        // return servo to mid-point angle
  delay(1000);                          // let us catch our breath
  panRightPulseWidth();                 // clockwise rotation from pulse width MIN to MAX
  delay(1000);                          // 1,000 milliseconds
  centerServo();                        // return servo to mid-point angle
  delay(1000);                          // let us catch our breath
  panLeftPulseWidth();                  // counter-clockwise rotation from pulse width MAX to MIN
  delay(1000);                          // 1,000 milliseconds
  centerServo();                        // return servo to mid-point angle
  delay(1000);
}

Credits

Matha Goram
27 projects • 23 followers
Working with discrete electronic components for a very long time but still suffering from the occasional dry soldering results.
Contact

Comments

Please log in or sign up to comment.