Node.js implementation of the Arduino Firmata protocol for controlling Arduino boards from JavaScript applications
Servo motor control with angle-based positioning for robotics, automation projects, and precise mechanical control applications.
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 position180 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');
});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);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);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`);
}
});
});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);
});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');
});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// Pin mode for servo control
ArduinoFirmata.SERVO = 4; // Servo control modeStandard servo connections:
Most Arduino digital pins can control servos, but PWM-capable pins provide the most reliable control:
Note: Continuous rotation servos use the same servoWrite() function, but angle values control speed and direction rather than position.
// 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);// 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;
}
});// 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