记录今天在淅淅沥沥的小雨下宅了一天的,算是收获吧。

之前就看到有文章写道利用树莓派系统内置命令获取主板温度的方法,由于处于学习阶段,只是尝试了一下获取温度重定向到另外的输出文件就停止了,今天没事做,于是就戳了一下相关的功能。

目的

获取树莓派主板的温度,并在页面上以图标的方式展现出来。

涉及知识(都是入门级的)

linux进程与系统调用
linux下文件操作
**
文件描述表
**进程标准输入、输出、重定向
jQuery+HighCharts图表插件

直接贴代码吧,搞完了剪头去。

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
#include<stdio.h>
#include<stdlib.h>

//默认执行的秒数
#define TIMES 60

//默认输出的文件路径
#define LOGFILE "temperature.log"

//第一个参数为执行的秒数
//第二个参数为重定向到新文件的路径(名称)
int main(int argc,char *argv[]) {
int times=TIMES;
FILE *f_log;

//初始化执行的次数
if(argv[1]!=NULL)
times=atoi(argv[1]);

//打开文件指针
if(argv[2]!=NULL)
f_log=fopen(argv[2],"a+");
else
f_log=fopen(LOGFILE,"a+");

//将默认输出管道重定向至文件指针,f_temp
dup2(fileno(f_log),1);
while(times>0) {
//system调用系统文件,默认输出将重定向至文件指针指向的文件
//获取主板温度
system("/opt/vc/bin/vcgencmd measure_temp");

//获取系统时间
system("date");
printf("%d\n",times);
times--;
sleep(1);
}

//关闭文件指针
fclose(f_log);

return 0;
}

编译与调用:
make pi_temp && ./pi_temp 60 temperature2.log

参数解释:
60表示会执行60次,也就是60秒

temperature2.log 获取主板温度之后的数据将输出到此文件中

等待60秒之后,*.log中的内容看起来是这样的:(请自动忽略时间部分)

**
temp=45.5’C**

Sat Apr 26 15:31:26 HKT 2014
temp=44.9’C
Sat Apr 26 15:31:27 HKT 2014
temp=45.5’C
Sat Apr 26 15:31:28 HKT 2014
temp=44.9’C
Sat Apr 26 15:31:29 HKT 2014
temp=44.9’C
Sat Apr 26 15:31:30 HKT 2014
temp=44.9’C
Sat Apr 26 15:31:31 HKT 2014

把这些内容复制到:http://lison.cc/pi_temp/temp.html 这个页面的文本框中,点击提交按钮,图标会根据数据展示特定时间内的温度变化曲线,如图:

树莓派图表

后续

1.既然能够获取主板温度,是不是也可以获取CPU温度等其他温度,如果可以的话,可以获取内容在同一图表进行展现。

2.既然能够获取这些温度,就可以外接风扇,监控温度,若超过设定值,自动开启风扇进行散热了,有时间再戳吧。

代码格式有点乱,直接来个图吧:

改进后的代码

改进版的代码:

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
#include<stdio.h>
#include<stdlib.h>
#include<sys/wait.h>

//默认执行的秒数
#define TIMES 60

//默认输出的文件路径
#define LOGFILE “temperature.log”

//循环条件,传入-1将无限循环
#define LOOPCONDITION(x)(x==-1?1:x)

//显示错误信息并退出程序
void error(char *msg) {
puts(msg);
exit(1);
}

/*
* argc 执行的秒数(次数)
* argv 重定向到新文件的路径(名称)
*/
int main(int argc,char *argv[])
int times;
FILE *f_log;

if(argc==1)
times=TIMES;
f_log=fopen(LOGFILE,”a+”);
}
else if(argc==2) {
//初始化执行的次数
if(atoi(argv[1]))
times=atoi(argv[1]);
else
fopen(argv[1],”a+”);
}
else if(argc==3)
if(atoi(argv[1]))
times=atoi(argv[1]);
else
error(“Invalid times formate”);

f_log=fopen(argv[2],”a+”);
}
else
error(“Unkow argument format”);

//克隆当前进程,产生子进程
pid_t pid=fork();

if(pid==-1)
error(“Cannot fork process”);

//创建父子进程连接管道
int fd[2];
if(pipe(fd)==-1)
error(“Cannot create pipe”);

//子进程
if(!pid)
//关闭子进程的输入管道
close(fd[0]);

//将子进程的输出管道重定向到f_log的输入管道
dup2(fileno(f_log),1);
}

int status;
while(LOOPCONDITION(times))
//system调用系统文件,默认输出将重定向至文件指针指向的文件
//获取主板温度
system(“/opt/vc/bin/vcgencmd measure_temp”);

//获取系统时间
system(“date”);

times–;
sleep(1);
}

//关闭文件指针
fclose(f_log);

return 0;
}