TypeScript SDK for Feetech servo motors using Web Serial API
npm install feetech-servo-tsA TypeScript SDK for controlling Feetech servo motors using Web Serial API. This library provides a modern, type-safe interface for interacting with STS, SMS, and SCS series servo motors in web browsers.
- 🌐 Web Serial API Integration - Direct browser-to-servo communication
- 📦 TypeScript Support - Full type definitions and IntelliSense
- 🔄 Synchronous Operations - Control multiple servos simultaneously
- 🛡️ Error Handling - Comprehensive error detection and reporting
- 🚀 Modern API - Promise-based async/await interface
- 📱 Cross-Platform - Works on any browser supporting Web Serial API
This SDK requires Web Serial API support:
- Chrome 89+
- Edge 89+
- Opera 75+
``bash`
npm install @feetech/servo-sdk
`typescript
import { FeetechServo } from '@feetech/servo-sdk';
// Create servo instance
const servo = new FeetechServo({ baudRate: 1000000 });
// Connect to servo
await servo.connect();
// Ping servo
const result = await servo.ping(1);
console.log(Found servo: ID=${result.id}, Model=${result.modelNumber});
// Enable torque
await servo.enableTorque(1);
// Move servo to center position
await servo.writePosition(1, 512, 200); // position: 512, speed: 200
// Read current position
const position = await servo.readPosition(1);
console.log(Current position: ${position});
// Disconnect
await servo.disconnect();
`
`typescript
// Connect to servo
await servo.connect();
// Check connection status
const isConnected = servo.getConnectionStatus();
// Disconnect
await servo.disconnect();
`
`typescript
// Ping servo
const pingResult = await servo.ping(servoId);
// Scan for servos
const foundServos = await servo.scan(0, 20); // Scan IDs 0-20
// Read/Write position
const position = await servo.readPosition(servoId);
await servo.writePosition(servoId, targetPosition, speed);
// Position control in degrees
await servo.setPositionInDegrees(servoId, 150); // 0-300 degrees
const degrees = await servo.getPositionInDegrees(servoId);
// Torque control
await servo.enableTorque(servoId);
await servo.disableTorque(servoId);
// Read complete status
const status = await servo.readStatus(servoId);
`
`typescript
// Sync write positions
await servo.syncWritePosition([
{ id: 1, position: 512 },
{ id: 2, position: 768 },
{ id: 3, position: 256 }
]);
// Sync read positions
const positions = await servo.syncReadPosition([1, 2, 3]);
positions.forEach((pos, id) => {
console.log(Servo ${id}: ${pos});`
});
`typescript
// Change servo ID
await servo.setID(currentId, newId);
// Set baud rate
await servo.setBaudRate(servoId, 1000000);
// Factory reset
await servo.factoryReset(servoId);
// Reboot servo
await servo.reboot(servoId);
// Direct register access
const value = await servo.readByte(servoId, address);
await servo.writeByte(servoId, address, value);
`
`typescript
// Create sync write group
const syncWrite = servo.createSyncWrite(ControlTable.GOAL_POSITION_L, 2);
syncWrite.addParam(1, new Uint8Array([0x00, 0x02])); // Position 512
syncWrite.addParam(2, new Uint8Array([0x00, 0x03])); // Position 768
await syncWrite.txPacket();
// Create sync read group
const syncRead = servo.createSyncRead(ControlTable.PRESENT_POSITION_L, 2);
syncRead.addParam(1);
syncRead.addParam(2);
await syncRead.txRxPacket();
const data1 = syncRead.getData(1);
const data2 = syncRead.getData(2);
`
`typescript
import { helpers } from '@feetech/servo-sdk';
// Check Web Serial support
if (helpers.isWebSerialSupported()) {
// Web Serial is available
}
// Convert between degrees and position values
const position = helpers.degreesToPosition(150); // 150° → position value
const degrees = helpers.positionToDegrees(512); // position → degrees
// Convert RPM to speed value
const speed = helpers.rpmToSpeed(60); // 60 RPM → speed value
const rpm = helpers.speedToRpm(512); // speed → RPM
// Clamp values to valid ranges
const safePosition = helpers.clampPosition(2000); // Returns 1023
const safeSpeed = helpers.clampSpeed(-100); // Returns 0
`
`typescript
import { ServoError, ErrorCode } from '@feetech/servo-sdk';
try {
await servo.connect();
} catch (error) {
if (error instanceof ServoError) {
switch (error.code) {
case ErrorCode.CONNECTION_FAILED:
console.error('Failed to connect to servo');
break;
case ErrorCode.TIMEOUT:
console.error('Operation timed out');
break;
case ErrorCode.CHECKSUM_ERROR:
console.error('Communication error');
break;
}
}
}
`
Check the examples directory for complete working examples:
1. Basic Control - Simple position and torque control
2. Servo Scanner - Scan and identify connected servos
3. Sync Control - Control multiple servos simultaneously
4. Advanced Settings - Change IDs, baud rates, and factory reset
To run examples:
`bash`
cd examples
npm install
npm run dev
Then open http://localhost:3000 in your browser.
`bashInstall dependencies
npm install
$3
When developing the SDK and testing with examples:
1. Start SDK build in watch mode (in the root directory):
`bash
npm run dev
`
This watches for changes in src/ and automatically rebuilds to dist/2. In a separate terminal, run the example (in the examples directory):
`bash
cd examples && npm run dev
`3. Both processes must run simultaneously for live updates:
- SDK changes in
src/ → automatically built to dist/
- Example imports from dist/ → sees updates immediately$3
`bash
Build once and run example
npm run build && cd examples && npm run dev
`$3
`bash
Run tests
npm run testLint code
npm run lintFormat code
npm run formatBuild for production
npm run build
``This SDK implements the Feetech servo protocol, compatible with:
- STS Series (Serial Bus Servo)
- SMS Series (Serial Bus Servo)
- SCS Series (Serial Bus Servo)
Default communication parameters:
- Baud Rate: 1,000,000 bps
- Data Bits: 8
- Stop Bits: 1
- Parity: None
MIT License - see LICENSE file for details
Contributions are welcome! Please feel free to submit a Pull Request.
For issues and feature requests, please use the GitHub issues page.