"""
Custom extension on pyb.Timer to handle the combination of hardware timers
and pins
"""
from pyb import Pin, Timer
from machine import ADC
from ._timer_channels import PINS_TO_TIMERS
def make_pin(pin: str) -> Pin:
"""Parse input into a Pin object
:param pin: Input object
"""
if isinstance(pin, Pin):
return pin
if isinstance(pin, str):
return Pin(pin)
raise ValueError('Cannot convert `{}` of type `{}` into a Pin '
'object'.format(pin, type(pin)))
[docs]class PWM:
"""Pulse-Width Modulation interface
Main purpose of the class is to automatically select the correct timers
and channels based on the target pin.
"""
def __init__(self, pin: str, freq: float = 1000):
"""Constructor
An error is thrown if the pin is not connected to a timer channel.
:param pin: Name of the pin (either STM or Arduino name),
or a Pin object directly
:param freq: PWM frequency
:raise ValueError: If the selected pin does not have a registered
timer
"""
self.pin = make_pin(pin)
self.freq = freq
stm_name = self.pin.name()
if stm_name in PINS_TO_TIMERS:
self.timer_number, self.channel_number = PINS_TO_TIMERS[stm_name]
else:
raise ValueError('The pin `{}` does not have a registered PWM '
'timer channel connected to '
'it'.format(self.pin.name()))
# Select the timer to be used and set PWM frequency
self.timer = Timer(self.timer_number, freq=self.freq)
# Set channel of timer to PWM _mode and attach the pin
self.channel = self.timer.channel(self.channel_number, Timer.PWM,
pin=self.pin)
[docs] def write(self, pwm: float):
"""Write PWM as a number between 0.0 and 1.0"""
self.write_percentage(pwm * 100.0)
[docs] def write_percentage(self, percentage: float):
"""Write PWM as a decimal percentage between 0.0 and 100.0"""
if percentage < 0.0:
percentage = 0.0
elif percentage > 100.0:
percentage = 100.0
self.channel.pulse_width_percent(percentage)
[docs]class AnalogIn:
"""Read analog signal
Extension of ADC
"""
def __init__(self, pin: str):
"""Constructor
An error will be throws if the pin does not have an
Analog-to-Digital converted connected.
:param pin: Name of a pin or Pin object
"""
self.pin = make_pin(pin)
self.adc = ADC(self.pin)
[docs] def read(self) -> float:
"""Get analog input value between 0.0 and 1.0
Corresponding to 0 to 3.3V. The Nucleo appears to be 5V tolerant.
The resolution is 16 bit.
"""
return float(self.adc.read_u16()) / 65535.0
[docs] def read_u16(self) -> int:
"""Get analog input as integer, from 0 to 65535"""
return self.adc.read_u16()