用纳芯微NSHT30芯片设计的手指测温板
该项目使用了NSHT30芯片,实现了测量温度和湿度的设计,它的主要功能为:以尽量小的体积,并且通讯接口引出,完成较小温湿度模块。
标签
WeDesign活动
温度测量
NSHT30
你豪吗
更新2025-01-02
41

视频链接:https://v.youku.com/v_show/id_XNjQ0MzQ3Mjg1Ng==.html

项目介绍

在参与硬禾学堂举办的WeDesign活动第六期活动中,选择了四款纳芯微的芯片之一的NSHT30传感器芯片,并且搭配带屏12指神探作为主控芯片,成功完成人体温湿度检测的这个任务。需要通过KiCAD这个开源软件绘制原理图和PCB,并且打板焊接调试,最终实现对人体温湿度的实时监测,后面我将介绍一下设计思路和过程。

项目设计思路(含设计框图)

完成这个项目,主要需要学习软件和硬件两大部分的知识:

  1. 软件方面:使用的是官方建议的带屏12指神探,主控芯片是RP2040,并且使用简单易用的micropython作为开发语言方便进行开,官方也提供了其他项目的开发代码,可以用于参考学习,
    1. IIC接口:用于读取传感器NSHT30
    2. 屏幕UI的设计,用于显示温湿度信息
  2. 硬件方面:需要需要KiCAD绘制原理图和PCB,并且需要导出Gerber文件,交给PCB生产公司打板,收到后需要进行元器件的焊接
    1. 焊接:注意不要短路了啊啊啊!不要虚焊了啊啊啊!

image.png

搜集素材的思路

