Skip to content

Commit 683ecec

Browse files
authored
Merge pull request #1 from adafruit/pwm_freq
adding pwm frequency knobs
2 parents 9bca578 + a36d3a9 commit 683ecec

File tree

2 files changed

+81
-26
lines changed

2 files changed

+81
-26
lines changed

adafruit_emc2101.py

Lines changed: 55 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@
4949
_FAN_CONFIG = const(0x4A)
5050
_FAN_SPINUP = const(0x4B)
5151
_REG_FAN_SETTING = const(0x4C)
52+
_PWM_FREQ = const(0x4D)
53+
_PWM_DIV = const(0x4E)
5254
_LUT_HYSTERESIS = const(0x4F)
5355

5456
_TEMP_FILTER = const(0xBF)
@@ -308,7 +310,10 @@ class EMC2101: # pylint: disable=too-many-instance-attributes
308310
"""When set to True, the magnitude of the fan output signal is inverted, making 0 the maximum
309311
value and 100 the minimum value"""
310312

313+
_fan_pwm_clock_select = RWBit(_FAN_CONFIG, 3)
311314
_fan_pwm_clock_override = RWBit(_FAN_CONFIG, 2)
315+
_pwm_freq = RWBits(5, _PWM_FREQ, 0)
316+
_pwm_freq_div = UnaryStruct(_PWM_DIV, "<B")
312317

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

350355
@property
351356
def external_temperature(self):
@@ -357,7 +362,55 @@ def external_temperature(self):
357362
full_tmp >>= 5
358363
full_tmp *= 0.125
359364

360-
return full_tmp # !!! it's RAAAAAAAAARW
365+
return full_tmp
366+
367+
def set_pwm_clock(self, use_preset=False, use_slow=False):
368+
"""
369+
Select the PWM clock source, chosing between two preset clocks or by configuring the
370+
clock using `pwm_frequency` and `pwm_frequency_divisor`.
371+
372+
:param bool use_preset:
373+
True: Select between two preset clock sources
374+
False: The PWM clock is set by `pwm_frequency` and `pwm_frequency_divisor`
375+
:param bool use_slow:
376+
True: Use the 1.4kHz clock
377+
False: Use the 360kHz clock.
378+
:type priority: integer or None
379+
:return: None
380+
:raises AttributeError: if use_preset is not a `bool`
381+
:raises AttributeError: if use_slow is not a `bool`
382+
383+
"""
384+
385+
if not isinstance(use_preset, bool):
386+
raise AttributeError("use_preset must be given a bool")
387+
if not isinstance(use_slow, bool):
388+
raise AttributeError("use_slow_pwm must be given a bool")
389+
390+
self._fan_pwm_clock_override = not use_preset
391+
self._fan_pwm_clock_select = use_slow
392+
393+
@property
394+
def pwm_frequency(self):
395+
"""Selects the base clock frequency used for the fan PWM output"""
396+
return self._pwm_freq
397+
398+
@pwm_frequency.setter
399+
def pwm_frequency(self, value):
400+
if value < 0 or value > 0x1F:
401+
raise AttributeError("pwm_frequency must be from 0-31")
402+
self._pwm_freq_div = value
403+
404+
@property
405+
def pwm_frequency_divisor(self):
406+
"""The Divisor applied to the PWM frequency to set the final frequency"""
407+
return self._pwm_freq_div
408+
409+
@pwm_frequency_divisor.setter
410+
def pwm_frequency_divisor(self, divisor):
411+
if divisor < 0 or divisor > 255:
412+
raise AttributeError("pwm_frequency_divisor must be from 0-255")
413+
self._pwm_freq_div = divisor
361414

362415
@property
363416
def fan_speed(self):
@@ -398,30 +451,6 @@ def lut_enabled(self):
398451
def lut_enabled(self, enable_lut):
399452
self._fan_lut_prog = not enable_lut
400453

401-
# def get_lut(self, lut_index):
402-
# """The Look Up Table used to determine what the fan speed should be based on the measured
403-
# temperature. `lut` acts similarly to a dictionary but with restrictions:
404-
405-
# * The LUT key is a temperature in celcius
406-
# * The LUT value is the corresponding fan speed in % of maximum RPM
407-
# * The LUT can only contain 8 entries. Attempting to set a ninth will
408-
# result in an `IndexError`
409-
410-
# Example:
411-
412-
# .. code-block:: python3
413-
414-
# # If the measured external temperature goes over 20 degrees C, set the fan speed to 50%
415-
# fan_controller.lut[20] = 50
416-
417-
# # If the temperature is over 30 degrees, set the fan speed to 75%
418-
# fan_controller.lut[30] = 75
419-
# """
420-
# return self._lut.__getitem__(self, lut_index)
421-
422-
# def set_lut(self, lut_temp, lut_speed):
423-
# self._lut.__setitem__(lut_temp, lut_speed)
424-
425454
@property
426455
def lut(self):
427456
"""The dict-like representation of the LUT"""

examples/set_pwm_freq.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# SPDX-FileCopyrightText: 2020 Bryan Siepert, written for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
import time
5+
import board
6+
import busio
7+
from adafruit_emc2101 import EMC2101
8+
9+
i2c = busio.I2C(board.SCL, board.SDA)
10+
11+
emc = EMC2101(i2c)
12+
emc.set_pwm_clock(use_preset=False)
13+
# Datasheet recommends using the maximum value of 31 (0x1F)
14+
# to provide the highest effective resolution
15+
emc.pwm_frequency = 14
16+
17+
# This divides the pwm frequency down to a smaller number
18+
# so larger divisor = lower frequency
19+
emc.pwm_frequency_divisor = 127
20+
21+
while True:
22+
print("External temperature:", emc.external_temperature, "C")
23+
emc.manual_fan_speed = 50
24+
time.sleep(1.5)
25+
print("Fan speed:", emc.fan_speed, "RPM")
26+
time.sleep(1)

0 commit comments

Comments
 (0)