1、任务介绍
本项目设计实现了一个基于RP2040微控制器的多通道高精度传感器数据采集与显示系统。核心目标是独立完成从传感器信号调理PCB的设计焊接,到嵌入式数据采集逻辑,再到TFT屏幕开发的整个开发流程。
2、器件与基本功能
温度监测:使用 NST461-DQNR 温度传感器,监测环境或设备的温度变化。
表压测量:使用 NSPGD1M006DT04 表压传感器,测量相对于大气压的压力,适用于气压、风压等场景。
绝压测量:使用 NSPAD1N200DR04 绝压传感器,测量相对于真空的绝对压力,可用于海拔高度或密封系统压力监测。
RP2040带屏十二指神探功能实现
1. 多传感器数据采集(D2/D3 I2C通信)
功能目标:通过 I2C接口(SCL/SDA) 采集 温度传感器、压片传感器、绝压传感器 的数据,并在OLED屏幕上实时显示。
硬件配置:
信号连接:
十二指神探的 D2(SCL) 和 D3(SDA) 分别连接至传感器的SCL 和 SDA。
传感器PCB需预留 4.7kΩ上拉电阻连接至VCC,确保I2C信号稳定。
PCB设计要点:
布局优化:
传感器尽量靠近I2C引脚,减少信号干扰。
避免长距离平行走线,必要时添加磁珠或滤波电容。
焊接验证:
使用万用表检查传感器引脚是否短路或虚焊。
测量电源部分的小电容就可以验证是否有短路。
通过I2C扫描确认传感器地址是否被识别。
2. 数据采集与显示
功能实现步骤:
初始化I2C外设:
配置RP2040的I2C模块,配置时钟频率,配置IO20,IO21。
传感器数据读取:
温度传感器:读取寄存器数据,转换为实际温度值(单位:℃)。
压片传感器:根据协议读取压力值(单位:kPa)。
绝压传感器:读取寄存器数据并转换为绝对压力值(单位:hPa)。
OLED显示:
使用SSD1306驱动库初始化分辨率OLED屏幕。
在屏幕上分区域显示温度、压片压力和绝压数据,定期进行刷新。
3、原理图

1、表压传感器 NSPGD1M006DT04
2、电源LDO芯片
3、绝压传感器 NSPAD1N200DR04
4、温度传感器 NST461-DQNR
5、外接连接座子与十二神探连接器
6、IIC上拉电阻
4、PCB图

5、3D图

6、连接示意图


