当前位置: 首页 > article >正文

嵌入式硬件篇---龙芯2k1000串口

针对串口错误 “device reports readiness to read but returned no data (Device disconnected or multiple access on port?)” 的排查和解决方法

硬件方面

  1. 检查连接
    • 确认串口设备(如串口线、连接的模块等)与龙芯设备之间的物理连接是否牢固,没有松动、脱落情况。尝试重新插拔串口线,确保两端都插紧。
    • 查看串口线是否有破损、断裂等物理损坏迹象,如有,更换新的串口线。
  2. 检查设备供电
    • 确保串口设备供电正常。如果是外接设备,检查其电源适配器是否正常工作,输出电压和电流是否符合设备要求。可以使用万用表测量电源适配器输出,若不正常,更换适配 器。
    • 对于由龙芯设备直接供电的串口设备,检查龙芯设备的电源输出是否稳定,可查看龙芯设备电源指示灯状态,或使用相关工具监测电源输出。
  3. 排查设备冲突
    • 确认是否有多个设备同时尝试访问该串口端口。如果有其他程序或设备在占用 /dev/ttyS3 端口,可能会导致冲突。关闭其他可能使用该串口的程序或设备,然后重新测试。

软件方面

  1. 权限检查
    • 确保当前用户对 /dev/ttyS3 端口有足够的读写权限。在龙芯系统的终端中,使用命令 ls -l /dev/ttyS3 查看端口权限。如果权限不足,可通过 sudo chmod 666 /dev/ttyS3 临时赋予读写权限(不建议长期使用这种宽泛的权限设置,生产环境可通过添加用户到 dialout 等相关组来解决权限问题,如 sudo usermod -a -G dialout your_username ,然后重新登录)。
  2. 驱动检查与更新
    • 确认串口设备的驱动程序已正确安装。在龙芯系统中,可通过查看系统日志(一般在 /var/log 目录下,如 dmesg 日志),搜索与串口设备相关的信息,看是否有驱动加载错误提示。
    • 如果驱动程序版本过旧,尝试更新驱动。可到龙芯官方或设备制造商官网查找适用于龙芯平台的最新驱动程序,按照说明进行安装。
  3. 程序逻辑检查
    • 检查使用串口的应用程序代码,确认打开串口的参数设置(如波特率、数据位、停止位、校验位等)是否与串口设备实际设置一致。如果设置不匹配,会导致数据读取异常。
    • 排查程序中是否存在多线程或异步操作对串口访问的影响,确保对串口的读写操作是线程安全的,避免出现竞争条件导致数据读取失败。

