news 2026/9/20 10:22:59

C++开发的智能电表读数程序:支持485与计算机读取电量并存功能

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++开发的智能电表读数程序:支持485与计算机读取电量并存功能

C++开发的智能电表读数程序,可用485和计算机读取电量并存

最近在搞一个C++开发的智能电表读数程序,主要是通过485接口和计算机通信,读取电量并存到数据库里。说实话,这玩意儿一开始还挺让人头疼的,毕竟涉及到硬件通信和数据处理,搞不好就各种bug满天飞。不过,经过一番折腾,总算搞定了,今天就来聊聊这个过程。

首先,485通信这块儿,C++里用到了libmodbus这个库。这个库挺方便的,封装了底层的通信细节,直接调用API就能搞定。先来看一下初始化485通信的代码:

#include <modbus/modbus.h> modbus_t *ctx; ctx = modbus_new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1); if (ctx == NULL) { fprintf(stderr, "Unable to create the libmodbus context\n"); return -1; } if (modbus_connect(ctx) == -1) { fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); modbus_free(ctx); return -1; }

这段代码主要是初始化一个modbust对象,指定了串口设备、波特率、校验位等参数。如果初始化失败,程序就直接退出了。modbusconnect函数用来建立连接,失败的话也会退出并释放资源。

接下来就是读取电表数据的部分了。电表的数据一般存储在寄存器里,通过读取寄存器来获取电量信息。我们假设电量的寄存器地址是0x0001,数据类型是16位无符号整数。代码如下:

uint16_t tab_reg[1]; int rc = modbus_read_registers(ctx, 0x0001, 1, tab_reg); if (rc == -1) { fprintf(stderr, "Failed to read registers: %s\n", modbus_strerror(errno)); modbus_close(ctx); modbus_free(ctx); return -1; } uint16_t power = tab_reg[0]; printf("Current power: %d kWh\n", power);

modbusreadregisters函数用来读取寄存器数据,参数分别是上下文、寄存器地址、读取数量和存储数据的数组。如果读取失败,程序会打印错误信息并退出。成功的话,数据会存储在tab_reg数组中,我们取出第一个元素就是当前的电量值。

C++开发的智能电表读数程序,可用485和计算机读取电量并存

读取到电量后,下一步就是存到数据库里了。这里我用的是SQLite,因为它轻量级,不需要额外的数据库服务器。先来看一下数据库的初始化代码:

#include <sqlite3.h> sqlite3 *db; char *err_msg = 0; int rc = sqlite3_open("power.db", &db); if (rc != SQLITE_OK) { fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); return -1; } char *sql = "CREATE TABLE IF NOT EXISTS PowerLog (id INTEGER PRIMARY KEY AUTOINCREMENT, power INTEGER, timestamp DATETIME DEFAULT CURRENT_TIMESTAMP);"; rc = sqlite3_exec(db, sql, 0, 0, &err_msg); if (rc != SQLITE_OK) { fprintf(stderr, "SQL error: %s\n", err_msg); sqlite3_free(err_msg); sqlite3_close(db); return -1; }

这段代码打开了一个SQLite数据库文件power.db,如果文件不存在会自动创建。然后执行了一个SQL语句,创建了一个PowerLog表,用来存储电量数据。表中有三个字段:id是自增主键,power是电量值,timestamp是记录时间,默认是当前时间。

最后一步就是把读取到的电量存到数据库里:

char sql_insert[100]; sprintf(sql_insert, "INSERT INTO PowerLog (power) VALUES (%d);", power); rc = sqlite3_exec(db, sql_insert, 0, 0, &err_msg); if (rc != SQLITE_OK) { fprintf(stderr, "SQL error: %s\n", err_msg); sqlite3_free(err_msg); } sqlite3_close(db);

这里用sprintf动态生成了一条SQL插入语句,把电量值插入到PowerLog表中。如果插入失败,程序会打印错误信息。最后别忘了关闭数据库连接。

整个过程就是这样了,从485通信到读取数据,再到存储到数据库,虽然步骤不少,但每个环节都还算清晰。当然,实际项目中可能会遇到更多问题,比如通信不稳定、数据格式复杂等等,这就需要根据具体情况来调整了。不过,掌握了这些基本操作,后续的优化和扩展就会容易很多。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 10:45:44

C#-使用OpenTK渲染3D模型

一.OpenTK&GLControlOpenTK:OpenGL的封装库,支持3D数据的加载和初始化GLControl:OpenGL的Winform渲染窗口,能将OpenGL渲染结果映射至Winform的控件上二.OpenTK网格初始化private void RenderCube() {GL.Begin(PrimitiveType.Lines);GL.Vertex3(-0.5f, -0.5f, 0.5f); // 左下…

作者头像 李华
网站建设 2026/9/19 3:04:52

实测才敢推!自考必备的降AI率平台 —— 千笔·专业降AIGC智能体

在AI技术日益渗透学术写作的当下&#xff0c;越来越多的学生开始借助AI工具提升论文效率。然而&#xff0c;随着知网、维普、万方等查重系统对AI生成内容的识别能力不断提升&#xff0c;以及Turnitin对AIGC的严格审查&#xff0c;论文中的“AI率超标”问题愈发成为影响毕业和学…

作者头像 李华
网站建设 2026/9/13 7:47:53

vue3+nodejs气象数据共享平台 天气预报数据共享系统

文章目录技术架构设计数据获取与处理数据可视化实现用户权限与共享机制性能优化策略部署与监控扩展性设计--nodejs技术栈--结论源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;技术架构设计 Vue3作为前端框架&#xff0c;结合Node.js后…

作者头像 李华
网站建设 2026/9/12 8:09:01

琐事如尘,生活如花

清晨六点半&#xff0c;闹钟响起前的五分钟&#xff0c;我已经睁开眼。厨房里&#xff0c;昨晚泡好的黄豆等着被打成豆浆&#xff0c;面包机里的面团正在最后一次发酵。这是我每天的序曲&#xff0c;平凡得像空气&#xff0c;却不可或缺。生活是由无数琐事织成的网——洗衣、做…

作者头像 李华
网站建设 2026/9/14 23:10:35

2025年AI技术栈大揭秘!顶尖互联网公司都在用的“黄金组合”

还在为技术选型纠结&#xff1f;这套被无数成功AI产品验证的技术栈&#xff0c;让你少走3年弯路&#xff01;在AI浪潮席卷全球的2025年&#xff0c;一个残酷的事实摆在眼前&#xff1a;**选对技术栈&#xff0c;成功率提升300%**。通过分析上百家成功AI创业公司的技术架构&…

作者头像 李华