本帖最后由 uQ1GA4qGEMEQ 于 2025-5-23 22:54 编辑
——很幸运能够参与本次DFR1188(基于RP2350)开发板的测试 先从一些小东西上手吧! 一、环境配置 首先本帖项目是使用Arduino完成的,安装arduino的步骤就先不赘述了,重点说一下arduino的配置过程。
1.添加json 在文件→首选项→附加开发板管理器网址中,添加该链接
- https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
复制代码
2.下载开发板管理包 接着在开发板管理器(旧版的arduino在顶层的“工具”中)中搜索rp2350并下载(受限于网络问题,可以尝试使用镜像站或离线包安装) 开发板选择“[backcolor=rgba(0, 92, 95, 0.1)]Generic RP2350” 连接USB线即可开始使用了! 二、Firework!BOOM! 这是一个简单的烟花效果生成的简单程序,使用i2c连接oled屏幕播放 1.材料与接线 本项目仅使用到一个oled(128x64)屏幕和一个无源蜂鸣器(用于模仿烟花声音) 接线如下 记得把蜂鸣器的+连接到支持pwm的引脚上,RP2350全GPIO皆支持pwm,所以我就随意了 注意!!!这里的oled和蜂鸣器都使用了开发板的板载供电,这是没问题的,但是如果有电机等大功率设备或各种感性、容性负载直接使用开发板供电极易引起开发板损坏!!!需要另接供电,与开发板共地即可。 2.程序设计 设计思路: (1)生成一个烟花本体向上运动; (2)记录本体的运动轨迹,在其后方添加拖尾特效; (3)上升至屏幕中央后** (4)**产生随机方向粒子效果,每个粒子的初始位置和速度方向使用随机数+极坐标初始化; (5)为粒子添加重力加速度模仿重力效果; (6)增加升空和**的音效 效果展示: https://mc.dfrobot.com.cn/forum.php?mod=attachment&aid=MTk0OTUzfDg0NmFiODgyYWU2NDQ1OTA1OWQ0ZDZiODdkZGU0MmI4fDE3NDgxODY5ODY%3D&request=yes&_f=.mp4 废话不多说,先把代码端上来: - #include <Adafruit_GFX.h>
- #include <Adafruit_SSD1306.h>
-
- #define SCREEN_WIDTH 128
- #define SCREEN_HEIGHT 64
- #define OLED_RESET -1
- Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
-
- #define PARTICLE_COUNT 30
- #define BUZZER_PIN 1 //蜂鸣器引脚
- #define TRAIL_LENGTH 8 //烟花的拖尾长度
- int trailX[TRAIL_LENGTH];
- int trailY[TRAIL_LENGTH];
-
- struct Particle {
- float x, y;
- float vx, vy;
- bool active;
- };
-
- Particle particles[PARTICLE_COUNT];
- bool exploded = false;
- unsigned long lastLaunch = 0;
-
- //升空音效
- void playLaunchSound() {
- for (int freq = 400; freq <= 1000; freq += 20) {
- tone(BUZZER_PIN, freq);
- delay(5);
- }
- noTone(BUZZER_PIN);
- }
- //**音效
- void playExplosionSound() {
- tone(BUZZER_PIN, 2000, 80); delay(90);
- tone(BUZZER_PIN, 1200, 60); delay(70);
- tone(BUZZER_PIN, 600, 50); delay(60);
- noTone(BUZZER_PIN);
- }
-
- void launchFirework() {
- exploded = false;
- for (int i = 0; i < PARTICLE_COUNT; i++) {
- particles[i].x = SCREEN_WIDTH / 2;
- particles[i].y = SCREEN_HEIGHT;
- particles[i].vx = 0;
- particles[i].vy = -3.5;
- particles[i].active = true;
- }
-
- //初始化拖尾
- for (int i = 0; i < TRAIL_LENGTH; i++) {
- trailX[i] = SCREEN_WIDTH / 2;
- trailY[i] = SCREEN_HEIGHT;
- }
- playLaunchSound();
- }
- //随机数生成**效果(极坐标)
- void explodeFirework() {
- exploded = true;
- for (int i = 0; i < PARTICLE_COUNT; i++) {
- float angle = (2 * PI / PARTICLE_COUNT) * i;
- float speed = random(10, 25) / 10.0;
- particles[i].vx = cos(angle) * speed;
- particles[i].vy = sin(angle) * speed;
- }
- playExplosionSound();
- }
-
- void setup() {
- Serial.begin(115200);
- display.clearDisplay();
- display.display();
- launchFirework();
- }
-
- void updateParticles() {
- for (int i = 0; i < PARTICLE_COUNT; i++) {
- if (!particles[i].active) continue;
-
- particles[i].x += particles[i].vx;
- particles[i].y += particles[i].vy;
- particles[i].vy += 0.1;
-
- // 出界了就消失
- if (particles[i].x < 0 || particles[i].x > SCREEN_WIDTH ||
- particles[i].y < 0 || particles[i].y > SCREEN_HEIGHT) {
- particles[i].active = false;
- }
- }
- }
-
- bool allParticlesInactive() {
- for (int i = 0; i < PARTICLE_COUNT; i++) {
- if (particles[i].active) return false;
- }
- return true;
- }
-
- void drawParticles() {
- if (!exploded) {
- //拖尾缓冲
- for (int i = TRAIL_LENGTH - 1; i > 0; i--) {
- trailX[i] = trailX[i - 1];
- trailY[i] = trailY[i - 1];
- }
- trailX[0] = (int)particles[0].x;
- trailY[0] = (int)particles[0].y;
-
- //拖尾绘制
- for (int i = 0; i < TRAIL_LENGTH; i++) {
- display.drawPixel(trailX[i], trailY[i], SSD1306_WHITE);
- if (i % 2 == 0 && i < TRAIL_LENGTH - 1) {
- display.drawPixel(trailX[i] + 1, trailY[i], SSD1306_WHITE);
- }
- }
-
- //画一个小球(烟花本体)
- display.fillCircle((int)particles[0].x, (int)particles[0].y, 2, SSD1306_WHITE);
-
- } else {
- //**
- for (int i = 0; i < PARTICLE_COUNT; i++) {
- if (particles[i].active) {
- display.drawPixel((int)particles[i].x, (int)particles[i].y, SSD1306_WHITE);
- }
- }
- }
- }
-
- void loop() {
- display.clearDisplay();
-
- if (!exploded && particles[0].y < random(20, 40)) {
- explodeFirework();
- }
-
- updateParticles();
- drawParticles();
- display.display();
- delay(30);
-
- if (allParticlesInactive() && millis() - lastLaunch > 1000) {
- lastLaunch = millis();
- launchFirework();
- }
- }
复制代码
代码注解: (1)两个音效函数使用pwm的频率变化控制无源蜂鸣器来模拟烟花升空和**的音效,所以不能有源蜂鸣器,不然就变成了pwm控制声音大小不能控制频率了 (2)launchFirework()对烟花效果进行初始化,explodeFirework()则是**粒子效果初始化,updateParticles()对粒子的位置信息进行实时更新。 总结:本项目涉及i2c外设配置、物理模拟与声音生成,使用比较低的硬件成本(只使用了rp2350开发板的3%flash和2%的ROM)完成了一次“赛博烟花”,给大家提供一个电子摆件的简单思路
|