这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 电子DIY+12指神探与纳芯微传感器DIY

共1条 1/1 1 跳转至

电子DIY+12指神探与纳芯微传感器DIY

高工
2026-03-18 08:00:22     打赏
一、硬件介绍温度传感器 NST461-DQNR一款“远程+本地”双通道数字温度传感器,具备小尺寸、高精度、低功耗特性。提供 12-bit ADC,温度分辨率达 0.0625°C,测量范围覆盖 -40°C 至 +125°C芯片本体及远程通道均适用。采用 I²C 接口,封装尺寸为 1mm² 级,适用于空间受限的嵌入式场景。绝压传感器 NSPAD1N200DR04纳芯微(NOVOSENSE)车规级 NSPAD1N 系列绝对压力传感器,以真空为基准,输出当前环境的绝对压力值。量程为 10 kPa 至 400 kPa(支持定制),精度在 -20°C 至 115°C 范围内数字输出误差 ≤±1%F.S.,全温区工作范围 -40°C 至 125°C。支持 I²C/SPI 数字输出,兼容多种通信协议。12指神探开发板基于 RP2040 微控制器,配备 240×240 分辨率 LCD 彩屏、两个轻触按键及一个拨轮。提供 12 根扩展管脚,支持对外供电、3 路 ADC 模拟输入、最多 9 路通用数字 IO,适用于嵌入式学习、控制与调试。

支持 C/C++ 及 MicroPython 编程,并配有 3D 打印外壳,内部预留空闲空间,便于集成传感器模块。


二、任务设计温度监测模块使用 NST461-DQNR 制作电路模块,通过 I²C 接口连接任意单片机,实时读取本地温度芯片本体及远程温度外部测温点。气压监测模块基于 NSPAD1N200DR04 设计电路,配置为 I²C 输出模式,测试不同环境下的绝对压力值,覆盖量程范围内的典型场景。环境信息展示摆件将上述两个传感器集成至 12指神探开发板 的 3D 打印外壳内,利用其空闲空间安装传感器芯片,体积小巧,适配性强。通过开发板的 LCD 彩屏动态显示 温度与气压数据,结合按键与拨轮实现交互控制,切换显示模式、调整刷新频率,打造桌面级环境监测终端。

0100928e-d315-4dd2-ab95-68b2a568da27.png

系统框架很简单,从传感器读取环境数据,然后展示到12指神探的屏幕上。


原理图

03cbfe2c-81dc-4b62-b7b8-eb777f7285d5.png

在硬件电路设计中,温度传感器 NST461-DQNR 与绝压传感器 NSPAD1N200DR04 均采用 I²C 总线 通信,因此将二者挂载于同一组 I²C 总线上以简化布线。供电方面,温度传感器使用 3.3V 电源,而绝压传感器原计划采用 5V 供电 以提升信号稳定性;I²C 总线的上拉电阻统一连接至 3.3V,以匹配温度传感器的电平标准。实际测试中,当绝压传感器接入 5V 电源 时,I²C 总线数据读取出现异常,表现为通信中断或数据错乱。经排查,问题源于电平不兼容:绝压传感器在 5V 供电下,其 I²C 接口的 SDA/SCL 信号高电平可能超过 3.3V,而温度传感器及主控芯片(如 RP2040)的 I²C 输入耐压为 3.3V,导致电平冲突。为解决此问题,最终将绝压传感器的供电调整为 3.3V,确保总线电平一致,通信恢复正常。此外,绝压传感器 NSPAD1N200DR04 为纯数字芯片,其模拟接口(AD)仅在部分型号中支持,而当前使用的版本无模拟输出功能。因此,设计初期预留的模拟引脚在最终方案中未被使用,仅通过 I²C 接口获取数字压力值,避免了硬件资源浪费。


实际成品

7ced667b-8f04-4280-afda-a7b397f5cb58.png

硬件测试

板子打好后,先再焊盘上焊上引线对板子做初步测试。首先是使用I2C扫描,看看是否能读取到两颗传感器芯片的I2C地址。

