基于Webserver的工业数据采集系统

本系统的设计流程大致如下:

 其中传感器模块和执行器模块使用Modbus slave软件代替。

        服务程序和从机之间的通信采用Modbus通信协议,因为Modbus协议是现在国内工业领域应用最多的协议,不仅仅用于PLC设备,还用于各种终端设备,如水表、电表、各种采集设备等等。

        其中Modbus通信协议有许多变种,最著名的三种版本有支持以太网的Modbus TCP,和支持串口的Modbus RTU、Modbus ASCII。

本系统使用Modbus TCP协议:

1.特点:

(1)采用主从问答方式通信。

(2)属于应用层协议,顾名思义,他是基于TCP实现通信。

(3)一般使用Modbus TCP的默认端口号是502,但也可以使用其他端口号,注意不要冲突就好。

2.协议格式

使用此协议发送的请求码包括三个部分:MBAP报文头(7字节)、功能代码(1字节)、数据。

其中报文头包含四个部分:

3.功能代码

        其通过离散量输入或者线圈来控制设备,输入和保持寄存器来存储设备。根据四种不同的寄存器设置了多种功能码,其中最常用的八种如下:

服务程序-----从机

       我们先从服务程序和从机之间的通信开始,如流程图所示,本系统只是实现了实时采集温湿度和控制LED灯、蜂鸣器基本功能。

1.设置slave端

      <-----设置读两个保持寄存器

    <-------给其初始温湿度

    <---------设置写两个项圈:LED BEEP

      <---------初始值设为关闭

 2.写服务程序

 先创建套接字,进行连接,连接成功后给从机发送请求码,从机收到后会返回数据。

         下面的是封装请求码的函数,因为使用的是TCP所以req[2]和req[3]都是0;req[6]是我们从机的ID,通过func来判断是要读取保持寄存器还是写线圈:当func为3时是读保持寄存器,func为1时是写线圈。

//func:功能码   addr:地址   nb:保持寄存器的个数或是线圈的发送数据 req:从机回过来的数据
int buildRequest(int func, int addr, int nb, uint8_t *req)
{
    req[0] = 0x00;
    req[1] = 0x00;
    req[2] = 0x00;
    req[3] = 0x00;
    req[4] = 0x00;
    req[5] = 0x06;
    req[6] = 0x01;
    req[7] = (uint8_t)func;
    req[8] = (uint8_t)(addr >> 8);
    req[9] = (uint8_t)(addr & 0xff);
    if (func == 0x03)
    {
        req[10] = (uint8_t)(nb >> 8);
        req[11] = (uint8_t)(nb & 0xff);
        return 12;
    }
    else if (func == 0x05)
    {
        if (nb == 0)
            req[10] = 0;
        else
            req[10] = 0xff;
        req[11] = 0x00;
        return 12;
    }
}

 读保持寄存器和写线圈:

void read_registers(int sockfd, int addr, int nb, uint16_t *dest)
{
    uint8_t data[32] = "";
    uint8_t req[32] = "";
    int len = buildRequest(3, addr, nb, req);
    send(sockfd, req, len, 0);
    //接收从机数据
    recv(sockfd, data, 32, 0);
    for (int i = 0, j = 0; i < data[8]; i += 2, j++)
    {
        dest[j] = data[9 + i] << 8 | data[10 + i];
    }
}
void write_bit(int sockfd, int addr, int val)
{
    uint8_t req[32] = "";
    int len = buildRequest(5, addr, val, req);
    send(sockfd, req, len, 0);
}

3.连接

    <--------先连接上slave端

       <------启动服务程序,成功获得了温湿度的值;

服务器------CGI

 本项目采用的是Lighttpd服务器。

        LigHttpd是一个开源的轻量级嵌入式Web server,是提供一个专门针对高性能网站,安全、快速、兼容性好并且灵活的web server环境。具有非常低的内存开销,cpu占用率低,效能好,以及丰富的模块等特点。

        Lighttpd 适合静态资源类的服务,比如图片、资源文件、静态HTML等等的应用,性能比较好,同时也适合简单的CGI应用的场合,lighttpd可以很方便的通过fastcgi支持php。

CGI:

           CGI(Common Gateway Interface)通用网关接口,是外部扩展应用程序与 Web 服务器交互的一个标准接口。

配置完成后运行Lighttpd服务器,

打开xterm:

进入cgi程序中,把标红的部分改成自己的。

 CGI------服务程序

通过共享内存获得从机中温湿度的值、消息队列来控制LED灯和蜂鸣器。具体代码如下:

CGI:当发送GET时获得温湿度的值,LED 0/1 BEEP 0/1进行控制

