0


基于web server实现工业数据采集

1、引言

    在工业自动化领域,数据采集是非常重要的一环。通过对工业设备的数据采集、存储和显示,可以实现对生产过程的监控和优化,提高生产效率和质量。而Modbus作为一种通信协议,在工业控制系统中被广泛应用于数据传输。因此,基于Modbus的工业数据采集系统成为了一种常见的解决方案。

2、相关研究

2、1 Modbus

    Modbus协议定义了设备之间的通信规范,包括数据帧格式、数据类型、寻址方式等。它主要包含以下几个关键概念:
  1. 主从结构:Modbus通信中存在主设备(Master)和从设备(Slave)两种角色。主设备负责发起通信请求和控制操作,而从设备则响应主设备的请求并执行相应的操作。(支持单主多从,多主多从需要总线仲裁的支持)

  2. 数据帧格式:Modbus协议使用二进制编码,将数据封装为称为数据帧(Frame)的通信单元。数据帧包括地址域、功能码、数据域和错误检测等字段。地址域用于标识从设备的地址,功能码表示主设备请求的操作类型,数据域存储具体的数据信息,错误检测字段用于确保数据的完整性和准确性。(ModbusRTU就是此类帧格式)

  3. 功能码:Modbus协议定义了一系列功能码,用于标识主设备请求的操作类型。常见的功能码包括读取数据、写入数据、读取设备状态等。不同的功能码对应不同的数据读写方式和操作。

  4. 寻址方式:Modbus协议支持不同的寻址方式,包括基于从设备地址的寻址(1到247)和基于扩展地址的寻址(1到65535)。主设备通过指定不同的地址来与特定的从设备进行通信。

     详见: 面试通信协议
    

2、2 Modbus三类衍生

  1. Modbus TCP: Modbus TCP是基于TCP/IP协议的一种Modbus传输方式。它通过以太网进行数据传输,使用标准的Modbus协议格式,将Modbus数据封装在TCP/IP报文中进行传输。Modbus TCP支持较高的通信速度和较大的数据量,并且可以通过网络连接实现分布式控制和监控。
  2. Modbus ASCII: Modbus ASCII是一种基于字符的Modbus传输方式。它使用ASCII码表示数据,并通过串口进行传输。在Modbus ASCII中,每个字节都用两个ASCII字符表示,因此传输速率较慢。Modbus ASCII具有较好的可读性,但对于大量数据的传输效率较低。
  3. Modbus RTU: Modbus RTU是一种基于二进制的Modbus传输方式。它使用二进制编码表示数据,并通过串口进行传输。Modbus RTU相比Modbus ASCII具有更高的传输速率和更高的传输效率,因为它直接传输二进制数据,不需要进行ASCII码的转换。Modbus RTU通常用于在串口通信环境下进行短距离的数据传输。

2、3 Modbus总结

2、3、1 使用总结

  • Modbus TCP适用于高速、远程通信的以太网环境,支持多主多从通信
  • Modbus ASCII适用于低速、短距离的串行通信环境,易于调试和诊断
  • Modbus RTU适用于中等速度和距离的串行通信环境,具有高效率、实时性和可靠性

2、3、2 协议总结

  1. 简单易用:Modbus协议采用简单的数据帧格式和功能码定义,易于理解和实现。它不仅适用于大型工业控制系统,也可以用于小型设备和嵌入式系统。
  2. 可靠性:Modbus协议具有良好的可靠性和容错性。它使用校验和机制来确保数据传输的准确性,同时支持错误检测和重发机制。
  3. 灵活性:Modbus协议支持多种物理层和传输方式,包括串口(如RS-232、RS-485)、以太网等,以适应不同的通信环境和需求。

3、系统设计

3、1 架构框图


图3-1 整体架构框图

3、2 流程讲解

    1、手动输入配置Modbus从机的设置,数据等。

    2、Modbus主机采用多线程技术,实现读写分离。Modbus主机每秒采集数据一次,然后使用共享内存这种IPC实现采集数据与web server服务器共享数据。

    3、网页可以点击或者发送GET或者POST请求,请求Web server 服务器响应对应的操作,倘若网页想关闭一盏灯,也就是说想操作从机的线圈,那么需要先通过http协议发送请求,Webserver接收到数据之后,进行相应判断处理,通过消息队列发送数据请求给Modbus主机,主机接收到数据之后,通过ModbusTCP通信协议格式操作从机线圈,即可实现通过网页控制灯灭。

4、代码分析

4、1 主机采集数据

