Skip to content

adding pwm frequency knobs #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 55 additions & 26 deletions adafruit_emc2101.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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, "<B")

dac_output_enabled = RWBit(_REG_CONFIG, 4)
"""When set, the fan control signal is output as a DC voltage instead of a PWM signal"""
Expand Down Expand Up @@ -345,7 +350,7 @@ def initialize(self):
@property
def internal_temperature(self):
"""The temperature as measured by the EMC2101's internal 8-bit temperature sensor"""
return self._int_temp # !!! it's RAAAAAAAAARW)
return self._int_temp

@property
def external_temperature(self):
Expand All @@ -357,7 +362,55 @@ def external_temperature(self):
full_tmp >>= 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):
Expand Down Expand Up @@ -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"""
Expand Down
26 changes: 26 additions & 0 deletions examples/set_pwm_freq.py
Original file line number Diff line number Diff line change
@@ -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)