Arduino UNO 用了快二十年,大家熟悉它的板形、接口和扩展板生态;但如果只停留在“换个更强 MCU”的 PCB 设计图上,这件事还只能算是一个不错的想法。
真正有意思的部分,是板子打回来之后——焊接能不能过?USB 能不能正常枚举?I2C、SPI、ADC、SD 卡、OLED、RGB 灯这些外设能不能跑起来?以及更现实一点:上电的时候,会不会踩坑?
在 Make Blocks 第一期阶段1中,作者鲜de芒果设计了一块基于 Raspberry Pi RP2040 的 Arduino UNO 板形开发板:RPDuino-2040。我们之前已经介绍过它的设计思路:UNO 外形不变、扩展板生态不变,核心换成双核 Cortex-M0+ 的 RP2040。
这次阶段2,作者把这块板子真正做出来,并完成了焊接、调试和功能验证。从“看起来不错的 PCB”,到“真的能跑的开发板”,中间隔着的,就是这篇阶段2记录。

01
从设计图到实物板
RPDuino-2040 的定位依然很清晰:它是一块基于 Raspberry Pi RP2040 的 Arduino UNO R3 板形开发板。
核心不再是传统 Arduino UNO 上的 ATmega328P,而是换成了 RP2040:
| 项目 | 配置 |
|---|---|
| 主控 | Raspberry Pi RP2040 |
| 内核 | 双核 Cortex-M0+ |
| 主频 | 133MHz |
| SRAM | 264KB |
| Flash | W25Q16,2MB QSPI Flash |
| 时钟 | 12MHz 晶振 |
| USB | Type-C,供电 + 数据 |
| 调试 | SWD 接口 |
| 板载资源 | BOOT / RESET 按键、电源 LED、用户 LED、WS2812B RGB 灯珠 |
| 扩展接口 | Arduino UNO R3 标准接口、I2C、SPI、UART、ADC、GPIO |

它保留了 Arduino UNO R3 的接口规范,也就是说,原本 UNO 生态里的很多扩展板、模块和接线习惯,都可以继续沿用。
这也是这个项目最核心的价值:不是单纯做一块 RP2040 开发板,而是把 RP2040 放进一个大家非常熟悉的 Arduino UNO 机械尺寸和接口体系里。
02
这次阶段2主要验证了什么?
阶段1更偏向“设计”:原理图、PCB、接口定义、板形兼容性。阶段2则进入“工程验证”:板子能不能焊,能不能上电,能不能正常跑程序。
作者这次完成的验证内容包括:
-
板载 LED 控制
-
WS2812B RGB 灯珠控制
-
USB 串口通信
-
I2C 设备扫描
-
SD 卡初始化、文件写入和读取
-
摇杆模拟信号采集
-
OLED 显示系统状态和 ADC 数据
这几个功能看起来分散,其实覆盖了嵌入式开发板最常见的几类基础能力:
| 功能 | 对应验证点 |
|---|---|
| LED / WS2812B | GPIO、时序控制、基础 IO 输出 |
| 串口通信 | USB CDC、调试信息输出 |
| I2C 扫描 | I2C 总线、OLED 地址识别 |
| SD 卡读写 | SPI 总线、文件系统、外部存储 |
| 摇杆采集 | ADC 模拟输入 |
| OLED 显示 | I2C 外设驱动、数据显示 |
也就是说,这不是简单地点个灯,而是把这块板作为一块“可用开发板”做了一轮比较完整的基础体检。
03
测试程序怎么跑?