我在搜集素材的时候,主要可以分为两部分:

  1. 软件方面:电子森林官网提供的带显示屏的、基于RP2040的多功能嵌入式编程学习、硬件调试平台(https://www.eetree.cn/platform/2585,这里面有详细的原理图和软件代码测试包,以及引出IO的管教的功能,非常方面用于参考
  2. 硬件方面:硬禾学堂有发布关于KiCad的教程(https://class.eetree.cn/page/627066),该教程十分封面,从原理图设计到PCB设计,最后还有一个实战项目来汇总练手
  3. NSHT30芯片:这款芯片是纳芯微厂商生产的,所以需要找到对应数据手册来参考如何绘制原理图和PCB图,在编写软件的时候还需要对应的接口时许图,比如这个芯片是IIC的,所以需要得到对应的地址和数据指令等

实现结果展示

调试遇到的问题:

  1. 芯片虚焊,导致RP2040的IIC读取不到数据,导致经过报错
  2. 屏幕的UI设计的时候,每次想在指定位置显示内容,都会出现不同程序的偏差和重合,需要不断的进行调整
  3. 字体的大小的问题,内置固件只有16×32和8×8的,想要显示大型字体就得另辟蹊径了


对于字体的方式,并没有找到为什么好的方法,一开始想模仿官方示例的做法,但是琢磨了好久也没有弄出来,于是转变了思路,使用画点的方式来调整不同大小的字体,还好需要保存 的数组数量不是很多且芯片内存足够,通过一个bit一个bit的判断数组中的数据来判断这个像素点是否绘制,从而来在局部形成一个大大的数字,因为是一个点一个点刷新的并且数量还很多,所以在刷新的时候会有一定的延迟,代码在下方或者附件中展示

Snipaste_2024-11-06_20-06-46.pngSnipaste_2024-11-06_20-07-02.png

微信图片_20241106200216.jpg微信图片_20241106200215.jpg

关键代码及说明

在主函数中,主要获取温湿度数据,然后取出每一位,来通过if判断显示对应的数据

while True:
display.fill(st7789.BLACK)

temperature,humidity = ReadDate()
temperature_1 = int(temperature) // 10 % 10
temperature_2 = int(temperature) % 10
temperature_3 = int((temperature - int(temperature)) * 10)
humidity_1 = int(humidity) // 10 % 10
humidity_2 = int(humidity) % 10

//……以下是显示的逻辑
if temperature_1 == 0:
draw_pixels(data0,64,128,0,18)
elif temperature_1 == 1:
//以下省略

读取NSHT30的代码函数

def ReadDate():
temperature = 0
humidity = 0
# write
senddata = bytearray(3)
senddata[0] = 0x24
senddata[1] = 0x0B
i2c.writeto(0x44, senddata)
# read
utime.sleep_ms(7)
readdata = i2c.readfrom(0x44, 6)
readdata1 = [byte for byte in readdata]
# merge
temperature = (readdata1[0]<<8) | readdata1[1]
humidity = (readdata1[3]<<8) | readdata1[4]
# convert
temperature = -45 + 175*temperature/(65536-1)
humidity = 100 * humidity/(65536-1)
return temperature,humidity

根据数组在指定位置绘制像素点函数

def draw_pixels(data, width, height, start_x, start_y):
byte_width = width // 8 # 每行的字节数
for y in range(height):
for x in range(width):
# 计算当前像素所在的字节索引
byte_index = y * byte_width + x // 8
# 计算当前像素在字节内的位索引
bit_index = 7 - (x % 8) # 从最高位开始计数
# 检查当前像素是否应该被点亮
if (data[byte_index] >> bit_index) & 1:
# 绘制单个像素点,考虑偏移量
display.pixel(start_x + x, start_y + y, st7789.WHITE)

通过上面draw_pixels这个函数,就可以在指定的位置绘制出以下数据了,这个可以通过取模软件然后修改一下得到,以下只是其中的一个

data0 = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0xff, 0xff, 0x80, 0x00, 0x00,
0x00, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x00,
0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00,
0x00, 0x00, 0x3f, 0xfc, 0x1f, 0xf8, 0x00, 0x00,
0x00, 0x00, 0x7f, 0xf0, 0x07, 0xfe, 0x00, 0x00,
0x00, 0x00, 0xff, 0xe0, 0x03, 0xff, 0x00, 0x00,
0x00, 0x01, 0xff, 0xc0, 0x01, 0xff, 0x00, 0x00,
0x00, 0x01, 0xff, 0x80, 0x00, 0xff, 0x80, 0x00,
0x00, 0x03, 0xff, 0x00, 0x00, 0x7f, 0xc0, 0x00,
0x00, 0x07, 0xfe, 0x00, 0x00, 0x7f, 0xe0, 0x00,
0x00, 0x07, 0xfe, 0x00, 0x00, 0x3f, 0xe0, 0x00,
0x00, 0x0f, 0xfc, 0x00, 0x00, 0x3f, 0xf0, 0x00,
0x00, 0x1f, 0xfc, 0x00, 0x00, 0x1f, 0xf0, 0x00,
0x00, 0x1f, 0xf8, 0x00, 0x00, 0x1f, 0xf8, 0x00,
0x00, 0x3f, 0xf8, 0x00, 0x00, 0x1f, 0xf8, 0x00,
0x00, 0x3f, 0xf0, 0x00, 0x00, 0x0f, 0xfc, 0x00,
0x00, 0x3f, 0xf0, 0x00, 0x00, 0x0f, 0xfc, 0x00,
0x00, 0x7f, 0xf0, 0x00, 0x00, 0x0f, 0xfe, 0x00,
0x00, 0x7f, 0xe0, 0x00, 0x00, 0x07, 0xfe, 0x00,
0x00, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xfe, 0x00,
0x00, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0x00,
0x00, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0x00,
0x00, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0x00,
0x01, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0x00,
0x01, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0x80,
0x01, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0x80,
0x01, 0xff, 0x80, 0x00, 0x00, 0x03, 0xff, 0x80,
0x03, 0xff, 0x80, 0x00, 0x00, 0x03, 0xff, 0x80,
0x03, 0xff, 0x80, 0x00, 0x00, 0x03, 0xff, 0x80,
0x03, 0xff, 0x80, 0x00, 0x00, 0x01, 0xff, 0x80,
0x03, 0xff, 0x80, 0x00, 0x00, 0x01, 0xff, 0xc0,
0x03, 0xff, 0x80, 0x00, 0x00, 0x01, 0xff, 0xc0,
0x03, 0xff, 0x80, 0x00, 0x00, 0x01, 0xff, 0xc0,
0x03, 0xff, 0x80, 0x00, 0x00, 0x01, 0xff, 0xc0,
0x03, 0xff, 0x80, 0x00, 0x00, 0x01, 0xff, 0xc0,
0x07, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff, 0xc0,
0x07, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff, 0xc0,
0x07, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff, 0xc0,
0x07, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff, 0xc0,
0x07, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff, 0xc0,
0x07, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff, 0xc0,
0x07, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff, 0xc0,
0x07, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff, 0xc0,
0x07, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff, 0xc0,
0x07, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff, 0xc0,
0x07, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff, 0xc0,
0x07, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff, 0xc0,
0x07, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff, 0xc0,
0x07, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff, 0xc0,
0x07, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff, 0xc0,
0x07, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff, 0xc0,
0x03, 0xff, 0x80, 0x00, 0x00, 0x01, 0xff, 0xc0,
0x03, 0xff, 0x80, 0x00, 0x00, 0x01, 0xff, 0xc0,
0x03, 0xff, 0x80, 0x00, 0x00, 0x01, 0xff, 0xc0,
0x03, 0xff, 0x80, 0x00, 0x00, 0x01, 0xff, 0xc0,
0x03, 0xff, 0x80, 0x00, 0x00, 0x01, 0xff, 0xc0,
0x03, 0xff, 0x80, 0x00, 0x00, 0x01, 0xff, 0x80,
0x03, 0xff, 0x80, 0x00, 0x00, 0x03, 0xff, 0x80,
0x03, 0xff, 0x80, 0x00, 0x00, 0x03, 0xff, 0x80,
0x01, 0xff, 0x80, 0x00, 0x00, 0x03, 0xff, 0x80,
0x01, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0x80,
0x01, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0x00,
0x01, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0x00,
0x00, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0x00,
0x00, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0x00,
0x00, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xfe, 0x00,
0x00, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xfe, 0x00,
0x00, 0x7f, 0xe0, 0x00, 0x00, 0x07, 0xfe, 0x00,
0x00, 0x7f, 0xf0, 0x00, 0x00, 0x0f, 0xfc, 0x00,
0x00, 0x7f, 0xf0, 0x00, 0x00, 0x0f, 0xfc, 0x00,
0x00, 0x3f, 0xf0, 0x00, 0x00, 0x0f, 0xfc, 0x00,
0x00, 0x3f, 0xf8, 0x00, 0x00, 0x1f, 0xf8, 0x00,
0x00, 0x1f, 0xf8, 0x00, 0x00, 0x1f, 0xf8, 0x00,
0x00, 0x1f, 0xfc, 0x00, 0x00, 0x1f, 0xf0, 0x00,
0x00, 0x0f, 0xfc, 0x00, 0x00, 0x3f, 0xf0, 0x00,
0x00, 0x07, 0xfe, 0x00, 0x00, 0x3f, 0xe0, 0x00,
0x00, 0x07, 0xfe, 0x00, 0x00, 0x7f, 0xc0, 0x00,
0x00, 0x03, 0xff, 0x00, 0x00, 0xff, 0xc0, 0x00,
0x00, 0x01, 0xff, 0x80, 0x00, 0xff, 0x80, 0x00,
0x00, 0x01, 0xff, 0x80, 0x01, 0xff, 0x00, 0x00,
0x00, 0x00, 0xff, 0xc0, 0x03, 0xfe, 0x00, 0x00,
0x00, 0x00, 0x7f, 0xf0, 0x0f, 0xfc, 0x00, 0x00,
0x00, 0x00, 0x3f, 0xfc, 0x3f, 0xf8, 0x00, 0x00,
0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00,
0x00, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x00,
0x00, 0x00, 0x01, 0xff, 0xff, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
]

原理图/PCB图

原理图和PCB比较简单,第一次使用KiCad都是参考着硬禾学堂官方的教程画的。

这属于NSHT30的最小系统板了,但有一个电源指示灯,十分小巧可以用于其他项目中去。

SCH.png

PCB.pngPCB_3D.png

实物

其中R3是预留的,怕浮空不能很好的使能。但是效果很好可以正常使用,不用焊接!

只需要使用控制器的四个引脚即可正常使用,1,电源。2,GND。3,SDA。4,SCL。对应接上即可

U1为本次项目的核心--NSHT30,外围电路灰常简单,一对IIC的上拉电阻和一颗电源的滤波电容,最后还有一颗电源指定灯,确定电源是正常的,

图片.png

微信图片_202412312156561.jpg


总结

感谢电子森林举办的WeDesign活动,此次活动不仅为我提供了一个宝贵的机会来了解并学习KiCad这款强大的开源电子设计自动化(EDA)软件,还让我亲身体验了动手焊接电子元件的乐趣和挑战。通过这次活动,我对从原理图设计到PCB布局的整个流程有了更全面的认识,同时也掌握了更多关于电路设计和制造的实际技能。

KiCad文件
使用说明
全屏
附件下载
KiCad.zip
原理图、PCB、KiCad工程
RP2040.zip
12指神探代码
团队介绍
个人玩家
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号