写代码之前

最近代码写慢了,磨了好久都没开始动手写代码。考虑的东西越多越多,甚至自己都认为过虑了。就像这个程序,写代码之前估计花了大半天或者一天在思考怎么写,不知道是好事还是年纪大了。所以专门写篇文章,把自己思考的内容写出来,作个回顾。

一, 需求

需求一定要了解清楚才动手,不然后面改出花来。这个程序看起来不算复杂,要实现的功能就是通过串口或者TCP实现Modbus协议,采集数据并存储到redis去,也会处理写操作和透传。(现在回顾起来,当时慢的一个原因是产品定义是自己,需求其实没想清楚,想需求时又考虑了技术实现,应该要优化。)

1.1 架构中的层次及接口

系统业务软件整体架构在《工业物联网关-整体框架》文章有介绍,业务软件架构如下图:

当前要实现的是上图中"底层采集程序(C语言)"这个软件,从图可以看出,上层接口是redis软件,包括了缓存和消息队列接口。下层是串口和网口,对接的是终端设备,软件要实现modbus-rtumodbus-tcp通信。

1.2 配置

需要通过串口和网口与哪些设备通信,采集的数据区有哪些,数据要解析为什么变量,这些都需要用户配置。我们网关提供了web界面给用户,支持手动和excel(CSV)导入的方式生成配置文件,程序读取这些配置后才能正常工作。
参考了物模型的概念(后面有更多的内容),有产品,设备配置文件,里面包括了数据区和变量的配置。串口和网口配置文件,主要包括通信参数和外挂了哪些设备。
一些思考:web 那边有提过下发配置给网关,可能跟现在差不多,是json格式的。这个兼容性的问题就值思考了,web那边是随时可以改的。网关的话,发货后再改就麻烦,就算是远程升级也是麻烦。目前的想法是找个标准,大家支持,web端可以生成配置文件,网关来导入,例如都支持thingsboard的标准。如果web要改,那恐怕是要支持另一个标准了,同时网关也得跟着改。

1.3 log & debug

开发阶段可以用gdb和printf来调试,后期debug主要靠log了,另外需要在web界面上dump通信的报文,以调试设备通信及协议等问题。log 支持开关和打印等级功能,支持输出到文件功能,要注意log文件不能太大。(调试和LOG相关花了不少时间,包括打印开关和等级控制,输出到文件后怎么清掉,web端怎么读log。其实最开始应该就用printf和gdb好了,log什么的后面再改,反正不影响程序逻辑。)

二, 数据结构

2.1 数据格式转换

在物联网之前,web跟硬件设备交集不多,又因为各自生存土壤的区别,数据存储及格式会有差异。对资源非常吝啬的硬件设备喜欢用寄存器存储数据,1个字节1个bit都斤斤计较,以节省存储空间和减少CPU(MCU)的运算。而web端相对财大气粗,不同含义的数据用变量解耦出来,分开处理和存储。更喜欢考虑分布式存储,负载均衡等技术。一个典型的例子是设备有个寄存器,有8bit,低4个bit代表某个数值,范围就是0-15,高4个bit分别代表某个硬件开关,例如为0就亮灯,为1就灭灯之类。到了web端通常用1个整型变量和1个boolean数组(或4个boolean变量)来存储。
网关的其中一个任务就是把设备的数据格式转化为web端的数据格式。参考过往modbus协议的生态和物模型的概念,常规的转换流程是: 寄存器 - 数据区 - 变量,双向的。网关是不知道数据的含义的,所以是提供配置方式,让用户来配置。
变量可以用一系列的属性来描述,下图是阿里云配置变量属性的界面:

配置完成后生成一个json格式的数据结构:

{"code": "energy_ALL","name": "合相有功电能","unit": "Kwh","area_code": "elec_power","area_offset": 120,"value_type": "float","value_size": 4,"byte_order": "1234","value_base": 0,"value_ratio": 0.1
}

这个数据结构在web端对应的变量可能是:

private double energy_ALL; // 合相有功电能,单位是:Kwh

网关缓存了一个标识名为"elec_power"的数据区,这个变量的值在数据区偏移120字节的位置,占4个字节,字节序是小头(1234),数据类型是浮点型(float)。

2.2 程序数据结构设计

