aramy

  • 2024-11-15
  • 回复了主题帖: 小米的四电机系统的圆规掉头、原地掉头,算法实现上难吗?

    有现成的运动模型。能够单独控制4个轮子旋转方向和转速就可以原地旋转。但是针对非理想环境要如何处理,4个轮子所处的地面摩擦力相差较大时,需要额外增加角速度传感器来进行闭环处理。

  • 加入了学习《FollowMe 第二季:3 - EK_RA6M5 开发板入门》,观看 EK-RA6M5 开发板入门

  • 加入了学习《鸿蒙 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-10-17 16:27 编辑 这次参与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 五、作品功能演示视频   六、项目总结 很伤心,没能完成最初设定的目标!本来想在这个板子上实现机器学习的内容的,实在是能力有限,无法完成。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
  • 回复了主题帖: 远距离无线充电

    感觉远距离可以考虑使用激光传递能量。方向性会好很多,不知道效率如何。

  • 2024-08-26
  • 回复了主题帖: 【Follow me第二季第1期】基础任务一、二、三

    秦天qintian0303 发表于 2024-8-26 11:29 红外发射和接收装置做测试,没能成功,主要原因出在出在了发射端,不能是常开的,要用PWM控制 没机会试错了。上次常开,冒烟了。

  • 2024-08-25
  • 发表了主题帖: 【Follow me第二季第1期】完结篇

    本帖最后由 aramy 于 2024-9-26 20:50 编辑 本次Follow Me 活动带来的Adafruit Circuit Playground Express这块板子非常有意思,绚烂的灯光加上传感器,很适合做成装饰品,出去玩肯定是最吸引眼球的哪一个。 项目视频演示 本项目完成了本期活动的全部内容,所有任务的展示如下: [localvideo]73f8efc42ccaf5a3e44a1a0d03df2e22[/localvideo] 任务成果展示 入门任务:开发环境搭建,板载LED点亮 对应论坛帖:【Follow me第二季第1期】开发环境的搭建和点亮LED灯 https://bbs.eeworld.com.cn/thread-1289781-1-1.html   1、环境搭建 这次打算用arduino来进行功能开发,所以使用了vscode+platformio来进行开发。使用vscode创建"adafruit_circuitplayground"工程。在github上下载这个板子的库文件。将下载的文件夹放到工程lib文件夹下。编译会有报错,提示:#error TinyUSB is not selected, please select it in "Tools->Menu->USB Stack" ,需要在platformio.iini文件中添加“lib_ignore = Adafruit TinyUSB Library”。再次编译,即可成功。   [env:adafruit_circuitplayground_m0] platform = atmelsam board = adafruit_circuitplayground_m0 framework = arduino lib_ignore = Adafruit TinyUSB Library 2、点灯 参考电路图,板子上D13管脚有接一颗红色LED灯。再参考官方提供的例程,先来点亮这颗红色LED灯。并且打开了串口,通过USB口与上位机进行通讯。 #include <Adafruit_CircuitPlayground.h> void setup() { CircuitPlayground.begin(); Serial.begin(115200); } void loop() { CircuitPlayground.redLED(HIGH); delay(500); CircuitPlayground.redLED(LOW); delay(500); Serial.println("Follow me Season 2!"); } 基础任务部分,对应论坛帖:【Follow me第二季第1期】基础任务一、二、三 https://bbs.eeworld.com.cn/thread-1290634-1-1.html 基础任务一:控制板载炫彩LED,跑马灯点亮和颜色变换   板子外边缘有一圈全彩LED灯,一共10颗。跑马灯就是依次逐个点亮LED灯,利用肉眼的视觉残留,感觉到灯光的运动。这里使用了最大的亮度,颜色使用一个随机数,让10颗LED灯依次亮起,每次亮20ms。 #include <Adafruit_CircuitPlayground.h> void setup() { CircuitPlayground.begin(); Serial.begin(115200); CircuitPlayground.strip.setBrightness(255); } void loop() { uint32_t color=random(0, 0xffffff); for (int i = 0; i < 10; ++i) { CircuitPlayground.strip.setPixelColor(i, color); CircuitPlayground.strip.show(); delay(20); CircuitPlayground.strip.clear(); } } 基础任务二:监测环境温度和光线,通过板载LED展示舒适程度 板子上集成了超多的传感器,其中就有温度计和光线传感器。因为没有显示屏,就需要使用LED展示温度和光线的信息。光线强弱直接和LED灯的亮度挂钩,光线越强,LED灯越亮。实测中光线传感器非常靠近0~2号LED灯的位置,这样LED灯的光线会影响到光线传感器读取环境光强数据。所以0~3号LED灯,没有去驱动,使其处于关闭状态。 环境光线强度由LED灯的亮度表现,温度就由LED灯的颜色来表现了。设定最低温度和最高温度,最低温度20摄氏度,最高40摄氏度。将这个温度区间映射到全彩色域。越靠近20度,颜色就越偏向冷色调(蓝色),越靠近40度,颜色就约偏向于暖色调(紫红),符合心理上对温度感知的映像。 #include <Adafruit_CircuitPlayground.h> float MinTemp = 20.0, MaxTemp = 40.0, a, b, c, d; float tempC; uint16_t lightval; void Getabcd() { a = MinTemp + (MaxTemp - MinTemp) * 0.2121; b = MinTemp + (MaxTemp - MinTemp) * 0.3182; c = MinTemp + (MaxTemp - MinTemp) * 0.4242; d = MinTemp + (MaxTemp - MinTemp) * 0.8182; } //浮点数转颜色 伪彩色 void GetColor(float val,uint8_t rgbval[]) { byte red = 0, green = 0, blue = 0; red = constrain(255.0 / (c - b) * val - ((b * 255.0) / (c - b)), 0, 255); if ((val > MinTemp) & (val < a)) { green = constrain(255.0 / (a - MinTemp) * val - (255.0 * MinTemp) / (a - MinTemp), 0, 255); } else if ((val >= a) & (val <= c)) { green = 255; } else if (val > c) { green = constrain(255.0 / (c - d) * val - (d * 255.0) / (c - d), 0, 255); } else if ((val > d) | (val < a)) { green = 0; } if (val <= b) { blue = constrain(255.0 / (a - b) * val - (255.0 * b) / (a - b), 0, 255); } else if ((val > b) & (val <= d)) { blue = 0; } else if (val > d) { blue = constrain(240.0 / (MaxTemp - d) * val - (d * 240.0) / (MaxTemp - d), 0, 240); } rgbval[0]=red; rgbval[1]=green; rgbval[2]=blue; // return red << 16 | green << 8 | blue; } void setup() { CircuitPlayground.begin(); Serial.begin(115200); CircuitPlayground.strip.setBrightness(255); Getabcd(); } void loop() { uint8_t rgbval[3]; tempC = CircuitPlayground.temperature(); lightval= CircuitPlayground.lightSensor(); Serial.print(tempC); Serial.print(" "); Serial.println(lightval); GetColor(tempC,rgbval); CircuitPlayground.strip.setBrightness(lightval>255?255:lightval); for(uint8_t i=3;i<10;i++) CircuitPlayground.strip.setPixelColor(i, rgbval[0], rgbval[1], rgbval[2]); CircuitPlayground.strip.show(); delay(200); CircuitPlayground.strip.clear(); } 基础任务三:接近检测——设定安全距离并通过板载LED展示,检测到入侵时,发起声音报警   板子上有红外发射和接收装置。看文档介绍是可以利用这两个传感器测量距离的。有做测试,但是没能成功。使用AD测量红外接收端,没有获得与距离正相关的数据。还发现长时间点亮红外LED灯,板子都快烤糊了,都出味了。遂放弃使用红外测距,改为超声波模块测距。效果也是非常不错。 距离继续使用上一个实验中的伪彩色转换方法,将距离映射到颜色。将10厘米到300厘米距离 完整映射到全彩色色域。设定阈值,当距离小于20厘米时,驱动蜂鸣器报警。 #include <Adafruit_CircuitPlayground.h> float MinTemp = 1.0, MaxTemp = 30.0, a, b, c, d; #define Trig A0 //引脚Tring #define Echo A1 //引脚Echo float dm; //距离变量 分米 float temp; // void Getabcd() { a = MinTemp + (MaxTemp - MinTemp) * 0.2121; b = MinTemp + (MaxTemp - MinTemp) * 0.3182; c = MinTemp + (MaxTemp - MinTemp) * 0.4242; d = MinTemp + (MaxTemp - MinTemp) * 0.8182; } //浮点数转颜色 伪彩色 void GetColor(float val, uint8_t rgbval[]) { byte red = 0, green = 0, blue = 0; red = constrain(255.0 / (c - b) * val - ((b * 255.0) / (c - b)), 0, 255); if ((val > MinTemp) & (val < a)) { green = constrain(255.0 / (a - MinTemp) * val - (255.0 * MinTemp) / (a - MinTemp), 0, 255); } else if ((val >= a) & (val <= c)) { green = 255; } else if (val > c) { green = constrain(255.0 / (c - d) * val - (d * 255.0) / (c - d), 0, 255); } else if ((val > d) | (val < a)) { green = 0; } if (val <= b) { blue = constrain(255.0 / (a - b) * val - (255.0 * b) / (a - b), 0, 255); } else if ((val > b) & (val <= d)) { blue = 0; } else if (val > d) { blue = constrain(240.0 / (MaxTemp - d) * val - (d * 240.0) / (MaxTemp - d), 0, 240); } rgbval[0] = red; rgbval[1] = green; rgbval[2] = blue; // return red << 16 | green << 8 | blue; } void setup() { CircuitPlayground.begin(); Serial.begin(115200); CircuitPlayground.strip.setBrightness(255); Getabcd(); pinMode(Trig, OUTPUT); pinMode(Echo, INPUT); } void loop() { uint8_t rgbval[3]; //给Trig发送一个低高低的短时间脉冲,触发测距 digitalWrite(Trig, LOW); //给Trig发送一个低电平 delayMicroseconds(2); //等待 2微妙 digitalWrite(Trig, HIGH); //给Trig发送一个高电平 delayMicroseconds(10); //等待 10微妙 digitalWrite(Trig, LOW); //给Trig发送一个低电平 temp = float(pulseIn(Echo, HIGH)); //存储回波等待时间, //pulseIn函数会等待引脚变为HIGH,开始计算时间,再等待变为LOW并停止计时 //返回脉冲的长度 //声速是:340m/1s 换算成 34000cm / 1000000μs => 34 / 1000 //因为发送到接收,实际是相同距离走了2回,所以要除以2 //距离(厘米) = (回波时间 * (34 / 1000)) / 2 //简化后的计算公式为 (回波时间 * 17)/ 1000 dm = (temp * 17) / 10000; //把回波时间换算成dm if (dm > 0) { Serial.print("距离="); Serial.println(dm); GetColor((30.0 - dm), rgbval); for (uint8_t i = 0; i < 10; i++) CircuitPlayground.strip.setPixelColor(i, rgbval[0], rgbval[1], rgbval[2]); CircuitPlayground.strip.show(); if (dm < 2) { //距离小于20cm时,拉响警报 CircuitPlayground.playTone(1000, 500); // 播放警报音500ms } } delay(500); CircuitPlayground.strip.clear(); }     进阶任务(必做):制作不倒翁——展示不倒翁运动过程中的不同灯光效果 板子上集成了运动传感器(LIS3DH 3轴XYZ加速度计),带有轻击和自由落体检测功能。这里意味着,这个板子能监测加速度变化,但是没有办法监测角速度变化,没有办法检测旋转动作的发生。库函数的例程提供了读取加速度的代码,参考着例程,很容易就读取到3个方向的加速度。 将板子水平放置,y方向就是重力方向,在静止状态下会有9.8的重力加速度。X方向为水平方向,通过X,Y两个轴方向的加速度,就可以求出板子当前的倾角,将倾角映射到颜色空间和LED灯的个数,就可以得到不同角度下绚烂的LED灯光了。 #include <Adafruit_CircuitPlayground.h> #include <math.h> #define PI 3.1415926 float MinTemp = 0.0, MaxTemp = 30.0, a, b, c, d; float tempC; uint16_t lightval; void Getabcd() { a = MinTemp + (MaxTemp - MinTemp) * 0.2121; b = MinTemp + (MaxTemp - MinTemp) * 0.3182; c = MinTemp + (MaxTemp - MinTemp) * 0.4242; d = MinTemp + (MaxTemp - MinTemp) * 0.8182; } // 浮点数转颜色 伪彩色 void GetColor(float val, uint8_t rgbval[]) { byte red = 0, green = 0, blue = 0; red = constrain(255.0 / (c - b) * val - ((b * 255.0) / (c - b)), 0, 255); if ((val > MinTemp) & (val < a)) { green = constrain(255.0 / (a - MinTemp) * val - (255.0 * MinTemp) / (a - MinTemp), 0, 255); } else if ((val >= a) & (val <= c)) { green = 255; } else if (val > c) { green = constrain(255.0 / (c - d) * val - (d * 255.0) / (c - d), 0, 255); } else if ((val > d) | (val < a)) { green = 0; } if (val <= b) { blue = constrain(255.0 / (a - b) * val - (255.0 * b) / (a - b), 0, 255); } else if ((val > b) & (val <= d)) { blue = 0; } else if (val > d) { blue = constrain(240.0 / (MaxTemp - d) * val - (d * 240.0) / (MaxTemp - d), 0, 240); } rgbval[0] = red; rgbval[1] = green; rgbval[2] = blue; } void setup() { Serial.begin(115200); CircuitPlayground.begin(); CircuitPlayground.strip.setBrightness(255); Getabcd(); } void loop() { uint8_t rgbval[3]; float x, y, angle; x = CircuitPlayground.motionX(); y = CircuitPlayground.motionY(); angle = atan2(y, x) * 180 / PI; Serial.println(angle); GetColor(abs(angle)/2, rgbval); for (uint8_t i = 0; i < abs(angle)/4; i++) CircuitPlayground.strip.setPixelColor(i, rgbval[0], rgbval[1], rgbval[2]); CircuitPlayground.strip.show(); delay(200); CircuitPlayground.strip.clear(); // delay(200); }  [localvideo]1b76cc0dda77a19aa2e9ef5de97f8f06[/localvideo]    创意任务二:章鱼哥——章鱼哥的触角根据环境声音的大小,章鱼哥的触角可舒展或者收缩 下单时购买了舵机,收到后发现,这个舵机与日常见到的舵机有所不同。平常见到的舵机多为180度舵机,这个是360度舵机。之前接触的舵机,驱动信号为50Hz方波,其中高电平变换从0.5ms到2.5ms对应着0~180度角度。这个舵机驱动信号也是50Hz方波,但是1.5ms对应着停止。0.5ms~1.5ms对应着顺时针旋转,1.5ms~2.5ms对应着逆时针旋转。其中距离1.5ms距离越近,旋转速度越慢,越远旋转速度越快。但是,无法控制指定角度的旋转,而且顺时针和逆时针旋转速度并不对等。这就导致很难很好地控制舵机悬臂的位置。 这里收集麦克风声音,简单地映射到舵机旋转上,去驱动舵机的旋转。 #include <Adafruit_CircuitPlayground.h> #include <Servo.h> float value; Servo myservo; void setup() { Serial.begin(115200); CircuitPlayground.begin(); myservo.attach(A1, 500, 2500); // 修正脉冲宽度 myservo.writeMicroseconds(1500); // 停机 } void loop() { // Take 10 milliseconds of sound data to calculate value = CircuitPlayground.mic.soundPressureLevel(10); Serial.print("Sound Sensor SPL: "); Serial.println(value-60); myservo.writeMicroseconds(1500+(value-65)*20); // 停机 delay(20); }   项目源码: 心得体会: 非常喜欢follow me这个活动,除了有好玩的开发板,还有很多厉害的大佬在论坛中指导。玩的同时还提升了技术。但是follow me活动不要设限制啊,这一季居然只让参加两期活动,每一期都不舍得错过啊!

  • 2024-08-23
  • 回复了主题帖: 【B-G431B-ESC1-电机开发板试用】-搭个测试环境,试着让电机转起来。

    申小林 发表于 2024-8-23 17:03 看样子很有可能是霍尔传感器的接线顺序不对, 请教一下,我这个电机是没有霍尔传感器的。所以也没接传感器。想用开环驱动电机旋转。需要怎么配置啊?

  • 回复了主题帖: 从工程师角度聊聊——你觉得设计一款性能优越的两轮电动车的重点和难点在哪里?

    首先是安全:行驶安全,充电安全,发生事故时对驾驶员的保护。 其次是续航:在质量有限的情况下,如何充分利用电量走更多的路。

  • 2024-08-19
  • 回复了主题帖: 【B-G431B-ESC1-电机开发板试用】-搭个测试环境,试着让电机转起来。

    秦天qintian0303 发表于 2024-8-18 21:34 这个电机看着不错,配置数据通过en.x-cube-mcsdk-ful.zip能够保存住吗 能保存。电机以前购买的,以前挺便宜的,现在貌似都涨价了  

最近访客

< 1/5 >

统计信息

已有64人来访过

  • 芯积分:308
  • 好友:--
  • 主题:31
  • 回复:39

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言