Edit online

咖啡点单 (order_coffee)

这个示例模板由三个页面组成,分别是点单页面、制作页面和状态页面,主要演示了以下几个功能:

  1. 页面之间的跳转

  2. 按键事件处理

  3. 自定义 custom 代码的实现

  4. UART 串口通信


    _images/oder_coffee_main.png

    1. 点单主页面

UART 串口通信实现

在 custom 目录中通过自定义代码实现了 UART 通信:

  1. 在 uart_device 中实现了串口设备的打开,UART 接收线程,以及 UART 数据发送接口

  2. 在 uart_msg_queue 中实现了消息队列,在 uart_device 中通过消息队列的方式把接收到的 UART 信息通知给 UART 接收线程

  3. 在 uart_msg_parse 中实现了对接收的 UART 信息的解析流程

  4. 在 uart_device 中的信息接收线程中,会调用 uart_rx_parse_frame 进行串口信息的解析

注:

目前只提供了 Luban-Lite 下的串口通信实现

UART 通信的初始化:
 // 初始化串口信息
g_uart_device = uart_device_create("uart4", 115200, 8, 1, 0);
// 设置串口接收回调函数
uart_device_set_cb(g_uart_device, serial_msg_cb);
// 开启串口接收线程,并设置线程优先级
uart_device_start_receive_thread(g_uart_device, 25);
UART 接收线程和 UI 主线程共享变量的互斥保护:
// 此函数会在串口接收线程中调用,通过互斥锁进行保护
static int machine_update_status(machine_info_t *machine, unsigned char *data)
{
    pthread_mutex_lock(&machine_mutex);
    machine->run_mode = data[0];
    machine->coffee_reserves = data[1];
    machine->temp_level = data[2];
    machine->status_updata = true;
    pthread_mutex_unlock(&machine_mutex);

    return 0;
}
// 此函数会在 LVGL 的 timer 中进行调(在 LVGL 的主线程中),用互斥锁进行保护
int machine_get_status(machine_info_t *machine, unsigned char *data)
{
    pthread_mutex_lock(&machine_mutex);
    data[0] = machine->run_mode;
    data[1] = machine->coffee_reserves;
    data[2] = machine->temp_level;
    machine->status_updata = false;
    pthread_mutex_unlock(&machine_mutex);
    return 0;
}
UART 消息回调:
void serial_msg_cb(unsigned char *payload, int size)
{
    switch (payload[0]) {
        case 0xAA:
            if (payload[1] == 0xA1) {
                app_logd("make success\n");
            } else if (payload[1] == 0xA1){
                printf("make fail\n");
            } else {
                printf("make command error\n");
            }
            break;
        case 0xBB:
            if (payload[1] == 0xB1) {
                app_logd("stop success\n");
            } else if(payload[1] == 0xB2) {
                printf("stop fail\n");
            } else {
                printf("stop command error\n");
            }
            break;
        case 0xCC:
            if (size == 4)
                machine_update_status(&g_machine, &payload[1]);

            break;
        default:
            printf("Invalid func code:%d\n", payload[0]);
            break;
    }
}

UART 通信协议

  1. 制作指令

    类别 帧头 帧长 功能码 饮品 ID 热饮/冷萃 咖啡浓度 杯形 预留 预留 校验 帧尾
    主机发送 0xCA 0x07 0xAA 0x00-0xFF

    0xA0 热饮

    0xA1 冷萃

    0xA0 常规

    0xA1 加浓

    0xA2 深度

    0xA0 小杯

    0xA1 大杯

    - - - 0xCB
    类别 帧头 帧长 功能码 执行状态 校验 帧尾
    从机回复 0xCA 0x02 0xAA

    0xA0 成功执行

    0xA1 无法执行

    - 0xCB
  2. 停止指令

    类别 帧头 帧长 功能码 指令 校验 帧尾
    主机发送 0xCA 0x02 0xBB 0xB1 停止 - 0xCB
    类别 帧头 帧长 功能码 指令状态 校验 帧尾
    从机回复 0xCA 0x02 0xBB 0xB0 成功执行 0xB1 无法执行 - 0xCB
  3. 状态指令

    类别 帧头 帧长 功能码 指令 校验 帧尾
    主机发送 0xCA 0x02 0xCC 0xC1 状态获取 - 0xCB
    类别 帧头 帧长 功能码 运行模式 咖啡储量 温度等级 校验 帧尾
    从机回复 0xCA 0x04 0xCC

    0xC0 待机

    0xC1 运行

    0xC0 充足

    0xC1 不足

    0xC0 标准

    0xC1 中温

    0xC2 高温

    - 0xCB

UART 串口协议定制

  1. 修改 uart_rx_parse 中的函数 uart_rx_parse_frame,定义自己的串口解析协议

  2. 修改 serial_msg_cb,对接收到的 payload 数据进行解析处理

制作页面

在主页面点击所选择的 咖啡图标,可以进入制作页面:


_images/oder_coffee_make.png

2. 制作页面
  1. 点击 开始制作 会发送制作命令给从设备

  2. 点击 暂停 会发送暂停命令给从设备

  3. 点击 返回 会返回主页面

状态页面

在主页面点击 状态 会进入状态页面


_images/oder_coffee_status.png

3. 状态页面
  1. 点击 更新 会发送更新指令给从设备,从设备收到指令会,会返回状态命令给主设备,主设备在当前页更新状态信息

  2. 点击 返回 会返回主页面

从机回复的命令示例:


_images/oder_coffee_data.png

按照字节序依次说明含义:

  1. 0xCA 为帧头

  2. 0x04 为帧长度

  3. 0xCC 表示功能为状态指令

  4. 0xC0 表示运行模式为待机

  5. 0xC0 表示咖啡储量充足

  6. 0xC1 表示温度等级为中

  7. 0xDB 表示 sum 校验值

  8. 0xCB 为帧尾