为了适配物联网数据转换的需求,程序里有物模型相关的产品类,设备类,有描述变量的属性类。有硬件设备相关的数据区结构体,整体如下:

上图的数据结构还关联了串口类,网口类,与这里无关,可以忽略。
如上图所示,属性描述类"attribute_desc_s"是变量相关的最顶层,产品类里面包含多个这样的描述,设备类其实是产品的一个对象,所以也会继承属性类的内容。这些数据结构代码如下:

// 属性结构体
struct attribute_desc_s
{char *code; // 唯一标识char *name; // 名字char *unit; // 单位char *area_code; // 数据区标识符unsigned int area_offset;    // 数据区偏移,单位:byteunsigned int bit_mask;       // 掩码,只有boolean 类型有用unsigned short value_size;   // 值占用空间大小,单位是byteunsigned char attr_type;     // 属性类型, ATTR_TYPE_, 目前就属性和遥测2种unsigned char value_type;    // 值类型, VAL_TYPE_unsigned char byte_order;    // 字节序, double value_base;           // 基值(默认0)double value_ratio;          // 系数(默认1.0)
};// 产品结构体
struct product_s
{char *code; // 唯一标识char *name; // 名字int area_num; // 数据区个数struct data_area_desc_s *area_descs; // 数据区描述数组int attr_num; // 属性(遥测)个数struct attribute_desc_s *attr_descs; // 属性(遥测)描述数组
};

从上图中还可以看出来,数据区"data_area_desc_s"是硬件设备相关最顶层结构体,设备类会继承,代码如下:

// 数据区结构体
struct data_area_desc_s
{char *code; // 唯一标识char *name; // 名字unsigned char  reg_type; // 寄存器类型, REG_TYPE_unsigned char  reg_size; // 寄存器占空间大小,单位byteunsigned short reg_num;  // 寄存器个数unsigned int reg_addr;   // 寄存器地址(modbus), 数据标识(dlt645)
};// 设备数据区结构体
struct dev_data_area_s
{struct data_area_desc_s *desc;  // 数据区描述unsigned char *val;             // 数据区指针
};// 设备结构体
struct device_s
{char *code; // 唯一标识char *name; // 名字char *id;   // id, modbus, dlt645 都需要char *product_code;             // 产品标识struct product_s *product;      // 产品 = 设备类unsigned int area_num;          // 数据区个数struct dev_data_area_s *areas;  // 设备数据区指针数组unsigned int attr_num;          // 属性个数struct dev_attribute_s *attrs;  // 设备属性指针数组unsigned char online;           // >0代表在线,=0代表离线long next_time_sec;             // 下次轮询的时间
};

三,线程设计

我认为,对于一个规模不大的程序来说,确定好数据结构和程序流程图(线程),基本上程序的框架出来了。这个程序我设计了3个类型的线程,分别是主线程,串口采集线程,网口采集线程。主线程的作用是初始化,外部命令处理。我为每个串口通道分配了1个线程,而所有网络通道处理共用1个线程,这样做是因为串口涉及底层硬件操作,分开线程好处理,网口所有通道其实只有"socket fd"不一样,可以用"fd_set"一并处理,在源码介绍的文章再详解。

上图有画得不好的地方,这里解释一下。主线程收到退出命令,会给其它线程发退出指令,等其它线程都退出后,主线程退出,然后整个程序结束。
下一篇介绍源码,待续。

