关键词:
树莓派4B PWM温控风扇 wiringpi库 PWM调整频率 54M PWM频率不对
总结
很多博客文章都是说树莓派PWM是按19.2M基频率来算的,今天用逻辑分析仪抓了一下波形后发现频率有问题,然后按测得的频率反推,算出来我这里好像是按54M的时钟频率来的,不清楚是什么情况。我这里的环境是wiringpi=2.52
+ 树莓派4B
+ Linux raspberrypi 5.10.52-v7l+ #1440 SMP Tue Jul 27 09:55:21 BST 2021 armv7l GNU/Linux
PWM 19.2M时钟的原文 https://www.cnblogs.com/miaoxiong/p/10556072.html
源码
思路就是读取cpu温度的文件,根据不同温度来控制PWM控制风扇转停,这个编译下来跑起来htop
看cpu占用一直等于0,对比原来python写的温控风扇2% 3%的cpu占用在跳,没想到差距这么大。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
| #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <wiringPi.h>
#define FAN_PIN 1
#define PWM_FRQ (200ul)
#define PWM_RANG (100ul)
#define TEMP_PATH "/sys/class/thermal/thermal_zone0/temp"
#define BUFF_MAX_SIZE 32u
#if 0 #define DBG_LOG(format, ...) do{ printf(format, ##__VA_ARGS__ ); }while(0) #else #define DBG_LOG(format, ...) #endif
static void GetTemperature(int *temp); static int GetDuty(int temp);
unsigned int Duty = 0; FILE *pFile = NULL; char buff[BUFF_MAX_SIZE] = {0}; float fTemperature = 0; int Temperature = 0;
int main(void) { DBG_LOG("Raspberry Pi wiringPi PWM test program\n"); if (wiringPiSetup() == -1) { DBG_LOG("GPIO setup error!\n"); exit(2); } pinMode(FAN_PIN, PWM_OUTPUT); pwmSetMode(PWM_MODE_MS); pwmSetRange(PWM_RANG); pwmSetClock(54000000/PWM_RANG/PWM_FRQ); pwmWrite(FAN_PIN, 0);
while (1) { GetTemperature(&Temperature); Duty = GetDuty(Temperature);
pwmWrite(FAN_PIN, Duty); DBG_LOG("Temp=%d Duty=%d\n", Temperature, Duty); delay(1000*10); }
return 0; }
static void GetTemperature(int *temp) { pFile = fopen(TEMP_PATH, "r"); if(pFile == NULL) { DBG_LOG("file can't open PATH=%s p=%p\n", TEMP_PATH, pFile); exit(1); } fgets(buff, BUFF_MAX_SIZE, pFile); *temp = (int)(atoi(buff)/1000.0+0.5); fclose(pFile); }
static int GetDuty(int temp) { if(temp >= 60) { return 100; } else if(temp >= 55) { return 80; } else if(temp >= 53) { return 70; } else if(temp >= 50) { return 60; } else if(temp >= 49) { return 50; } else { return 0; } }
|
最后编译一下
gcc -Wall -O -o fan fan.c -lwiringPi
再加个开机启动
1 2 3
| sudo nano /etc/rc.local # 在文件exit前加上 fan程序 sudo ./path/fan &
|
这个温度控制不是很好,转转停停的(估计是PWM值太小风扇转的不好, 尝试加电容电感应该会好些)