char buf[100]="";
    key_t key = ftok("/home/hq/work/web/cgi_demo/ftok.txt", 'A');
    if (key < 0)
    {
        perror("ftok err");
        return -1;
    }
    int msgid = msgget(key, IPC_CREAT | IPC_EXCL | 0666);
    if (msgid < 0)
    {
        if (errno == EEXIST)
        {
            msgid = msgget(key, 0666);
        }
        else
        {
            perror("msgget err");

            return -1;
        }
    }
    struct msgbuf msg;
    msg.mtype = 'A';
    if (strncmp(input, "GET",3) == 0)
    {
        key_t key1 = ftok("/home/hq/work/web/cgi_demo/shm.txt", 'C');

        if (key1 < 0)

        {
            perror("ftok err");
            return -1;
        }
        int shmid = shmget(key1, 16, IPC_CREAT | IPC_EXCL |0666);

        if (shmid < 0)
        {
            if (errno == EEXIST)

            {
                shmid = shmget(key1, 16,0666);
            }
            else
            {
                perror("shmget err");
                return -1;
            }
        }
        char *sp = (char *)shmat(shmid, NULL, 0);
        if (sp == (char *)-1)
        {
            perror("shmat err");
            return -1;
        }
        strcpy(buf, sp);
    }
    else if (strncmp(input, "LED 0",5)==0)
    {
        strcpy(msg.mtext, val_buf);
        msgsnd(msgid, &msg, sizeof(msg), 0);
        strcpy(buf,"灯已关闭");
    }
    else if (strncmp(input, "LED 1",5)==0)
    {
        strcpy(msg.mtext, val_buf);
        msgsnd(msgid, &msg, sizeof(msg), 0);
        strcpy(buf,"灯已打开");
    }
    else if (strncmp(input, "BEEP 0",6)==0)
    {
        strcpy(msg.mtext, val_buf);
        msgsnd(msgid, &msg, sizeof(msg), 0);
        strcpy(buf,"蜂鸣器关闭");
    }
    else if (strncmp(input, "BEEP 1",6)==0)
    {
        strcpy(msg.mtext, val_buf);
        msgsnd(msgid, &msg, sizeof(msg), 0);
        strcpy(buf,"蜂鸣器打开");
    }
    strcpy(val_buf,buf);

服务程序收到信号后给出相应的回复或控制设备即可。

程序测试:

接着再简单的制作一个小网页后即可通过网页获取数据和控制设备了。

注意:子系统自能在同一局域网中进行

  <-----点击获取温度

   <-------点击获取湿度

  <-------点击控制开关

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
TopFisher是新一代的WEB数据采集系统,只要是有网址的页面,TopFisher都能从该页面中精确的采集您想要的数据,并按照用户指定的表结构把数据保存到本地或远程的数据库中,数据可以直接被采集为文本/数字/日期等各种数据类型,在数据采集期间所有的工作都是由TopFisher来完成的,用户不需要做任何的工作。 一、全新的脚本解析网页架构的方式:传统的数据采集软件都是通过配置复杂的属性对话框来解释目标网页框架的,这种方式的缺点是不够灵活,稍微遇到复杂或结构特别一点的网站就无能为力了。而TopFisher是通过脚本代码的方式来解析网页架构的,因为不论目标网页有多复杂,都可以通过TopFisher提供的IF,FOR语句和丰富的函数来完成网页架构的分析。  二、更加适合于“数字/数据”的采集,而不局限于新闻文字采集:通过TopFisher提供的数字变量和相关函数,TopFisher能够轻松的把网页中的数字/数据,或日期时间精确的剥离出来,让您的TopFisher不再是简单的新闻采集器,而是一个功能全面的数据捕手。  三、真正做到了无需人工值守的定期循环采集:TopFisher解释器运行极其稳定,经大量测试,连续运行数周或数月都不会出现问题。并且在循环采集数据的空闲期间占用的计算机资源微乎其微,保证服务器中的其它程序或系统能够正常快速的运行。 四、支持其它由高级语言自制的DLL文件调用:TOPFISHER在功能上通过与其它高级语言的联动而得到极大的扩展,如果有部分功能在TOPFISHER上无法实现或很难实现,那么用户可以通过自己编写DLL函数来用其它高级语言完成TOPFISHER自己不能完成任务。 TopFisher对我来说有什么价值? 在TopFisher诞生之前,互联网中的所有的信息和数据都是“分散”的,TopFisher最有价值的地方就是能够把这些分散的数据“聚集”起来,并能够24小时的实时更新这些“聚集”的数据。他使得一个普通的网站站长自己搭建一个强大的行业搜索引擎不再是一个梦想,当然您也可以把这些数据和信息用于价格PK,统计等其它业务上。 总之,TopFisher提供了把“分散”的信息“聚集”起来的可能,这也许意味着TopFisher的出现为互联网市场开辟了一片新的金矿。您将会怎样利用这些“聚集”的信息呢?现在就好好的想一想吧!一个好的点子可是在互联网行业中迅速成功的关键!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值