diff --git a/adafruit_emc2101.py b/adafruit_emc2101.py index 7db89ee..6e9deb4 100644 --- a/adafruit_emc2101.py +++ b/adafruit_emc2101.py @@ -49,6 +49,8 @@ _FAN_CONFIG = const(0x4A) _FAN_SPINUP = const(0x4B) _REG_FAN_SETTING = const(0x4C) +_PWM_FREQ = const(0x4D) +_PWM_DIV = const(0x4E) _LUT_HYSTERESIS = const(0x4F) _TEMP_FILTER = const(0xBF) @@ -308,7 +310,10 @@ class EMC2101: # pylint: disable=too-many-instance-attributes """When set to True, the magnitude of the fan output signal is inverted, making 0 the maximum value and 100 the minimum value""" + _fan_pwm_clock_select = RWBit(_FAN_CONFIG, 3) _fan_pwm_clock_override = RWBit(_FAN_CONFIG, 2) + _pwm_freq = RWBits(5, _PWM_FREQ, 0) + _pwm_freq_div = UnaryStruct(_PWM_DIV, ">= 5 full_tmp *= 0.125 - return full_tmp # !!! it's RAAAAAAAAARW + return full_tmp + + def set_pwm_clock(self, use_preset=False, use_slow=False): + """ + Select the PWM clock source, chosing between two preset clocks or by configuring the + clock using `pwm_frequency` and `pwm_frequency_divisor`. + + :param bool use_preset: + True: Select between two preset clock sources + False: The PWM clock is set by `pwm_frequency` and `pwm_frequency_divisor` + :param bool use_slow: + True: Use the 1.4kHz clock + False: Use the 360kHz clock. + :type priority: integer or None + :return: None + :raises AttributeError: if use_preset is not a `bool` + :raises AttributeError: if use_slow is not a `bool` + + """ + + if not isinstance(use_preset, bool): + raise AttributeError("use_preset must be given a bool") + if not isinstance(use_slow, bool): + raise AttributeError("use_slow_pwm must be given a bool") + + self._fan_pwm_clock_override = not use_preset + self._fan_pwm_clock_select = use_slow + + @property + def pwm_frequency(self): + """Selects the base clock frequency used for the fan PWM output""" + return self._pwm_freq + + @pwm_frequency.setter + def pwm_frequency(self, value): + if value < 0 or value > 0x1F: + raise AttributeError("pwm_frequency must be from 0-31") + self._pwm_freq_div = value + + @property + def pwm_frequency_divisor(self): + """The Divisor applied to the PWM frequency to set the final frequency""" + return self._pwm_freq_div + + @pwm_frequency_divisor.setter + def pwm_frequency_divisor(self, divisor): + if divisor < 0 or divisor > 255: + raise AttributeError("pwm_frequency_divisor must be from 0-255") + self._pwm_freq_div = divisor @property def fan_speed(self): @@ -398,30 +451,6 @@ def lut_enabled(self): def lut_enabled(self, enable_lut): self._fan_lut_prog = not enable_lut - # def get_lut(self, lut_index): - # """The Look Up Table used to determine what the fan speed should be based on the measured - # temperature. `lut` acts similarly to a dictionary but with restrictions: - - # * The LUT key is a temperature in celcius - # * The LUT value is the corresponding fan speed in % of maximum RPM - # * The LUT can only contain 8 entries. Attempting to set a ninth will - # result in an `IndexError` - - # Example: - - # .. code-block:: python3 - - # # If the measured external temperature goes over 20 degrees C, set the fan speed to 50% - # fan_controller.lut[20] = 50 - - # # If the temperature is over 30 degrees, set the fan speed to 75% - # fan_controller.lut[30] = 75 - # """ - # return self._lut.__getitem__(self, lut_index) - - # def set_lut(self, lut_temp, lut_speed): - # self._lut.__setitem__(lut_temp, lut_speed) - @property def lut(self): """The dict-like representation of the LUT""" diff --git a/examples/set_pwm_freq.py b/examples/set_pwm_freq.py new file mode 100644 index 0000000..faf8dc8 --- /dev/null +++ b/examples/set_pwm_freq.py @@ -0,0 +1,26 @@ +# SPDX-FileCopyrightText: 2020 Bryan Siepert, written for Adafruit Industries +# +# SPDX-License-Identifier: MIT +import time +import board +import busio +from adafruit_emc2101 import EMC2101 + +i2c = busio.I2C(board.SCL, board.SDA) + +emc = EMC2101(i2c) +emc.set_pwm_clock(use_preset=False) +# Datasheet recommends using the maximum value of 31 (0x1F) +# to provide the highest effective resolution +emc.pwm_frequency = 14 + +# This divides the pwm frequency down to a smaller number +# so larger divisor = lower frequency +emc.pwm_frequency_divisor = 127 + +while True: + print("External temperature:", emc.external_temperature, "C") + emc.manual_fan_speed = 50 + time.sleep(1.5) + print("Fan speed:", emc.fan_speed, "RPM") + time.sleep(1)