EMC2101 + TCA9548A I2C Excitement

General project help for Adafruit customers

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
mven
 
Posts: 11
Joined: Tue Jun 21, 2022 12:02 am

EMC2101 + TCA9548A I2C Excitement

Post by mven »

I am having an issue with reading the RPM setting from some Noctua NF-A20 fans. The fans have a max RPM of around 800 and a min of around 350. They should in theory stop moving below 20% PWM duty cycle. This info from:

https://noctua.at/en/nf-a20-pwm-chromax ... cification

If I set the fan speed to 100% vs 25% there is definitely a noticeable difference in how fast the fans spin. I can also change the speeds on them independently. Reading temperatures from internal both and external (2N3904 NPN transistor) seems to work as well. I can touch the transistors or the chip on the breakout and see the temps rise.

However when I read the fan speeds I get numbers that don't match up with the expected speed. See here:

Code: Select all

 
Setting fan 1 speed to 0%
Setting fan 2 speed to 0%
Fan 1 speed 382.35502372017277
Fan 2 speed 411.4912748609312
Setting fan 1 speed to 15%
Setting fan 2 speed to 15%
Fan 1 speed 425.63253724284704
Fan 2 speed 450.63840440624216
Setting fan 1 speed to 25%
Setting fan 2 speed to 25%
Fan 1 speed 234782.60869565216
Fan 2 speed 15041.782729805014
Setting fan 1 speed to 100%
Setting fan 2 speed to 100%
Fan 1 speed 82.39871824216068
Fan 2 speed 82.39871824216068

Setting fan 1 speed to 0%
Setting fan 2 speed to 0%
Fan 1 speed 412.37113402061857
Fan 2 speed 430.24460202374314
Setting fan 1 speed to 15%
Setting fan 2 speed to 15%
Fan 1 speed 425.49838468205814
Fan 2 speed 447.0568755691696
Setting fan 1 speed to 25%
Setting fan 2 speed to 25%
Fan 1 speed 12529.002320185615
Fan 2 speed 234782.60869565216
Setting fan 1 speed to 100%
Setting fan 2 speed to 100%
Fan 1 speed 82.39871824216068
Fan 2 speed 82.39871824216068

Setting fan 1 speed to 0%
Setting fan 2 speed to 0%
Fan 1 speed 397.6728772369099
Fan 2 speed 428.6054448765775
Setting fan 1 speed to 15%
Setting fan 2 speed to 15%
Fan 1 speed 425.3643166601024
Fan 2 speed 458.1318401628913
Setting fan 1 speed to 25%
Setting fan 2 speed to 25%
Fan 1 speed 234782.60869565216
Fan 2 speed 234782.60869565216
Setting fan 1 speed to 100%
Setting fan 2 speed to 100%
Fan 1 speed 82.39871824216068
Fan 2 speed 82.39871824216068

Setting fan 1 speed to 0%
Setting fan 2 speed to 0%
Fan 1 speed 403.85909804801435
Fan 2 speed 428.6054448765775
Setting fan 1 speed to 15%
Setting fan 2 speed to 15%
Fan 1 speed 426.03550295857985
Fan 2 speed 450.18757815756567
Setting fan 1 speed to 25%
Setting fan 2 speed to 25%
Fan 1 speed 234782.60869565216
Fan 2 speed 234782.60869565216
Setting fan 1 speed to 100%
Setting fan 2 speed to 100%
Fan 1 speed 82.39871824216068
Fan 2 speed 82.39871824216068
I saw in this post: viewtopic.php?f=8&t=188722 someone was having a similar issue, it looks like they resolved communicating over I2C but it wasn't clear if they also somehow solved the RPM readings.

As far as I can tell I don't have any issues communicating over I2C and everything seems to work other than the RPM settings and that I cannot stop the fans from spinning by setting the speed to 0%. Here is the simple code I am using to test:

Code: Select all

import time
import board
import adafruit_tca9548a
from adafruit_emc2101.emc2101_lut import EMC2101_LUT as EMC2101

i2c = board.I2C()

tca = adafruit_tca9548a.TCA9548A(i2c)

emc1 = EMC2101(tca[2])
emc2 = EMC2101(tca[6])