void *handler_read(void *arg)//主机读取从机的数据(线程处理函数)
{
    modbus_t *ctx = (modbus_t *)arg; //创建实例
    int addr, nb, len;
    addr = 0;
    nb = 4;
    uint16_t *p=NULL;
    while (1)
    {
        p=share_mem();//调用共享内存函数
        if ((len = modbus_read_registers(ctx, addr, nb, p)) < 0)//采集从机的数据,将其共享到共享内存
        {
            perror("modbus read err\n");
            modbus_close(ctx);
            modbus_free(ctx);
            return NULL;
        }
        sleep(1);
    }
}

4、2 主机写线圈

void *handler_write(void *arg)//线程处理函数
{
    modbus_t *ctx = (modbus_t *)arg;//创建实例
    struct msg buf;
    int len=sizeof(buf)-sizeof(long);
    int msgid=msg_init();
    while (1)
    {
        msgrcv(msgid, &buf, len, 1, 0);//接收Webserver服务器发送的数据
        if (buf.data[12] == '0')//判断数据格式,进行不同的处理
        {
            if (modbus_write_bit(ctx, 0, buf.data[14]-48) < 0)//0 0 代表灯灭 0 1 代表灯亮
            {
                perror("write err\n");
                modbus_close(ctx);
                modbus_free(ctx);
                return NULL;
            }
        }
        else
        {
            if (modbus_write_bit(ctx, 1, buf.data[14]-48) < 0)//1 0 代表蜂鸣器不响 1 1 代表蜂鸣器响
            {
                perror("write err\n");
                modbus_close(ctx);
                modbus_free(ctx);
                return NULL;
            }
        }
    }
}

4、3 Webserver服务器响应网页采集数据

static int handler_read(int sock, const char *input)//读取数据函数

{

    u_int16_t *p=NULL;

    p=share_mem();//获取共享内存

    char reply_buf[HTML_SIZE] = {0};

    sprintf(reply_buf,"light = %d x/y/z=%d/%d/%d",p[0],p[1],p[2],p[3]);//写入数据到数组

    printf("resp = %s\n", reply_buf);

    send(sock,reply_buf,strlen(reply_buf),0);//回复数据给网页

    return 0;

}

4、4 Webserver服务器响应网页操作MCU

static int handle_write(int sock,const char *input)//发送;改变设备状态函数

{

    struct msg buf;

    int len=sizeof(buf)-sizeof(long);   

    int msgid=msg_init();

    buf.type=1;//定义消息类型

    strcpy(buf.data,input);//拷贝数据

    msgsnd(msgid, &buf, len, 0);//发送数据给Modbus主机

    printf("send buf = %s\n",buf.data);

    return 0;

}

4、5 网页配置

<body>
    <h1>基于Modbus模拟工业数据采集</h1>

    <div class="container">
        <div class="data-input">光线:<input type="text" name="data" value1="0"></div>
        <div class="data-input">x 轴:<input type="text" name="data" value2="0"></div>
        <div class="data-input">y 轴:<input type="text" name="data" value3="0"></div>
        <div class="data-input">z 轴:<input type="text" name="data" value4="0"></div>
        <button class="button" type="button" name="flash" onclick="get_data()">数据采集</button>

        <div class="radio-group led-group">
            <span>led:</span>
            <input type="radio" name="led" id="led-on" onclick="led_control(id)">
            <label for="led-on">On</label>
            <input type="radio" name="led" id="led-off" onclick="led_control(id)">
            <label for="led-off">Off</label>
        </div>

        <div class="radio-group fans-group">
            <span>fan:</span>
            <input type="radio" name="fans" id="fans-on" onclick="fans_control(id)">
            <label for="fans-on">On</label>
            <input type="radio" name="fans" id="fans-off" onclick="fans_control(id)">
            <label for="fans-off">Off</label>
        </div>
    </div>

</body>

5、实验结果


图5-1 网页界面


图5-2 数据采集与设备控制图

6、结论

    基于Web服务器的工业数据采集系统为工业用户提供了一种灵活、高效的解决方案,使他们能够实时监测设备状态、收集并分析生产数据。
  1. 实时监测:基于Web服务器的工业数据采集系统能够实时监测设备状态和生产数据。通过采集节点与传感器或PLC等设备的连接,系统可以及时获取各种类型的数据,如温度、湿度等,以及设备的开关状态等。

  2. 数据采集与存储:系统通过合适的通信协议与数据采集设备进行通信,并将采集到的数据传输到Web服务器。

  3. 数据处理与分析:系统通过编写数据处理和分析程序,对采集到的数据进行实时计算和智能分析,进行相应的处理操作。

  4. 可视化展示与报表生成:通过Web服务器提供的前端界面,系统将数据以可视化的方式展示给用户,提供简单直观的操作与观赏方式。

     感谢阅读,希望对你有所帮助。
    


本文转载自: https://blog.csdn.net/qq_52305085/article/details/134087241
版权归原作者 嵌入式小企鹅 所有, 如有侵权,请联系我们删除。

“基于web server实现工业数据采集”的评论:

还没有评论