modbus tcp 主站-基于libmodbus开源库

news/2024/7/10 20:57:29 标签: tcp/ip, 开源, 网络, 网络协议

一、知识点介绍

    在Modbus TCP协议中,主站被称为客户端(Client),它是发起通讯的一方。主站的功能类似于RTU主站,会向从站(服务器)发起数据请求。主站通过TCP/IP协议与从站进行通讯,发送查询操作数据的请求,并接收从站返回的响应数据。主站可以同时与多个从站进行通讯,每个从站都有一个唯一的地址标识。在Modbus TCP协议中,主站可以通过IP地址和端口号来识别从站

84021fdffa932b240861138c9130fe56.png

二、modbus tcp 主站

基于libmodbus开源库,编写modbus tcp的主站,读取bits和registers,测试代码如下:

#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>


#include <modbus.h>


#define LOOP          1
#define SERVER_ID     17
#define ADDRESS_START 0
#define ADDRESS_END   9


int main(void)
{
    modbus_t *ctx;
    int rc;
    int nb_fail;
    int nb_loop;
    int addr;
    int nb;
    uint8_t *tab_bits;
    uint8_t *tab_in_bits;
    uint16_t *tab_registers;
    uint16_t *tab_in_registers;


    ctx = modbus_new_tcp("192.168.1.188", 1502);
    modbus_set_slave(ctx, SERVER_ID);
    modbus_set_debug(ctx, TRUE);


    if (modbus_connect(ctx) == -1) 
    {
        fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
        modbus_free(ctx);
        return -1;
    }


    /* Allocate and initialize the different memory spaces */
    nb = ADDRESS_END - ADDRESS_START;


    tab_bits = (uint8_t *) malloc(nb * sizeof(uint8_t));
    memset(tab_bits, 0, nb * sizeof(uint8_t));


    tab_in_bits = (uint8_t *) malloc(nb * sizeof(uint8_t));
    memset(tab_in_bits, 0, nb * sizeof(uint8_t));


    tab_registers = (uint16_t *) malloc(nb * sizeof(uint16_t));
    memset(tab_registers, 0, nb * sizeof(uint16_t));


    tab_in_registers = (uint16_t *) malloc(nb * sizeof(uint16_t));
    memset(tab_in_registers, 0, nb * sizeof(uint16_t));




    nb_loop = nb_fail = 0;
    while (nb_loop++ < LOOP) 
    {
        for (addr = ADDRESS_START; addr < ADDRESS_END; addr++) 
        {
            int i;


            nb = ADDRESS_END - addr;


            /* read BIT */
            
            rc = modbus_read_bits(ctx, addr, 1, tab_bits);
            if (rc != 1 ) 
            {
                printf("ERROR modbus_read_bits single (%d)\n", rc);
                printf("address = %d\n", addr);
                nb_fail++;
            }
            else
            {
                printf("Address = %d, value %d (0x%X) \n",
                                   addr,
                                   tab_bits[0],
                                   tab_bits[0]);
            }
            


            /* MULTIPLE BITS */
            
            rc = modbus_read_bits(ctx, addr, nb, tab_bits);
            if (rc != nb) 
            {
                printf("ERROR modbus_read_bits\n");
                printf("Address = %d, nb = %d\n", addr, nb);
                nb_fail++;
            } 
            else 
            {
                for (i = 0; i < nb; i++) 
                {
                    
                        printf("Address = %d, value %d (0x%X) \n",
                                addr+i,
                                tab_bits[i],
                                tab_bits[i]);


                }
            }


            //read input bits
            //modbus_read_input_bits
            


            /* SINGLE REGISTER */
            rc = modbus_read_registers(ctx, addr, 1, tab_registers);
            if (rc != 1) 
            {
                printf("ERROR modbus_read_registers single (%d)\n", rc);
                printf("Address = %d\n", addr);
                nb_fail++;
            } 
            else 
            {
                    printf("Address = %d, value = %d (0x%X) \n",
                            addr,
                            tab_registers[0],
                            tab_registers[0]);
            }
            


            /* MULTIPLE REGISTERS */
            
            rc = modbus_read_registers(ctx, addr, nb, tab_registers);
            if (rc != nb) 
            {
                printf("ERROR modbus_read_registers (%d)\n", rc);
                printf("Address = %d, nb = %d\n", addr, nb);
                nb_fail++;
            } 
            else 
            {
                for ( i = 0; i < nb; i++) 
                {
                        printf("Address = %d, value %d (0x%X) \n",
                                addr+i,
                                tab_registers[i],
                                tab_registers[i]);


                }
            }
            // read intput registers
            //modbus_read_input_registers


            sleep(5);
        }


        printf("Test: ");
        if (nb_fail)
            printf("%d FAILS\n", nb_fail);
        else
            printf("SUCCESS\n");
    }


    /* Free the memory */
    free(tab_bits);
    free(tab_in_bits);
    free(tab_registers);
    free(tab_in_registers);


    /* Close the connection */
    modbus_close(ctx);
    modbus_free(ctx);


    return 0;
}

