今年寒假我给自己布置了一份非交不可的寒假实验报告——不是老师留的那种应付型作业,而是真想让数字替我说一次话:家里的温度和湿度到底怎么变、什么时候变、为什么变。起因很简单,每天早晨起来总觉得屋里干得鼻子不舒服,但干到什么程度、一天里什么时候最干,完全说不清。与其靠体感瞎猜,不如拿传感器记下来看。这份报告从选题、搭设备、连续记录到得出结论,前后花了10天,传感器加配件总成本不到50元。今天把完整过程整理出来,包括每一步的坑和补救办法,给想在家里做类似小实验的朋友一个能直接照着抄的参考。
1. 为什么寒假实验选了“室内环境观测”——选题逻辑与预期收获
寒假实验最容易踩的坑,是选一个“看起来好玩但收尾很尴尬”的项目。比如泡醋蛋、种豆芽、做个小手工,基本半天搞完,剩下半个月不知道干嘛,最后报告全凭想象力补数据。我自己以前也干过这种事,写完自己都不信。这次我给自己定了三条选题标准:第一,实验必须产生连续数据,不是一次性结果;第二,在家就能完成,不用跑实验室;第三,要能回答一个自己真正好奇的问题。室内温湿度观测完美满足前两条,而第三条正好对准了我“屋里到底干不干”的困惑。
定了方向之后,我把实验目标拆成三个具体问题,相当于给自己立了三个能被数据直接回答的假设:
- 室内温度在一天里怎么波动?昼夜差距有没有想象中大?
- 湿度高峰是不是真的跟着做饭、洗澡的时间走?
- 一次开窗通风,温度和湿度多久能回到原来的水平?
这三个问题都不复杂,但都能用数据说话,而且任何一个普通家庭环境里都能复现。实验范围最后定为连续记录7天,每分钟采一条,温度和湿度同时记录。这个采样频率不会让数据量爆掉,又足够看清分钟级的变化。
在做这个实验之前,我对室内环境的认知基本停留在“冬天冷、夏天热、供暖期更干”这种模糊层面。把数据一摆出来才发现,很多体感结论根本不靠谱。比如我一直以为晚上湿度比白天高,因为晚上不通风,结果数据告诉我开窗那段时间湿度跳水才是最剧烈的。这种“原以为是”和“实际是”之间的落差,恰恰是实验最有价值的地方。无论你是做学科作业,还是给家里找改善环境的依据,这套方法都能迁移过去。
2. 实验系统搭建:传感器选型、电路连接与自动记录
2.1 为什么选DHT22,而不是更便宜的DHT11
很多人第一次接触温湿度传感器会先看到DHT11,因为它便宜、库多、教程满天飞。但如果你要做的是“找出1℃级别的温度变化”,DHT11的精度直接不够看。
| 项目 | DHT11 | DHT22 |
|---|---|---|
| 温度精度 | ±2℃ | ±0.5℃ |
| 湿度精度 | ±5%RH | ±2%RH |
| 典型售价(模块) | 5元左右 | 13元左右 |
| 刷新周期 | 1Hz | 2Hz |
DHT11误差是±2℃,而我在前面假设里要观察的昼夜温差可能只有2-3℃,信号和误差混在一起,根本分不清哪个是真实变化、哪个是器件噪声。DHT22的±0.5℃精度虽然也不算绝对精准,但测量误差小于待测信号,结论才有说服力。多花8块钱把整个实验的可信度提上去,这笔账怎么算都划算。选传感器的第一原则不是越贵越好,而是误差必须明显小于你要测量的最小值。
2.2 硬件连接:一个面包板就能搞定
我用的是一块Arduino Nano加一个DHT22模块,接线极简。市面上大多数DHT22模块是三个引脚:VCC、DATA、GND,模块上已经带了上拉电阻,直接怼到开发板上就能用。
- VCC接Arduino的5V
- GND接GND
- DATA接D2
如果你买到的是裸传感器而不是模块,那DAT引脚需要接一个4.7kΩ上拉电阻到VCC。没有这颗电阻,数据脚在高阻状态下非常容易被干扰,表现出来就是读数疯狂跳变或者隔三差五报NaN。模块自带电阻的话就省了这一步,但买之前要看清商品页标注。
还有两个容易被忽略的物理细节。第一,传感器不要紧贴Arduino板子,USB口和稳压芯片发热能让局部温度比环境高好几度,我一开始把传感器用双面胶直接粘在板子旁边,读出来的温度稳定高出实际值1.5℃,后来用三根母对母杜邦线延长到离板子20厘米才修正。第二,传感器周围要保持空气流通,不要塞进柜子、抽屉,也别放在暖气片正上方。
2.3 固件代码:稳定输出两列数据
Arduino端程序很简单,核心逻辑就是定期读传感器,把温度和湿度通过串口打印出来。这里有个设计细节:Arduino不输出时间戳,只输出两个数值,因为Arduino本体没有可靠时钟,上电时间也不准,时间戳由电脑端写入CSV时统一加,这样数据在时间轴上是连续的。
#include "DHT.h" #define DHTPIN 2 #define DHTTYPE DHT22 DHT dht(DHTPIN, DHTTYPE); void setup() { Serial.begin(9600); dht.begin(); } void loop() { float h = dht.readHumidity(); float t = dht.readTemperature(); if (isnan(h) || isnan(t)) { Serial.println("failed"); delay(3000); return; } Serial.print(t); Serial.print(","); Serial.println(h); delay(60000); }很多教程会让人把数据格式写成带逗号的纯文本再解析,我保留了字符输出而不是二进制传输,就是为了方便任何语言的脚本直接解析。isnan(h) || isnan(t)这个检查不能删,DHT22刚上电前几秒经常读不到有效值,如果不做判断,程序会打印一堆垃圾行污染数据文件。
读取频率上我用的是60秒一次。DHT22本身的刷新周期是2秒,意味着你每隔2秒才能读到一个新值。1秒读一次会经常读到同一个数值,造成假性的“平台期”。60秒间隔足够捕捉室内环境的长期趋势,一天1440条记录,跑7天也就是一万条左右,Excel和pandas都能轻松处理。
2.4 自动落盘:Python脚本把串口数据转成CSV
Arduino上电之后,串口会不停地输出数据。问题是谁来把数据保存下来?Windows上虽然可以用串口监视器的“保存时间戳”功能直接存文件,但那个格式后期处理起来非常别扭。我更推荐写一个Python脚本,把串口内容追加写入CSV,每行附带当前系统时间。
import serial import csv from datetime import datetime port = 'COM3' # Windows示例;Linux/macOS通常为/dev/ttyUSB0 ser = serial.Serial(port, 9600, timeout=10) with open('home_env.csv', 'a', newline='', encoding='utf-8') as f: writer = csv.writer(f) writer.writerow(['timestamp', 'temperature_c', 'humidity_rh']) while True: line = ser.readline().decode('utf-8').strip() if line == 'failed': continue try: t, h = line.split(',') now = datetime.now().strftime('%Y-%m-%d %H:%M:%S') writer.writerow([now, float(t), float(h)]) print(now, t, h) except ValueError: continue脚本只管追加行,不加去重逻辑,不修改历史数据,这样即使中断重跑也不会破坏之前的记录。唯一的问题是这台电脑得连续开机跑几天,为了实验让笔记本电源策略调成“从不休眠”,屏幕关掉就行。如果手头有树莓派或者旧安卓板,替代电脑会更省心,后面我会专门说这个。
数据记录环节,我还给自己加了一个必须同步完成的工作:纸笔记录每天的关键事件。几点开窗、几点做饭、几点洗澡、暖气大约几点开始有噪声,这些环境事件就是解开数据形态的钥匙,电脑只负责记下“是什么”,纸笔才能记下“为什么”。
3. 七天连续记录,数据告诉我的三件事
实验从假期第二周正式开始,头一天晚上接线,跑了个通宵确认一切正常,然后连续记录了7天。期间出现过一次断档,第三天下午Python脚本因为串口被另一个程序占用直接退出,等我发现已经丢了3个小时,这个坑后面细说。最终拿到了大约9500条有效记录,温度范围18.3-24.6℃,平均20.8℃;湿度范围42%-78%,平均58%。整体感觉是室内的湿度和温度变化远比体感能察觉到的剧烈,这里挑三个最有说服力的发现讲。
3.1 昼夜温差比想象中大,而且最低点不在半夜
我以前以为室温晚上最多降1℃,数据打脸。记录期内温度最低点几乎都出现在早上6点到7点之间,而不是凌晨两三点。比如某天凌晨2点室内20.5℃,到早晨6点40分降到18.3℃,下降了2.2℃。为什么最低点出现在清晨而不是半夜?因为外墙白天吸收了太阳辐射热量,夜间慢慢往外释放,前半夜墙体还在回补室内热量,到后半夜墙体也凉透了,室内温度才跌到谷底。这个现象只有拿连续曲线才能看出来,单看某一时刻的数值完全发现不了。
同时白天的温度曲线也不是一条平线。有人活动的时候,厨房和客厅连通的区域温度会缓慢上升,最高点通常在晚饭后的19点半左右,因为烹饪散发的热量加人体活动让房间整体升温。
3.2 湿度峰值几乎贴着饭点,做饭是室内湿度的最大贡献源
这是我最开始没预料到的规律。看7天数据,湿度超过70%的时刻,绝大多数出现在11:30-12:30和18:00-19:00这两个时间段。有一次晚饭时间煮了一大锅汤面,湿度在半小时内从54%飙升到76%,然后花了一个多小时慢慢回落。
之前我总觉得冬天屋里干燥是因为外界空气干燥,理论上没错,但一旦人在室内做饭、烧水,水蒸气短时间大量释放,局部湿度完全可以冲到人体不适感偏高的区间。湿度不是一个恒定值,它一天里像过山车一样在40%到75%之间来回折腾。时刻保持同样干燥程度的直觉判断,本身就是错的。
3.3 一次开窗通风,数据上留下明显的锯齿痕迹
第三天上午我开窗户通风20分钟,数据曲线立刻出现了一个典型的漩涡形态。开窗前温度20.1℃、湿度58%,开窗8分钟时温度降到17.9℃、湿度跌到45%,关窗之后温度和湿度慢慢回升,大约40分钟后湿度回到54%,温度则花了一个小时才回到19.5℃以上。
这段数据的价值在于把“通风降湿”从一句常识变成了可量化的关系:20分钟的通风让温度下降约2.2℃,湿度下降约13个百分点。代价是屋里能耗掉了不少热量,而且关窗后回温非常慢。在供暖季,如果只是单纯想降湿度,开窗的代价必须提前想清楚。这一发现直接让我妈改变了每天早上开窗半小时的习惯——她说原来降温比降湿明显得多。
下面截取开窗前后那段时间的真实数据片段,你能很直观感受到变化形状:
| 时间 | 温度 | 湿度 |
|---|---|---|
| 08:40 | 20.5 | 59 |
| 08:50 | 20.2 | 57 |
| 09:00 | 18.7 | 49 |
| 09:10 | 17.9 | 45 |
| 09:20 | 18.2 | 47 |
| 09:30 | 18.6 | 50 |
| 09:40 | 19.1 | 53 |
| 10:00 | 19.6 | 55 |
4. 差点毁掉实验的四个细节:传感器放置、校准、采样与断档处理
七天记录过程并非一帆风顺。如果不是中途调整,这份实验数据的可信度可能连及格线都到不了。下面这四件事,是我最想让复刻这个实验的人提前避开的坑。
4.1 传感器放在窗台上,测出的湿度长期偏高
实验第一天我把传感器放在书桌靠窗的位置,紧挨着窗玻璃。数据出来非常奇怪:温度比房间别处明显低1℃左右,湿度却高出10个百分点以上,早晨尤为明显。原因是窗玻璃是室内最冷的表面,冷空气下沉、水汽在附近凝结,传感器测到的是“窗边微气候”,而不是整个房间代表点的环境。后来我把传感器移到屋子中间的开放式书架上,离地约1.3米,避开暖气片、门窗边框和家电出风口。这个位置才是站在房间里的人体最关心的呼吸高度。条件允许的话,可以在房间对角各放一个传感器,取平均值会更有代表性。
4.2 DHT22也会有偏差,最好和家用温湿度计做交叉校准
模块出厂时虽然标定了参数,但个体之间的差异依然存在。我的方法很土但有效:把家用温湿度计和DHT22放在同一位置,等20分钟让两者读数稳定下来,同时记录3次数值取平均。结果发现我的DHT22温度比参考计低0.4℃,湿度高出2%RH。
校准方法是在固件里加一个修正量:Serial.print(t + 0.4);相对湿度同理。更讲究的做法是把修正系数单独存起来,保留原始数据和修正后数据两列。我做的时候偷了个懒,直接在输出里加了修正值,原始数据没留,后来想复盘只能靠回忆。建议严谨一点的复刻方案,原始读数一行都不动,修正值单独成列,这样报告里写“数据处理”部分才有内容可以展示,结论也更有说服力。
4.3 采样太快反而会造成假读数:间隔60秒是平衡点
我一开始图方便,把间隔设成2秒,觉得数据密度越大越好。结果发现DHT22的刷新周期是2秒,2秒一次读取刚好卡在传感器数据刷新临界点上,每隔一段时间就会连续两次输出同一个数值,曲线变成一个接一个的台阶,特别难看。改用60秒间隔之后,数据点之间几乎每次都会有微小变化,真实性和自然度都更好了。更重要的是每分钟一条的曲线已经足够识别出做饭、通风带来的分钟级波动,没必要用更短间隔去为难传感器和数据文件。
4.4 断档事故:串口被抢占,3小时数据不翼而飞
第三天下午的断档原因,是我同时用Arduino IDE打开了串口监视器,把Python脚本原本占用的COM3抢走了。Python脚本直接抛异常退出,等我看的时候已经补不回来。这不是硬件故障,纯粹是自己操作分心造成的。解决办法很简单:跑数据期间不要开任何第二个占用串口的程序,并且把Python脚本里的异常处理补上,串口断开之后自动重连:
while True: try: ser = serial.Serial(port, 9600, timeout=10) while True: # 读写逻辑 pass except serial.SerialException: print('串口断开,5秒后重连...') time.sleep(5)还有一个小技巧:把脚本放到计划任务里开机自启,电脑断电重启后自动重新开始记录,这样断档窗口可以缩到最小。
5. 从数据到结论:一份实验报告该怎么组织
实验做了,数据拿到了,接下来就是怎么把它变成一份能给人看的寒假实验报告。我不建议直接打开Word从“实验目的”开始写模板式作文,而应该先整理数据、再搭报告骨架、最后补上下文说明。这样整份报告的逻辑是自下而上长出来的,而不是套子填出来的。
我的报告最终分成了六个部分:
- 一页摘要:用100字说清楚“我做了什么、发现了什么”,让人扫一眼就知道报告核心。
- 背景与问题:直接列出开头那三个假设,说明为什么关心这些问题。
- 设备与方法:写明传感器型号、连接方式、采样间隔、数据量。这段要像菜谱一样细致,让别人能复现。
- 数据总览:用一张汇总表加两条曲线把7天数据拿出来,不做解读,只呈现。
- 分析与讨论:针对三个假设逐一分析,结合事件日志解释数据形态。
- 结论与局限:明确回答每个假设“成立/不成立/部分成立”,并承认这次实验样本量小、单测点、仪器精度有限。
5.1 图表怎么配,才能不误导人
Excel里做曲线图就行,但有个细节值得注意:温度和湿度不是同一个量纲,数值范围差距很大。如果画在一张图里,湿度60和温度20会挤在同一高度附近,两条曲线高度重叠,根本看不清细节。解决办法是把湿度放到次坐标轴,温度用主坐标轴,让两条曲线在各自的范围里舒展。
我在Excel里的具体操作是:选中时间、温度两列插入折线图,然后把湿度那一条曲线的“系列格式”设成“次坐标轴”。这样温度曲线在主坐标轴的18-25℃区间内扇动,湿度曲线在次坐标轴的40-80%区间内扇动,两条曲线互不压制,变化关系一眼能看出来。
还推荐加一条“全天平均湿度”参考线,能直观看到哪些时段的湿度显著偏离均值。Excel里用“图表-添加趋势线-平均值”就能加,几秒钟的事,但报告的专业感会明显提升。
5.2 结论只回答假设,不要无限外推
实验报告的结论部分是翻车重灾区。很多人写结论喜欢说“通过这次实验,我明白了生活处处有科学”这类话,正确但无用。好的结论是精确的,只回答开头提出的问题,并且明确区分“数据支持的”和“数据不支持的”。
比如我写的这两条结论:
- 假设一“昼夜温差明显”:成立。7天数据最低点集中在清晨6-7点,与体感预期的“半夜最冷”不同,夜间温度降幅可达2.2℃。
- 假设二“湿度高峰跟随做饭时间”:成立。湿度峰值时段与厨房活动时间段高度重合,单次做饭最大湿度抬升约22个百分点。
- 假设三“开窗通风能明显改变室内湿度”:成立。20分钟开窗湿度下降13个百分点,但温度同步下降约2.2℃,恢复时间超过40分钟。
同时我也写了这份报告的局限:只测了一个房间的一个点位,周期只有7天,没有包含整个供暖季的长周期变化;所用DHT22传感器经校准后仍有±0.5℃以内的残余误差。主动承认局限,不是为了显得谦虚,而是说明你真的理解实验结论的适用范围。
6. 如果重新来一次,我会调整什么——给复刻者的几条实在建议
实验收尾之后我又多留了几天,想了想如果把这个项目再往深做一步,应该优化哪里。下面这几条是我真实做完之后产生的体会,不是套话。
第一,先试跑24小时再决定正式采集。我第一次直接开跑,结果第二天看数据发现传感器位置有问题,整个前两天的数据基本不能用,等于白记了48小时。正确做法是至少花一天时间把传感器放到几个候选位置各跑几小时,对比曲线稳定性之后,再定一个最能代表空间的位置启动正式记录。
第二,手动事件日志的价值不亚于传感器数据。我的记录内容是“几点开窗、几点做饭、几点电视待机、几点家里人出门”。没有这些日志,那条湿度曲线就只是一根会动的线;结合日志,它就能变成“做饭时段湿度升高22个百分点”这样有解释力的结论。记录不用很正式,手机备忘录随手写,事后整理成表就行。
第三,硬件不复杂,但供电和物理位置是最大的隐性变量。如果用电脑USB供电,要确保电脑不锁屏休眠;如果用手机充电头供电,充电头本身的发热会抬升环境温度,充电头不能和传感器放太近。我后来换了一个旧的5V 1A充电头给Nano单独供电,传感器放书房中央,充电头放桌角,再把电脑只做数据接收端,干扰因素就分开了。
第四,如果条件允许,把Arduino换成ESP32,可以直接连家里网络把数据发到本地,手机随时查看实时曲线,体验完全是另一个层次。这个扩展对电路能力要求不高,但能把单机版实验升级成“物联网小项目”。寒假预算宽裕的话,值得用几天尝试。
最后说一句我自己的感受。做完这次实验,我看家里环境的眼光完全变了:开窗不再只是“换气”,而是会在心里默算降温两度和降湿十个百分点值不值;暖气开一晚上也不再是无感的背景音,而是能看到温度曲线上那一段缓慢的爬升。一次实验带来的不只是一份报告,更是一种“拿数据替感觉做决定”的习惯,这个习惯对做任何方向的学习都通用。如果你也打算在寒假试一次家庭小实验,别犹豫,挑一个自己能真正好奇的问题,几十块钱的传感器和数据记录板就能开始,剩下的交给时间和耐心。数据会比直觉诚实。