d4f62aa1-7f7b-4549-bb25-9f642c8144e8.png

只能读到一个传感器的地址。先是怀疑板子焊接问题,仔仔细细、来来回回检查了PCB板子,确认了焊脚都是OK的。于是向群里各位老师求教。老师们介绍这个12指神探能做逻辑分析仪,可以抓取I2C波形图来寻找问题所在。

3553a46a5c5ea6b41a7016e689e1c112.png

在硬件调试过程中,通过逻辑分析仪抓取 I²C 总线波形时,仅观察到与温度传感器 NST461-DQNR 的通信数据,而绝压传感器 NSPAD1N200DR04 的通信波形完全缺失。进一步排查发现,问题根源在于该绝压传感器的 I²C 地址配置:其官方文档明确标注设备地址为 0x7F,但此地址在标准的 7-bit I²C 地址空间 中属于 保留区,通常用于特殊协议或未定义设备。

常规的 I²C 扫描程序会默认跳过保留地址段,导致主机无法识别该传感器。许多开源库的扫描范围仅覆盖 0x03-0x77,因此 0x7F 被自动忽略。这一机制解释了为何波形图中未出现绝压传感器的通信数据——主机根本未尝试访问该地址。

#include <Wire.h>
#include "SPI.h"
#include "TFT_eSPI.h"
#include "U8g2_for_TFT_eSPI.h"
arduino::MbedI2C Wire0(20, 21);
TFT_eSPI tft = TFT_eSPI(); // tft instance
U8g2_for_TFT_eSPI u8f;     // U8g2 font instance
void setup()
{
  Wire0.begin();
  tft.begin();
  tft.setRotation(0);
  tft.fillScreen(TFT_BLACK);
  u8f.setFontMode(0);                // use u8g2 none transparent mode
  u8f.setFontDirection(0);           // left to right (this is default)
  u8f.setForegroundColor(TFT_WHITE); // apply color
  u8f.setFont(u8g2_font_wqy15_t_gb2312);
  u8f.begin(tft); // connect u8g2 procedures to TFT_eSPI
  Serial.begin(115200);
  Serial.println("\nI2C Scanner");
}
void loop()
{
  byte error, address;
  int nDevices;
  char buf[20];
  Serial.println("Scanning...");
  u8f.setCursor(0, 20);
  u8f.print("Scanning...");
  nDevices = 0;
  for (address = 1; address <= 127; address++)
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire0.beginTransmission(address);
    error = Wire0.endTransmission();


    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      u8f.setCursor(0, 40 + 20 * nDevices);
      sprintf(buf, "I2C device address 0x%02x", address);
      u8f.print(buf);
      if (address < 16)
        Serial.print("0");
      Serial.print(address, HEX);
      Serial.println("  !");
      nDevices++;
    }
    else if (error == 4)
    {
      Serial.print("Unknow 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");
  delay(5000); // wait 5 seconds for next scan
}

经过调整出来了地址

image.png

项目实现

搞定了硬件,接下来的开发就变得很简单了。

47830018-10f6-43e2-a651-4987e3818366.png

读取温度。温度分两个温度:一个本地温度,一个远端温度。远端温度通过读取的温度值和实际温度做比较,高了约1.83℃。查阅官方手册,可以通过寄存器进行校准,不过可惜是寄存器校准,这就意味着一旦断电,就需要重新校正,所以这里将这个1.83℃的温差,写死在了程序里。

2aa93a7d-e1d0-4efb-8d50-44a635410494.png

代码