三、测试结果

打开modbus slave的测试软件,从站地址为0x11,配置如下:

e690a1f5268aa249056cf83b69f78046.png

modbus tcp主站,读取信息如下:

be9976048f51ecaf2094fdc6ba0946a5.png

主站正确读取到了从站的信息。

欢迎关注公众号:嵌入式学习与实践


http://www.niftyadmin.cn/n/5117291.html

相关文章

hdlbits系列verilog解答(4输入门操作)-15

文章目录 一、问题描述二、verilog源码三、仿真结果 一、问题描述 构建具有四个输入的组合电路&#xff0c; in[3:0] 。它有三种输出&#xff1a; out_and:4输入与门的输出out_or:4输入或门的输出out_xor:4输入异或门的输出 二、verilog源码 module top_module( input [3:0…

07-类文件结构

类文件结构 JVM 的“无关性” 谈论 JVM 的无关性&#xff0c;主要有以下两个&#xff1a; 平台无关性&#xff1a;任何操作系统都能运行 Java 代码语言无关性&#xff1a; JVM 能运行除 Java 以外的其他代码 Java 源代码首先需要使用 Javac 编译器编译成 .class 文件&#…

Linux CentOS 8(firewalld的配置与管理)

Linux CentOS 8&#xff08;firewalld的配置与管理&#xff09; 目录 一、firewalld 简介二、firewalld 工作概念1、预定义区域&#xff08;管理员可以自定义修改&#xff09;2、预定义服务 三、firewalld 配置方法1、通过firewall-cmd配置2、通过firewall图形界面配置 四、配置…

Overmind VS Redux

Overmind Overmind 是一个状态管理库&#xff0c;它可以帮助你管理应用程序的状态和副作用。下面是一个使用 Overmind 的简单示例&#xff1a; 首先&#xff0c;我们需要安装 Overmind 和它的 React 绑定&#xff1a; npm install overmind overmind-react然后&#xff0c;我…

AnkiPDF Guru软件评测:打开全新学习方式的大门

在当今信息爆炸的时代&#xff0c;如何高效学习和记忆成为了每个人关注的焦点。AnkiPDF Guru软件作为结合了Anki和PDF的学习利器&#xff0c;向我们展示了一种全新的学习方式。本文将以软件的实用性和使用场景为切入点&#xff0c;从专业的角度客观分析和评测该软件&#xff0c…

C# 写入文件比较

数据长度&#xff1a;128188个long BinaryWriter每次写一个long 耗时14.7828ms StreamWriter每次写一个long 耗时44.0934 ms FileStream每次写一个long 耗时20.5142 ms FileStream固定chunk写入&#xff0c;循环操作数组&#xff0c;耗时13.4126 ms byte[] chunk new byte[d…

迅为龙芯2K1000开发板加载PMON镜像

注意&#xff1a;这里不建议大家在没有 Ejtag 的情况下对 PMON 进行操作&#xff0c;以免开发板变砖。 设置完网络后&#xff0c;我们输入命令 load -f 0xbfc00000 -r tftp://192.168.1.38/gzrom-dtb.bin&#xff0c;其中 192.168.1.38 为虚拟机 Ubuntu 的 IP 地址&#xff0…

《语音优先》智能语音技术驱动的交互界面设计与语音机器人设计(译者序)...

“言为心声,语为心境”&#xff0c;语言与对话是我们沟通与协作的重要方式。而智能语音技术是一种基于人工智能和自然语言处理技术的语音交互技术。它可以通过语音识别技术将用户的语音指令转换为文本&#xff0c;然后通过自然语言处理技术对文本进行分析和理解&#xff0c;最终…