"""Default values provided are from the DS3218MG. Pins GPIOs 34 to 39 can’t generate PWM on the ESP32. Description: High-precision metal gears with hard anodizing CNC aluminum middle Shell water proof rubber seals screws Specification: Stall Torque (5V): 19 kg/cm (263.8oz/in) Stall Torque (6.8V): 21.5 kg/cm (298.5 oz/in) Dead band: 3μs Speed : 0.16 sec/60°(5V) / 0.14 sec/60°(6.8V) Operating Voltage: 4.8 ~ 6.8 DC Volts Weight: 60 g (2.12 oz) Motor Type: DC Motor Gear Type: Copper & Aluminum Working frequence: 1520μs / 333hz CE Certification: Yes Size: 40 x 20 x 40.5 mm ( 1.58 x 0.79 x 1.60 in) Package Includes: 4 X DS3218 Digital Servo 20KG 4 X 25T Servo Arm micro-seconds on 10**-6 seconds. """ from machine import Pin, PWM import math class Servo: def __init__(self, pin, freq=40, min_us=500, max_us=2500, degrees=270): """ :param pin: machine.Pin A PWM enabled Pin :param freq: int The frequency in Hz. Typical values for servos are 40 or 50. :param min_us: int The minimum number of microseconds :param max_us: The maximum number of microseconds :param degrees: int The range in degrees of the motor """ self.period = 1000000 / freq self.min_duty = self._us2duty(min_us) self.max_duty = self._us2duty(max_us) self.degrees = degrees self.freq = freq self.pin = PWM(pin, freq=freq) def _us2duty(self, value): """Converts a microsecond value to a duty cycle value.""" return int(1024 * value / self.period) def position(self, degrees=None, radians=None, us=None, duty=None): span = self.max_duty - self.min_duty # 409.6 if degrees is not None: duty = self.min_duty + span * degrees / self.degrees elif radians is not None: duty = self.min_duty + span * radians / math.radians(self.degrees) elif us is not None: duty = self._us2duty(us) elif duty is not None: pass else: return self.pin.duty() duty = min(self.max_duty, max(self.min_duty, int(duty))) self.pin.duty(duty) def release(self): self.pin.duty(0)