树莓派读取USB扫码枪数据

3 篇文章 0 订阅

写在前面的话

项目需求,使用扫码枪扫描二维码,并把内容写入单片机内。一开始的要求是把固件和生产信息同时写入

单片机的 FLASH 内,从网上采购了带 USB 扫码枪触发的离线下载器,达到了要求。

可惜现在开发环境变成了模组的 SDK 开发,只能想办法外部交互写入。

看看手头上的东西:

1、树莓派3B

2、ScanHome SH-410

3、USB转485

决定使用如下的方式,完成数据写入:


为什么要用树莓派呢

之前项目买的 USB 扫码枪原理是模拟键盘输出,不是工业串口输出。为了省下100多块钱,我决定用树莓派来代替。为啥没有赚了的感觉??

要求

必须要带 GUI, 但是界面要越简单越好。要有数据回显,方便使用者确认数据确实写入到设备当中。

GUI 框架选择了熟悉的 QT,编程语言选择了 Python, 原因是第三方库多,操作串口和 USB 比较简单。

实际编写过程中,发现没有拖拽的 Qt Designer 确实比较困难。虽然也可以导入 ui 文件,但是需要来回切换,很麻烦。

我决定采用极简风,没有设计就是最好的设计。两个输入框和两个按钮搞定,哈哈。


主界面代码

UI线程和子线程分离,这样串口任务和usb扫码枪的任务不会阻塞 UI 线程.

点击启动按钮后,串口读取和usb扫描线程启动。当两个线程分别轮询到有数据到来时,主动发信信号,触发 UI 类里的自定义槽函数。

我们可以在槽函数中对数据做分析处理,做响应的动作。

from PySide2.QtCore import Slot
from PySide2.QtWidgets import QWidget, QApplication, QMainWindow
from PySide2.QtWidgets import QLineEdit, QLabel, QPushButton
from PySide2.QtWidgets import QGridLayout
from scan_code import UsbScanSH410
from serial_com import SerialComThread
import json

class MyCodeDisplay(QWidget):

    def __init__(self, parent: QWidget = None):
        super().__init__(parent)
        self.scan_thread = UsbScanSH410("SM SM-2D PRODUCT HID KBW")
        self.scan_thread.signal_received.connect(self.slot_recv_data_from_usb_scan)

        self.com_thread = SerialComThread("/dev/ttyUSB0")
        self.com_thread.signal_received.connect(self.slot_recv_data_from_serial)

        self.line_edit_scan_input = QLineEdit()
        self.line_edit_echo = QLineEdit()

        self.label_scan_input = QLabel("扫描输入")
        self.label_edit_echo = QLabel("设备回显")

        self.btn_run = QPushButton("启动运行")
        self.btn_run.clicked.connect(self.slot_run)
        self.btn_stop = QPushButton("停止运行")
        self.btn_stop.clicked.connect(self.slot_stop)

        self.grid_layout = QGridLayout()
        self.grid_layout.addWidget(self.label_scan_input, 1, 1)
        self.grid_layout.addWidget(self.line_edit_scan_input, 1, 2)
        self.grid_layout.addWidget(self.label_edit_echo, 2, 1)
        self.grid_layout.addWidget(self.line_edit_echo, 2, 2)
        self.grid_layout.addWidget(self.btn_run, 3, 1)
        self.grid_layout.addWidget(self.btn_stop, 3, 2)

        self.setLayout(self.grid_layout)

    @Slot()
    def slot_run(self):
        """
        槽函数,启动子线程任务
        :return:
        """
        if not self.com_thread.isRunning():
            self.com_thread.start()
            print("{0} start success."
                  .format(self.com_thread.objectName()))
        else:
            print("Warning: {0} already run!"
                  .format(self.com_thread.objectName()))

        if not self.scan_thread.isRunning():
            self.scan_thread.start()
            print("{0} start success."
                  .format(self.scan_thread.objectName()))
        else:
            print("Warning: {0} already run!"
                  .format(self.scan_thread.objectName()))

    @Slot()
    def slot_stop(self):
        """
        槽函数,停止子线程任务
        :return:
        """
        self.scan_thread.stop()
        self.com_thread.stop()

    @Slot()
    def slot_recv_data_from_usb_scan(self, content):
        """
        槽函数,接收usb数据,通过串口发出写入指令
        :param content:
        :return:
        """
        self.line_edit_echo.clear()
        self.line_edit_scan_input.setText(content)

        val = {
            "func": "set_qrcode",
            "content": content,
        }

        self.com_thread.write(json.dumps(val).encode())

    @Slot()
    def slot_recv_data_from_serial(self, content: bytes):
        """
        槽函数,接收串口数据,并显示在输入框内
        :param content:
        :return:
        """
        self.line_edit_echo.setText(content.decode())


def main_loop():
    app = QApplication()
    main_window = QMainWindow()

    # 设置界面最小尺寸
    main_window.setMinimumSize(450, 320)
    main_window.setMaximumSize(450, 320)

    # 中心窗口
    q = QWidget()
    main_window.setCentralWidget(q)

    # TODO: 点击 X 关闭主窗口,通知子线程停止运行
    d = MyCodeDisplay(q)
    main_window.destroyed.connect(d.slot_stop)

    main_window.show()

    app.exec_()


if __name__ == "__main__":
    try:
        main_loop()
    except KeyboardInterrupt as e:
        print(e)

全部代码文件地址

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值