class PWMOut(object): """PWM output.""" def __init__(self, pin, freq=50, duty=0, verbose=False, channel=-1): if channel in [i for i in range(RMT_MAX_CHAN)]: self._chanRMT = channel self._pin = RMT(channel, pin=Pin(pin), clock_div=RMT_CLOCK_DIV) self.__setRMTDuty(duty) self._pin.loop(True) else: self._chanRMT = -1 self._pin = PWM(Pin(pin)) self._pin.init(freq=freq, duty=duty) self._verbose = verbose if self._verbose: self.__logFrequency() def deinit(self): self._pin.deinit() @property def duty_percent(self): """ duty in percent """ if self._chanRMT < 0: return self._pin.duty() / MAX_DUTY * 100 else: return self._dutyRMT / RMT_DUTY_SCALER @duty_percent.setter def duty_percent(self, value): if self._chanRMT < 0: self._pin.duty(int(min(max(0, value / 100.0 * MAX_DUTY), MAX_DUTY))) else: self.__setRMTDuty( min(max(0, value / 100. * RMT_MAX_DUTY), RMT_MAX_DUTY)) @property def duty(self): """ duty as raw value """ if self._chanRMT < 0: return self._pin.duty() else: return self._dutyRMT @duty.setter def duty(self, value): if self._chanRMT < 0: self._pin.duty(int(value)) else: self.__setRMTDuty(value) @property def freq_Hz(self): """ frequency in [Hz] """ if self._chanRMT < 0: return self._pin.freq() else: return self._pin.source_freq() / RMT_CLOCK_DIV @freq_Hz.setter def freq_Hz(self, value): if self._chanRMT < 0: self._pin.freq(value) else: if value == 0: self._pin.loop(False) else: self._pin.loop(True) d2 = int( (self._pin.source_freq() / RMT_CLOCK_DIV) / value // 2) self._pin.write_pulses((d2, d2)) if self._verbose: self.__logFrequency() @property def max_duty(self): if self._chanRMT < 0: return MAX_DUTY else: return RMT_MAX_DUTY @property def uses_rmt(self): return self._chanRMT >= 0 def __logFrequency(self): print("PWM frequency is {0:.1f} kHz".format(self.freq_Hz / 1000)) def __setRMTDuty(self, value): self._dutyRMT = int(min(max(1, value), RMT_MAX_DUTY)) self._pin.write_pulses((self._dutyRMT, RMT_MAX_DUTY - self._dutyRMT))