BMC的风扇控制算一个蛮重要的功能,那这个功能包含了"TACH"和"PWM"这两个常用讯号怎么解读,还有最常用的控制演算法"PID(closed loop)"和"Stepwise(openloop)",而Error control ,因为每家做法不同,就不会在这边作介绍

##实作代码是来自Facebook的openBMC

Why and how to do fan speed control ?

在服务器中的风扇是非常高速也耗电的,根据统计在数据中心的运维成本上,电费占了7成,并且如果让风扇长期处在全转状态也会有噪音和耗损度的问题。

目前CPU可以达到单一耗电量200W以上,伴随而来的高热也会使个晶片老化速度加快,当然服務器中的SSD, NIC card, E1.S等装置也是有同样的情况,因此我们希望能根据这些高热的元件温度来决定风扇的转速,达到省电和正常运作的效果

风扇控制的做法如下:

  1. Thermal team(热流部门) 通常会提供一个fan table,里面会详细描述风扇要怎么转
  2. BMC (controller) 会透过PWM讯号去设定风扇转速
  3. 风扇也能透过TACH讯号来回传目前的转速

PWM(Pulse-Width Modulation)

PWM是透过平均电压来传递类比讯号,简单来说就是在一个cycle中,高电为占百分之多少,就表示他要传递的值是多少

例如在一个周期中,如果高电位占25%,低电位占75%,这样表示我们要传递的值是25%,风扇就会转25%

那如果今天我们都一直是high (高电位),这样风扇就会全转,因此在线路图的review过程中,都会注意PWM有没有pull high,避免在BMC更新过程或是死掉后,机器过热

那每个周期的时间是多少呢?  PWM的传递频率会定义在风扇的spec中,每一颗风扇的接收频率有可能会不一样

TACH (Tachometer)

我们可以透过Tach来传递风扇的转速,有修过机械方面的课程就会知道,马达会有n个机械原点,传一圈的话会产生n个pulse,一圈会产生几个pulse也是定义在风扇的spec中

假如今天风扇转一圈会产生两个pulse,我们在一秒内收到1000个pulse,这样表示风扇一秒转了500圈,风扇转速是用rpm(一分钟转几圈)表示的,因此500*60 rpm就是我们要求的值

TACH的讯号大概就长得像底下这样,只要统计一秒钟有几个讯号,就能得到风扇的转速

Picture provided by: http://www.angelfire.com/super/ghettoretta/m90/windowswitch.htm

System Control

在传统控制(Classical Control )理论中,通常会用有没有feedback 来区分open loop control 和 closed loop control,前者通常就是我们常说的stepwise,后者就是工业控制中广泛使用的PID control,他们的示意图如下,接下来会分别介绍这两个算法的的内容

Open loop control  演算法 (Stepwise)

Open loop,会根据input来直接求出output并输出,不会参考feedback或任何的actuating error

通常thermal team会给BMC一个表(fan table),表示Sensor 温度(input)为多少的时候,风扇转速(output)为多少,大概如下

CPU 温度 风扇转速
60 40
70 50
80 70
90 80
100 98

实作也相对简单,就一个for 回圈就可以了

# Threshold table
class TTable:
    def __init__(self, table, neg_hyst=0.0, pos_hyst=0.0):
        self.table = sorted(
            table, key=lambda in_thr_out: in_thr_out[0], reverse=True)
        self.compare_fsc_value = 0
        self.last_out = None
        self.neghyst = neg_hyst
        self.poshyst = pos_hyst

def run(self, value, ctx):
        mini = 0

if value >= self.compare_fsc_value:
            if math.fabs(self.compare_fsc_value - value) <= self.poshyst:
                return self.last_out

if value <= self.compare_fsc_value:
            if math.fabs(self.compare_fsc_value - value) <= self.neghyst:
                return self.last_out

for (in_thr, out) in self.table:
            mini = out
            if value >= in_thr:
                self.compare_fsc_value = value
                self.last_out = out
                return out

self.compare_fsc_value = value
        self.last_out = mini
        return mini

PID  algorithm

PID分别是proportional(比例) , integral(积分) and derivative(微分) 三个单字的缩写所组成的

我们在做风扇控制的时候,会希望我们的电脑上元件的温度维持在几度,以下会以CPU温度为例子。假设今天我们希望CPU温度维持在60度左右,那60就是set-point (S),而CPU目前温度就是process value (P),那S和P之间的差值就是error value (E) ,他们之间的关系就是E=S-P

PID演算法就是拿求得的E分别做比例运算,积分和微分,如下图所示,算出来的结果会输出PWM去控制风扇

那我们现在来分别聊聊PID这三个算法

Proportional(比例)

