TPFanCtrl2 icon indicating copy to clipboard operation
TPFanCtrl2 copied to clipboard

Fans still spinning at low rpms after achiving Level 0

Open array3 opened this issue 2 years ago • 5 comments

Hi. Every 5-30 changes between Level 1 -> Level 0 fans are still spining, they should be turned off. UI shows 0rpm on both fans, but I can still hear them. Changing mode from Smart to Bios and than to Smart resolve the issue. My current Smart mode levels: Level=64 0 Level=65 1 Level=72 2 Level=76 3 Level=80 64

My laptop: Lenovo P52 Bios version 1.51 Windows 11 TPFanCtrl2 version V2.1.5

Edit: But sometimes there is over 0rpm in UI and the log shows that Level 0 was triggered but nothing happened

tpfcd

array3 avatar Dec 07 '23 14:12 array3

Hmm I honestly don't know why that might be happening. From the picture it seems like the fan is slowly wining down from level 1 to level 0, and it takes a very long time to do that, maybe increasing the temp level would help? Also maybe try decreasing the cycle time so it refreshes more.

Shuzhengz avatar Dec 18 '23 22:12 Shuzhengz

Hi. I've tried various configurations of Mode levels (increasing, decreasing temps) but it doesn't work. Also it may not apply only to this particular change from level 1 to level 0 but to all levels (what is harder to notice refering to more dynamics in temps and high fan rpms).

I think the problem may refer to:

  • bad readings of current rpm status
  • command is not applied and stuck on the previous level

The speeds on the picture refer to that set on the manual level 1, so they doesn't spinning down but are stuck on the lowest spinning level 1. My Cycle temperature check is already lowered from 5 to 1 second. Will try to increase cycle time to default 5 seconds and see if it helps.

Thank you for response.

array3 avatar Dec 19 '23 08:12 array3

Hi, I think that it is unlikely to be bad reading of current rpm, but it is very likely that the write command to EC conflicts in other operations to the EC and therefore is not applied. There was a problem where the program was unable to read before, and the solution I added was to spam the command many times in hope that one of them goes through (see this commit for read and this one for write). I could try to do more of that, but it will increase the load on the CPU.

Also, when the issue happens, does setting speed to 0 make the fan eventually go to level 0 after a long time or is there no change? Is there any error messages after a long time of waiting?

Shuzhengz avatar Dec 28 '23 23:12 Shuzhengz

Hi. I previously said to check if changing Cycle in settings file would resolve the problem, but no. Maybe there are some differences with the time when it appears but nothing significant. I have checked Cycyle between 1-7. Answearing the bottom questions, the rpm's never go to level 0 regarding 10 minutes or even 2 hours, they stay at the same level (~1900) and there are no messages about any error.

I have looked at the code but am not a C++ guy ;) In general the program executes ok, but there is only the problem with going down from level 1 to level 0. In fanstuff.cpp function FANCONTROL::SmartControl there is a code for checking if fan level has changed.

// fan speed needs change?

if (newfanctrl != -1 && newfanctrl != this->State.FanCtrl) {
	//if (newfanctrl==0x80) { // switch to BIOS-auto mode
	//	//this->ModeToDialog(1); // bios
	//}
	ok = this->SetFan("Smart", newfanctrl);
}

But even when the issue appears and the level is set to level 0 the rpm is still 1900+ (in most cases). If we could check level and time of fans spinning, than we could manage execute command once again. I thought about something like below:

// fan speed needs change?

// global var LEVEL_0_time = 0 - count the total time when level 0 persist with the fans running
if(fanctrl == 0 && this->fanspeed > 0 && LEVEL_0_time == 0)
	LEVEL_0_time = GetTickCount();
else if(fanctrl > 0 || this->fanspeed == 0)
	LEVEL_0_time = 0;
 
// time to spin down the fans from 1900rpm to 0 rpm take about 15 seconds

if ((newfanctrl != -1 && newfanctrl != this->State.FanCtrl) || (LEVEL_0_time > 0 && GetTickCount()-LEVEL_0_time >= 15000)) {
	//if (newfanctrl==0x80) { // switch to BIOS-auto mode
	//	//this->ModeToDialog(1); // bios
	//}
	ok = this->SetFan("Smart", newfanctrl);
}

array3 avatar Dec 29 '23 12:12 array3