import json
import time
import paho.mqtt.client as mqtt
import serial# 配置
MQTT_BROKER = "115.28.209.116"
MQTT_PORT = 1883
MQTT_USERNAME = "bkrc"
MQTT_PASSWORD = "88888888"
CLIENT_ID = "*************"
DEVICE_ID = "*************"TOPIC_UP = f"device/{DEVICE_ID}/up"
TOPIC_DOWN = f"device/{DEVICE_ID}/down"SERIAL_PORT = "COM4"
BAUDRATE = 115200
TIMEOUT = 1# 连接成功回调
def on_connect(client, userdata, flags, reason_code, properties):if reason_code == 0:print("已连接到MQTT服务器")client.subscribe(TOPIC_DOWN)else:print(f"连接失败,错误码:{reason_code}")def on_message(client, userdata, msg):print(f"收到下行消息:{msg.topic} -> {msg.payload.decode()}")# 从串口读取温度和湿度数据
def read_data_from_serial(ser):"""从串口读取温湿度数据,格式:26.7C24.0 %RH"""if ser and ser.is_open:raw_data = ser.readline().decode('utf-8').strip()  # 读取串口数据if raw_data:try:temperature = Nonehumidity = Noneweight = None# # 提取温度数据(温度后面跟着 'C')# temp_str = raw_data.split('C')[0]  # 以 'C' 为分隔符提取温度# temperature = float(temp_str) if temp_str else None## # 提取湿度数据(湿度后面跟着 '%RH')# humidity_str = raw_data.split('C')[1].split('%')[0]  # 先分割 'C',然后分割 '%'# humidity = float(humidity_str) if humidity_str else None## # 提取温度数据(温度后面跟着 'C')# weight_str = raw_data.split('g')[0]  # 以 'C' 为分隔符提取温度# weight = float(weight_str) if weight_str else None# 判断是温度if raw_data.endswith("C"):temperature = float(raw_data[:-1])  # 去掉 C# 湿度:如 24.5 %RH 或 24.5%%RHelif "%RH" in raw_data:humi_str = raw_data.replace("%RH", "").replace("%%RH", "").strip()humidity = float(humi_str)# 重量:如 25.7g(独立上报)elif raw_data.endswith("g"):weight = float(raw_data[:-1])  # 去掉 greturn temperature, humidity,weightexcept ValueError:print("无法解析串口数据:", raw_data)return None, None,Nonereturn None, None,None# 创建MQTT客户端
client = mqtt.Client(client_id=CLIENT_ID, protocol=mqtt.MQTTv5)
client.username_pw_set(MQTT_USERNAME, MQTT_PASSWORD)
client.on_connect = on_connect
client.on_message = on_messageclient.connect(MQTT_BROKER, MQTT_PORT, keepalive=60)
client.loop_start()# 串口连接
try:ser = serial.Serial(SERIAL_PORT, BAUDRATE, timeout=TIMEOUT)print(f"成功连接串口 {SERIAL_PORT}")temperature_from_sensor = Nonehumidity_from_sensor = Noneweight_from_sensor = Nonewhile True:# 获取温度和湿度数据t, h, w = read_data_from_serial(ser)if t is not None:temperature_from_sensor = tif h is not None:humidity_from_sensor = hif w is not None:weight_from_sensor = w  # 缓存最新重量# 只要温湿度都有数据,就上传if temperature_from_sensor is not None and humidity_from_sensor is not None:data = {"sign": DEVICE_ID,"type": "1","data": {"Temp": {"temp": str(temperature_from_sensor)},"Humi": {"humi": str(humidity_from_sensor)},}}if w is not None:data["data"]["Weight"] = {"weight": str(weight_from_sensor)}weight_from_sensor = None  # 上传后清空缓存client.publish(TOPIC_UP, json.dumps(data, ensure_ascii=False))print(f"上报数据:{json.dumps(data, ensure_ascii=False)}")# 立刻清空温湿度数据,避免重复上传同样数据temperature_from_sensor = Nonehumidity_from_sensor = Nonetime.sleep(0.1)except KeyboardInterrupt:print("程序终止")client.loop_stop()client.disconnect()except serial.SerialException as e:print(f"串口错误:{str(e)}")except Exception as e:print(f"程序运行错误:{str(e)}")finally:if 'ser' in locals() and ser.is_open:ser.close()print("串口已关闭")

这段代码实现了一个通过 MQTT 协议将串口设备数据上传到服务器的功能。它从串口读取温湿度和重量数据,然后将这些数据封装成 JSON 格式发布到 MQTT 服务器。以下是对代码的详细解释:

模块导入和配置

import json
import time
import paho.mqtt.client as mqtt
import serial# 配置
MQTT_BROKER = "115.28.209.116"
MQTT_PORT = 1883
MQTT_USERNAME = "bkrc"
MQTT_PASSWORD = "88888888"
CLIENT_ID = "1c097bc15129e3e2ef44f88c286b4475"
DEVICE_ID = "29c9c7bf1dafd9ca"TOPIC_UP = f"device/{DEVICE_ID}/up"
TOPIC_DOWN = f"device/{DEVICE_ID}/down"SERIAL_PORT = "COM4"
BAUDRATE = 115200
TIMEOUT = 1

  • 模块导入:导入了处理 JSON、时间、MQTT 通信和串口通信的模块。
  • MQTT 配置:设置了 MQTT 服务器的地址、端口、用户名、密码以及客户端 ID 和设备 ID,并定义了上下行消息的主题
  • 串口配置:设置了串口的端口号、波特率和超时时间

MQTT 回调函数

