大狗爱科学:Arduino温度监测

夏天到了,每天在办公室上班的时候尽管开着中央空调,吹着电扇,仍然感到热气袭人。但是这究竟因为办公区人多造成的心理作用,还是确实温度居高不下呢?大狗决定为大家找出答案。

具体来说,我们需要就以下几个问题进行分析:

  1. 如果办公室很热,那么,究竟有多热?
  2. 办公室全天温度都很高,还是只是一段时间很热?
  3. 办公室温度高的原因是什么?

三个问题,简单而直接。但是我们要如何找出答案呢?大狗觉得理想的解决方案应该符合如下几条:

  1. 硬件成本低廉(因为我穷啊[哭])
  2. 运行可靠,无需人工参与(好的解决方案应该是插上电源,就可以运行到天荒地老,每天都要重启的系统简直弱爆了好不)
  3. 体积小巧(在办公区使用,低调一点比较稳妥,no zuo no die)
  4. 独立运行,无需网络支持(因为不想被QS组请喝咖啡)

比较了几种解决方案后,大狗决定使用Arduino单片机实现一个简单的温度监测节点,每隔十秒钟记录一次温度,然后在此基础上进行数据分析。我们需要以下几种硬件:

  1. Arduino单片机(出于性价比考虑,选用Arduino UNO)
  2. SD卡存储模块
  3. DS18B20温度传感器(可以精确到0.5℃,对于办公区温度监测,已经足够了)
  4. DS1307时钟模块(因为Arduino没有内置时钟,而我们需要记录温度对应的时间)
  5. 面包板一块(否则就得鼓捣电烙铁)
  6. 4.7K欧姆电阻器一只
  7. 杜邦线若干
  8. SD卡一张

首先,我们需要设计电路,这个比较简单,在设计软件里随手画画,接线的时候心里有有谱啦。
另外,就是需要编写Arduino的控制程序,使用的是C语言,但是Arduino已经封装了很多的功能,而且可以从GitHub上找到很多开源的类库,就不用重新发明轮子啦。

大概是,这个样子的:


大狗爱科学:Arduino温度监测_第1张图片
电路图

如果程序可以编译成功,就可以用USB线缆连接电脑和Arduino,把控制程序“烧”进去。

//Libraries for clock chip
#include 
#include "DS1307.h"
DS1307 clock;//define a object of DS1307 class

//Libraries for SD writing
#include 
const int cs=4;
File file;
char fileName[]="log.csv";

//Libraries for temperature reading
#include 
#include 

//Initialize temperature sensor
#define ONE_WIRE_BUS 8
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