比例控制就是依据当前温度来决定风扇转速,将求得的E乘上一个Kp常数

因为当E 最大,表示P离S很远,风扇的转速需要变化大一点,举例来说

Set-point: 60, Kp = -2

case 1 : CPU 温度 70度 → E=60-70 = -10

case 2 : CPU 温度 90度 → E=60-70 = -30

从两个case当中,我们可以发现当 | E | 越大,风扇需要的转速变化也要很大,所以风扇转速分别就是20 (=-2*-10) 和60 (=-30*-2)

class PID:
    def __init__(self, setpoint, kp=0.0, ki=0.0, kd=0.0, neg_hyst=0.0, pos_hyst=0.0):
        self.last_error = 0
        self.I = 0
        self.kp = kp
        self.ki = ki
        self.kd = kd
        self.minval = setpoint - neg_hyst
        self.maxval = setpoint + pos_hyst
        self.last_out = None

def run(self, value, ctx):
        dt = ctx["dt"]
        # don't accumulate into I term below min hysteresis
        if value < self.minval:
            self.I = 0
            self.last_out = None
        # calculate PID values above max hysteresis
        if value > self.maxval:
            error = self.maxval - value
            self.I = self.I + error * dt
            D = (error - self.last_error) / dt
            out = self.kp * error + self.ki * self.I + self.kd * D
            self.last_out = out
            self.last_error = error
            return out
        # use most recently calc'd PWM value
        return self.last_out

Integral(积分) 

积分控制是根据历史经验来决定风扇转速,将从刚开机到现在的Error value全部相加起来,在乘上Ki

E0~Ei相加的值越大表示目前的历史经验告诉我们风扇变化要大一点,而相加的值是不会为无限大的,因为E值是有正有负

但I 有个问题 就是overshoot ,在CPU温度已经达到set-point的时候,风扇却仍没减少风量,造成CPU温度持续下降,原因是因为sum(E)仍未趋近于0,这个问题是存在于PID演算法的,大部分的程式码会在这个问题上做work around

底下蓝色的字就是对overshoot所做的workaround

class PID:
    def __init__(self, setpoint, kp=0.0, ki=0.0, kd=0.0, neg_hyst=0.0, pos_hyst=0.0):
        self.last_error = 0
        self.I = 0
        self.kp = kp
        self.ki = ki
        self.kd = kd
        self.minval = setpoint - neg_hyst
        self.maxval = setpoint + pos_hyst
        self.last_out = None

def run(self, value, ctx):
        dt = ctx["dt"]
        # don't accumulate into I term below min hysteresis
        if value < self.minval:
            self.I = 0
            self.last_out = None

        # calculate PID values above max hysteresis
        if value > self.maxval:
            error = self.maxval - value
            self.I = self.I + error * dt
            D = (error - self.last_error) / dt
            out = self.kp * error + self.ki * self.I + self.kd * D
            self.last_out = out
            self.last_error = error
            return out
        # use most recently calc'd PWM value
        return self.last_out

Derivative(微分) 

来到最后的微分,D就是求Error value的变化量,以最近一两次的误差变化量来决定风扇转速

把这次的error和上次的error做相减在除上时间差,就是D值了

代码大概如下:

class PID:
    def __init__(self, setpoint, kp=0.0, ki=0.0, kd=0.0, neg_hyst=0.0, pos_hyst=0.0):
        self.last_error = 0
        self.I = 0
        self.kp = kp
        self.ki = ki
        self.kd = kd
        self.minval = setpoint - neg_hyst
        self.maxval = setpoint + pos_hyst
        self.last_out = None

def run(self, value, ctx):
        dt = ctx["dt"]
        # don't accumulate into I term below min hysteresis
        if value < self.minval:
            self.I = 0
            self.last_out = None
        # calculate PID values above max hysteresis
        if value > self.maxval:
            error = self.maxval - value
            self.I = self.I + error * dt
            D = (error - self.last_error) / dt
            out = self.kp * error + self.ki * self.I + self.kd * D
            self.last_out = out
            self.last_error = error
            return out
        # use most recently calc'd PWM value
        return self.last_out

风扇控制会用到的概念大概就这些 :)
剩下的部分因为各家做法都不一样,所以就先不讨论

