硬件成本5元-USB串口采集电表数据完整方案-ThingsPanel快速入门

ThingsPanel开源物联网平台支持广泛的协议,灵活自由,本文介绍ThingsPanel通过串口来采集电表数据,简单易行,成本低廉,适合入门者学习试验,也适合一些特定的应用场景做数据采集。

适用场景:

  • 降低Modbus设备数据采集成本
  • 快速测试Modbus电表数据采集
  • 物联网入门学习Modbus相关知识

效果图

方案价值

这套方案最大的价值在于:

  • 最低代码改动,复制修改配置即可运行

  • 硬件成本低,5块钱,一个USB转RS485连接器即可

  • 能快速实现电表数据远程监控,适用于学习、以及正式用途等各种场景

  • 支持数据可视化和历史记录查询

  • 无需布置复杂的网络,只需要一台电脑和网络即可

    接入结构图

所需设备

USB转RS485连接器(淘宝搜索"USB转485",5元左右)

支持Modbus协议的电表

一台电脑(Windows/Mac都可以)

操作步骤

1. 硬件连接

  1. 将USB转RS485连接器插入电脑
  2. 将连接器的A+和B-接线端子与电表对应端子连接
  3. A+ 接电表的 A+
  4. B- 接电表的 B-

2. 确认设备端口

Windows用户:

打开设备管理器

查看"端口(COM和LPT)"下的COM端口号

Mac用户:

打开终端

输入命令:ls /dev/tty.*

找到类似 /dev/tty.usbserial-110 的设备名

3. 安装Python环境

访问 https://www.python.org/downloads/

下载并安装Python 3.x版本

4. 安装必要的软件包

打开终端或命令提示符,运行:

pip install pyserial pip install pymodbus==3.7.2 pip install paho-mqtt

5. 创建并运行采集程序

创建一个新文件 meter_collector.py

将以下代码复制到文件中(注意修改端口号):

===================代码区域开始=====================

import time

import json

from pymodbus.client.serial import ModbusSerialClient

from pymodbus.constants import Endian

from pymodbus.payload import BinaryPayloadDecoder

import paho.mqtt.client as mqtt

MQTT配置-信息来自ThingsPanel平台,创建设备后在设备连接信息中。

MQTT_CONFIG = {

"broker": "47.115.210.16",

"port": 1883,

"username": "fe917b16-d786-3297-8f1",

"password": "f129542",

"client_id": "mqtt_3243936a-c23",

"telemetry_topic": "devices/telemetry",

"control_topic": "devices/telemetry/control/3243936a-c237-8cc5-7ea9-ba586098c2b7"

}

Modbus配置(来自电表说明书,port需要自行在本机查询)

METER_CONFIG = {

"port": "/dev/tty.usbserial-110",

"baudrate": 9600,

"parity": 'E',

"stopbits": 1,

"bytesize": 8,

"byte_order": Endian.BIG

}

如下配置来自于电表设备说明书

DATA_ITEMS = [

{"name": "Voltage", "address": 0, "data_type": "int16-1", "factor": 0.1, "registers": 1},

{"name": "Current", "address": 3, "data_type": "int16-1", "factor": 0.01, "registers": 2},

{"name": "TotalActivePower", "address": 7, "data_type": "int16-1", "factor": 1, "registers": 1},

{"name": "TotalReactivePower", "address": 11, "data_type": "int16-1", "factor": 1, "registers": 1},

{"name": "TotalApparentPower", "address": 15, "data_type": "int16-1", "factor": 1, "registers": 1},

{"name": "TotalPowerFactor", "address": 19, "data_type": "int16-1", "factor": 0.001, "registers": 1},

{"name": "VoltageFrequency", "address": 26, "data_type": "int16-1", "factor": 0.01, "registers": 1}

]

MQTT回调函数

def on_connect(client, userdata, flags, rc):

print(f"Connected to MQTT broker with result code {rc}")

订阅控制主题

client.subscribe(MQTT_CONFIG['control_topic'])

def on_message(client, userdata, msg):

try:

print(f"Received message on topic {msg.topic}: {msg.payload.decode()}")

这里可以添加处理接收到的控制命令的逻辑

data = json.loads(msg.payload.decode())

if 'switch' in data:

print(f"Received switch command: {data['switch']}")

except Exception as e:

print(f"Error processing message: {e}")

def create_mqtt_client():

client = mqtt.Client(client_id=MQTT_CONFIG['client_id'])

client.username_pw_set(MQTT_CONFIG['username'], MQTT_CONFIG['password'])

client.on_connect = on_connect

client.on_message = on_message

try:

client.connect(MQTT_CONFIG['broker'], MQTT_CONFIG['port'], 60)

client.loop_start()

return client

except Exception as e:

print(f"MQTT连接失败: {e}")

return None

Modbus函数(与之前相同)

def create_modbus_client():

return ModbusSerialClient(

port=METER_CONFIG['port'],

baudrate=METER_CONFIG['baudrate'],

parity=METER_CONFIG['parity'],

stopbits=METER_CONFIG['stopbits'],

bytesize=METER_CONFIG['bytesize'],

timeout=1,

retries=3

)

def read_meter_data(client, slave_id):

data = {}

for item in DATA_ITEMS:

try:

result = client.read_holding_registers(

address=item['address'],

count=item['registers'],

slave=slave_id

)

if result and not result.isError():

decoder = BinaryPayloadDecoder.fromRegisters(

result.registers,

byteorder=METER_CONFIG['byte_order'],

wordorder=Endian.BIG

)

if item['data_type'] == 'int16-1':

value = decoder.decode_16bit_int()

else:

value = decoder.decode_16bit_uint()

data[item['name']] = value * item['factor']

else:

data[item['name']] = None

except Exception as e:

print(f"读取 {item['name']} 时出错: {str(e)}")

data[item['name']] = None

return data

def main():

print("正在连接Modbus设备...")

modbus_client = create_modbus_client()

if not modbus_client.connect():

print("无法连接到Modbus设备")

return

print("正在连接MQTT服务器...")

mqtt_client = create_mqtt_client()

if not mqtt_client:

print("无法连接到MQTT服务器")

modbus_client.close()

return

print("开始数据采集和上报循环...")

try:

while True:

data = read_meter_data(modbus_client, slave_id=1)

过滤掉读取失败的数据

valid_data = {k: v for k, v in data.items() if v is not None}

if valid_data:

发布数据到MQTT

try:

mqtt_client.publish(

MQTT_CONFIG['telemetry_topic'],

json.dumps(valid_data)

)

print(f"数据已上报: {valid_data}")

except Exception as e:

print(f"MQTT发布失败: {e}")

等待10秒

time.sleep(10)

except KeyboardInterrupt:

print("\n程序终止...")

finally:

print("正在关闭连接...")

modbus_client.close()

mqtt_client.loop_stop()

mqtt_client.disconnect()

print("连接已关闭")

if name == "main":

main()

===================代码区域结束=====================

6. 运行程序

  • 打开终端或命令提示符
  • 进入程序所在目录
  • 运行命令:

python meter_collector.py

7. 查看数据

  • 登录 ThingsPanel 平台
  • 进入设备详情页面
  • 可以看到实时上报的电表数据

常见问题

连接不上设备?

  • 检查接线是否正确
  • 确认端口号是否正确
  • 验证电表波特率是否为9600

数据显示异常?

  • 确认电表地址是否为1
  • 检查接线是否松动

无法连接平台?

  • 检查网络连接
  • 验证MQTT配置信息是否正确

扩展功能

  • 可以通过修改代码中的 time.sleep(10) 来调整数据上报频率
  • 支持添加多个电表,只需修改 slave_id 即可

现在,您的电表数据就可以实时推送到云平台了!

相关推荐
薛慕昭11 小时前
《从硬件到云端:STC8H ADC数据采集与华为物联网平台对接全解析》
服务器·物联网
zskj_zhyl11 小时前
银发科技:AI健康小屋如何破解老龄化困局
人工智能·科技·物联网
Blossom.11812 小时前
量子计算在密码学中的应用与挑战:重塑信息安全的未来
人工智能·深度学习·物联网·算法·密码学·量子计算·量子安全
龙大大L1 天前
第五章:5.3 ESP32物联网应用:阿里云IoT平台与腾讯云IoT平台的数据上传与远程控制
java·物联网·struts·esp32
移远通信1 天前
QuecPython+GNSS:实现快速定位
物联网·gnss·quecpython
小叮当⇔1 天前
IOT项目——物联网 GPS
物联网
程序边界1 天前
DeepSeek在物联网设备中的应用:通过轻量化模型实现本地化数据分析
物联网·struts·数据分析
网易独家音乐人Mike Zhou1 天前
【Linux应用】交叉编译环境配置,以及最简单粗暴的环境移植(直接从目标板上复制)
linux·stm32·mcu·物联网·嵌入式·iot
塔能物联运维2 天前
解析塔能科技:绿色低碳智慧节能一站式破局之匙
大数据·人工智能·物联网
无脑学c++2 天前
STM32串口重定向:MDK与GCC重定向需重写的不同函数
stm32·单片机·物联网