while True:

    print("Setting fan 1 speed to 0%")
    emc1.manual_fan_speed = 0
    print("Setting fan 2 speed to 0%")
    emc2.manual_fan_speed = 0

    time.sleep(10)
    print("Fan 1 speed", emc1.fan_speed)
    print("Fan 2 speed", emc2.fan_speed)

    print("Setting fan 1 speed to 15%")
    emc1.manual_fan_speed = 15
    print("Setting fan 2 speed to 15%")
    emc2.manual_fan_speed = 15

    time.sleep(10)
    print("Fan 1 speed", emc1.fan_speed)
    print("Fan 2 speed", emc2.fan_speed)

    print("Setting fan 1 speed to 25%")
    emc1.manual_fan_speed = 25
    print("Setting fan 2 speed to 25%")
    emc2.manual_fan_speed = 25

    time.sleep(10)
    print("Fan 1 speed", emc1.fan_speed)
    print("Fan 2 speed", emc2.fan_speed)

    print("Setting fan 1 speed to 100%")
    emc1.manual_fan_speed = 100
    print("Setting fan 2 speed to 100%")
    emc2.manual_fan_speed = 100

    time.sleep(10)
    print("Fan 1 speed", emc1.fan_speed)
    print("Fan 2 speed", emc2.fan_speed)
    print("")
Any help would be greatly appreciated!

User avatar
adafruit_support_carter
 
Posts: 29168
Joined: Tue Nov 29, 2016 2:45 pm

Re: EMC2101 + TCA9548A I2C Excitement

Post by adafruit_support_carter »

Are you seeing a similar behavior without the TCA in the mix?

User avatar
mven
 
Posts: 11
Joined: Tue Jun 21, 2022 12:02 am

Re: EMC2101 + TCA9548A I2C Excitement

Post by mven »

Thanks for the response. Here is the output with the same settings using just one EMC2101 and no TCA:

Code: Select all

Setting fan speed to 0%
Fan speed 509.67437470504956
Setting fan speed to 15%
Fan speed 506.8043172219615
Setting fan speed to 25%
Fan speed 234782.60869565216
Setting fan speed to 100%
Fan speed 82.39871824216068

Setting fan speed to 0%
Fan speed 531.9672938626736
Setting fan speed to 15%
Fan speed 494.55078303873984
Setting fan speed to 25%
Fan speed 234782.60869565216
Setting fan speed to 100%
Fan speed 82.39871824216068

Setting fan speed to 0%
Fan speed 506.2341801818693
Setting fan speed to 15%
Fan speed 499.67613583788284
Setting fan speed to 25%
Fan speed 234782.60869565216
Setting fan speed to 100%
Fan speed 82.39871824216068
Here is the simple code used to test for just the single EMC:

Code: Select all

import time
import board
from adafruit_emc2101.emc2101_lut import EMC2101_LUT as EMC2101

i2c = board.I2C()

emc = EMC2101(i2c)

while True:
    print("Setting fan speed to 0%")
    emc.manual_fan_speed = 0

    time.sleep(10)
    print("Fan speed", emc.fan_speed)

    print("Setting fan speed to 15%")
    emc.manual_fan_speed = 15

    time.sleep(10)
    print("Fan speed", emc.fan_speed)

    print("Setting fan speed to 25%")
    emc.manual_fan_speed = 25

    time.sleep(10)
    print("Fan speed", emc.fan_speed)

    print("Setting fan speed to 100%")
    emc.manual_fan_speed = 100

    time.sleep(10)
    print("Fan speed", emc.fan_speed)
    print("")
It seems like the results are pretty similar with or without the TCA.

User avatar
adafruit_support_carter
 
Posts: 29168
Joined: Tue Nov 29, 2016 2:45 pm

Re: EMC2101 + TCA9548A I2C Excitement

Post by adafruit_support_carter »

Is the fan still spinning when you set manual_fan_speed=0? Or does the fun stop spinning but fan_speed still reports a non-zero value?

User avatar
mven
 
Posts: 11
Joined: Tue Jun 21, 2022 12:02 am

Re: EMC2101 + TCA9548A I2C Excitement

Post by mven »

It spins no matter what the setting is, though if you look at the fan specs page it seems like it should stop with a PWM duty cycle below 20%.

It definitely spins faster at 100% than it does at 0% though. You can hear it spin at 100% to hear it at 0% you have have your ear inches away.

User avatar
mven
 
Posts: 11
Joined: Tue Jun 21, 2022 12:02 am

Re: EMC2101 + TCA9548A I2C Excitement

Post by mven »

Still haven't figured this one out. Thinking I may try a different power supply, or maybe buy an arduino or something and try that instead of the RasPi or maybe try a different 12v PSU.

I may just try messing with the LUTs to get the behavior I want and ignore the RPM setting. I was hoping to print the RPM on the screen with the temperature for each EMC2101 but I guess it's not essential that I do so.

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: EMC2101 + TCA9548A I2C Excitement

Post by adafruit_support_bill »

See the white paper from Noctua here. Looks like the NF-A20 does not go below 20%:

https://noctua.at/pub/media/wysiwyg/Noc ... _paper.pdf
Operation below 20% PWM duty-cycle is not officially supported in the Intel specification
(undefined behaviour). However, most Noctua PWM fans can be operated at below 20%
and will stop at 0% duty-cycle. Only the following models keep running at their specified
minimum speed when the input is below 20%: NF-A20 PWM, NF-S12B redux 1200 PWM
and NF-B9 redux 1600 PWM

User avatar
mven
 
Posts: 11
Joined: Tue Jun 21, 2022 12:02 am

Re: EMC2101 + TCA9548A I2C Excitement

Post by mven »

adafruit_support_bill wrote:See the white paper from Noctua here. Looks like the NF-A20 does not go below 20%:

https://noctua.at/pub/media/wysiwyg/Noc ... _paper.pdf
Operation below 20% PWM duty-cycle is not officially supported in the Intel specification
(undefined behaviour). However, most Noctua PWM fans can be operated at below 20%
and will stop at 0% duty-cycle. Only the following models keep running at their specified
minimum speed when the input is below 20%: NF-A20 PWM, NF-S12B redux 1200 PWM
and NF-B9 redux 1600 PWM
Good find. Makes sense from the behavior I was seeing. I think for my application it doesn't really matter that much if they never stop as they are pretty low power anyway and very quiet. If I decide I need to stop them I might throw in some small relays or something.

Now if I can just figure out the RPM excitement and some fun display issues (a different thread) I'll be ready to build this lol.

User avatar
adafruit_support_carter
 
Posts: 29168
Joined: Tue Nov 29, 2016 2:45 pm

Re: EMC2101 + TCA9548A I2C Excitement

Post by adafruit_support_carter »

That behavior is new to me too. Sort of weird and unexpected. There are probably Reasons(c) why they do that, but potentially confusing. Added some information about this behavior to the guide here:
https://learn.adafruit.com/emc2101-fan- ... 3079895-13

User avatar
mven
 
Posts: 11
Joined: Tue Jun 21, 2022 12:02 am

Re: EMC2101 + TCA9548A I2C Excitement

Post by mven »

So I finally got around to digging out an Uno and testing with that. Weirdly it seems to measure the RPM just fine all else the same:

modified example code:

Code: Select all

// Basic demo for readings from Adafruit EMC2101
#include <Adafruit_EMC2101.h>

Adafruit_EMC2101  emc2101;

void setup(void) {
  Serial.begin(115200);
  while (!Serial) delay(10);     // will pause Zero, Leonardo, etc until serial console opens

  Serial.println("Adafruit EMC2101 test!");

  // Try to initialize!
  if (!emc2101.begin()) {
    Serial.println("Failed to find EMC2101 chip");
    while (1) { delay(10); }
  }
  Serial.println("EMC2101 Found!");

  //  emc2101.setDataRate(EMC2101_RATE_1_16_HZ);
  Serial.print("Data rate set to: ");
  switch (emc2101.getDataRate()) {
    case EMC2101_RATE_1_16_HZ: Serial.println("1/16_HZ"); break;
    case EMC2101_RATE_1_8_HZ: Serial.println("1/8_HZ"); break;
    case EMC2101_RATE_1_4_HZ: Serial.println("1/4_HZ"); break;
    case EMC2101_RATE_1_2_HZ: Serial.println("1/2_HZ"); break;
    case EMC2101_RATE_1_HZ: Serial.println("1 HZ"); break;
    case EMC2101_RATE_2_HZ: Serial.println("2 HZ"); break;
    case EMC2101_RATE_4_HZ: Serial.println("4 HZ"); break;
    case EMC2101_RATE_8_HZ: Serial.println("8 HZ"); break;
    case EMC2101_RATE_16_HZ: Serial.println("16 HZ"); break;
    case EMC2101_RATE_32_HZ: Serial.println("32 HZ"); break;
  }

  emc2101.enableTachInput(true);
  emc2101.setPWMDivisor(0);
  emc2101.setDutyCycle(20);
}



