@@ -16,6 +16,8 @@ class EventFailedScheduleQueueFull(Exception):
1616# SUPPORTING CLASSES
1717###############################################################################
1818
19+ def clamp (n , low , high ): return max (low , min (n , high ))
20+
1921class PinMixin :
2022 """
2123 Mixin used by devices that have a single pin number.
@@ -264,13 +266,6 @@ class DigitalOutputDevice(OutputDevice, PinMixin):
264266 :param int pin:
265267 The pin that the device is connected to.
266268
267- :param int freq:
268- The frequency of the PWM signal in Hertz. Defaults to 100.
269-
270- :param int duty_factor:
271- The duty factor of the PWM signal. This is a value between 0 and 65535.
272- Defaults to 65535.
273-
274269 :param bool active_high:
275270 If :data:`True` (the default), the :meth:`on` method will set the Pin
276271 to HIGH. If :data:`False`, the :meth:`on` method will set the Pin to
@@ -365,8 +360,8 @@ class PWMOutputDevice(OutputDevice, PinMixin):
365360 LOW (the :meth:`off` method always does the opposite).
366361
367362 :param bool initial_value:
368- If :data:`False ` (the default), the LED will be off initially. If
369- :data:`True `, the LED will be switched on initially.
363+ If :data:`0 ` (the default), the device will be off initially. If
364+ :data:`1 `, the device will be switched on initially.
370365 """
371366
372367 PIN_TO_PWM_CHANNEL = ["0A" ,"0B" ,"1A" ,"1B" ,"2A" ,"2B" ,"3A" ,"3B" ,"4A" ,"4B" ,"5A" ,"5B" ,"6A" ,"6B" ,"7A" ,"7B" ,"0A" ,"0B" ,"1A" ,"1B" ,"2A" ,"2B" ,"3A" ,"3B" ,"4A" ,"4B" ,"5A" ,"5B" ,"6A" ,"6B" ]
@@ -1400,6 +1395,74 @@ def close(self):
14001395
14011396Rover = Robot
14021397
1398+ class Servo (PWMOutputDevice ):
1399+ """
1400+ Represents a PWM-controlled servo motor.
1401+
1402+ Setting the `value` to 0 will move the servo to its minimum position,
1403+ 1 will move the servo to its maximum position. Setting the `value` to
1404+ :data:`None` will turn the servo "off" (i.e. no signal is sent).
1405+
1406+ :type pin: int
1407+ :param pin:
1408+ The pin the servo motor is connected to.
1409+
1410+ :param bool initial_value:
1411+ If :data:`0`, the servo will be set to its minimum position. If
1412+ :data:`1`, the servo will set to its maximum position. If :data:`None`
1413+ (the default), the position of the servo will not change.
1414+
1415+ :param float min_pulse_width:
1416+ The pulse width corresponding to the servo's minimum position. This
1417+ defaults to 1ms.
1418+
1419+ :param float max_pulse_width:
1420+ The pulse width corresponding to the servo's maximum position. This
1421+ defaults to 2ms.
1422+
1423+ :param float frame_width:
1424+ The length of time between servo control pulses measured in seconds.
1425+ This defaults to 20ms which is a common value for servos.
1426+
1427+ :param int duty_factor:
1428+ The duty factor of the PWM signal. This is a value between 0 and 65535.
1429+ Defaults to 65535.
1430+ """
1431+ def __init__ (self , pin , initial_value = None , min_pulse_width = 1 / 1000 , max_pulse_width = 2 / 1000 , frame_width = 20 / 1000 , duty_factor = 65535 ):
1432+ self ._min_duty = int ((min_pulse_width / frame_width ) * duty_factor )
1433+ self ._max_duty = int ((max_pulse_width / frame_width ) * duty_factor )
1434+
1435+ super ().__init__ (pin , freq = int (1 / frame_width ), duty_factor = duty_factor , initial_value = initial_value )
1436+
1437+ def _state_to_value (self , state ):
1438+ return None if state == 0 else clamp ((state - self ._min_duty ) / (self ._max_duty - self ._min_duty ), 0 , 1 )
1439+
1440+ def _value_to_state (self , value ):
1441+ return 0 if value is None else int (self ._min_duty + ((self ._max_duty - self ._min_duty ) * value ))
1442+
1443+ def min (self ):
1444+ """
1445+ Set the servo to its minimum position.
1446+ """
1447+ self .value = 0
1448+
1449+ def mid (self ):
1450+ """
1451+ Set the servo to its mid-point position.
1452+ """
1453+ self .value = 0.5
1454+
1455+ def max (self ):
1456+ """
1457+ Set the servo to its maximum position.
1458+ """
1459+ self .value = 1
1460+
1461+ def off (self ):
1462+ """
1463+ Turn the servo "off" by setting the value to `None`.
1464+ """
1465+ self .value = None
14031466
14041467###############################################################################
14051468# INPUT DEVICES
0 commit comments