小项目——基于嵌入式 web 服务器的测控系统

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/dxd_123456/article/details/78429743

在 Linux 下,移植一个 boa 服务器,编写相应 cgi,在网页上动态刷新串口数据(使用虚拟串口),使用到串口编程,数据库编程及简单前端知识。
该测控系统测量数据通过虚拟串口传递(由于条件限制未使用传感器),目前只有测的功能,未来会进一步改进。

以下是具体内容

读取串口数据程序:
这里用到串口编程,写一个程序读取串口数据,然后将读取数据插入数据库,有用到数据库编程的知识。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <sqlite3.h>

#define BUFFER_SIZE 200

int open_port()
{
    int fd;

    fd = open("/dev/ttyS1",O_RDWR | O_NOCTTY | O_NDELAY);//打开串口

    if(fd < 0)
    {
        perror("open serial port");
    return (-1);
    }

    if(fcntl(fd,F_SETFL,0) < 0)//回复串口为阻塞状态
    {
        perror("fcntl F_SETFL\n");
    }

    if(isatty(fd) == 0)//测试打开的文件是否为终端设备
    {
        perror("This is not a terminal device");
    }

    return fd;
}

int set_com_config(int fd)
{
    struct termios new_cfg,old_cfg;
    int speed;

    if(tcgetattr(fd,&old_cfg) != 0)//保留原串口配置
    {
        perror("tcgetattr");
    return -1;
    }
    new_cfg = old_cfg;
    cfmakeraw(&new_cfg);//将终端设置为原始模式
    new_cfg.c_cflag &= ~CSIZE;//用数据位掩码清空数据位设置

    speed = B115200;
    cfsetispeed(&new_cfg,speed);//设置波特率
    cfsetospeed(&new_cfg,speed);

    new_cfg.c_cflag |= CS8;//重新设置字符大小

    new_cfg.c_cflag &= ~PARENB;//设置奇偶校验位
    new_cfg.c_iflag &= ~INPCK;

    new_cfg.c_cflag &= ~CSTOPB;//设置停止位

    new_cfg.c_cc[VTIME] = 0;//设置最少字符和等待时间
    new_cfg.c_cc[VMIN] = 1;
    tcflush(fd,TCIFLUSH);//清空缓冲区
    if((tcsetattr(fd,TCSANOW,&new_cfg)) != 0)//激活配置
    {
        perror("tcsetattr");
    return -1;
    }
    return 0;
}

int main(void)
{
    int fd;
    int nread;
    char buff[BUFFER_SIZE];
    int rc,i;
    sqlite3 *db = NULL;
    sqlite3_stmt *stmt;
    char *errmsg = NULL;
    char sql[512];

    rc = sqlite3_open("ph.db",&db);//打开数据库

    if((fd = open_port()) < 0)//打开串口
    {
        perror("open_port");
    return 1;
    }

    if(set_com_config(fd) < 0)//串口设置
    {
        perror("set_com_config");
    return 1;
    }

    while(1)
    {
        printf("receive is \n");
    memset(buff,0,BUFFER_SIZE);
    read(fd,buff,BUFFER_SIZE);
    printf("%s\n",buff);
    sprintf(sql,"update PHdata set id = %c,Pid = %c,Pph = %c,we = %c",buff[0],buff[1],buff[2],buff[3]);
    sqlite3_exec(db,sql,NULL,NULL,errmsg);//向数据库插入数据
    printf("%s\n",sql);
    }
    sqlite3_close(db);
    close(fd);

    return 0;
}

简易CGI:由于前端只是还在起步阶段,所以这个网页界面做的比较简单,未来会进一步改进。

代码:

#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>

int main()
{
        sqlite3 *pdb=NULL;
        sqlite3_stmt *stmt;
        char *szErrMsg=0;
        int rc,i;
        rc=sqlite3_open("ph.db",&pdb);
        if(rc)
        {
                fprintf(stderr,"can't open database: %s",sqlite3_errmsg(pdb));
                sqlite3_close(pdb);
                return -1;
        }
        printf("Content-type:text/html\n\n");
        printf("<html>\n<head>\n<Meta http-equiv=\"Refresh\" Content=\"1;\"><title>test</title></head>\n<body>\n");
        printf("<h1 align=\"center\">PHDATA</h1>\n");
        printf("<table border=\"1\" align=\"center\">\n");
        printf("<tr>\n");
        printf("<th>id</th><th>Pid</th><th>Pph</th><th>we</th>\n");
        printf("</tr>\n");

        char sql[512];
        //char *sql="select *from wsd where id=(select max(id)from wsd where dnum=1)";
 //       int j=1;
   //     for(;j<=3;j++)
     //   {
                sprintf(sql,"select * from PHdata;");
                sqlite3_prepare(pdb,sql,-1,&stmt,0);
                //sqlite3_bind_int(stmt,kk,i);
                //sqlite3_bind_int(stmt,1,i);
/*
                rc=sqlite3_column_count(stmt);
                for(i=0;i<rc;i++)
                {
                printf("%s\t",sqlite3_column_name(stmt,i));
                }
                printf("\n");
*/                printf("<tr>\n");
                while(sqlite3_step(stmt)==SQLITE_ROW)
                {
                        printf("<td>%d</td>",sqlite3_column_int(stmt,0));
                       printf("<td>%d</td>",sqlite3_column_int(stmt,1));
                        printf("<td>%.1f</td>",sqlite3_column_double(stmt,2));
                        printf("<td>%s</td>\n",sqlite3_column_text(stmt,3));

                /*
                        for(i=0;i<rc-1;i++)
                        {
                                printf("%d\t",sqlite3_column_int(stmt,i));
                        }
                        printf("%s\n",sqlite3_column_text(stmt,i));
                        //sqlite3_reset(stmt);
                */
                }
                printf("</tr>\n");
       // }
        printf("</table>\n</body>\n</html>");
        sqlite3_finalize(stmt);
        sqlite3_close(pdb);
        return 0;
}

通过boa服务器对数据库内容定时刷新,数据库内容由串口收到数据定时刷新。

猜你喜欢

转载自blog.csdn.net/dxd_123456/article/details/78429743