CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-arduino-firmata

Node.js implementation of the Arduino Firmata protocol for controlling Arduino boards from JavaScript applications

Overview
Eval results
Files

servo.mddocs/

Servo Control

Servo motor control with angle-based positioning for robotics, automation projects, and precise mechanical control applications.

Capabilities

Servo Position Control

Control servo motor position by specifying target angle in degrees.

/**
 * Control servo motor position by angle
 * Automatically configures pin for servo control
 * @param pin - Digital pin number connected to servo signal wire
 * @param angle - Target angle in degrees (0-180)
 * @param callback - Optional callback function called when position command is sent
 */
servoWrite(pin: number, angle: number, callback?: Function): void;

Angle Range:

  • 0 degrees - Minimum position (typically far counter-clockwise)
  • 90 degrees - Center/neutral position
  • 180 degrees - Maximum position (typically far clockwise)

Usage Examples:

// Move servo to center position
arduino.servoWrite(9, 90);

// Move servo to minimum position
arduino.servoWrite(9, 0);

// Move servo to maximum position
arduino.servoWrite(9, 180);

// Precise positioning
arduino.servoWrite(9, 45);  // Quarter turn from center
arduino.servoWrite(9, 135); // Three-quarter turn from center

// With callback
arduino.servoWrite(9, 90, function() {
  console.log('Servo moved to center position');
});

Servo Sweep Animation

Create smooth servo movements and animations.

// Simple servo sweep back and forth
let angle = 0;
let direction = 1;

setInterval(function() {
  arduino.servoWrite(9, angle);

  angle += direction * 2;
  if (angle >= 180 || angle <= 0) {
    direction = -direction;
  }
}, 50);

Multiple Servo Control

Control multiple servos independently for complex mechanical systems.

// Control multiple servos
arduino.servoWrite(9, 45);   // Servo 1 to 45 degrees
arduino.servoWrite(10, 135); // Servo 2 to 135 degrees
arduino.servoWrite(11, 90);  // Servo 3 to center

// Synchronized movement
const servoPins = [9, 10, 11];
let targetAngle = 0;

setInterval(function() {
  // Move all servos to the same angle
  servoPins.forEach(pin => {
    arduino.servoWrite(pin, targetAngle);
  });

  targetAngle += 10;
  if (targetAngle > 180) {
    targetAngle = 0;
  }
}, 500);

Sensor-Controlled Servo

Use sensors to control servo position for responsive mechanical systems.

arduino.on('connect', function() {
  // Control servo position based on potentiometer input
  arduino.on('analogChange', function(event) {
    if (event.pin === 0) { // Potentiometer on A0
      // Map potentiometer reading (0-1023) to servo angle (0-180)
      const angle = Math.round((event.value / 1023) * 180);
      arduino.servoWrite(9, angle);
      console.log(`Servo angle set to ${angle} degrees`);
    }
  });
});

Robotic Arm Example

const ArduinoFirmata = require('arduino-firmata');
const arduino = new ArduinoFirmata();

arduino.connect();

arduino.on('connect', function() {
  console.log('Robotic arm controller ready');

  // Define servo pins for robotic arm joints
  const servos = {
    base: 9,      // Base rotation
    shoulder: 10, // Shoulder joint
    elbow: 11,    // Elbow joint
    wrist: 6      // Wrist joint
  };

  // Move to home position
  function homePosition() {
    arduino.servoWrite(servos.base, 90);     // Center
    arduino.servoWrite(servos.shoulder, 45); // Shoulder up
    arduino.servoWrite(servos.elbow, 135);   // Elbow bent
    arduino.servoWrite(servos.wrist, 90);    // Wrist center
    console.log('Moved to home position');
  }

  // Predefined positions
  function pickupPosition() {
    arduino.servoWrite(servos.base, 90);
    arduino.servoWrite(servos.shoulder, 120);
    arduino.servoWrite(servos.elbow, 60);
    arduino.servoWrite(servos.wrist, 0);
    console.log('Moved to pickup position');
  }

  // Initialize to home position
  setTimeout(homePosition, 1000);

  // Demo sequence
  setTimeout(function() {
    pickupPosition();
    setTimeout(homePosition, 2000);
  }, 3000);
});

Smooth Servo Movement

Create smooth servo transitions instead of immediate jumps.

function smoothServoMove(pin, fromAngle, toAngle, duration, callback) {
  const steps = Math.abs(toAngle - fromAngle);
  const stepDelay = duration / steps;
  const direction = toAngle > fromAngle ? 1 : -1;

  let currentAngle = fromAngle;

  const moveInterval = setInterval(function() {
    arduino.servoWrite(pin, currentAngle);
    currentAngle += direction;

    if (currentAngle === toAngle) {
      clearInterval(moveInterval);
      if (callback) callback();
    }
  }, stepDelay);
}

// Usage: move servo from 0 to 180 degrees over 2 seconds
smoothServoMove(9, 0, 180, 2000, function() {
  console.log('Smooth movement completed');
});

