本帖最后由 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://mcmobileapi.dfrobot.com.cn/forum.php?mod=attachment&aid=MTk0OTUzfGU5YmY4Y2Y0OTRhYTdlMjE1NWVmYjQ2MWIxZDM1ZTE0fDE3NjIyMjMyOTE%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)完成了一次“赛博烟花”,给大家提供一个电子摆件的简单思路 
  
 |