7、代码
uint8_t PData[3] = {0}; // 定义3字节数组,用于存储从传感器读取的原始压力数据
// 状态检查:读取传感器状态寄存器0x30
NSPGD1M_ReadByte(0x30, Reg30);
if(Reg30[0] == 0x02) { // 检查状态位,0x02表示传感器就绪或特定状态
number = 1; // 设置状态标志位
}
char buf[12]; // 格式化输出缓冲区
// 读取各类传感器数据
float tLocal = readLocalTemp(); // 读取本地温度传感器数值(单位:℃)
float tRemot = readRemoteTemp(); // 读取远端温度传感器数值(单位:℃)
float p = nspad1n_readPressure(); // 读取绝压传感器数值(单位:kPa)
// 串口打印温度压力数据(调试信息)
Serial.print(tLocal, 4); // 打印本地温度,保留4位小数
Serial.print(F(" °C "));
Serial.print(tRemot, 4); // 打印远端温度,保留4位小数
Serial.print(F(" °C "));
Serial.print(p, 2); // 打印绝压值,保留2位小数
Serial.println(" kPa");
// 读取压力传感器原始数据(3字节,寄存器地址0x06-0x08)
NSPGD1M_Read3Byte(0x06, PData);
REG06 = PData[0]; // 压力数据高字节
REG07 = PData[1]; // 压力数据中字节
REG08 = PData[2]; // 压力数据低字节
// 合成24位原始压力数据(传感器输出为24位补码格式)
PCode = (REG06 << 16) | (REG07 << 8) | REG08;
// 符号处理:将24位补码转换为有符号整数
if(PCode > 8388607) { // 8388607 = 2^23 -1(24位有符号数的正数最大值)
Pdata = PCode - 16777216; // 负数转换:PCode - 2^24
} else {
Pdata = PCode; // 正数直接使用
}
// 压力值换算:将数字量转换为实际物理量(根据传感器量程和灵敏度)
// 换算公式:Pressure = (原始数据/满量程) * 灵敏度 - 零点偏移
Pressure = (static_cast<float>(Pdata) / 8388607.0) * 0.13333 - 0.1;
// 串口输出换算后的表压值
Serial.print("Pressure: ");
Serial.print(Pressure, 2); // 保留2位小数
Serial.println(" kPa");
// ========== 屏幕显示界面绘制 ========== //
// 绘制界面标题栏
u8f.setCursor(100, 30); // 设置标题显示位置
u8f.setFont(u8g2_font_ncenB14_tf); // 设置英文字体
u8f.print("纳芯微 WEDsien"); // 显示英文标题
u8f.setCursor(40, 30); // 设置中文标题位置
u8f.setFont(u8g2_font_wqy16_t_gb2312); // 设置中文字体
u8f.print("纳芯微"); // 显示中文标题
// 绘制数据标签和单位
u8f.setCursor(5, 70);
u8f.setFont(u8g2_font_wqy16_t_gb2312);
u8f.print("温度1:"); // 温度
u8f.setCursor(215, 70);
u8f.print("℃"); // 温度单位
u8f.setCursor(5, 120);
u8f.print("温度2:"); // 温度
u8f.setCursor(215, 120);
u8f.print("℃");
u8f.setCursor(5, 175);
u8f.print("绝压3:"); // 绝压数据
u8f.setCursor(210, 170);
u8f.print("kPa"); // 压力单位
u8f.setCursor(5, 220);
u8f.print("表压4:"); // 表压数据
u8f.setCursor(210, 220);
u8f.print("hPa"); // 压力单位
u8f.drawGlyph(0, 150, 280); // 绘制分割线或图标(根据字体定义)
// 显示本地温度数值(大字体显示)
u8f.setFont(u8g2_font_inb33_mn); // 设置大号数字字体
sprintf(buf, "%.1f", tLocal); // 格式化温度值,保留1位小数
u8f.setCursor(65, 80); // 设置数值显示位置
u8f.print(buf); // 显示温度值
// 显示远端温度数值
sprintf(buf, "%.1f", tRemot);
u8f.setCursor(65, 130);
u8f.print(buf);
// 显示绝压数值
u8f.setFont(u8g2_font_inb33_mn);
sprintf(buf, "%.1f", p);
u8f.setCursor(65, 180);
u8f.print(buf);
// 显示表压数值
u8f.setFont(u8g2_font_inb33_mn);
sprintf(buf, "%.1f", Pressure);
u8f.setCursor(65, 230);
u8f.print(buf);
delay(5000); // 数据刷新间隔:5秒
8、软件工作流程图

9、采集传感器打印结果

十二指显示结果:

10、BOM资料

11、调试与总结
调试
先看下图,绝压传感器这里飞了一条线,当时发PCB板检查时只对了PCB与原理图文件,没有检查规格书里的原理图引脚定义,导致出错。
LDO那里略过,只是当时扫不到其它的传感以为是电源有问题,移了一下,这里增加LDO是为了兼容5V,不过我把LDO移开,现在是3.3V供电。

总结
从这个项目开始到结束,折腾算比较久的,特别是在处理IIC上面,算是收获很丰富,学到了如何使用纳芯微的传感器,读不到地址时怎么去解决问题,特别是调试的时候,怎么排除问题,是软件还是硬件的问题,最终到解决问题,整体把项目完成,并记录,这就是我这次的收获。