# 连接成功回调
def on_connect(client, userdata, flags, reason_code, properties):if reason_code == 0:print("已连接到MQTT服务器")client.subscribe(TOPIC_DOWN)else:print(f"连接失败,错误码:{reason_code}")def on_message(client, userdata, msg):print(f"收到下行消息:{msg.topic} -> {msg.payload.decode()}")

  • on_connect:当成功连接到 MQTT 服务器时被调用,订阅下行消息主题。
  • on_message:当收到 MQTT 服务器的消息时被调用,打印收到的消息内容。

串口数据读取函数

# 从串口读取温度和湿度数据
def read_data_from_serial(ser):"""从串口读取温湿度数据,格式:26.7C24.0 %RH"""if ser and ser.is_open:raw_data = ser.readline().decode('utf-8').strip()  # 读取串口数据if raw_data:try:temperature = Nonehumidity = Noneweight = None# 判断是温度if raw_data.endswith("C"):temperature = float(raw_data[:-1])  # 去掉 C# 湿度:如 24.5 %RH 或 24.5%%RHelif "%RH" in raw_data:humi_str = raw_data.replace("%RH", "").replace("%%RH", "").strip()humidity = float(humi_str)# 重量:如 25.7g(独立上报)elif raw_data.endswith("g"):weight = float(raw_data[:-1])  # 去掉 greturn temperature, humidity,weightexcept ValueError:print("无法解析串口数据:", raw_data)return None, None,Nonereturn None, None,None

  • 该函数从串口读取一行数据,并根据数据的后缀(C、% RH、g)来判断数据类型(温度、湿度、重量)。
  • 处理了可能出现的格式错误,确保数据能够被正确解析。

MQTT 客户端初始化和连接

# 创建MQTT客户端
client = mqtt.Client(client_id=CLIENT_ID, protocol=mqtt.MQTTv5)
client.username_pw_set(MQTT_USERNAME, MQTT_PASSWORD)
client.on_connect = on_connect
client.on_message = on_messageclient.connect(MQTT_BROKER, MQTT_PORT, keepalive=60)
client.loop_start()
  • 创建 MQTT 客户端实例,设置用户名和密码,绑定回调函数。
  • 连接到 MQTT 服务器并启动后台线程处理网络通信

串口连接和数据处理主循环

# 串口连接
try:ser = serial.Serial(SERIAL_PORT, BAUDRATE, timeout=TIMEOUT)print(f"成功连接串口 {SERIAL_PORT}")temperature_from_sensor = Nonehumidity_from_sensor = Noneweight_from_sensor = Nonewhile True:# 获取温度和湿度数据t, h, w = read_data_from_serial(ser)if t is not None:temperature_from_sensor = tif h is not None:humidity_from_sensor = hif w is not None:weight_from_sensor = w  # 缓存最新重量# 只要温湿度都有数据,就上传if temperature_from_sensor is not None and humidity_from_sensor is not None:data = {"sign": DEVICE_ID,"type": "1","data": {"Temp": {"temp": str(temperature_from_sensor)},"Humi": {"humi": str(humidity_from_sensor)},}}if w is not None:data["data"]["Weight"] = {"weight": str(weight_from_sensor)}weight_from_sensor = None  # 上传后清空缓存client.publish(TOPIC_UP, json.dumps(data, ensure_ascii=False))print(f"上报数据:{json.dumps(data, ensure_ascii=False)}")# 立刻清空温湿度数据,避免重复上传同样数据temperature_from_sensor = Nonehumidity_from_sensor = Nonetime.sleep(0.1)except KeyboardInterrupt:print("程序终止")client.loop_stop()client.disconnect()except serial.SerialException as e:print(f"串口错误:{str(e)}")except Exception as e:print(f"程序运行错误:{str(e)}")finally:if 'ser' in locals() and ser.is_open:ser.close()print("串口已关闭")

  • 串口连接:尝试打开指定的串口。
  • 数据处理循环
    • 不断从串口读取数据,并更新缓存的温湿度和重量数据。
    • 当同时有温度和湿度数据时,将它们封装成 JSON 格式并发布到 MQTT 服务器。
    • 如果有重量数据,也一并封装到 JSON 中,并在上传后清空重量缓存
    • 上传数据后清空温湿度缓存,避免重复上传相同数据
  • 异常处理:捕获键盘中断、串口异常和其他异常,确保程序能够优雅地退出,并在退出前关闭串口和 MQTT 连接。

