- 2024-12-18
-
回复了主题帖:
泰坦触觉 TITAN Core开发套件的示例工程代码给大家要来啦
想玩,可惜机会好少,感觉渺茫!
- 2024-12-08
-
回复了主题帖:
【Follow me第二季第3期】EK-RA6M5任务提交
御坂10032号 发表于 2024-12-8 18:30
这个树莓派有固件吗佬
应该是stm芯片的。
-
回复了主题帖:
【Follow me第二季第3期】EK-RA6M5任务提交
御坂10032号 发表于 2024-12-8 18:30
这个树莓派有固件吗佬
没有,按示波器购买的,到手就是这样,不过据说开源,没去找过源码。这个小东西叫 梅雀林
- 2024-11-28
-
加入了学习《FollowMe 第二季:3 - EK_RA6M5 开发板入门》,观看 EK-RA6M5 开发板入门
-
发表了主题帖:
【Follow me第二季第3期】EK-RA6M5任务提交
本帖最后由 aramy 于 2024-12-3 20:32 编辑
很开心参加“Follow me第二季第3期”活动,这次板子是瑞萨的EK-RA6M5 。这款开发板超级大的。还配了网线、usb转接线和microUSB数据线。
入门任务:搭建环境,下载调试示例程序,Blink,按键
开发软件,我是使用官方的IDE,内核应该是eclipse。参考着老师的视频安装IDE环境,我这里安装的是“setup_fsp_v5_5_0_e2s_v2024-07.exe”。然后下载例程包“ra-fsp-examples-5.6.0.example.1.zip”,导入例程包中的“_quickstart”例程。
点击图标栏里边的“锤子”图标,或者在项目上右键鼠标选择构建,即可编译项目,有一些警告,不用管它。然后通过microUSB线,插到板子的“usb full”口。官方例程中提供了按键和LED的控制。蓝色LED闪烁。左边的按钮控制蓝色LED灯的亮度:10%、50%、90%;右边的按键控制闪烁频率1Hz、5Hz、10Hz。查看例程的源码,可以找到控制LED灯亮度的方法:
void gpt_blue_callback(timer_callback_args_t * p_args)
{
/* Void the unused params */
FSP_PARAMETER_NOT_USED(p_args);
switch (s_blueled_flashing)
{
case ON:
{
if ((s_intense++ ) < s_duty)
{
TURN_BLUE_ON
}
else
{
TURN_BLUE_OFF
}
if (s_intense >= 100)
{
s_intense = 0;
s_duty = g_pwm_dcs[g_board_status.led_intensity];
}
break;
}
default:
{
TURN_BLUE_OFF
s_intense = 0;
s_duty = g_pwm_dcs[g_board_status.led_intensity];
}
}
}
两个按键使用了中断的处理方法。
/* SW 1 */
/**********************************************************************************************************************
* Function Name: button_irq10_callback
* Description : SW1 Interrupt handler.
* Argument : p_args
* Return Value : None
*********************************************************************************************************************/
void button_irq10_callback(external_irq_callback_args_t *p_args)
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
BaseType_t xResult = pdFAIL;
EventBits_t uxBits;
/* Void the unused args */
FSP_PARAMETER_NOT_USED(p_args);
uxBits = xEventGroupGetBitsFromISR (g_update_console_event);
if ((uxBits & (STATUS_UPDATE_INTENSE_INFO)) != (STATUS_UPDATE_INTENSE_INFO))
{
/* Cast, as compiler will assume calc is int */
g_board_status.led_intensity = (uint16_t) ((g_board_status.led_intensity + 1) % 3);
xResult = xEventGroupSetBitsFromISR(g_update_console_event, STATUS_UPDATE_INTENSE_INFO,
&xHigherPriorityTaskWoken);
/* Was the message posted successfully? */
if (pdFAIL != xResult)
{
/* If xHigherPriorityTaskWoken is now set to pdTRUE then a context
switch should be requested. The macro used is port specific and will
be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - refer to
the documentation page for the port being used. */
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
}
}
/**********************************************************************************************************************
End of function button_irq10_callback
*********************************************************************************************************************/
/* SW 2 */
/**********************************************************************************************************************
* Function Name: button_irq9_callback
* Description : SW2 interrupt handler.
* Argument : p_args
* Return Value : None
*********************************************************************************************************************/
void button_irq9_callback(external_irq_callback_args_t *p_args)
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
BaseType_t xResult = pdFAIL;
EventBits_t uxBits;
/* Void the unused args */
FSP_PARAMETER_NOT_USED(p_args);
uxBits = xEventGroupGetBitsFromISR (g_update_console_event);
if ((uxBits & (STATUS_UPDATE_FREQ_INFO)) != (STATUS_UPDATE_FREQ_INFO))
{
/* Cast, as compiler will assume calc is int */
g_board_status.led_frequency = (uint16_t) ((g_board_status.led_frequency + 1) % 3);
xResult = xEventGroupSetBitsFromISR(g_update_console_event, STATUS_UPDATE_FREQ_INFO, &xHigherPriorityTaskWoken);
/* Was the message posted successfully? */
if (pdFAIL != xResult)
{
/* If xHigherPriorityTaskWoken is now set to pdTRUE then a context
switch should be requested. The macro used is port specific and will
be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - refer to
the documentation page for the port being used. */
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
}
}
基础任务:quad-spi flash和octo-spi flash配置及读写速度测试;DAC配置生成波形及性能测试。这里使用两根microUSB数据线连接到开发板。一根线连接到“USB FULL”口,用来烧写调试程序,一根线连接到板子下方的“DEBUG”口,用来通过串口与板子通讯。
依然是使用例程中的测试代码,具体代码在ospi_test.c中实现。
DAC输出。依然使用“_quickstart”例程。
1、添加DAC功能,这里DAC输出使用P014管脚,直接设置会报错,原因是P014管脚已经被ADC0使用了,找到ADC0的设置,取消P014的使用,就可以了。
参考着老师的视频讲解,初始化DAC的使用。
在gpt_blue_callback方法中,添加DAC的调用,这里创建了一个锯齿波。设置一个变量,变量累加。因为“R_DAC_Write”最大输入值为4095.所以将变量自加,当值大于等于4095时就归零。使用示波器观察波形输出。
进阶任务:示例程序中新增命令打印信息。在“menu_main.c ”文件中找到例程的菜单,添加一行自定义菜单。
编写自定义菜单对应方法。
test_fn follow_me(void)
{
int8_t c = -1;
sprintf (s_print_buffer, "%s%s", gp_clear_screen, gp_cursor_home);
print_to_console((void*)s_print_buffer); //清屏
sprintf (s_print_buffer, "%s", "Follow me Season 2 Issue 3");
print_to_console((void*)s_print_buffer);
while (CONNECTION_ABORT_CRTL != c)
{
c = input_from_console ();
if ((MENU_EXIT_CRTL == c) || (CONNECTION_ABORT_CRTL == c))
{
break;
}
}
xEventGroupClearBits (g_update_console_event, STATUS_DISPLAY_MENU_KIS);
return (0);
}
然后调试运行,就可以看见自己增加的菜单了。
扩展任务:设计一个类似信号发生器功能的例程。可在示例程序上修改。通过命令或按键,设置DAC输出波形,可通过flash存储历史波形等信息。
这里简单地设计了两个波形:锯齿波、方波。通过DAC输出。使用外接示波器来做观察。模仿着例程设计一个菜单,显示用户可以选择的选项。选择1,显示锯齿波;选择2,显示方波。还有“w”、“r”两个选项,用户选择“w”则将当前显示的波形类型写入flash中。选择“r”则从flash中读取已经保存了的波形类型,并且通过DAC输出。
首先,在例程的基础上添加一个DAC输出波形的方法。通过一个全局变量来判断,输出的波形是锯齿波还是方波。
void DAC_Wave(char wavetype)
{
static int value=0;
if(wavetype==1) R_DAC_Write(&g_dac0_ctrl, value);//锯齿波
if(wavetype==2) R_DAC_Write(&g_dac0_ctrl, value > 2050 ? 4095 : 0);//方波
value=value+20;
if(value>=4095) value=0;
}
然后启动一个新菜单,通过键盘与用户交互,可以选择熟人波形类型,或者读写flash。这里使用了汉字输出,但在串口终端上实际输出的效果不太好,汉字的最后部分总是显示不全。
test_fn follow_me(void)
{
int8_t c = -1;
uint16_t buffer[1];
sprintf (s_print_buffer, "%s%s", gp_clear_screen, gp_cursor_home);
print_to_console ((void*) s_print_buffer); //清屏
sprintf (s_print_buffer, "%s", "波形控制:\r\n1:三角波 \r\n2:方波 \r\nr: 从flash存储读取\r\nw: 写入到flash存储\r\n");
print_to_console ((void*) s_print_buffer);
while (CONNECTION_ABORT_CRTL != c)
{
c = input_from_console ();
if ((MENU_EXIT_CRTL == c) || (CONNECTION_ABORT_CRTL == c))
{
break;
}
if (0 != c)
{
/* Cast, as compiler will assume calc is int */
sprintf (s_print_buffer, "select %c \r\n", c);
print_to_console ((void*) s_print_buffer);
if ('1' == c)
wavetype = 1; //输入1 选择三角波
if ('2' == c)
wavetype = 2; //输入2 选择方波
if ('r' == c) //输入r 读取保存的参数
{
readFromFlash (buffer);
sprintf (s_print_buffer, "read from buf %d \r\n", buffer[0]);
print_to_console ((void*) s_print_buffer);
// if (buffer[0] == '1' || buffer[0] == '2')
wavetype = buffer[0];
}
if ('w' == c) //输入w 保存方波类型参数
{
buffer[0] = wavetype;
saveToFlash (buffer);
}
}
}
xEventGroupClearBits (g_update_console_event, STATUS_DISPLAY_MENU_KIS);
return (0);
}
最后添加两个函数,用来读写flash。因为需要写入和读取的数据只有一个波形类型的数据,只需要一个整形数据即可。
void saveToFlash(uint16_t *buffer)
{
fsp_err_t err = FSP_SUCCESS;
uint32_t page_write_count = 0;
uint8_t *p_mem_addr = (uint8_t*) QSPI_DEVICE_START_ADDRESS;
spi_flash_protocol_t current_spi_mode;
/* Cast to req type */
p_mem_addr = (uint8_t*) QSPI_DEVICE_START_ADDRESS;
// err = R_QSPI_Open(&g_qspi_ctrl, &g_qspi_cfg);
// if (FSP_SUCCESS != err)
// {
// sprintf(s_print_buffer, "Failed to open QSPI module\r\n");
// return;
// }
/* initialise the QSPI, and change mode to that set in FSP */
err = qpi_init ();
if (FSP_SUCCESS == err)
{
/* The comms mode has changed. So if recovering, this new mode required */
current_spi_mode = g_qspi_cfg.spi_protocol;
}
/* 擦除 QSPI 的指定扇区 */
err = R_QSPI_Erase (&g_qspi_ctrl, p_mem_addr, SECTOR_SIZE);
if (FSP_SUCCESS != err)
{
sprintf (s_print_buffer, "Failed to erase QSPI flash\r\n");
return;
}
/* 等待擦除完成 */
err = get_flash_status ();
if (FSP_SUCCESS != err)
{
sprintf (s_print_buffer, "Failed to get flash status after erase\r\n");
return;
}
err = R_QSPI_Write (&g_qspi_ctrl, &buffer[0], p_mem_addr, 1);
if (FSP_SUCCESS != err)
{
sprintf (s_print_buffer, "Failed to write data to QSPI flash\r\n");
}
else
{
err = get_flash_status ();
if (FSP_SUCCESS != err)
{
sprintf (s_print_buffer, "Failed to get flash status after write\r\n");
}
}
// err = R_QSPI_Close(&g_qspi_ctrl);
// if (FSP_SUCCESS != err)
// {
// sprintf(s_print_buffer, "Failed to close QSPI module\r\n");
// }
/* close QSPI module */
deinit_qspi (current_spi_mode);
}
void readFromFlash(uint16_t *buffer)
{
fsp_err_t err = FSP_SUCCESS;
uint32_t page_read_count = 0;
uint8_t *p_mem_addr = (uint8_t*) QSPI_DEVICE_START_ADDRESS;
spi_flash_protocol_t current_spi_mode;
/* The comms mode of the FLASH device is EXTENDED_SPI by default */
current_spi_mode = SPI_FLASH_PROTOCOL_EXTENDED_SPI;
/* initialise the QSPI, and change mode to that set in FSP */
err = qpi_init ();
if (FSP_SUCCESS == err)
{
/* The comms mode has changed. So if recovering, this new mode required */
current_spi_mode = g_qspi_cfg.spi_protocol;
}
memcpy (&buffer[0], p_mem_addr, 1);
deinit_qspi (current_spi_mode);
}
心得体会:非常开心参加Follow me活动,这次活动推出的瑞萨的EK-RA6M5开发板功能超级强悍。但与此同时,掌握开发板的开发方法也相当的困难。好在有老师在视频课中事无巨细地耐心讲解,通过反复观看老师的视频,总算是入门了这块开发板,但是远远没有能发挥出这块开发板的能力,期待着后续看到各位老师优秀的作品。
- 2024-11-17
-
加入了学习《FollowMe 第二季: 1 Adafruit Circuit Playground Express及任务讲解》,观看 Adafruit Circuit Playground Express 及任务讲解
- 2024-11-15
-
回复了主题帖:
小米的四电机系统的圆规掉头、原地掉头,算法实现上难吗?
有现成的运动模型。能够单独控制4个轮子旋转方向和转速就可以原地旋转。但是针对非理想环境要如何处理,4个轮子所处的地面摩擦力相差较大时,需要额外增加角速度传感器来进行闭环处理。
-
加入了学习《鸿蒙 HarmonyOS NEXT星河版零基础入门到实战》,观看 ArkTS-认识和存储数据
- 2024-11-06
-
回复了主题帖:
想搞自动驾驶小车,在B站看到一个成本300的,在犹豫中
nmg 发表于 2024-11-6 15:52
扫地机器人的地图建模应该用的不是激光雷达吧,这个激光雷达是不是挺贵的
海鲜市场整个二手的,很便宜的。小50拿下!
- 2024-11-05
-
回复了主题帖:
想搞自动驾驶小车,在B站看到一个成本300的,在犹豫中
不推荐这个,建议买个大点的车体。扩展性强点。
- 2024-10-31
-
回复了主题帖:
【Follow me第二季第3期】 EK-RA6M5 开发前准备工作
感谢!
- 2024-10-27
-
回复了主题帖:
【Follow me第二季第3期】 EK-RA6M5 开发前准备工作
感谢!感谢!
- 2024-10-25
-
回复了主题帖:
【2024 DigiKey创意大赛】赛博竖笛完成
赞!
- 2024-10-19
-
加入了学习《得捷电子专区》,观看 【2024 DigiKey 创意大赛】红外温度检测及火灾报警器
- 2024-10-18
-
回复了主题帖:
【2024 DigiKey 创意大赛】用esp32-s3-lcd-ev-board制作华容道拼图游戏
wangerxian 发表于 2024-10-17 16:29
这游戏有点意思,从零开发的呀?
不是,移植开源的项目!
- 2024-10-17
-
发表了主题帖:
【2024 DigiKey 创意大赛】用esp32-s3-lcd-ev-board制作华容道拼图游戏
本帖最后由 aramy 于 2024-12-17 18:05 编辑
这次参与2024 DigiKey“感知万物,乐享生活”大赛,我选择的板子是“esp32-s3-lcd-ev-board”。这块板子非常豪华地配备了一块480*480的触摸屏,这么大的屏幕,能够非常好滴让单片机与人交互。
作品简介
ESP32-S3-LCD-EV-Board 是一款基于 ESP32-S3 芯片的屏幕交互开发板,通过搭配不同类型的 LCD 子板,可以驱动 IIC、SPI、8080 以及 RGB 接口的 LCD 显示屏。同时它还搭载双麦克风阵列,支持语音识别和近/远场语音唤醒,具有触摸屏交互和语音交互功能,满足用户对多种不同分辨率以及接口的触摸屏应用产品的开发需求。本项目是使用ESP32-S3-LCD-EV-Board加上480x480 LCD触摸屏,完成了经典游戏“华容道”拼图游戏。
系统框图
ESP32-S3-LCD-EV-Board开发板带着一块480X480的触摸屏,很适合与用户以触摸方式进行交互。项目使用了LVGL来进行图形展示和与用户交互。将屏幕分为游戏区和控制区两个部分。
控制区负责控制游戏难度等级,提供了三个按钮。一个按钮为退出按钮,可以退出游戏。另外两个按钮,为调整游戏难度按钮,可以调整游戏难度,一共有16级难度(0~15),调整难度后,都会按当前难度重新初始化游戏界面。
游戏区显示当前各个图块的位置,一共有四种类型的图块,每个图块均可上下左右四个方向移动,用户可以在游戏区通过触摸移动相应的图块进行移动,系统判断当前图块是否符合移动条件,条件符合时就重绘游戏区域,达到移动图块的效果。
当图块符合胜利条件,就胜利,并升级到下一难度等级。
系统开发使用esp-idf,版本选择esp-idf 5.2.1,使用vscode作为开发工具,选择LVGL8.4.0作为UI开发的库。
三、各部分功能说明
基础框架:使用官方的例程库作为基础框架。https://github.com/espressif/esp-dev-kits
官方例程库下载下来后,找到esp32-s3-lcd-ev-board下examples里的lvgl_demos项目作为基础项目,在这个基础上叠加自己的功能。
现在esp-idf使用了组件方式进行编程,组件无法进行修改。这里将lvgl组件移到本地。建立“components”文件夹,将“managed_components”文件夹下的lvgl__lvgl文件夹移动到“components”文件夹下,并改名为lvgl。
修改main文件夹下的CMakeLists.txt文件。
set(LV_DEMO_DIR ../components/lvgl/demos)
file(GLOB_RECURSE LV_DEMOS_SOURCES ${LV_DEMO_DIR}/*.c)
在main文件夹下,删除原有的“ui_printer”和“ui_tuner”文件夹,这两个文件夹,项目中用不到。再创建game文件夹,在game下创建文件夹“huarongdao”,用来存放自己的游戏代码文件。最后还需要修改一下CMakeLists.txt文件。
修改代码。在main.c主函数中,先引入自己的头函数#include "huarongdao/huaorngdao.h" 。在主函数中保留官方例程的lvgl初始化部分,其余部分删除,添加游戏的调用函数。
void app_main(void)
{
bsp_i2c_init();
lv_disp_t *disp = bsp_display_start();
ESP_LOGI(TAG, "Display LVGL demo");
/**
* To avoid errors caused by multiple tasks simultaneously accessing LVGL,
* should acquire a lock before operating on LVGL.
*/
bsp_display_lock(0);
huarongdao();
/* Release the lock */
bsp_display_unlock();
}
游戏入口函数huarongdao(),在这里开始初始化游戏界面。包括绘制游戏背景图片,绘制按钮,给按钮添加回调事件,游戏负责与用户交互的回调事件为“move_obj_cb”,由这个方法来驱动整个游戏的运作。
static void move_obj_cb(lv_event_t *e)
{
static lv_point_t click_point1, click_point2;
int movex, movey, direction;
game_obj_type *stage_data = (game_obj_type *)e->user_data;
if (e->code == LV_EVENT_PRESSED)
{
lv_indev_get_point(lv_indev_get_act(), &click_point1);
return;
}
if (e->code == LV_EVENT_RELEASED)
{
lv_indev_get_point(lv_indev_get_act(), &click_point2);
movex = click_point2.x - click_point1.x;
movey = click_point2.y - click_point1.y;
if ((movex == 0 && movey == 0) || (movex == movey) || (movex == -movey))
return;
if ((movex < 0 && movey < 0 && movex > movey) || (movex > 0 && movey < 0 && movex < -movey))
direction = up;
if ((movex > 0 && movey < 0 && movex > -movey) || (movex > 0 && movey > 0 && movex > movey))
direction = right;
if ((movex < 0 && movey < 0 && movex < movey) || (movex < 0 && movey > 0 && movex < -movey))
direction = left;
if ((movex < 0 && movey > 0 && movex > -movey) || (movex > 0 && movey > 0 && movex < movey))
direction = down;
if (direction == up)
{
if (stage_data->obj_type == little)
{
if (stage_data->y == 0)
return;
if (game_map[stage_data->y - 1][stage_data->x] == 0)
{
game_map[stage_data->y - 1][stage_data->x] = 1;
game_map[stage_data->y][stage_data->x] = 0;
stage_data->y--;
step_count++;
lv_label_set_text_fmt(step_lable, "STEP:%d", step_count);
lv_obj_set_pos(stage_data->obj, lv_pct((stage_data->x) * 25), lv_pct((stage_data->y) * 20));
}
}
if (stage_data->obj_type == big)
{
if (stage_data->y == 0)
return;
if (game_map[stage_data->y - 1][stage_data->x] == 0 && game_map[stage_data->y - 1][(stage_data->x) + 1] == 0)
{
game_map[stage_data->y - 1][stage_data->x] = 1;
game_map[stage_data->y - 1][(stage_data->x) + 1] = 1;
game_map[stage_data->y + 1][stage_data->x] = 0;
game_map[stage_data->y + 1][(stage_data->x) + 1] = 0;
stage_data->y--;
step_count++;
lv_label_set_text_fmt(step_lable, "STEP:%d", step_count);
lv_obj_set_pos(stage_data->obj, lv_pct((stage_data->x) * 25), lv_pct((stage_data->y) * 20));
}
}
if (stage_data->obj_type == hor)
{
if (stage_data->y == 0)
return;
if (game_map[stage_data->y - 1][stage_data->x] == 0 && game_map[stage_data->y - 1][(stage_data->x) + 1] == 0)
{
game_map[stage_data->y - 1][stage_data->x] = 1;
game_map[stage_data->y - 1][(stage_data->x) + 1] = 1;
game_map[stage_data->y][stage_data->x] = 0;
game_map[stage_data->y][(stage_data->x) + 1] = 0;
stage_data->y--;
step_count++;
lv_label_set_text_fmt(step_lable, "STEP:%d", step_count);
lv_obj_set_pos(stage_data->obj, lv_pct((stage_data->x) * 25), lv_pct((stage_data->y) * 20));
}
}
if (stage_data->obj_type == ver)
{
if (stage_data->y == 0)
return;
if (game_map[stage_data->y - 1][stage_data->x] == 0)
{
game_map[stage_data->y - 1][stage_data->x] = 1;
game_map[stage_data->y + 1][stage_data->x] = 0;
stage_data->y--;
step_count++;
lv_label_set_text_fmt(step_lable, "STEP:%d", step_count);
lv_obj_set_pos(stage_data->obj, lv_pct((stage_data->x) * 25), lv_pct((stage_data->y) * 20));
}
}
}
if (direction == down)
{
if (stage_data->obj_type == little)
{
if (stage_data->y == 4)
return;
if (game_map[stage_data->y + 1][stage_data->x] == 0)
{
game_map[stage_data->y + 1][stage_data->x] = 1;
game_map[stage_data->y][stage_data->x] = 0;
stage_data->y++;
step_count++;
lv_label_set_text_fmt(step_lable, "STEP:%d", step_count);
lv_obj_set_pos(stage_data->obj, lv_pct((stage_data->x) * 25), lv_pct((stage_data->y) * 20));
}
}
if (stage_data->obj_type == big)
{
if (stage_data->y == 3)
return;
if (game_map[stage_data->y + 2][stage_data->x] == 0 && game_map[stage_data->y + 2][(stage_data->x) + 1] == 0)
{
game_map[stage_data->y + 2][stage_data->x] = 1;
game_map[stage_data->y + 2][(stage_data->x) + 1] = 1;
game_map[stage_data->y][stage_data->x] = 0;
game_map[stage_data->y][(stage_data->x) + 1] = 0;
stage_data->y++;
step_count++;
lv_label_set_text_fmt(step_lable, "STEP:%d", step_count);
lv_obj_set_pos(stage_data->obj, lv_pct((stage_data->x) * 25), lv_pct((stage_data->y) * 20));
}
}
if (stage_data->obj_type == hor)
{
if (stage_data->y == 4)
return;
if (game_map[stage_data->y + 1][stage_data->x] == 0 && game_map[stage_data->y + 1][(stage_data->x) + 1] == 0)
{
game_map[stage_data->y + 1][stage_data->x] = 1;
game_map[stage_data->y + 1][(stage_data->x) + 1] = 1;
game_map[stage_data->y][stage_data->x] = 0;
game_map[stage_data->y][(stage_data->x) + 1] = 0;
stage_data->y++;
step_count++;
lv_label_set_text_fmt(step_lable, "STEP:%d", step_count);
lv_obj_set_pos(stage_data->obj, lv_pct((stage_data->x) * 25), lv_pct((stage_data->y) * 20));
}
}
if (stage_data->obj_type == ver)
{
if (stage_data->y == 3)
return;
if (game_map[stage_data->y + 2][stage_data->x] == 0)
{
game_map[stage_data->y + 2][stage_data->x] = 1;
game_map[stage_data->y][stage_data->x] = 0;
stage_data->y++;
step_count++;
lv_label_set_text_fmt(step_lable, "STEP:%d", step_count);
lv_obj_set_pos(stage_data->obj, lv_pct((stage_data->x) * 25), lv_pct((stage_data->y) * 20));
}
}
}
if (direction == left)
{
if (stage_data->obj_type == little)
{
if (stage_data->x == 0)
return;
if (game_map[stage_data->y][stage_data->x - 1] == 0)
{
game_map[stage_data->y][stage_data->x - 1] = 1;
game_map[stage_data->y][stage_data->x] = 0;
stage_data->x--;
step_count++;
lv_label_set_text_fmt(step_lable, "STEP:%d", step_count);
lv_obj_set_pos(stage_data->obj, lv_pct((stage_data->x) * 25), lv_pct((stage_data->y) * 20));
}
}
if (stage_data->obj_type == big)
{
if (stage_data->x == 0)
return;
if (game_map[stage_data->y][stage_data->x - 1] == 0 && game_map[stage_data->y + 1][(stage_data->x) - 1] == 0)
{
game_map[stage_data->y][stage_data->x - 1] = 1;
game_map[stage_data->y + 1][(stage_data->x) - 1] = 1;
game_map[stage_data->y][stage_data->x + 1] = 0;
game_map[stage_data->y + 1][(stage_data->x) + 1] = 0;
stage_data->x--;
step_count++;
lv_label_set_text_fmt(step_lable, "STEP:%d", step_count);
lv_obj_set_pos(stage_data->obj, lv_pct((stage_data->x) * 25), lv_pct((stage_data->y) * 20));
}
}
if (stage_data->obj_type == hor)
{
if (stage_data->x == 0)
return;
if (game_map[stage_data->y][stage_data->x - 1] == 0)
{
game_map[stage_data->y][stage_data->x - 1] = 1;
game_map[stage_data->y][stage_data->x + 1] = 0;
stage_data->x--;
step_count++;
lv_label_set_text_fmt(step_lable, "STEP:%d", step_count);
lv_obj_set_pos(stage_data->obj, lv_pct((stage_data->x) * 25), lv_pct((stage_data->y) * 20));
}
}
if (stage_data->obj_type == ver)
{
if (stage_data->x == 0)
return;
if (game_map[stage_data->y][stage_data->x - 1] == 0 && game_map[stage_data->y + 1][(stage_data->x) - 1] == 0)
{
game_map[stage_data->y][stage_data->x - 1] = 1;
game_map[stage_data->y + 1][stage_data->x - 1] = 1;
game_map[stage_data->y][stage_data->x] = 0;
game_map[stage_data->y + 1][stage_data->x] = 0;
stage_data->x--;
step_count++;
lv_label_set_text_fmt(step_lable, "STEP:%d", step_count);
lv_obj_set_pos(stage_data->obj, lv_pct((stage_data->x) * 25), lv_pct((stage_data->y) * 20));
}
}
}
if (direction == right)
{
if (stage_data->obj_type == little)
{
if (stage_data->x == 3)
return;
if (game_map[stage_data->y][stage_data->x + 1] == 0)
{
game_map[stage_data->y][stage_data->x + 1] = 1;
game_map[stage_data->y][stage_data->x] = 0;
stage_data->x++;
step_count++;
lv_label_set_text_fmt(step_lable, "STEP:%d", step_count);
lv_obj_set_pos(stage_data->obj, lv_pct((stage_data->x) * 25), lv_pct((stage_data->y) * 20));
}
}
if (stage_data->obj_type == big)
{
if (stage_data->x == 2)
return;
if (game_map[stage_data->y][stage_data->x + 2] == 0 && game_map[stage_data->y + 1][(stage_data->x) + 2] == 0)
{
game_map[stage_data->y][stage_data->x + 2] = 1;
game_map[stage_data->y + 1][(stage_data->x) + 2] = 1;
game_map[stage_data->y][stage_data->x] = 0;
game_map[stage_data->y + 1][(stage_data->x)] = 0;
stage_data->x++;
step_count++;
lv_label_set_text_fmt(step_lable, "STEP:%d", step_count);
lv_obj_set_pos(stage_data->obj, lv_pct((stage_data->x) * 25), lv_pct((stage_data->y) * 20));
}
}
if (stage_data->obj_type == hor)
{
if (stage_data->x == 2)
return;
if (game_map[stage_data->y][stage_data->x + 2] == 0)
{
game_map[stage_data->y][stage_data->x + 2] = 1;
game_map[stage_data->y][stage_data->x] = 0;
stage_data->x++;
step_count++;
lv_label_set_text_fmt(step_lable, "STEP:%d", step_count);
lv_obj_set_pos(stage_data->obj, lv_pct((stage_data->x) * 25), lv_pct((stage_data->y) * 20));
}
}
if (stage_data->obj_type == ver)
{
if (stage_data->x == 3)
return;
if (game_map[stage_data->y][stage_data->x + 1] == 0 && game_map[stage_data->y + 1][(stage_data->x) + 1] == 0)
{
game_map[stage_data->y][stage_data->x + 1] = 1;
game_map[stage_data->y + 1][stage_data->x + 1] = 1;
game_map[stage_data->y][stage_data->x] = 0;
game_map[stage_data->y + 1][stage_data->x] = 0;
stage_data->x++;
step_count++;
lv_label_set_text_fmt(step_lable, "STEP:%d", step_count);
lv_obj_set_pos(stage_data->obj, lv_pct((stage_data->x) * 25), lv_pct((stage_data->y) * 20));
}
}
}
if (stage_data->obj_type == big && stage_data->x == 1 && stage_data->y == 3)
{
lv_obj_t *clear_lable = lv_label_create(game_window);
lv_label_set_text(clear_lable, "STAGE CLEAR");
lv_obj_set_style_text_color(clear_lable, lv_color_hex(0xffffff), 0);
lv_obj_center(clear_lable);
if (current_stage < max_stage - 1)
{
current_stage++;
}
stage_clear();
}
}
}
四、作品源码
https://download.eeworld.com.cn/detail/aramy/634585
五、作品功能演示视频
[localvideo]81c55357bcb9974f9a08340a6336b835[/localvideo]
六、项目总结
很伤心,没能完成最初设定的目标!本来想在这个板子上实现机器学习的内容的,实在是能力有限,无法完成。LVGL作为UI实现的工具,功能非常强大,可是总觉着版本有些混乱,不同版本方法差异好大,学习成本有点太高了,但是作为一个连接单片机和人的桥梁还是非常好用的,通过单片机、传感器来感知万物,再用合适的UI展示出来,与人互动。非常喜欢ESP32-S3-LCD-EV-Board开发板,希望能借助这个项目留下这块板子!
-
上传了资料:
【2024 DigiKey 创意大赛】用esp32-s3-lcd-ev-board制作华容道拼图游戏
- 2024-10-08
-
回复了主题帖:
邀您云逛展《TE Connectivity 线上工博会》报名有好礼!
已报名,望好运。
- 2024-09-10
-
回复了主题帖:
不做定制产品都不会遇到这么多傻X
其实吧!只要钱给得足,以上都可以不是缺点。
- 2024-09-05
-
回复了主题帖:
远距离无线充电
感觉远距离可以考虑使用激光传递能量。方向性会好很多,不知道效率如何。