void setup() {
  Serial.begin(9600);

  //Initialize SD Card
  Serial.println("Initializing SD card...");
  if (!SD.begin(cs)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  file=SD.open(fileName, FILE_WRITE);
  
  //Start Clock
  clock.begin();
  
  //Turn on the temperature sensor
  sensors.begin();
}

void loop() {
  String currentTime = getTime();
  Serial.println(currentTime);

  //Get temperature from sensor
  sensors.requestTemperatures(); // 发送命令获取温度
  float temperature = sensors.getTempCByIndex(0);
  Serial.println("Temperature: " + String(temperature));

  //Write data to SD card
  if (file) {
    file.println(currentTime + "," + String(temperature));
  } 
  else {
    // if the file didn't open, print an error:
    Serial.println("Error when open file");
  }

  file.flush();

  delay(10000);
}

String getTime()
{
  String result = "";
  clock.getTime();
  if(clock.hour > 9){
    result += String(clock.hour);
  }
  else{
    result += ("0" + String(clock.hour));
  }
  result += ":";
  if(clock.minute > 9){
    result += String(clock.minute);
  }
  else{
    result += ("0" + String(clock.minute));
  }
  result += ":";
  if(clock.second > 9){
    result += String(clock.second);
  }
  else{
    result += ("0" + String(clock.second));
  }
  result += " ";
  result += String(clock.year+2000);
  result += "-";
  if(clock.month > 9){
    result += String(clock.month);
  }
  else{
    result += ("0" + String(clock.month));
  }
  result += "-";
  if(clock.dayOfMonth > 9){
    result += String(clock.dayOfMonth);
  }
  else{
    result += ("0" + String(clock.dayOfMonth));
  }
  return result;
}

接下来,就可以接线啦,接好后,是这个样子的:

大狗爱科学:Arduino温度监测_第2张图片
接好的效果图

这里,大狗偷了个懒,在Arduino上加了一块传感器扩展板。左侧是DS1307,下面是面包板,面包板上最左侧就是DS18B20温度传感器(比黄豆粒还小),中间是Arduino本体和传感器扩展板,右侧是SD卡存储模块。

把电路接好后,就可以放在一个测试点上,接上电源(其实也可以用9V的叠层电池,但是不确定可以支撑多久,所有还是用的USB线缆,从手机充电器取电,5V妥妥的),让Arduino自己忙活去。大狗该喝咖啡喝咖啡,该刷case刷case。

让Arduino哼哧哼哧忙活了几天后,大狗断开了Arduino的电源,拔下SD卡,把数据文件复制到电脑上,喏,就像这个样子(逗号前面是记录的时间,逗号后面是温度数值):

08:08:592016-05-11,27.69
08:09:102016-05-11,27.63
08:09:212016-05-11,27.56
08:09:312016-05-11,27.50
08:09:422016-05-11,27.50
08:09:532016-05-11,27.44

但是有几万条数据,一条条看下来会累死狗,于是,大狗又用python写了一个数据解析程序,把温度数值用图表呈现出来(python下有一个叫做matplotlib的类库做工精良还免费我会乱说么~),就像,这样子:

import datetime, csv, os, sys, re
import matplotlib.pyplot as mp
import matplotlib.dates as md
import numpy as np

currentPath = ''
sysPath = sys.path[0]
if os.path.isdir(sysPath):
    currentPath = sysPath
elif os.path.isfile(sysPath):
    currentPath = os.path.dirname(sysPath)
csvFilePath = '%s%s%s' % (currentPath, os.sep, 'log.csv')
reader = csv.reader(file(csvFilePath,'r'))

currentDate = ''
timeList = []
temperatureList = []
colors = ['Aquamarine', 'green', 'red', 'Cyan','Chartreuse', 'Orange', 'Maroon', 'Orchid', 'Salmon', 'Chartreuse']

def addCurve(colorIndex):
    print '%s has %s data items.\n' % (currentDate, len(temperatureList))
    datenums = md.date2num(timeList)
    mp.plot_date(x=datenums, y=temperatureList, xdate=True, ydate=False, color=colors[colorIndex], alpha=0.2, label=currentDate,  linewidth=0.2)

r = re.compile(r'^(?P\d+):(?P\d+):(?P\d+)\s(?P.+)$')

i = 0
for line in reader: # 08:08:59 2016-05-11,27.69
    matchObject = r.match(line[0])
    hour = int(matchObject.group('hour'))
    minute = int(matchObject.group('minute'))
    second = int(matchObject.group('second'))
    date = matchObject.group('date')

    if date != currentDate:
        if currentDate in ('2016-05-17', '2016-05-16', '2016-05-13', '2016-05-12', '2016-05-14'):
            addCurve(i)
            i += 1
        currentDate = date
        timeList = []
        temperatureList = []

    dotTime = datetime.datetime(year=2000, month=1, day = 1, hour = hour, minute = minute, second = second)
    timeList.append(dotTime)
    temperatureList.append(float(line[1]))

#addCurve(i)

mp.xlabel('Time')
mp.ylabel('Temperature')
mp.legend(loc = 'upper left', ncol = 1, borderaxespad = 0, fontsize = 12)
mp.title('Temperature in Office')
mp.show()

在这里,大狗取了2016年5月12,13,16和17四个工作日,以及5月14日这个周末进行对比,运行的结果,是这样的:

大狗爱科学:Arduino温度监测_第3张图片
温度图线

从图表中可以得到如下结论:

  1. 在工作日,办公区的温度确实很高,根据国内外的实验,夏季,人们感到最舒适的气温是19—24℃,从图表中可以看出,即使是相对凉爽的5月16日,办公区测试点的全天温度仍然高于24℃,而在5月17日,最高温度甚至逼近30℃。
  2. 在工作日中,温度最高的时间是下午两点至六点之间,上午则相对温度减低。除去气温因素外,由于我选取的温度测试点位于28层,有部分同事上中国时间,部分同事上欧洲时间,而下午两点至六点之间是办公室人最多的时间段,开启的电脑设备也最多,从而直接拉高了办公区的温度。请大家对比一下图表中红色图线,这是5月14日(周六)的温度曲线,大家可以明显看出,周末的温度变化明显区别于工作日,所以人员和电脑设备是导致办公区温度上升的主要因素之一。
  3. 还有一个有趣的现象,大家可以从图表中看出,在上午九点前后,在温度曲线上会出现一个小的波峰(在5月13日和16日的图线上尤为明显)。这是由于早晨伴随阳光的射入,办公室温度逐渐上升,九点之后,陆续有同事到办公室并开启中央空调,由于空调吹入的冷空气,测试点温度随后降低。但遗憾的是,给力的中央空调也无法与一百台电脑设备和一百多个热(ku)情(bi)的同事相匹敌[坏笑]
    实际上,我们还可以进一步找出其他结论,例如可以在28层部署多个温度测试点,找到28层最热的地方和最凉快的地方,或者增加一个树莓派,利用ZigBee链接多个Arduino节点,实现温度实时监测等,再或者利用Web Service获取外部实时温度,找出办公室的温度变化和外部温度的关系等等。
    只有我们有好的创意,心有多大,舞台就有多大。

除了鼓捣Arduino,大狗还在运营一个专注于天津人故事的有内涵无节操的网络播客,欢迎大家通过荔枝FM,网易云音乐,喜马拉雅或苹果Podcast搜索“** 大狗汪叨叨 ”订阅收听,
欢迎大家关注我们的微信公众号“
大狗汪叨叨 **”,我们将不定期推送节目相关内容。

你可能感兴趣的:(大狗爱科学:Arduino温度监测)