LCD示例代码

app_main.cpp

#include "who_camera.h"
#include "who_color_detection.hpp"
#include "who_lcd.h"
#include "who_button.h"
#include "event_logic.hpp"
#include "who_adc_button.h"

static QueueHandle_t xQueueAIFrame = NULL;
static QueueHandle_t xQueueLCDFrame = NULL;
static QueueHandle_t xQueueADCKeyState = NULL;
static QueueHandle_t xQueueGPIOKeyState = NULL;
static QueueHandle_t xQueueEventLogic = NULL;
static button_adc_config_t buttons[4] = {{1, 2800, 3000}, {2, 2250, 2450}, {3, 300, 500}, {4, 850, 1050}};

#define GPIO_BOOT GPIO_NUM_0

extern "C" void app_main()
{
    gpio_config_t gpio_conf;
    gpio_conf.mode = GPIO_MODE_OUTPUT_OD;
    gpio_conf.intr_type = GPIO_INTR_DISABLE;
    gpio_conf.pin_bit_mask = 1LL << GPIO_NUM_3;
    gpio_config(&gpio_conf);
    
    xQueueAIFrame = xQueueCreate(2, sizeof(camera_fb_t *));
    xQueueLCDFrame = xQueueCreate(2, sizeof(camera_fb_t *));
    xQueueADCKeyState = xQueueCreate(1, sizeof(int));
    xQueueGPIOKeyState = xQueueCreate(1, sizeof(int));
    xQueueEventLogic = xQueueCreate(1, sizeof(int));

    register_camera(PIXFORMAT_RGB565, FRAMESIZE_240X240, 2, xQueueAIFrame);
    register_adc_button(buttons, 4, xQueueADCKeyState);
    register_button(GPIO_NUM_0, xQueueGPIOKeyState);
    register_event(xQueueADCKeyState, xQueueGPIOKeyState, xQueueEventLogic);
    register_color_detection(xQueueAIFrame, xQueueEventLogic, NULL, xQueueLCDFrame, false);
    register_lcd(xQueueLCDFrame, NULL, true);

}

event_logic.hpp

#pragma once

#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "freertos/task.h"

/**
 * @brief 
 * 
 * @param key_state_i_adc 
 * @param key_state_i_gpio 
 * @param event_o 
 */
void register_event(const QueueHandle_t key_state_i_adc, const QueueHandle_t key_state_i_gpio, const QueueHandle_t event_o);

event_logic.cpp

#include <stdio.h>
#include "event_logic.hpp"
#include "who_button.h"
#include "who_color_detection.hpp"

typedef enum
{
    MENU = 1,
    PLAY,
    UP,
    DOWN
} key_name_t;

static QueueHandle_t xQueueKeyStateIGPIO = NULL;
static QueueHandle_t xQueueKeyStateIADC = NULL;
static QueueHandle_t xQueueEventO = NULL;
static key_state_t key_state;
static key_name_t adc_button_name;
static color_detection_state_t detector_state;

void event_generate_from_gpio_button(void *arg)
{
    color_detection_state_t switch_mode = SWITCH_RESULT;
    while (1)
    {
        xQueueReceive(xQueueKeyStateIGPIO, &key_state, portMAX_DELAY);
        xQueueSend(xQueueEventO, &switch_mode, portMAX_DELAY);
    }
}

void event_generate_from_adc_button(void *arg)
{
    bool register_mode = false;
    while (1)
    {
        xQueueReceive(xQueueKeyStateIADC, &adc_button_name, portMAX_DELAY);
        switch (adc_button_name)
        {
        case MENU:
            detector_state = register_mode ? CLOSE_REGISTER_COLOR_BOX : OPEN_REGISTER_COLOR_BOX;
            register_mode = !register_mode;
            break;

        case PLAY:
            detector_state = register_mode ? REGISTER_COLOR : DELETE_COLOR;
            register_mode = false;
            break;

        case UP:
            detector_state = INCREASE_COLOR_AREA;
            break;

        case DOWN:
            detector_state = DECREASE_COLOR_AREA;
            break;

        default:
            detector_state = COLOR_DETECTION_IDLE;
            break;
        }
        xQueueSend(xQueueEventO, &detector_state, portMAX_DELAY);
    }
}

void register_event(const QueueHandle_t key_state_i_adc, const QueueHandle_t key_state_i_gpio, const QueueHandle_t event_o)
{
    xQueueKeyStateIADC = key_state_i_adc;
    xQueueKeyStateIGPIO = key_state_i_gpio;
    xQueueEventO = event_o;
    if (xQueueKeyStateIADC != NULL)
        xTaskCreatePinnedToCore(event_generate_from_adc_button, "event_logic_task1", 1024, NULL, 5, NULL, 0);
    if (xQueueKeyStateIGPIO != NULL)
        xTaskCreatePinnedToCore(event_generate_from_gpio_button, "event_logic_task2", 1024, NULL, 5, NULL, 0);
}

color_detection(AI开发框架esp-who)_单片机

esp32-s3-eye开发板的摄像头获取到数据后,通过register_camera()的函数将每一帧的数据输出到xQueueAIFrame队列缓冲区中。按键MENU PLAY UP和DN键在本示例充当的是ADC button的功能,可以将模拟信号转换为数字信号,这4个ADC按键的状态的先后顺序也需要有一个队列缓冲区去排队进行管理,就可以调用
register_adc_button()的函数,将按键的状态输出到xQueueADCKeyState队列缓冲区里面。同样,BOOT按键的状态也需要进行记录,通过register_button()将BOOT按键的状态输出到xQueueGPIOKeyState队列缓冲区中。这样就记录了这5个按键的按下与松开,那么其实按键在按下与松开的时候会触发一些事件,通过调用register_event()的函数将xQueueADCKeyState和xQueueGPIOKeyState传入,传出一个xQueueEventLogic事件队列。调用register_color_detection()函数将帧的输入流xQueueAIFrame和事件队列xQueueEventLogic传入,输出一个作为帧的输出流的队列缓冲区xQueueLCDFrame,再调用register_lcd()函数将xQueueLCDFrame作为帧的输入流传入,即可显示到LCD屏幕上。

如何运行示例

  • 交互按键为Boot键,MENU键,PLAY键,UP键和DN键。
  • 按下BOOT键:切换输出显示模式。
  • 按下MENU:切换录入模式和检测模式。
  • 按下PLAY键(录入模式): 录入指示框内的颜色。
  • 按下PLAY键(检测模式): 删除最后一个被录入的颜色。
  • 按下UP键(录入模式): 增大指示框的尺寸。
  • 按下UP键(检测模式): 增大颜色检测过滤的最小色块的面积。
  • 按下DN键(录入模式): 减小指示框的尺寸。
  • 按下DN键(检测模式): 减小颜色检测过滤的最小色块的面积。