Servo Position Feedback

While standard servos don't provide position feedback, you can track commanded positions.

class ServoController {
  constructor(arduino, pin) {
    this.arduino = arduino;
    this.pin = pin;
    this.currentAngle = 90; // Assume starting at center
  }

  moveTo(angle, callback) {
    if (angle < 0 || angle > 180) {
      console.error('Servo angle must be between 0 and 180 degrees');
      return;
    }

    this.arduino.servoWrite(this.pin, angle, () => {
      this.currentAngle = angle;
      console.log(`Servo on pin ${this.pin} moved to ${angle} degrees`);
      if (callback) callback();
    });
  }

  getCurrentAngle() {
    return this.currentAngle;
  }

  moveRelative(deltaAngle, callback) {
    const newAngle = Math.max(0, Math.min(180, this.currentAngle + deltaAngle));
    this.moveTo(newAngle, callback);
  }
}

// Usage
const servo1 = new ServoController(arduino, 9);
servo1.moveTo(45);
servo1.moveRelative(30); // Move 30 degrees from current position

Constants

// Pin mode for servo control
ArduinoFirmata.SERVO = 4; // Servo control mode

Servo Specifications

Standard Servo Characteristics

  • Control Signal: PWM signal with 20ms period (50Hz)
  • Pulse Width Range: 1ms (0°) to 2ms (180°), with 1.5ms for center (90°)
  • Angle Range: 0° to 180° (some servos may have different ranges)
  • Response Time: Typically 0.1 to 0.2 seconds per 60° movement
  • Torque: Varies by servo model (measured in kg⋅cm or oz⋅in)

Power Requirements

  • Voltage: Most servos operate at 4.8V to 6V
  • Current: Varies by servo size and load (typically 100mA to 2A+)
  • Power Supply: External power supply recommended for multiple or high-torque servos

Wiring

Standard servo connections:

  • Red wire: Power (4.8V - 6V)
  • Black/Brown wire: Ground (GND)
  • Yellow/White/Orange wire: Signal (connect to Arduino digital pin)

Compatible Pins

Most Arduino digital pins can control servos, but PWM-capable pins provide the most reliable control:

Arduino UNO Servo Pins

  • Pins 3, 5, 6, 9, 10, 11: PWM-capable pins (recommended)
  • Pins 2, 4, 7, 8, 12, 13: Digital pins (also supported)

Simultaneous Servo Limit

  • Arduino UNO can typically control 8-12 servos simultaneously
  • More servos may require external servo controller boards
  • Each servo adds processing overhead to the Arduino

Servo Types

Standard Servos

  • Rotation: 0° to 180° (approximately 180° of travel)
  • Applications: Robotic arms, camera mounts, control surfaces
  • Control: Position-based control

Continuous Rotation Servos

  • Rotation: Full 360° continuous rotation
  • Control: Speed and direction rather than position
  • Applications: Robot wheels, conveyor systems

Note: Continuous rotation servos use the same servoWrite() function, but angle values control speed and direction rather than position.

Common Applications

Camera Gimbal

// Two-axis camera gimbal control
const panServo = 9;   // Horizontal pan
const tiltServo = 10; // Vertical tilt

// Center gimbal
arduino.servoWrite(panServo, 90);
arduino.servoWrite(tiltServo, 90);

// Smooth pan movement
let panAngle = 90;
setInterval(function() {
  arduino.servoWrite(panServo, panAngle);
  panAngle += 2;
  if (panAngle > 160) panAngle = 20;
}, 100);

Robotic Joint Control

// Multi-joint robot control with sensor input
arduino.on('analogChange', function(event) {
  switch(event.pin) {
    case 0: // Joystick X-axis controls base rotation
      const baseAngle = Math.round((event.value / 1023) * 180);
      arduino.servoWrite(9, baseAngle);
      break;
    case 1: // Joystick Y-axis controls arm elevation
      const armAngle = Math.round((event.value / 1023) * 180);
      arduino.servoWrite(10, armAngle);
      break;
  }
});

Best Practices

Servo Control Guidelines

  1. Power Supply: Use external power for multiple or high-torque servos
  2. Startup: Allow servos to reach position before sending new commands
  3. Speed: Don't send position updates too frequently (limit to ~20Hz)
  4. Range: Stay within 0-180° range to avoid servo damage
  5. Wiring: Keep signal wires short and away from power wires to reduce noise

Performance Optimization

// Throttle servo updates to avoid overwhelming the servo
let lastServoUpdate = 0;
const SERVO_UPDATE_INTERVAL = 50; // 50ms minimum between updates

function updateServo(pin, angle) {
  const now = Date.now();
  if (now - lastServoUpdate > SERVO_UPDATE_INTERVAL) {
    arduino.servoWrite(pin, angle);
    lastServoUpdate = now;
  }
}

Install with Tessl CLI

npx tessl i tessl/npm-arduino-firmata

docs

analog-io.md

connection.md

digital-io.md

events.md

index.md

servo.md

sysex.md

tile.json