相关文章:

嵌入式硬件篇---龙芯2k1000串口

针对串口错误 “device reports readiness to read but returned no data (Device disconnected or multiple access on port?)” 的排查和解决方法 硬件方面 检查连接 确认串口设备(如串口线、连接的模块等)与龙芯设备之间的物理连接是否牢固&#xf…...

4-C#的不同窗口传值

C#的不同窗口传值 1.通过构造函数传值 this.Hide(); Form1 form01 new Form1(textBox2.Text); //Application.Run(form01); form01.Show();public Form1(string aaa) {InitializeComponent();label12.Text aaa; }2.全局类传值 namespace WindowsFormsApp1 {public class G…...

谷歌地图苹果版v6.138.2 - 前端工具导航

谷歌地图(Google maps)苹果版是是由谷歌官方推出的一款手机地图应用。软件功能强大,支持本地搜索查找世界各地的地址、地点和商家;支持在街景视图中查看世界各地的360度全景图;支持查找乘坐火车、公交车和地铁的路线,或者查找步行…...

NSSCTF [LitCTF 2025]test_your_nc

[复现]绕过学的还是太差了&#xff0c;多积累吧 ​​​​​​题目 题目: 给了一个python文件 #!/bin/python3 import osprint("input your command")blacklist [cat,ls, ,cd,echo,<,${IFS},sh,\\]while True:command input()for i in blacklist:if i in com…...

第十九章 正则表达式

第十九章 正则表达式 文本型数据在所有的类UNIX系统(如 Linux)中会扮演着重要角色&#xff0c;在完全领会这些工具的全部特征之前&#xff0c;要先了解一下工具最为复杂的用法和相关技术&#xff1a;正则表达式。 什么是正则表达式 简单地说&#xff0c;正则表达式是一种用于…...

browser-use Agent 日志链路分析

browser-use Agent 日志链路分析 本节详细梳理 browser-use Agent 的日志输出&#xff0c;从 Agent 初始化到每一步的行为日志&#xff0c;帮助理解其行为轨迹。 1. Agent 初始化阶段 日志点&#xff1a; logger.info(&#x1f9e0; Starting a browser-use agent ...) 记录 …...

Qwen3高效微调

高效微调 场景、模型、数据、算力 高效微调的应用场景 对话风格微调&#xff1a;高效微调可以用于根据特定需求调整模型的对话风格。例如&#xff0c;针对客服系统、虚拟助理等场景&#xff0c;模型可以通过微调来适应不同的 语气、礼貌程度 或 回答方式&#xff0c;从而在与…...

Gitee Wiki:重塑关键领域软件研发的知识管理范式

在数字化转型浪潮席卷全球的当下&#xff0c;关键领域软件研发正面临前所未有的知识管理挑战。传统文档管理模式的局限性日益凸显&#xff0c;知识传承的断层问题愈发严重&#xff0c;团队协作效率的瓶颈亟待突破。Gitee Wiki作为新一代知识管理平台&#xff0c;正在通过技术创…...

redis的哨兵模式和Redis cluster

目录 一. redis的主从复制 二. 哨兵模式 2.1 定义 2.2 作用 2.3 配置实例 三. Redis cluster 3.1 定义 3.2 作用 3.3 配置实例 1. 新建集群文件目录 2. 准备可执行文件到每个文件夹 3. 开启群集功能 4. 启动redis节点 5. 查看是否启动成功 6. 启动集群 7. 测试…...

MySQL计算精度计算加减乘除取模方式和方法总计

以下是 MySQL 中常用计算方式和方法 的总结,涵盖不同场景下的使用方式及示例说明: 1. 基本算术运算 适用场景: 对表中的字段或数值进行基础数学运算(加、减、乘、除、取模)。适用于单条记录的字段计算(如单价+税金、折扣后的价格等)。运算符: 运算符描述示例+加法SELE…...

农业机器人的开发

