韦德斯 2024-05-27 15:58 采纳率: 42.9%
浏览 22

lvgl的串口读写以及UI设计

linux C的LVGL和串口读写怎么实现:1.数据轮询,一共有30个网关,会给每个网关发送JSON格式的查询指令,10分钟轮询一次这30个网关,当发送串口轮询一个网关时,2s之内读取串口,如果没有收取返回指令,再次发送轮询指令,2s之内读取串口,如果还是没有收到返回指令,则再一次发送查询指令,如果2s之内还是没有收到返回指令,则进行下一个网关的查询,每个网关的查询都像前面描述一样,如果3次之内有一次收取到返回数据,则直接进行查询下一个,如果3次都没有查询到该网关返回指令,则对该网关进行标记离线。等30个网关轮询过后,10分钟重新开始下一次大轮询,就是每10分钟要进行一次大轮询。如果刚刚离线的网关有查询到返回指令的话,则清除标记。
2.数据清零:按钮按下清零键时,当前数据轮询操作会停止,串口会发送清零指令,5s内读取到串口清零成功的数据,则打印ok,如果没有读到清零成功的数据或者读到清零失败的数据,则打印error,结束之后继续刚刚停止的数据轮询操作
3.报警逻辑:另一个串口实现:当读取串口数据是报警json数据,则UI的led控件就会闪动,开发板的蜂鸣器就会间隔两秒叫一次

用定时器还是多线程?提供思路即可

  • 写回答

1条回答 默认 最新

  • 阿里嘎多学长 2024-05-27 16:07
    关注

    以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:


    在Linux环境下使用C语言实现LVGL UI界面和串口通信,通常有两种编程模型可以选择:使用定时器和使用多线程。下面我将提供一些思路和建议,帮助你决定使用哪种模型,并设计相应的UI界面和串口通信逻辑。

    使用定时器

    优点

    • 简化设计,不需要管理多线程的同步和通信问题。
    • 定时器可以很容易地实现周期性任务,如每10分钟的轮询。

    缺点

    • 定时器的精度可能不如实时操作系统中的线程调度。
    • 如果串口通信或UI更新操作耗时较长,可能会影响定时器的触发。

    实现思路

    1. 使用LVGL创建UI界面,包括轮询按钮、清零按钮和LED指示灯。
    2. 设计一个定时器,用于每10分钟触发一次数据轮询。
    3. 在定时器的回调函数中,实现对30个网关的轮询逻辑。
    4. 对于每个网关,使用延时函数(如sleep)来实现2秒的等待时间。
    5. 如果在2秒内读取到数据,继续下一个网关;否则,重新发送查询指令。
    6. 实现数据清零的逻辑,使用另一个定时器或延时函数来实现5秒的等待。
    7. 实现报警逻辑,通过轮询或中断方式读取串口,一旦检测到报警数据,更新UI和蜂鸣器。

    使用多线程

    优点

    • 可以并行处理UI更新和串口通信,提高响应速度。
    • 更好的控制和调度串口通信和UI操作。

    缺点

    • 需要处理线程间的同步和通信问题。
    • 线程管理比定时器复杂。

    实现思路

    1. 创建一个主线程,负责UI界面的创建和事件处理。
    2. 创建一个或多个工作线程,专门负责串口通信。
    3. 主线程通过信号或消息队列与工作线程通信。
    4. 在工作线程中实现数据轮询、清零和报警逻辑。
    5. 使用条件变量或信号量来同步轮询和清零操作。
    6. 当检测到报警数据时,工作线程通过信号或消息队列通知主线程更新UI。

    UI设计

    • 使用LVGL创建一个主窗口,包含必要的控件。
    • 添加一个轮询按钮,用于启动或停止轮询操作。
    • 添加一个清零按钮,用于发送清零指令。
    • 添加一个LED指示灯,用于显示网关状态或报警状态。
    • 可以添加一个状态栏或日志窗口,用于显示操作日志和状态信息。

    代码实现

    由于这是一个相对复杂的项目,完整的代码实现超出了这个回答的范围。但是,我可以提供一些关键函数的伪代码,帮助你开始实现:

    // 伪代码:数据轮询函数
    void poll_gateways() {
        for (int i = 0; i < 30; ++i) {
            send_query_to_gateway(i);
            if (!receive_data_within_2s()) {
                retry_query(i);
            }
            if (!receive_data_within_2s()) {
                mark_gateway_offline(i);
            }
        }
        schedule_next_poll(10 * 60); // 10分钟后再次轮询
    }
    
    // 伪代码:发送查询指令
    void send_query_to_gateway(int gateway_id) {
        // 发送JSON格式的查询指令到指定网关
    }
    
    // 伪代码:2秒内尝试读取数据
    bool receive_data_within_2s() {
        // 尝试在2秒内从串口读取数据
    }
    
    // 伪代码:重试查询
    void retry_query(int gateway_id) {
        // 对指定网关重试查询
    }
    
    // 伪代码:标记网关离线
    void mark_gateway_offline(int gateway_id) {
        // 标记指定网关为离线状态
    }
    
    // 伪代码:安排下一次轮询
    void schedule_next_poll(int seconds) {
        // 使用定时器或多线程调度下一次轮询
    }
    

    参考资料

    请注意,这些只是实现思路和伪代码示例,具体的实现细节需要根据你的项目需求和环境进行调整。希望这些信息能帮助你开始你的项目!

    评论 编辑记录

报告相同问题?

问题事件

  • 修改了问题 5月27日
  • 创建了问题 5月27日

悬赏问题

  • ¥15 Coze智能助手搭建过程中的问题请教
  • ¥15 12864只亮屏 不显示汉字
  • ¥20 三极管1000倍放大电路
  • ¥15 vscode报错如何解决
  • ¥15 前端vue CryptoJS Aes CBC加密后端java解密
  • ¥15 python随机森林对两个excel表格读取,shap报错
  • ¥15 基于STM32心率血氧监测(OLED显示)相关代码运行成功后烧录成功OLED显示屏不显示的原因是什么
  • ¥100 X轴为分离变量(因子变量),如何控制X轴每个分类变量的长度。
  • ¥30 求给定范围的全体素数p的(p-2)/p的连乘积值
  • ¥15 VFP如何使用阿里TTS实现文字转语音?