BMC的风扇控制 (Fan speed control)相关推荐

  1. 简易蓝牙的遥控系统基于c语言,基于Android平台的遥控风扇控制系统设计

    黄进皇+黄咏梅+黄胡萍+陈章毅+马来宾 摘要:针对现有风扇智能化程度不足,控制不够便捷等问题,利用现有的蓝牙通信技术.单片机控制技术和安卓平台,设计开发了一个基于Android平台的遥控风扇控制系统, ...

  2. 计算机主板的风扇控制,主板风扇调速知识【图文详解】

    导语:对于现在的青少年来说电脑已经成为了他们生活中的必不可缺少的东西,他们用电脑上网.他们用电脑打游戏.在大学的网友朋友们都会知道,当他们在玩游戏很久的时候电脑的 风扇 会变得的越来越热,那么今天小兔 ...

  3. 计算机主板的风扇控制,如何调整主板风扇的速度

    如何调整主板风扇的速度?对于当今的青少年来说,计算机已成为生活中不可或缺的东西. 他们使用计算机上网,并使用计算机玩游戏. 大学里的网民会知道风扇调速器怎么连主板,长时间玩游戏时,电脑迷会越来越热. ...

  4. 步进电机加减速算法介绍和基于AVR446_Linear speed control of stepper motor的步进电机加减速实现

    本文大部分内容来自<硬石电机控制专题指导手册> 一.引出 1.步进电机速度,是根据输入的脉冲信号的变化来改变的.理论上,给一个脉冲,步进电机就旋转一个步距角.但实际上,如果脉冲信号变化太快 ...

  5. 直流无刷电机仿真分析——基于simulink官方例程BLDC Speed Control

    这里分析一下simulink自带的demo-BLDC Speed Control: 整体的框图如下所示: 我在图中标注了12个部分的区域,每个区域的作用如下: Signal Builder:创建和产生 ...

  6. 【基于STM32F103C8T6的智能风扇控制】

    基于STM32F103C8T6的智能风扇控制 前言 一.功能介绍 二.硬件介绍 三.部分源码 前言 本次分享的是基于STM32F103的智能风扇的制作,相关的硬件和部分源码可看下面哦,需要成品的可私( ...

  7. Jetson Nano风扇控制脚本

    简介 Jetson Nano的PWM风扇控制小脚本,一共五个风速档位,可控制打开风扇或者关闭风扇. 获取和部署方式 打开控制台,在控制台输入(记得检查一下有没有安装git): git clone ht ...

  8. UNIX高级环境编程(9)进程控制(Process Control)- fork,vfork,僵尸进程,wait和waitpid...

    本章包含内容有: 创建新进程 程序执行(program execution) 进程终止(process termination) 进程的各种ID 1 进程标识符(Process Identifiers ...

  9. jetson nano风扇控制、远程控制和远程桌面

    风扇控制: 1.写风扇转速: sudo sh -c 'echo 255 > /sys/devices/pwm-fan/target_pwm' 2.创建/etc/rc.local(18.04没有r ...

最新文章

  1. cad打印样式ctb丢失_我的第一次打印:cad模型空间套图框打印图纸
  2. TensorFlow 2.0 - Checkpoint 保存变量、TensorBoard 训练可视化
  3. 计算机科学专业必读的44册经典著作
  4. Cloudflare通过集成ENS和IPFS推出通往分布式Web的网关
  5. 三种跨线程控件访问方法
  6. FR公式形态定义及运用范例
  7. vs+python 更新pip 成功解决You are using pip version 9.0.3, however version 10.0.1 is available.
  8. 虚拟机使用宿主机全局代理
  9. 请谈谈你对volatile的理解?--最近小李子与面试官的一场“硬核较量”
  10. php 菱形问号,python爬虫出现菱形问号乱码的解决方法
  11. ③电子产品拆解分析-充电宝台灯
  12. 最后3天!生信入门转录组和可视化学习捷径
  13. Datawhale十月组队学习_推荐系统3
  14. GPIO口 多引脚操作
  15. HDU - 1173 采矿
  16. 20款国内外免费使用 主流杀毒软件
  17. Unity骚操作:Spine动画打包成AssetBundle资源到安卓平台时,材质丢失的问题解决方案
  18. 专利授权费用如何收取?
  19. Makefile自动依赖写法
  20. 区块链金融格局再生变:谁也没想到韭菜财经会成为一匹黑马

热门文章

  1. 【秃头系列】-【本科生毕设论文格式Word】自动生成页面布局
  2. Mac配置VScode
  3. 三角函数π/2转化_@东莞同学,初中数学三角函数公式大汇总
  4. (Modern Family S01E03) Part 3  MitchCam  准备买diaper Cam说Mitch势力 逛超市Mitch像是发现了新大陆
  5. 网站加入QQ在线即时交谈的代码
  6. ios共享账号公众号_家人公众号和共享相册
  7. 关于第一次面试总结(嵌入式软件开发工程师)
  8. mysql exit quit_MySQL数据库5.5基础 exit quit \q 退出MySQL数据库
  9. ultra fast lane detection数据集制作
  10. 高新技术企业申请容易吗?如何提高申报通过的机率?