农业机器人的开发 喷农药机器人 番茄采摘机器人 葡萄采摘机器人 黄瓜采摘机器人 西瓜采摘机器人 蘑菇采摘机器人 草莓采摘机器人 草莓采摘机器人综述 视觉系统 CCD摄像机&#xff0c;距离传感器&#xff0c;PC计算机 其中CCD摄像机的作用是进行彩色图像的采集和进行果…...

Swift 解锁 LeetCode 热门难题:不改数组也能找出重复数字?

文章目录 摘要描述题解答案题解代码分析解读&#xff1a; 示例测试及结果时间复杂度空间复杂度总结实际场景类比可运行 Demo&#xff08;Swift Playground&#xff09;未来展望 摘要 在数组中找出唯一的重复数字&#xff0c;听起来像一道简单的题目&#xff0c;但如果你不能修…...

2025年微信小程序开发:趋势、最佳实践与AI整合

引言 微信小程序自2017年推出以来&#xff0c;已成为中国互联网生态中不可或缺的一部分。根据最新数据&#xff0c;截至2024年&#xff0c;微信小程序的日活跃用户超过4.5亿&#xff0c;总数超过430万个&#xff0c;95%的中国企业拥有自己的小程序&#xff08;WeChat Mini Pro…...

【深度学习】15. Segment Anything Model (SAM) :基于提示的分割新时代

Segment Anything Model (SAM) &#xff1a;基于提示的分割新时代 基本介绍 The first foundation model for promptable segmentation. Segment Anything Model&#xff08;简称 SAM&#xff09;是 Meta AI 于 2023 年提出的一种通用型图像分割基础模型。与以往分割模型不同&…...

Java从入门到精通 - 常用API(一)

常用 API 此笔记参考黑马教程&#xff0c;仅学习使用&#xff0c;如有侵权&#xff0c;联系必删 文章目录 常用 API1. 包代码演示 2. String2.1 String 概述代码演示总结 2.2 String 的常用方法代码演示 2.3 String 使用时的注意事项第一点第二点代码演示 总结题目 2.4 String…...

SQL 筛选出在表1但不在表2中的数据

SQL 筛选出在表1但不在表2中的数据 在SQL中&#xff0c;要筛选出存在于表1但不存在于表2中的数据&#xff0c;有几种常见的方法&#xff1a; 方法1&#xff1a;使用LEFT JOIN WHERE IS NULL SELECT t1.* FROM table1 t1 LEFT JOIN table2 t2 ON t1.join_key t2.join_key W…...

MATLAB实战:实现数字调制解调仿真

以下是使用MATLAB实现BPSK和QPSK数字调制解调仿真的完整代码。该代码包括调制、AWGN信道、匹配滤波/相关解调、星座图绘制以及误码率计算与理论值比较。 %% 清理环境 clear all; close all; clc; %% 参数设置 numBits 100000; % 传输比特数 EbN0_dB 0:2:10; …...

ccf中学生计算机程序设计入门篇课后题p164页test(1)-2 输入一个数,统计这个数二进制中1的个数

