adafruit_emc2101
Brushless fan controller
Author(s): Bryan Siepert
Implementation Notes
Hardware:
Adafruit EMC2101 Breakout (Product ID: 4808)
Software and Dependencies:
Adafruit CircuitPython firmware for the supported boards: https://circuitpython.org/downloads
Adafruit’s Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice
Adafruit’s Register library: https://github.com/adafruit/Adafruit_CircuitPython_Register
- class adafruit_emc2101.EMC2101(i2c_bus)
Basic driver for the EMC2101 Fan Controller.
- Parameters:
i2c_bus (I2C) – The I2C bus the EMC is connected to.
See
adafruit_emc2101.EMC2101_EXT
for (almost) complete device register set. Seeadafruit_emc2101.EMC2101_LUT
for the temperature look up table functionality.Quickstart: Importing and using the device
Here is an example of using the
EMC2101
class. First you will need to import the libraries to use the sensorimport board from adafruit_emc2101.emc2101_lut import EMC2101_LUT as EMC2101
Once this is done you can define your
board.I2C
object and define your sensor objecti2c = board.I2C() # uses board.SCL and board.SDA emc = EMC2101(i2c)
Now you have access to the
manual_fan_speed
attribute to setup the desired fanspeedemc.manual_fan_speed = 25
If you need control over PWM frequency and the controller’s built in temperature/speed look-up table (LUT), you will need
emc2101_lut.EMC2101_LUT
which extends this class to add those features, at the cost of increased memory usage.Datasheet: https://ww1.microchip.com/downloads/en/DeviceDoc/2101.pdf
- property conversion_rate
The rate at which temperature measurements are taken.
- Return int:
corresponding to the ConversionRate enumeration.
- property dac_output_enabled
When set, the fan control signal is output as a DC voltage instead of a PWM signal.
- property devconfig
Read the main device config register. See the CONFIG_* bit definitions in the emc2101_regs module, or refer to the datasheet for more detail. Note: this is not the Fan Config register!
- property devstatus
Read device status (alerts) register. See the STATUS_* bit definitions in the emc2101_regs module, or refer to the datasheet for more detail.
- property external_temperature
The temperature measured using the external diode. The value is read as a fixed-point 11-bit value ranging from -64 to approx 126, with fractional part of 1/8 degree.
- Returns:
float temperature in degrees centigrade.
- Raises:
RuntimeError – if the sensor pind (DP,DN) are open circuit (the sensor is disconnected).
RuntimeError – if the external temp sensor is a short circuit (not behaving like a diode).
- property fan_speed
The current speed in Revolutions per Minute (RPM).
- Returns:
float fan speed rounded to 2dp.
- forced_ext_temp
The value that the external temperature will be forced to read when
forced_temp_enabled
is set. This can be used to test the behavior of the LUT without real temperature changes. Force Temp is 7-bit + sign (one’s complement?).
- forced_temp_enabled
When True, the external temperature measurement will always be read as the value in
forced_ext_temp
. Not applicable if LUT disabled.
- initialize()
Reset the controller to an initial default configuration
- property internal_temperature
The temperature as measured by the EMC2101’s internal 8-bit temperature sensor, which validly ranges from 0 to 85 and does not support fractions (unlike the external readings).
- Returns:
int temperature in degrees centigrade.
- invert_fan_output
When set to True, the magnitude of the fan output signal is inverted, making 0 the maximum value and 100 the minimum value
- property lut_enabled
Enable or disable the internal look up table used to map a given temperature to a fan speed.
When the LUT is disabled (the default), fan speed can be changed with
manual_fan_speed
. To actually set this to True and modify the LUT, you need to use the extended version of this driver,emc2101_lut.EMC2101_LUT
.
- property manual_fan_speed
The fan speed used while the LUT is being updated and is unavailable. The speed is given as the fan’s PWM duty cycle represented as a float percentage. The value roughly approximates the percentage of the fan’s maximum speed.
- property part_info
manufacturer, part id and revision. Normally returns (0x5d, 0x16, 0x1).
- Type:
The part information
- property spinup_drive
The drive strength of the fan on spinup in % max PWM duty cycle (which approximates to max fan speed).
- Return int:
corresponding to the SpinupDrive enumeration.
- property spinup_time
The amount of time the fan will spin at the currently set drive strength.
- Return int:
corresponding to the SpinupTime enumeration.
adafruit_emc2101.emc2101_regs
Brushless fan controller EMC2101 Register addresses.
Register offset definitions for the SMC EMC2101 fan controller.
Author(s): Bryan Siepert, Ruth Ivimey-Cook
Implementation Notes
Hardware:
Adafruit EMC2101 Breakout (Product ID: 4808)
Software and Dependencies:
Adafruit CircuitPython firmware for the supported boards: https://circuitpython.org/downloads
Adafruit’s Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice
Adafruit’s Register library: https://github.com/adafruit/Adafruit_CircuitPython_Register
adafruit_emc2101.emc2101_lut
Brushless fan controller: extended functionality
Author(s): Bryan Siepert, Ryan Pavlik
Implementation Notes
Hardware:
Adafruit EMC2101 Breakout (Product ID: 4808)
Software and Dependencies:
Adafruit CircuitPython firmware for the supported boards: https://circuitpython.org/downloads
Adafruit’s Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice
Adafruit’s Register library: https://github.com/adafruit/Adafruit_CircuitPython_Register
The class defined here may be used instead of adafruit_emc2101.EMC2101
,
if your device has enough RAM to support it. This class adds LUT control
and PWM frequency control to the base feature set.
- class adafruit_emc2101.emc2101_lut.EMC2101_LUT(i2c_bus)
Driver for the EMC2101 Fan Controller, with PWM frequency and temperature look-up-table (LUT) control.
See
adafruit_emc2101.EMC2101
for the base/common functionality. Seeadafruit_emc2101.EMC2101_EXT
for (almost) complete device register set but no temperature look-up-table LUT support.- Parameters:
i2c_bus (I2C) – The I2C bus the EMC is connected to.
- initialize()
Reset the controller to an initial default configuration.
- Raises:
RuntimeError – if auto_check_status and an alert status bit is set
- property lut
The dict-like representation of the LUT, an instance of
FanSpeedLUT
. Use this to update or read the current LUT.You can use python ‘with’ on this class to perform a multiple update of the LUT. Usage:
with emc2101.lut as lut: lut[20] = 0 lut[40] = 10
The device only supports 8 entries in the LUT. If you try to add more than this the update will fail with a ValueError. If the add is part of a ‘with’ block, this happens when the block ends.
To delete an entry from the current table, assign None to the current temperature slot(s).
with emc2101.lut as lut: lut[20] = 0 lut[40] = 10 emc2101.lut[20] = None print(emc2101.lut.lookup_table)
will print one item, for temp 40, speed 10%.
- property lut_enabled
Enable or disable the internal look up table used to map a given temperature to a fan speed. When the LUT is disabled fan speed can be changed with
manual_fan_speed
. :return enable_lut
- lut_temperature_hysteresis
The amount of hysteresis, in degrees centigrade, of hysteresis applied to temperature readings used for the LUT. As the temperature drops, the controller will switch to a lower LUT entry when the measured value is below the lower entry’s threshold, minus the hysteresis value.
- property pwm_frequency
Selects the base clock frequency used for the fan PWM output
- property pwm_frequency_divisor
The Divisor applied to the PWM frequency to set the final frequency.
- Raises:
RuntimeError – if auto_check_status and an alert status bit is set
- set_pwm_clock(use_preset=False, use_slow=False)
Select the PWM clock source, choosing between two preset clocks or by configuring the clock with
pwm_frequency
andpwm_frequency_divisor
.- Parameters:
use_preset (bool) – True: Select between two preset clock sources False: The PWM clock is set by
pwm_frequency
andpwm_frequency_divisor
use_slow (bool) – True: Use the 1.4kHz clock False: Use the 360kHz clock.
- Returns:
None
- Raises:
RuntimeError – if auto_check_status and an alert status bit is set
adafruit_emc2101.emc2101_fanspeed
Brushless fan controller: extended functionality
Author(s): Bryan Siepert, Ryan Pavlik
Implementation Notes
Hardware:
Adafruit EMC2101 Breakout (Product ID: 4808)
Software and Dependencies:
Adafruit CircuitPython firmware for the supported boards: https://circuitpython.org/downloads
Adafruit’s Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice
Adafruit’s Register library: https://github.com/adafruit/Adafruit_CircuitPython_Register
- class adafruit_emc2101.emc2101_fanspeed.FanSpeedLUT(fan_obj)
A class used to provide a dict-like interface to the EMC2101’s Temperature to Fan speed Look Up Table (LUT).
Keys are integer temperatures, values are fan duty cycles between 0 and 100. A max of 8 values may be stored.
To remove a single stored point in the LUT, assign it as
None
.Usage: At 50 C the speed should be 62% of max duty cycle. (Updates the chip immediately).
emc2101.lut[50] = 62
Set two values up and write to the chip on exit from ‘with’ block.
with emc2101.lut as lut: lut[20] = 0 lut[40] = 10
Delete an unneeded temperature point: (Updates the chip immediately).
emc2101.lut[20] = None
Read a dict of the currently set values:
values = emc2101.lut.lookup_table # returns: # { 40: 10, 50: 62 }
Delete some LUT values, assign None:
for temp in emc2101.lut.lookup_table: emc2101.lut[temp] = None
Delete all LUT values at once:
emc2101.lut.clear()
- clear()
Clear all LUT entries.
- property lookup_table
Return a dictionary of LUT values.
adafruit_emc2101.emc2101_ext
Brushless fan controller: extended functionality
Author(s): Bryan Siepert, Ryan Pavlik
Implementation Notes
Hardware:
Adafruit EMC2101 Breakout (Product ID: 4808)
Software and Dependencies:
Adafruit CircuitPython firmware for the supported boards: https://circuitpython.org/downloads
Adafruit’s Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice
Adafruit’s Register library: https://github.com/adafruit/Adafruit_CircuitPython_Register
The class defined here may be used instead of adafruit_emc2101.EMC2101
,
if your device has enough RAM to support it. This class adds LUT control
and PWM frequency control to the base feature set.
- class adafruit_emc2101.emc2101_ext.EMC2101_EXT(i2c_bus)
Driver for EMC2101 Fan, adding definitions for all (but LUT) device registers.
See
adafruit_emc2101.EMC2101
for the base/common functionality. Seeadafruit_emc2101.EMC2101_LUT
for the temperature look up table functionality.- Parameters:
i2c_bus (I2C) – The I2C bus the EMC is connected to.
- auto_check_status = False
Enable checking status register before many operations. Slows other uses down but useful to catch limit or overtemp alerts. checks can also be made by calling check_status(). Default: ON
- check_status()
Read the status register and check for a fault indicated. If one of the bits in STATUS_ALERT indicates an alert, raise an exception.
Note: The action of reading the status register also clears any outstanding alert reports, so a second read will return 0 unless the condition causing the alert persists.
- Raises:
RuntimeError – if auto_check_status and an alert status bit is set
- property dev_temp_critical_hysteresis
The critical temperature hysteresis for the device (measured by the internal sensor), in degrees centigrade.
Hysteresis is a lag in fan switching activity added to prevent too-rapid switching. It results in the temperature needing to fall to a lower temperature before the fan switches off than the higher temperature that caused the fan to switch on. The value here is the number of degrees centigrade of this difference. The device does not to support setting this value to 0.
- Parameters:
temp (float) – the new limit temperature
- Raises:
ValueError – if the supplied temperature is out of range.
- property dev_temp_critical_limit
The critical temperature limit for the device (measured by internal sensor), in degrees centigrade.
Note: this value can only be written one time during any power-up sequence. To re-write it you must power cycle the chip. In order to write the limit, the tcrit override bit must first be set in the config register.
- Returns:
int the device internal critical limit temperature.
- Raises:
RuntimeError – if auto_check_status and an alert status bit is set
- property dev_temp_high_limit
The high limit temperature for the internal sensor, in degrees centigrade.
- property devstatus
Read device status (alerts) register. See the STATUS_* bit definitions in the emc2101_regs module, or refer to the datasheet for more detail.
Note: The action of reading the status register also clears any outstanding alert reports, so a second read will return 0 unless the condition causing the alert persists.
- property external_temp_high_limit
The high limit temperature for the external sensor.
- property external_temp_low_limit
The low limit temperature for the external sensor.
- property external_temperature
The temperature measured using the external diode. The value is read as a fixed-point 11-bit value ranging from -64 C to just over approx 126 C, with fractional part of 1/8 degree centigrade.
- Returns:
Float temperature in degrees centigrade.
- Raises:
RuntimeError – if auto_check_status and an alert status bit is set.
RuntimeError – if the sensor pind (DP,DN) are open circuit (the sensor is disconnected).
RuntimeError – if the external temp sensor is a short circuit (not behaving like a diode).
- property fan_speed
The current speed in Revolutions per Minute (RPM).
- Returns:
float speed in RPM.
- initialize()
Reset the controller to an initial default configuration.
- property internal_temperature
The temperature as measured by the EMC2101’s internal 8-bit temperature sensor.
- Returns:
int temperature in degrees centigrade.
- property last_status
Read the saved copy of the device status register. This is kept because the action of reading the status register also clears any outstanding alert reports, so a second read will return 0 unless the condition causing the alert persists.
This method is mainly of use after a check_status call.
- Returns:
int the 8-bit device status register as last read, or 0
adafruit_emc2101.emc2101_enums
Brushless fan controller
Author(s): Bryan Siepert
Implementation Notes
Hardware:
Adafruit EMC2101 Breakout (Product ID: 4808)
Software and Dependencies:
Adafruit CircuitPython firmware for the supported boards: https://circuitpython.org/downloads
Adafruit’s Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice
Adafruit’s Register library: https://github.com/adafruit/Adafruit_CircuitPython_Register
- class adafruit_emc2101.emc2101_enums.CV
struct helper
- classmethod add_values(value_tuples)
Creates CV entries
- classmethod is_valid(value)
Returns true if the given value is a member of the CV
- class adafruit_emc2101.emc2101_enums.ConversionRate
Options for
conversion_rate
- class adafruit_emc2101.emc2101_enums.SpinupDrive
Options for
spinup_drive
- class adafruit_emc2101.emc2101_enums.SpinupTime
Options for
spinup_time