uQ1GA4qGEMEQ 发表于 2025-5-23 22:48:35

Firework!BOOM!(基于DFR1188简单的烟花生成)

本帖最后由 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.json2.下载开发板管理包接着在开发板管理器(旧版的arduino在顶层的“工具”中)中搜索rp2350并下载(受限于网络问题,可以尝试使用镜像站或离线包安装)开发板选择“Generic RP2350”连接USB线即可开始使用了!二、Firework!BOOM!这是一个简单的烟花效果生成的简单程序,使用i2c连接oled屏幕播放1.材料与接线本项目仅使用到一个oled(128x64)屏幕和一个无源蜂鸣器(用于模仿烟花声音)接线如下记得把蜂鸣器的+连接到支持pwm的引脚上,RP2350全GPIO皆支持pwm,所以我就随意了注意!!!这里的oled和蜂鸣器都使用了开发板的板载供电,这是没问题的,但是如果有电机等大功率设备或各种感性、容性负载直接使用开发板供电极易引起开发板损坏!!!需要另接供电,与开发板共地即可。2.程序设计设计思路:(1)生成一个烟花本体向上运动;(2)记录本体的运动轨迹,在其后方添加拖尾特效;(3)上升至屏幕中央后**(4)**产生随机方向粒子效果,每个粒子的初始位置和速度方向使用随机数+极坐标初始化;(5)为粒子添加重力加速度模仿重力效果;(6)增加升空和**的音效效果展示:attach://194953.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;
int trailY;

struct Particle {
float x, y;
float vx, vy;
bool active;
};

Particle particles;
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.x = SCREEN_WIDTH / 2;
    particles.y = SCREEN_HEIGHT;
    particles.vx = 0;
    particles.vy = -3.5;
    particles.active = true;
}

//初始化拖尾
for (int i = 0; i < TRAIL_LENGTH; i++) {
    trailX = SCREEN_WIDTH / 2;
    trailY = 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.vx = cos(angle) * speed;
    particles.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.active) continue;

    particles.x += particles.vx;
    particles.y += particles.vy;
    particles.vy += 0.1;

    // 出界了就消失
    if (particles.x < 0 || particles.x > SCREEN_WIDTH ||
      particles.y < 0 || particles.y > SCREEN_HEIGHT) {
      particles.active = false;
    }
}
}

bool allParticlesInactive() {
for (int i = 0; i < PARTICLE_COUNT; i++) {
    if (particles.active) return false;
}
return true;
}

void drawParticles() {
if (!exploded) {
    //拖尾缓冲
    for (int i = TRAIL_LENGTH - 1; i > 0; i--) {
      trailX = trailX;
      trailY = trailY;
    }
    trailX = (int)particles.x;
    trailY = (int)particles.y;

    //拖尾绘制
    for (int i = 0; i < TRAIL_LENGTH; i++) {
      display.drawPixel(trailX, trailY, SSD1306_WHITE);
      if (i % 2 == 0 && i < TRAIL_LENGTH - 1) {
      display.drawPixel(trailX + 1, trailY, SSD1306_WHITE);
      }
    }

    //画一个小球(烟花本体)
    display.fillCircle((int)particles.x, (int)particles.y, 2, SSD1306_WHITE);

} else {
    //**
    for (int i = 0; i < PARTICLE_COUNT; i++) {
      if (particles.active) {
      display.drawPixel((int)particles.x, (int)particles.y, SSD1306_WHITE);
      }
    }
}
}

void loop() {
display.clearDisplay();

if (!exploded && particles.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)完成了一次“赛博烟花”,给大家提供一个电子摆件的简单思路

页: [1]
查看完整版本: Firework!BOOM!(基于DFR1188简单的烟花生成)