void loop() {
  Serial.print("External Temperature: ");
  Serial.print(emc2101.getExternalTemperature());
  Serial.println(" degrees C");

  Serial.print("Internal Temperature: ");
  Serial.print(emc2101.getInternalTemperature());
  Serial.println(" degrees C");
  delay(1000);
  emc2101.setDutyCycle(0);
  delay(10000);
  Serial.print("Duty Cycle: ");
  Serial.print(emc2101.getDutyCycle());
  Serial.print("% / Fan RPM: ");
  Serial.print(emc2101.getFanRPM());
  Serial.println(" RPM");
  Serial.println("");
  delay(1000);
  emc2101.setDutyCycle(20);
  delay(10000);
  Serial.print("Duty Cycle: ");
  Serial.print(emc2101.getDutyCycle());
  Serial.print("% / Fan RPM: ");
  Serial.print(emc2101.getFanRPM());
  Serial.println(" RPM");
  Serial.println("");
  delay(1000);
  emc2101.setDutyCycle(50);
  delay(10000);
  Serial.print("Duty Cycle: ");
  Serial.print(emc2101.getDutyCycle());
  Serial.print("% / Fan RPM: ");
  Serial.print(emc2101.getFanRPM());
  Serial.println(" RPM");
  Serial.println("");
  delay(1000);
  emc2101.setDutyCycle(75);
  delay(10000);
  Serial.print("Duty Cycle: ");
  Serial.print(emc2101.getDutyCycle());
  Serial.print("% / Fan RPM: ");
  Serial.print(emc2101.getFanRPM());
  Serial.println(" RPM");
  Serial.println("");
  delay(1000);
  emc2101.setDutyCycle(100);
  delay(10000);
  Serial.print("Duty Cycle: ");
  Serial.print(emc2101.getDutyCycle());
  Serial.print("% / Fan RPM: ");
  Serial.print(emc2101.getFanRPM());
  Serial.println(" RPM");
  Serial.println("");
}
output:

Code: Select all

Adafruit EMC2101 test!
EMC2101 Found!
Data rate set to: 32 HZ
External Temperature: 21.62 degrees C
Internal Temperature: 23 degrees C
Duty Cycle: 0% / Fan RPM: 401 RPM

Duty Cycle: 19% / Fan RPM: 393 RPM

Duty Cycle: 49% / Fan RPM: 410 RPM

Duty Cycle: 74% / Fan RPM: 677 RPM

Duty Cycle: 100% / Fan RPM: 903 RPM

External Temperature: 21.75 degrees C
Internal Temperature: 23 degrees C
Duty Cycle: 0% / Fan RPM: 419 RPM

Duty Cycle: 19% / Fan RPM: 393 RPM

Duty Cycle: 49% / Fan RPM: 404 RPM

Duty Cycle: 74% / Fan RPM: 679 RPM

Duty Cycle: 100% / Fan RPM: 902 RPM
Seems to be much closer to the expected behavior (assuming about 50% duty cycle is about as slow as it will spin).

I wonder if there is some difference in the Arduino library vs the CircuitPython version that doesn't play nice with these fans. I used the same Fan/EMC2101/12V PSU, just swapped the SCL/SDA/5V/GND pins connections from the Pi to the Uno.

I may see if I have a Pi 3 laying around to try instead of the 4.

User avatar
mven
 
Posts: 11
Joined: Tue Jun 21, 2022 12:02 am

Re: EMC2101 + TCA9548A I2C Excitement

Post by mven »

Well now I feel dumb. When reconnecting the Pi to the breadboard I discovered the wire between the two GND rails was not making a good connection. Replaced it with a different wire and now the readings seem to be correct. Going to reconnect the TCA9548A and see if everything plays nice together.

User avatar
mven
 
Posts: 11
Joined: Tue Jun 21, 2022 12:02 am

Re: EMC2101 + TCA9548A I2C Excitement

Post by mven »

That seems to have been the issue!

output with 2 EMC2101s on TCA9548A:

Code: Select all

Setting fan 1 speed to 0%
Setting fan 2 speed to 0%
Fan 1 speed: 388
Fan 2 speed: 410
Setting fan 1 speed to 20%
Setting fan 2 speed to 20%
Fan 1 speed: 432
Fan 2 speed: 458
Setting fan 1 speed to 50%
Setting fan 2 speed to 50%
Fan 1 speed: 456
Fan 2 speed: 491
Setting fan 1 speed to 75%
Setting fan 2 speed to 75%
Fan 1 speed: 675
Fan 2 speed: 693
Setting fan 1 speed to 100%
Setting fan 2 speed to 100%
Fan 1 speed: 890
Fan 2 speed: 909

Setting fan 1 speed to 0%
Setting fan 2 speed to 0%
Fan 1 speed: 408
Fan 2 speed: 427
Setting fan 1 speed to 20%
Setting fan 2 speed to 20%
Fan 1 speed: 437
Fan 2 speed: 458
Setting fan 1 speed to 50%
Setting fan 2 speed to 50%
Fan 1 speed: 476
Fan 2 speed: 492
Setting fan 1 speed to 75%
Setting fan 2 speed to 75%
Fan 1 speed: 686
Fan 2 speed: 699
Setting fan 1 speed to 100%
Setting fan 2 speed to 100%
Fan 1 speed: 894
Fan 2 speed: 904
Thanks for all the help. Figures it would be something small.

Locked
Please be positive and constructive with your questions and comments.

Return to “General Project help”