作者使用 PlatformIO 工程完成开发板功能测试,程序主要分成几部分:
-
第一步,初始化串口、LED、摇杆输入、WS2812B 和 OLED。程序启动后,会打开 115200 波特率的串口,初始化板载 LED、摇杆 ADC 引脚和 WS2812B RGB 灯珠,同时启动 OLED,并设置 I2C 地址为 0x3C。
-
接着,程序会执行 I2C 扫描,看看总线上是否能找到 OLED 等 I2C 设备。
-
再往后,是 SD 卡测试,包括 SD 卡初始化、卡类型识别、容量读取、文件写入和文件读取。
-
最后进入主循环:
-
串口持续输出 “Hello!”
-
读取摇杆 ADC 值
-
WS2812B 和板载 LED 交替闪烁
-
OLED 显示项目名称、作者信息、运行时间和 ADC 数值
这套测试程序的好处是,它把多个外设串在了一起。只要它能稳定运行,就能说明这块板的基本硬件链路是通的。
I2C:先扫描,再驱动
在调试开发板时,I2C 扫描是一个非常实用的小工具。
很多时候 OLED 不亮,不一定是代码逻辑问题,可能是:
-
I2C 地址不对
-
SDA / SCL 接反
-
上拉电阻问题
-
模块没供电
-
焊接虚焊
-
总线被其他器件拉住
作者的程序中先对 1 到 126 的 I2C 地址逐一扫描,如果设备响应,就通过串口打印出地址。
这一步很适合放在开发板 bring-up 的早期。不要一上来就写复杂显示逻辑,先确认总线上确实有设备,地址也正确,再进入 OLED 驱动部分。
核心初始化
void setup() {Serial.begin(115200); // 串口delay(5000);pinMode(LED_BUILDIN, OUTPUT); // 板载LED引脚初始化pinMode(JOYSTICK_PIN, INPUT); // 摇杆引脚初始化FastLED.addLeds(leds, NUM_LEDS); // 板载WS2812B灯珠初始化 // 初始化OLED并设置其IIC地址为 0x3Cdisplay.begin(SSD1306_SWITCHCAPVCC, 0x3C);// 扫描IIC地址Serial.println("\nI2C Scanner");scanI2c();Serial.println("I2C Scanner done.");readSDFile();}
I2C设备扫描
void scanI2c() {byte error, address;int nDevices = 0;Serial.println("Scanning...");for(address = 1; address < 127; address++ ) {Wire.beginTransmission(address);error = Wire.endTransmission();if (error == 0) {Serial.print("I2C device found at address 0x");if (address<16)Serial.print("0");Serial.print(address,HEX);Serial.println(" !");nDevices++;} else if (error==4) {Serial.print("Unknown error at address 0x");if (address<16)Serial.print("0");Serial.println(address,HEX);}}if (nDevices == 0) {Serial.println("No I2C devices found\n");} else {Serial.println("done\n");}}
SD卡:看似简单,实际最容易踩坑
SD 卡测试是这次阶段2里很值得看的部分。
作者一开始使用的是 adafruit/SdFat - Adafruit Fork 库,但编译和读取都不顺利。后面改用 RP2040_SD 库,并通过逐步输出调试信息,才定位到 SD 卡格式相关的问题。
这其实是很多嵌入式项目都会遇到的情况:
硬件连接看起来没问题,SPI 引脚也配置了,代码也用了成熟库,但就是读不出来。
这时候最怕的是直接判断“板子坏了”或者“线连错了”。更好的方式是像作者这样,把初始化过程拆开:
-
先打印当前使用的 CS、SCK、MOSI、MISO 引脚
-
再检查 SD 卡是否能初始化
-
再识别 SD 卡类型
-
再读取容量
-
最后再做文件写入和读取
void readSDFile() {Serial.println(BOARD_NAME);Serial.println(RP2040_SD_VERSION);Serial.print("Initializing SD card with SS = "); Serial.println(PIN_SD_SS);Serial.print("\tSCK = "); Serial.println(PIN_SD_SCK);Serial.print("\tMOSI = "); Serial.println(PIN_SD_MOSI);Serial.print("\tMISO = "); Serial.println(PIN_SD_MISO);if(!card.init(SPI_HALF_SPEED, PIN_SD_SS)) {Serial.println("initialization failed. Things to check:");Serial.println("* is a card inserted?");Serial.println("* is your wiring correct?");Serial.println("* did you change the chipSelect pin to match your shield or module?");return;}// 卡类型检测switch (card.type()) {case SD_CARD_TYPE_SD1:Serial.println("SD1");break;case SD_CARD_TYPE_SD2:Serial.println("SD2");break;case SD_CARD_TYPE_SDHC:Serial.println("SDHC");break;default:Serial.println("Unknown");}// 计算卡容量uint32_t volumesize;volumesize = volume.blocksPerCluster();volumesize *= volume.clusterCount();volumesize *= 512;Serial.print("Volume size (bytes): ");Serial.println(volumesize);Serial.print("Volume size (Kbytes): ");Serial.println(volumesize / 1024);Serial.print("Volume size (Mbytes): ");Serial.println((float)volumesize / 1048576.0);// 初始化SD库if (!SD.begin(PIN_SD_SS)) {Serial.println("Initialization failed!");return;}Serial.println("Initialization done.");// 写入测试char writeData[] = "Testing writing to " TEST_FILE_NAME;myFile = SD.open(TEST_FILE_NAME, FILE_WRITE);if (myFile) {Serial.print("Writing to "); Serial.print(TEST_FILE_NAME);Serial.print(" ==> "); Serial.println(writeData);myFile.println(writeData);myFile.close();Serial.println("done.");} else {Serial.print("Error opening "); Serial.println(TEST_FILE_NAME);}// 读取测试myFile = SD.open(TEST_FILE_NAME, FILE_READ);if (myFile) {Serial.print("Reading from "); Serial.println(TEST_FILE_NAME);Serial.println("===============");while (myFile.available()) {Serial.write(myFile.read());}myFile.close();Serial.println("===============");} else {Serial.print("Error opening "); Serial.println(TEST_FILE_NAME);}}
OLED显示:把板卡状态可视化
OLED 部分的显示内容并不复杂,但很实用。
屏幕上显示:
-
RPDuino Test
-
Author 信息
-
开机后的运行时间
-
摇杆 ADC 采样值
这类小屏幕在调试开发板时很有帮助。因为很多时候,串口调试需要接电脑;而 OLED 可以让开发板自己把状态显示出来。
void words_display() {// 清除屏幕display.clearDisplay();// 设置字体颜色,白色可见display.setTextColor(WHITE);//设置字体大小display.setTextSize(1.5);//设置光标位置display.setCursor(0, 0);display.print("RPDuino Test");display.setCursor(0, 14);display.print("Author: ");display.print("Bunco");display.setCursor(0, 28);display.print("time: ");//打印自开发板重置以来的秒数:display.print(millis() / 1000);display.print(" s");display.setCursor(0, 42);display.print("adc : ");display.print(joystick_adc_value);}
04
测试结果:基础功能全部通过
作者整理了一张测试结果表,阶段2验证项基本都通过了。
| 测试项 | 预期结果 | 实际结果 | 状态 |
|---|---|---|---|
| 系统初始化 | 所有设备初始化成功 | 成功 | ✅ |
| 串口通信 | 正常输出调试信息 | 成功 | ✅ |
| I2C 扫描 | 检测到 OLED 设备 | 成功 | ✅ |
| SD 卡初始化 | 识别 SD 卡类型和容量 | 成功 | ✅ |
| 文件读写 | 成功创建和读取文件 | 成功 | ✅ |
| LED 控制 | 板载 LED 闪烁 | 成功 | ✅ |
| WS2812B 控制 | RGB 灯珠点亮 | 成功 | ✅ |
| 摇杆采集 | 正确读取模拟值 | 成功 | ✅ |
| OLED 显示 | 显示系统信息 | 成功 | ✅ |
从这个结果看,RPDuino-2040 已经完成了作为一块基础开发板最关键的 bring-up。
它不只是“焊上电源灯亮了”,而是把数字 IO、模拟输入、I2C、SPI、USB 串口、外部存储和显示模块都做了验证。
05
踩坑记录
相比“功能全部成功”,这篇项目记录里更值得工程师看的,其实是两个问题。
Type-C母座连焊,差点烧电脑USB口
作者在完成打板、贴片和焊接后,先测了一下 VIN、5V、3.3V,没有发现对地短路。于是直接插上 USB,结果差点把电脑 USB 口烧毁。最后排查发现,是 Type-C 母座焊脚存在连焊,造成 USB 短路。
这个问题非常典型。
USB Type-C 母座引脚密、焊盘小,如果是手焊或者回流后没有认真检查,很容易出现细小连焊。更麻烦的是,很多短路并不一定出现在 5V 到 GND 这种一眼能量到的位置,也可能藏在接口附近。
所以开发板首次上电时,建议多加几步:
-
先检查 Type-C、LDO、主控、电源入口这些高风险区域
-
用万用表量 VBUS、5V、3.3V、GND 之间是否短路
-
条件允许时,用限流电源先上电
-
USB 接电脑前,最好先用电流表或 USB 测试表看一下输入电流
-
Type-C 座子焊完后,用放大镜或显微镜检查焊脚
很多板子的第一次 bring-up,真正危险的不是代码,而是电源和接口焊接。
SD卡读不出来
作者最开始使用 adafruit/SdFat - Adafruit Fork 库,结果编译和读取都不顺利。后面换成 RP2040_SD 库,并逐步打印调试信息,才发现问题与 SD 卡格式有关。
SD 卡相关问题通常会混在一起:
-
库是否支持当前平台
-
SPI 引脚是否定义正确
-
CS 引脚是否配置正确
-
SD 卡格式是否兼容
-
卡座焊接是否可靠
-
供电是否稳定
-
线长和速率是否合适
所以调 SD 卡时,不建议直接写复杂业务代码。先用最小测试程序确认初始化、类型识别、容量读取、写文件、读文件,再往上叠加应用逻辑。
06
这块板后续可以怎么玩?
RPDuino-2040 已经具备 Arduino UNO 板形、RP2040 性能和多种外设接口。后续可以继续扩展出很多玩法。
比如:
- 用作高性能 Arduino UNO 替代板
对于原本基于 UNO 的项目,如果遇到 Flash、SRAM 或主频不够的问题,可以考虑迁移到这类 RP2040 UNO 兼容板上。
尤其是需要更多缓存、更快采样、更复杂控制逻辑的应用,RP2040 会比 ATmega328P 宽裕很多。
- 用作学习套件主控
项目页里提到,这块板主要用于开发学习套件主控,常用于实时信号采集与处理场景。
这类场景下,Arduino UNO 的生态和 RP2040 的性能结合起来,确实比较适合教学和实验:
-
初学者可以继续用 Arduino 风格开发
-
进阶用户可以使用 RP2040 C/C++ SDK
-
想玩脚本化开发的人可以使用 MicroPython / CircuitPython
-
想研究底层时序的人可以继续探索 PIO
- 用作 Make Blocks 模块化系统的一块主控板
既然它兼容 UNO 板形,又引出了 GPIO、I2C、SPI、UART、ADC 等接口,那么后续很适合作为模块化硬件系统中的主控板使用。
传感器、显示、通信、存储、控制类模块,都可以围绕它继续扩展。
07
总结
很多开源硬件项目看起来都很顺:画板、打样、上电、成功。
但真正做过板子的人都知道,中间最磨人的地方,往往是那些不起眼的小问题:一个 Type-C 焊脚连焊、一张 SD 卡格式不对、一个库不适配、一个引脚定义没确认,都可能让你查半天。
RPDuino-2040 阶段2已经把“设计”推进到了“验证”。这块基于 RP2040 的 Arduino UNO 板形开发板,已经完成了焊接调试,并跑通了串口、I2C、SD 卡、LED、WS2812B、摇杆 ADC 和 OLED 显示等基础功能。
从结果看,它已经具备了一块学习型主控开发板的基本形态;从过程看,它也留下了不少值得参考的 bring-up 经验。
对于想学习 RP2040、Arduino 兼容板设计、开发板调试流程,或者正在做 Make Blocks 模块化硬件设计的同学来说,这个项目值得点进去看看。
完整项目查看:
项目链接:https://www.eetree.cn/project/detail/5135
附件:RPDuino-test.zip内容:开发板功能测试、PlatformIO 工程源码

点击阅读原文查看项目
