实现了采集温度和温度对应的时间并发送到主机端。。主机端保存到数据库中的函数
主机是虚拟机centos6。。linux系统。。客户端采集是fl2440的板子。。s3c2440的芯片。。跑的linux3.0的内核
因为是采集温度。。所以务必先完成板子的温度传感器的驱动实现。。因为是通过网络上报。。所以也务必实现wifi的sta模式可以ping通外网。。还有是要在主机断安装数据库。。我安装的是sqlite3.。安装别的的朋友可以酌情改一下sql.c中的代码
客户端代码如下
temperature.c
1 #include"head.h"
2 char get_tem(void)
3 {
4 int fd;
5 unsigned char buf[2];
6 unsigned short temp=0;
7 double result=0;
8 int flag=0;
9
10 if ((fd=open("/dev/DS18B20",O_RDWR | O_NDELAY | O_NOCTTY)) < 0)
11 {
12 printf("Open Device DS18B20 failed.\r\n");
13 exit(1);
14 }
15 else
16 {
17 read(fd, buf, sizeof(buf));
18 temp=((unsigned short)buf[1])<<8;
19 temp|=(unsigned short)buf[0];
20 result=0.0625*((double)temp);
21 printf("temperature is %4f \r\n", result);
22 sleep(2);
23
24 close(fd);
25 }
26
27 return (char)result;
28 }
实现的功能是通过ds.ko温度传感器驱动。。采集温度并返回温度数值
socket.c
14 #include
15 #include
16 #include
17 #include
18 #include
19 #include
20 #include
21 #include
22 #include
23
24 #define MAXLINE 4096
25
26 int main(int argc, char **argv)
27 {
28 int sockfd, n;
29 char buff[4096];
30 struct sockaddr_in servaddr;
31
32 if (argc != 2)
33 {
34 printf("usage: ./client
35 exit(0);
36 }
37
38 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
39 {
40 printf("create socket error: %s(errno: %d)\n", strerror(errno),errno);
41 exit(0);
42 }
43
44 memset(&servaddr, 0, sizeof(servaddr));
45 servaddr.sin_family = AF_INET;
46 servaddr.sin_port = htons(6666);
47 if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
48 {
49 printf("inet_pton error for %s\n",argv[1]);
50 exit(0);
51 }
52
53 if (connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) <0 )
54 {
55 printf("connect error: %s(errno: %d)\n",strerror(errno),errno);
56 exit(0);
57 }
58 /* make information */
59 time_t rawtime;
60 struct tm* timeinfo;
61 char timE[80];
62 time(&rawtime);
63 timeinfo=localtime(&rawtime);
64 strftime(timE,80,"%m-%d %I:%M:%S",timeinfo);
65
66 double num = get_tem();
67 int sig = 4;
68 gcvt(num, sig, buff);
69
70 strcat(buff, "|");
71 strcat(buff, timE);
72 strcat(buff, "\0");
73
74 if (send(sockfd, buff, strlen(buff), 0) <0 )
75 {
76 printf("send msg error: %s(errno: %d)\n", strerror(errno), errno);
77 exit(0);
78 }
79
80 close(sockfd);
81 return 0;
82 }
实现的是采集系统当前时间并和温度整理成一个字符串。。通过网络socket上报
head.h
14 #include
15 #include
16 #include
17 #include
18 #include
19 #include
20 #include
21 #include
22 #include
23 #include
24 #include
25 #include
26 #include
27
28 #define MAXLINE 4096
头文件。。本来准备写Makefile。。后来懒得写了。。这个头文件是为了Makefile写的。。在采集温度的函数中有调用
这就是全部的客户端代码。。下面介绍主机端
sql.c
14 #include"head.h"
15
16 sqlite3 *open_sql(void)
17 {
18 int ret = 0;
19 sqlite3 *db;
20
21 ret = sqlite3_open("temperature", &db);
22 if(ret != SQLITE_OK)
23 {
24 printf("open erri!\n");
25 return (sqlite3 *)-1;
26 }
27
28 return db;
29 }
30
31 int close_sql(sqlite3 *db)
32 {
33 sqlite3_close(db);
34 return 0;
35 }
36
37 int create_table(void)
38 {
39 char *err = 0;
40 int ret = 0;
41 sqlite3 *db;
42
43 db = open_sql();
44
45 ret = sqlite3_exec(db, "create table t(tem text, time text perimary key);", NULL, NULL, &err);
46 if(ret != SQLITE_OK)
47 {
48 printf("create table err!\n");
49 sqlite3_close(db);
50 return -1;
51 }
52
53 close_sql(db);
54 return 0;
55
56 }
57
58 int write_table(char *tem, char *time)
59 {
60 sqlite3 *db;
61 int ret;
62 char *err = 0;
63 char data[50] = "insert into t values(\"";
64
65 db = open_sql();
66
67 strcat(data, tem);
68 strcat(data, "\", \"");
69 strcat(data, time);
70 strcat(data, "\");");
71
72 printf("%s\n", data);
73
74 ret = sqlite3_exec(db, data, NULL, NULL, NULL);
75 printf("1\n");
76 if(ret != SQLITE_OK)
77 {
78 printf("write err\n");
79 close_sql(db);
80 return -1;
81 }
82
83 }
84
85 int myfunc(void *p, int argc, char **argv, char **argvv)
86 {
87 int i;
88
89 for(i =0; i < argc; i++)
90 {
91 printf("%s = %s ", argvv[i], argv[i]);
92 }
93
94 putchar('\n');
95 return 0;
96 }
97
98 int read_table(void)
99 {
100 sqlite3 *db;
101 int ret;
102 char *err = 0;
103
104 db = open_sql();
105
106 ret = sqlite3_exec(db, "select * from t;", myfunc, NULL, &err);
107 if(ret != SQLITE_OK)
108 {
109 printf("exec err\n");
110 close_sql(db);
111 return -1;
112 }
113
114 close_sql(db);
115
116 return 0;
117 }
这就是全部的操作数据库的代码。。包括打开创建表和读写。。读是读出数据。。要打印到屏幕上还要实现里面的回调函数myfun。。
socket.c
13 #include"head.h"
14
15 int main(int argc, char** argv)
16 {
17 int listenfd, connfd;
18 struct sockaddr_in servaddr;
19 char buff[MAXLINE];
20 int n;
21
22 if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
23 {
24 printf("create socket error:%s(errno:%d)\n", strerror(errno),errno);
25 exit(0);
26 }
27
28 memset(&servaddr, 0, sizeof(servaddr));
29 servaddr.sin_family = AF_INET;
30 servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
31 servaddr.sin_port = htons(6666);
32
33 if((bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr))) == -1)
34 {
35 printf("bind error:%s(errno:%d)\n", strerror(errno), errno);
36 exit(0);
37 }
38
39 if (listen(listenfd, 10) == -1)
40 {
41 printf("listen socket error:%s(errno:%d)\n", strerror(errno), errno)
42 exit(0);
43 }
44
45 printf("=================waiting for client's request=====================\n");
46 while(1)
47 {
48 if((connfd = accept(listenfd, (struct sockaddr*)NULL, NULL)) == -1)
49 {
50 printf("accept error:%s(errno:%d)\n", strerror(errno), errno);
51 continue;
52 }
53 n = recv(connfd, buff, MAXLINE, 0);
54 /* solve information */
55 char tem1[10];
56 char time1[20];
57 char *tem = (char *)tem1;
58 char *time = (char *)time1;
59 char *ptr;
60 char *opt = buff;
61
62 memset(tem1, 0, strlen(tem1));
63 memset(time1, 0, strlen(time1));
64
65 ptr = strchr(opt, '|');
66 if(ptr-opt == 0)
67 printf("tem is NULL!\n");
68 else
69 strncpy(tem1, opt, ptr-opt);
70
71 opt = ptr + 1;
72 ptr = strchr(opt, '\0');
73 if(ptr-opt == 0)
74 printf("time is NULL!\n");
75 else
76 strncpy(time1, opt, ptr-opt);
77 printf("%s,%s", tem1, time1);
78
79 create_table();
80 write_table(tem1, time1);
81 read_table();
82
83
84 close(connfd);
85 }
86
87 close(listenfd);
88 }
这就是全部的socket主机段的函数。。主要功能是完成socket的链接。。并且将解析出的两个温度和时间的字符串调用对应的读写函数。。
head.h
14 #include
15 #include
16 #include
17 #include
18 #include
19 #include
20 #include
21 #include
22
23 #define MAXLINE 4096
头文件
Makefile
1 CC=gcc
2
3 objs =sql.o socket.o
4 srcs =sql.c socket.c
5
6 tem: $(objs)
7 $(CC) -o tem $(objs) -lsqlite3
8 @make clean
9
10
11 socket.o: $(srcs) head.h
12 $(CC) -c $(srcs)
13
14 sql.o: sql.c head.h
15 $(CC) -c sql.c
16
17 clear:
18 @rm tem
19
20 .PHONY: clean
21 clean:
22 @rm *.o
Makefile。。上面客户端的Makefile也可以参照这个写。。
这里要说明的几点是。。
第一。。传温度我考虑的是传客户端的温度。。因为我们这个采集什么的不算精准。。而且短距离。。所以客户端的时间和主机端时间基本同步。。但是监控肯定是实时准确的。。采集的是当地当时的温度。。出于标准化我这里的时间也是打包传递过来的客户端时间。。
第二。。这里的我的数据库是不支持时间date数据格式的。。所以我这里自己配置了字符串时间格式。。并以字符串的形式写入了数据库
第三。。这里给sqlite3_exec的sql语句不能过长。。过长会出现段错误。。所以我这里对数据进行了适当的调整。。将时间格式缩短并且简化了表的名称。。