// 手工测的 远端与本地温度相差为1.83°C   将偏差温度写入寄存器
void setTempOffset()
{
  uint8_t buf[2];
  float offset = -1.83;
  buf[0] = (int8_t)(floor(offset));
  buf[1] = (uint8_t)((offset - floor(offset)) * 16);
  writeReg8(REG_R_OFFS_H, buf[0]);
  writeReg8(REG_R_OFFS_L, buf[1]);
}
// 读取远本地温度,返回单位为 °C 的 float
float readLocalTemp()
{
  uint8_t buf[2];
  /* 读本地温度 */
  Wire0.beginTransmission(NST_ADDR);
  Wire0.write(REG_L_TEMP_H);
  Wire0.endTransmission(false);
  Wire0.requestFrom(NST_ADDR, 2);
  buf[0] = Wire0.read();
  buf[1] = Wire0.read();
  return (int16_t)((buf[0] << 8 | buf[1]) >> 4) * 0.0625f;
}
// 读取远端温度,返回单位为 °C 的 float
float readRemoteTemp()
{
  uint8_t buf[2];
  /* 读远端温度 */
  Wire0.beginTransmission(NST_ADDR);
  Wire0.write(REG_R_TEMP_H);
  Wire0.endTransmission(false);
  Wire0.requestFrom(NST_ADDR, 2);
  buf[0] = Wire0.read();
  buf[1] = Wire0.read();
  return (int16_t)((buf[0] << 8 | buf[1]) >> 4) * 0.0625f;
}

绝压传感器读取也是比较简单的,直接读取出气压值。

// --------------绝压传感器NSPAD1N200DR04------------------------------------------
/* 向寄存器写 1 字节 */
bool nspad1n_writeReg(uint8_t reg, uint8_t val)
{
  Wire0.beginTransmission(I2C_ADDR);
  Wire0.write(reg);
  Wire0.write(val);
  return Wire0.endTransmission(true) == 0;
}


/* 从寄存器连续读 n 字节 */
bool nspad1n_readRegs(uint8_t reg, uint8_t *buf, uint8_t len)
{
  Wire0.beginTransmission(I2C_ADDR);
  Wire0.write(reg);
  if (Wire0.endTransmission(false) != 0)
    return false; // restart
  Wire0.requestFrom(I2C_ADDR, len);
  if (Wire0.available() != len)
    return false;
  for (uint8_t i = 0; i < len; ++i)
    buf[i] = Wire0.read();
  return true;
}

/* 触发转换并等待完成,最大等待 100 ms */
bool nspad1n_triggerAndWait(void)
{
  if (!nspad1n_writeReg(REG_CMD, 0x0A))
    return false;
  uint8_t status = 0;
  unsigned long t = millis();
  do
  {
    if (!nspad1n_readRegs(REG_CMD, &status, 1))
      return false;
    if (status & 0x02)
      return true; // bit1 = 1 表示转换完成
  } while (millis() - t < 100);
  return false; // 超时
}

/* 读取压力并返回单位 kPa,失败返回 NAN */
float nspad1n_readPressure(void)
{
  uint8_t buf[3];
  if (!nspad1n_triggerAndWait())
    return NAN;
  if (!nspad1n_readRegs(REG_PDATA, buf, 3))
    return NAN;

  int32_t code = ((uint32_t)buf[0] << 16) | ((uint16_t)buf[1] << 8) | buf[2];
  if (code > 8388607)
    code -= 16777216; // 符号扩展
  return (float)code * A / 8388607.0f + B;
}
在成功读取温度传感器 NST461-DQNR 的本地与远程温度数据,以及绝压传感器 NSPAD1N200DR04 的气压值后,采用 U8g2_for_TFT_eSPI 库在 LCD 彩屏上实现数据可视化。该库专为嵌入式设备优化,支持流畅的图形渲染与文本显示。

通过调用库函数,在屏幕固定区域绘制本地温度与远程温度,单位为 °C,并动态更新数值;在右侧区域显示当前气压值,单位为 kPa。为提升可读性,添加标题标签并调整字体大小与颜色,确保信息清晰区分。整个绘制过程占用少量 CPU 资源,与传感器数据读取任务并行运行,实现实时环境监测的桌面摆件功能。

实现效果

d9b35b57-51f1-4d34-b1c2-db81c522b13e.png







共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]