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);
}
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键(检测模式): 减小颜色检测过滤的最小色块的面积。