工业物联网关-modbus数据采集程序(1-程序设计)相关推荐

  1. 物联网知识:工业物联网关具备那些优秀的功能及特点

    工业物联网关简述 工业物联网关S47x是一款多功能可编程控制器的无线网络工业物联网数据监控收集操纵报警短信终端设备,广泛运用于工业物联网全产业链中远程数据监测及其收集,如智慧能源. 智慧交通.智能家居 ...

  2. 别再傻傻分不清:工业物联网关与PLC采集网关的区别了

    工业物联网关与PLC采集网关的区别 工业物联网网关是指支持多种协议转换且可以接入工业物联云平台的网关,比如下行支持DLT645.Modbus协议,上行支持Thingsboard.Azure.AWS.华 ...

  3. 工业能源的背后,边缘计算工业物联网关发挥着怎样的作用

    随着"双碳"目标的深入发展,能源行业作为护航"双碳"目标的排头兵,其行业数字化转型已进入高质量发展阶段,为更好推动发电集团数字化转型业务,各集团都在积极探索并构 ...

  4. 基于开源硬件Banana Pi 的工业物联网关设计

    产品简介 FCIGC-600M大型工业物联网智能网关是新一代物联网接入设备,配备2个独立IP以太网和8个RS485接口,配置灵活,广泛适用于电力.石油.厂矿.及物联网行业的自动化监控场合. 为满足现场 ...

  5. 为啥不用PC机做物联网关?物联网关有啥特征?工业物联网产业的发展之道?

    PC主机其实是可以做物联网关的,PC主机有各种本地设备接口,串口,HDMI口,可以插扩展卡拓展本地的设备接口,南向对接OT物联没问题,各种数采终端设备.传感器.智能仪器仪表.工控设备开发时就支持上位机 ...

  6. 基于LoRa水表数据采集的工业物联网网关

    随着无线通信技术的飞速发展,物联网技术已经和人们的生产生活融合在一起,发挥出各种便利的作用.工业物联网技术让水务行业变得更加智能,水表数据可以采集上传到云平台,实现远程监控智能管理. 在智慧工厂和智慧 ...

  7. 4G MQTT RTU物联网关选型参考

    4G MQTT RTU物联网关选型参考 4G RTU是指基于4G网络传输的Remote Terminal Unit, 即遥测终端.因其本身带有IO口,逻辑控制.定时器.历史记录存储.以及通过RS485 ...

  8. 西门子SIMATIC IOT2050与钡铼技术BL102工业物联网智能网关的区别

    工业物联网智能网关是工业物联网技术不断发展的必然产物,是融合IT与OT的纽带.不管是工业控制领域的国际大品牌玩家,还是国内的小精专企业,都根据市场需求推出了自己的产品.这些工业物联网智能网关广泛应用于 ...

  9. 北京财经频道专访|美信CEO 胡建强:让IT和工业物联网没有难采的数据

    北京财经频道专访|美信CEO 胡建强:让IT和工业物联网没有难采的数据 10月31日下午,北京电视台财经频道<北京直通车>节目--<美信科技CEO 胡建强:让IT和工业物联网没有难采 ...

最新文章

  1. 51CTO让我成长【我与51CTO的故事】
  2. matlab如何配置weka,matlab调用weka
  3. electron 剪贴板 截图_用electron开发了一个屏幕截图工具
  4. 公共基础选择题前10t
  5. Sublime Text 3插件收集
  6. 搭建JAVA可视化开发环境
  7. HDU 2822 Dogs【两次bfs】
  8. 怎样去掉警告 log4j:WARN No appenders could be found for logger
  9. vue项目中对axios的全局封装
  10. C++primer第十章 泛型算法 10.4 再探迭代器 10.5 泛型算法结构
  11. oracle unpivot 索引_Oracle 行转列pivot 、列转行unpivot 的Sql语句总结
  12. linux测试硬盘的ipos,Linux/Unix平台data-recovery常用的工具
  13. 1603. 设计停车系统
  14. 一个完整的c语言程序~~简单的实例
  15. 历年计算机信息系统管理师真题,历年计算机软考信息系统项目管理师真题
  16. 计算机出现蓝屏怎么恢复,重启电脑后出现蓝屏怎么办
  17. 编译原理 C-Minus 语法分析(Flex / Bison)
  18. 安装UltraISO后,删除 Win10 电脑中多出的“CD驱动器”盘符
  19. 使用Python代码实现一个简单的分子动力学模拟程序
  20. Codeforces Round #495 (Div. 2) D. Sonya and Matrix[思维构造]

热门文章

  1. 一指闪付,Huawei Pay让钱包、银行卡和公交卡统统下岗
  2. autocad打开时多个文件时任务栏也出现多窗口
  3. 01_生活要有仪式感,换个blog
  4. 苹果5g手机什么时候上市
  5. Android仿虾米音乐播放器之service
  6. tkinter.ttk 资料整理+笔记(大全)
  7. 小学生算法系统 c语言编程,小学生心算C系统.doc
  8. xp怎样升级win7系统的傻瓜教程--win10专业版
  9. Python绘制桑基图Sankey,Pyecharts不显示html页面,桑基图只显示标题,原因总结
  10. 程序员的成长故事之 袁红岗的程序人生