include <iostream> using namespace std;int main() {int x;int n 0;// 输入数据cin >> x;// 统计x二进制中1的个数for (n 0; x ! 0; x & x - 1) {n;}// 输出结果cout << n << endl;return 0; }程序解释&#xff1a; 输入&#xff1a;程序从标…...

实现Cursor + Pycharm 交互

效果演示&#xff1a; 直接可以在cursor或Pycharm中点击右键点击&#xff0c;然后就可以跳转到另一个应用的对应位置了 使用方法&#xff1a; 分别在两个应用中安装插件【Switch2Cursor Switch2IDEA&#xff0c;这两个插件分别安装在 IDEA 和 Cursor 中】&#xff1a; Switc…...

C++标准模板库

C标准库参考&#xff1a; C 标准库-CSDN博客 标准模板库STL C 标准库 和 STL 的关系 1. 严格来说&#xff0c;STL ≠ C 标准库 STL&#xff08;Standard Template Library&#xff09; 是 C 标准库的一个子集&#xff0c;主要提供泛型编程相关的组件&#xff08;如容器、迭代器…...

dvwa6——Insecure CAPTCHA

captcha&#xff1a;大概是“我不是机器人”的一个勾选框或者图片验证 LOW: 先输入密码正常修改试一下&#xff08;123&#xff09;&#xff0c;发现报错 查看源码&#xff1a; <?phpif( isset( $_POST[ Change ] ) && ( $_POST[ step ] 1 ) ) {// Hide the C…...

【机器学习及深度学习】机器学习模型的误差:偏差、方差及噪声

机器学习模型的误差分析 V1.0机器学习模型的衡量准则概念引入机器学习模型误差分析误差出现的原因及消除 V1.0 机器学习模型的衡量准则 衡量机器学习模型的好坏可以考虑以下几个方面&#xff1a; 偏差&#xff08;Bias&#xff09;&#xff1a; 在充分训练的情况下&#xff0…...

【学习笔记】On the Biology of a Large Language Model

On the Biology of a Large Language Model 1 Introduction 目标是对这些模型的内部工作机制进行逆向工程&#xff0c;从而更好地理解它们&#xff0c;并评估它们是否适合特定用途。 正如细胞是生物系统的基本构建单元&#xff0c;我们假设特征是模型内部计算的基本单位。仅仅…...

飞腾D2000,麒麟系统V10,docker,ubuntu1804,小白入门喂饭级教程

#下载docker Index of linux/static/stable/ 根据电脑的CPU类型选择&#xff1a; Intel和AMD选x86_64飞腾D2000选aarch64 #选择较新的版本 #在包含下载的docker-XX.X.X.tgz的文件夹中右键->打开终端 # 解压安装包&#xff08;根据实际下载的文件&#xff09; tar -zxvf …...

星野录(博客系统)测试报告

目录 一. 项目背景 二、项目功能 三、测试计划 1. 功能测试 1.1 测试用例 1.2 执行测试部分操作截图 2. 使用selenium进行自动化测试 2.1 添加相关依赖 2.2 登录页面测试 3.3 注册页面测试 3.4 博客列表页面测试 3.5 博客详情页测试 3.6 博客编辑页面测试 3.7 个人…...

使用 Java 实现一个简单且高效的任务调度框架

目录 一、任务调度系统概述 (一)任务调度的目标 (二)任务调度框架的关键组成 二、任务状态设计 (一)任务状态流转设计 (二)任务表设计(SQL) 三、单机任务调度实现 (一)获取待处理任务 (二)执行任务 代码实现(单线程版本) (三)多线程提高吞吐量 四…...

2022—2025年:申博之路及硕士阶段总结

文章目录 1 前景概要2 打造神兵利器2.1 夺天地之精2.2 锻兵魂之形2.3 契人兵之命 3 潜心闭关修炼3.1 第一阶段&#xff1a;苦心智3.2 第二阶段&#xff1a;劳筋骨3.3 第三阶段&#xff1a;摧意志 4 突破晋级4.1 突破失败4.2 聚气凝神4.3 心魔再现4.4 新起点 5 回顾及深思 1 前景…...

项目执行中缺乏灵活应对机制,如何增强适应性?

项目执行中缺乏灵活应对机制可以通过建立风险预警机制、培养团队快速响应能力、制定动态调整方案、加强团队沟通协作、引入敏捷管理理念来增强适应性。 其中&#xff0c;培养团队快速响应能力尤为重要。这种能力意味着当项目遇到突发状况时&#xff0c;团队能迅速评估问题、确定…...

Agentic Workflow是什么?Agentic Workflow会成为下一个AI风口吗?

无论是想要学习人工智能当做主业营收&#xff0c;还是像我一样作为开发工程师但依然要运用这个颠覆开发的时代宠儿&#xff0c;都有必要了解、学习一下人工智能。 近期发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;入行门槛低&#x…...

大模型模型推理的成本过高,如何进行量化或蒸馏优化

在人工智能的浪潮中,大模型已经成为推动技术革新的核心引擎。从自然语言处理到图像生成,再到复杂的多模态任务,像GPT、BERT、T5这样的庞大模型展现出了惊人的能力。它们在翻译、对话系统、内容生成等领域大放异彩,甚至在医疗、金融等行业中也开始扮演重要角色。可以说,这些…...