串口通信之(一)获取传感器数据(modbus rtu master)

一天领导拿了几个传感器设备丢给我,给我把这些数据取到。

 

我一看,好家伙。这是要搞硬件了啊。那就搞他丫的。

 

可是,怎么搞是个问题。我是一头雾水。

 

还好,和传感器丢给我的,还有传感器厂家一起给的一些相关的资料(传感器的接线说明,调试软件,和java写的demo)

 

曾以为有文档和demo在手,就是让我上天,我也给走上一遭。可哪想到,即便是能上了天,

所遇到的问题,也能把磨到,上天的只剩下灵魂。

 

由于什么都不懂,真是困难重重。线,接起来不对。代码运行不进来。我想哭,怎么办?

 

于是我把着厂家技术支持这根稻草不放了。一个劲的问人家,都把人家问得烦了。线虽然接对了,可是代码还是运行起来。我再问,这下可好,人家是真烦了,被随便应付了。

 

可是,我知道了,要把这个传感的数据取到。需要用到485串口通信。于是我网上搜485串口通信。找到一份代码,而且能用。这可把我牛逼坏了,嘿嘿,果然没有什么是能难到程序员的。算是能成功取到了数据。

 

这里贴出这个程序的博客的地址。后面我也把我整理了一下的代码附上。

https://www.cnblogs.com/new-life/p/9345849.html

后来,我才知道这篇博客是写了一个相当于master程序,只能从传感器上获取到数据。

 

后来由于这个程序没有处理线程和粘包的问题,不太能满足需求,所以又需要改。

 

这时,已经知道了rtxxComm就是直接对串口进行操作的(读写数据),在上面的程序就是基于这个来写的。而rxtxComm中读写数据也是基于流来的。所以想到了结合netty,来写一个master。一下给出在代码没有处理粘包(写一个Decoder,在其中处理好一个完整的包,再传到handler就是了)

 

master.java

public class Mater{
    private String portName;//串口名
    private int baudrate;//波特率
    RxtxChannel channel;
    List<String> data;//将设备返回的数据,解析后存于改list


    public Mater(String portName, int baudrate,List<String> data) {
        this.data=data;
        this.portName = portName;
        this.baudrate = baudrate;
    }

    public void run(){

        try {
            OioEventLoopGroup group = new OioEventLoopGroup();
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channelFactory(new ChannelFactory<RxtxChannel>() {
                        public RxtxChannel newChannel() {
                            return channel;
                        }
                    })
                    .handler(new ChannelInitializer<RxtxChannel>() {
                        @Override
                        public void initChannel(RxtxChannel ch) throws Exception {
                            ch.pipeline().addLast(
                                    new RxtxHandler()
                            );
                        }
                    });

            channel = new RxtxChannel();
            channel.config().setBaudrate(baudrate);
            channel.config().setDatabits(RxtxChannelConfig.Databits.DATABITS_8);
            channel.config().setParitybit(RxtxChannelConfig.Paritybit.EVEN);
            channel.config().setStopbits(RxtxChannelConfig.Stopbits.STOPBITS_1);
            ChannelFuture future = b.connect(new RxtxDeviceAddress(portName)).sync();
            System.out.println("rxtx启动成功");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }



    public void writeAndFlush(String hexString) {
        String s = CRC16Util.crcDeal(hexString);
        System.out.println("手动发送数据:"+s);
        byte[] bytes = ByteUtil.hexStringToBytes(s);
        ByteBuf buffer = channel.alloc().buffer();
        ByteBuf byteBuf = buffer.writeBytes(bytes);
        channel.writeAndFlush(byteBuf);
    }

    public void inputCmd(){
        Scanner sc=new Scanner(System.in);
        while (true){
            String s = sc.nextLine();
            writeAndFlush(s);
        }
    }
    //不断请求传感器数据
    public void request() throws InterruptedException {
        String [] cmds = new String[]{"030300000002","020300020001","040300030001"};
        for (int i = 0; i < cmds.length; i++) {
            Thread.sleep(500);
            writeAndFlush(cmds[i]);
        }

    }

    //程序入口
    public static void main(String[] args) {
        Master master =new Master("COM3",9600,new ArrayList());
        master.run();
        master.request();
    }

}
RxtxHandler.java

public class RxtxHandler  extends ChannelInboundHandlerAdapter {



    /**
     * 客户端接收到数据的回调
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception{

         byte[] read =new byte[in.readableBytes()];
         in.readBytes(read);
         //将byte数据转成16进制的数据报文
         //String packet = ByteUtil.BinaryToHexString(read).toUpperCase();
         //可以对数据进行处理
         //System.out.println(packet);
    }

 

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {

        cause.printStackTrace();

        ctx.close();
    }





}

 

 

  • 10
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
在Linux下,我们可以使用开源的Modbus库来开发一个Modbus RTU主站应用。下面是一个300字左右的示例案例: Modbus RTU是一种串行通信协议,广泛应用在工业自动化中。在Linux下开发Modbus RTU主站应用需要使用一个可靠的Modbus库,比如libmodbus。首先,我们需要在Linux系统上安装该库。 接下来,我们可以使用C语言编写一个简单的Modbus RTU主站应用程序。首先,我们需要初始化一个modbus_t结构体来表示一个Modbus主站设备。我们需要指定串口设备文件名、波特率、奇偶校验等参数。然后,我们可以使用modbus_set_slave函数设置从站地址。 接下来,我们可以使用modbus_connect函数打开与从站的串口连接。然后,我们可以使用modbus_read_registers函数从从站中读取寄存器的值。也可以使用modbus_write_registers函数向从站写入寄存器的值。 在主站应用程序中,我们可以根据需要周期性地读写从站的寄存器,从而实现与从站之间的数据交换。我们可以使用modbus_close函数关闭与从站的连接。 最后,我们可以使用modbus_t结构体中的其他函数来释放资源,比如modbus_free函数用于释放主站设备所占用的内存。 总结起来,对于一个Modbus RTU主站开发案例,在Linux下我们可以使用libmodbus库来开发一个高效可靠的应用程序。我们需要熟悉libmodbus库的API,然后使用C语言编写一个主站应用,实现与从站之间的数据交换。这样我们就能够在Linux系统下开发出一个功能完善、稳定可靠的Modbus RTU主站应用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值