序言
各位小伙伴,不管是在办公室还是学校里,你们是不是有的时候总觉得头晕目眩,感觉非常的难受。
这种现象在人多的时候特别明显。
如果有这种问题的小朋友,可以在后面留言告诉我你的感受。
根据我的了解,我认为这种情况大部分的情况是缺氧造成的。
大家都知道在我们的大气中,有21%左右是氧气,一般来说这个数据是不会有大的变化的。
但是在密闭的环境中,特别是人多的情况,例如人多的会议室,在聚集的大礼堂中。由于大量的人群聚集,大气不流通,二氧化碳聚集,相对的来说含氧量就相对的降低了。
但是降到什么时候人会觉得难受呢?
我也不知道。但是有什么办法可以让我们来研究一下这个情况呢?
在之前我们是没有办法来验证的,因为我们没有一种传感器来帮助我们检查氧气的含量。
我在淘宝曾经搜索过,氧气传感器确实是有买的,但是大家都知道他们用在哪里吗?
答案让我非常的震惊,一般的氧气传感器竟然是给汽车用的。
传统的油车,通过吸入空气和燃料油混合后在气缸中爆燃,产生巨大的化学能并通过气缸的运动将化学能转换成动能,驱动汽车前进。
在化油器时代,汽车是不需要什么传感器的,直接通过油门来控制进气阀门来控制通入气缸的气量。
现在早已是电喷时代,出于对效率的追求和环保的要求,车厂利用强大的车载计算机和发达的传感器技术,精确的对进气进行控制。氧气传感器在这里主要是控制进气和出气的氧含量,通过氧气含量的变化来自动调节进气节流阀的开度,确保反应的完全、高效运转、排气最少。
因此在淘宝上,大家可以发现大量用于汽车的氧气传感器。这些传感器需要各种各样的条件,由于缺乏材料,一般人是没有办法用起来的。
好在我现在拿到了由DFRobot开发的氧气传感器。由于我拿到的这款传感器是还在开发的样板,因此还没有经典的DFRobot配色,但相信很快大家就能拿到这块有趣的氧气传感器了。
和传统的DFRobot Gravity™传感器一样,该传感器采用的是IIC的接口,因此通过提供的IIC传感器接线就可以直接接在支持IIC的主板上,通过提供的样例就可以直接读取相应数据。
回到一开始的问题,你会在办公室昏昏沉沉吗?当然会的,而且大概率我们是因为缺氧造成的。
所以我们需要一个传感器来进行了解,是不是有缺氧的情况。
但是这里有一个问题,如果在一个办公室里,你放一堆的主板和传感器会让整个环境变得异常的奇怪。
我们能让我们的氧气检测仪更无感的出现在我们的会议室、办公室、室内操场里吗?
我的回答是可以的。
我们可以给整个系统设计一个有趣的外壳。
在这里我给到的答案是一个感叹号。
氧气是生命的重要元素,感叹号要表达的就是对这种司空见惯事物的感叹!
让我们对那些我们必须但却被忽视的元素给与更多的关注。
我们不仅需要了解当前的氧气含量,我们更希望能通过连续的数据来找到相应的规律,通过这些数据来建立模型,并提出有效的建议和意见。
好了说了那么多,让我们开始项目的制作吧。
项目分析
项目需求
根据以上的分析,我将我们项目的一些需求整理了一下,可以发现大致,我们需要一个具有以下功能的设备。
监测实时的氧气含量
氧气含量通过物联网上传
低功耗
氧气含量低提醒
氧气含量现场读取
外观在办公室不突兀
可移动使用
根据功能的要求,我们需要在众多的物联网平台单片机中进行选择。
正好,最近在DFRobot的网站上一款tinkernode的物联网主控器正在推广。
我看了下,深得我心。
让我觉得非常满意的点如下。
有NB-IoT的模块,我可以直接联网。物联网功能完美符合要求。
有电源管理模块,我不需要考虑供电的选择,随便找各种电池。满足可移动使用。
低功耗集成,满足低功耗满足需求。
和阿里云高度结合,可以直接调用相应模型,省的自己写代码。氧气含量低报警的功能可以通过钉钉来实现,而钉钉是阿里旗下产品,可以很方便的打通。
I2C接口支持,直接就可以读取氧气传感器数据
电子部分的内容基本上都能直接满足。
就选tinkernode他了。
材料表
氧气传感器 1个
TinkerNode主板 1个
TinkerNode扩展板 1个(如果不想焊接,我还是强烈建议用扩展板)
12864LCD屏幕
锂电池
原本我认为不需要现场显示检测的数据,因为氧气的变化可能没有想象中的那么,可能引起人不适的含量会在小数点后一位二位而已,但考虑到一个检测设备如果不能在现场反应器数据,还是让人觉得有点不可思议。于是还是到处找了下显示的设备,正好手头有一个12864的小型的LCD屏幕,就这样使用吧。好在这块LCD屏也是I2C的,所以点亮他也不是很麻烦。
材料准备好了,就可以开干了,总体来说,通过Gravity™的接口,其实连接这些传感器和主板是非常简单的。特别是由于采用了扩展板,我只要将I2C的接口接在扩展板上对应的I2C接口上,连接就完成了。
由于采用了标准的电池接口,所以标准的电池也只要一插到主板上就好了。好像连接这个问题竟然根本不需要多考虑。
这对完成一个项目显得一点挑战都没有……
如果不用显示器,甚至我觉得我都可以不用扩展板……
好了,接下来就看看怎么设计外观了。
虽然我现在已经可以用了……
就是那么的简单……
但是好看的感叹号还等着我们去设计,不是吗?
外观设计
正如前面所叙述的,我希望这个装置能不那么突兀。所以需要对其进行下设计。
于是我画了一个草图:
问了下大部分人,还是喜欢大图中的感叹号,而不需要将O2也加上。
于是开干!
三维设计 一直以来我用的三维设计软件是sketchup,但随着sketchup被谷歌卖掉,后面的厂家对他的管理让我很难用到免费的版本,我不得不换软件。
众所众知,我是Autodesk的粉丝,所以我换用了TinkerCAD,不过后来发现Fusion360在功能上更强大,于是我换成了Fusion360。
我注册的是教育版,教育版本非常适合新人,免费使用。我估计今后到期后,我可能会付费使用。
那就看下怎么进行设计吧。
Fusion360的工作流程和sketchup很像,所以需要先画好平面图,然后在用拉伸的方法来建立实体。但如何画好一个模型呢?
我的工作流程是这样的。
首先把所有的元器件都画好,或者找到。注意在这里我们需要注意几个关键尺寸。在这个案例里,氧气传感器的直径,和屏幕的长宽都非常重要。
然后把这些元件摆好位置,在软件里摆好位置,当然我在画草图的时候,已经大致有了相关的位置,在软件里只是更仔细的确定他们的位置而已。
这个感叹号有上盖和下盖,需要分别处理。
先把代码放上来,大家先慢慢的看一下。
<font face="微软雅黑"><font face="微软雅黑">[mw_shl_code=cpp,false]
#include "DFRobot_Iot.h"
#include "DFRobot_BC20.h"
#include "DFRobot_GasSensor.h"
#include "DFRobot_OLED12864.h"
DFRobot_OLED12864 display(0x3c);
DFRobot_GasSensor Oxygen;
DFRobot_Iot myDevice;
DFRobot_BC20 myBC20;
/*Configure device certificate information*/
String ProductKey = "Your_Product_Key";
String ClientId = "12345";/*Custom id*/
String DeviceName = "Your_Device_Name";
String DeviceSecret = "Your_Device_Secret";
/*Configure the domain name and port number*/
String ALIYUN_SERVER = "iot-as-mqtt.cn-shanghai.aliyuncs.com";
uint16_t PORT = 1883;
/*Product identifier that needs to be operated*/
String Identifier = "Your_Identifier";
/*TOPIC that need to be published and subscribed*/
const char * subTopic = "Your_subTopic";//****set
const char * pubTopic = "Your_pubTopic";//******post
DFRobot_Iot myIot;
void ConnectCloud() {
while (!myBC20.connected()) {
Serial.print("Attempting MQTT connection...");
if (myBC20.connect(myDevice._clientId, myDevice._username, myDevice._password)) {
Serial.println("Connect Server OK");
}
else {
myBC20.getQMTCONN();
}
}
}
void setup(){
Serial.begin(115200);
display.init();
display.setContrast(255);
display.flipScreenVertically();
display.clear();
delay(1000);
display.drawString(16,24,"Oxygen:");
display.drawString(96,24,"%");
display.display();
while(!Oxygen.begin(ADDRESS_3)) {
Serial.println("I2c device number error !");
delay(1000);
}
Serial.println("I2c connect success !");
/* Pass in the key value marked on the oxygen sensor */
Oxygen.SetKeys(20.9 / 90);
Serial.print("Starting the BC20.Please wait. . . ");
while(!myBC20.powerOn()){
delay(1000);
Serial.print(".");
}
Serial.println("BC20 started successfully !");
Serial.println("check OK");
while (!myBC20.checkNBCard()) {
Serial.println("Please insert the NB card !");
delay(1000);
}
Serial.println("Waitting for access ...");
while (myBC20.getGATT() == 0) {
Serial.print(".");
delay(1000);
}
myDevice.init(ALIYUN_SERVER, ProductKey, ClientId, DeviceName, DeviceSecret);
myBC20.setServer(myDevice._mqttServer, PORT);
//myBC20.setCallback(callback);
ConnectCloud();
}
void loop(){
float oxygenData = Oxygen.ReadOxygenData();
display.clear();
delay(1000);
display.drawString(16,24,"Oxygen:");
display.drawString(96,24,"%");
display.drawString(64,24,String(oxygenData));
display.display();
Serial.print(" Oxygen concentration is ");
Serial.print(oxygenData);
Serial.println(" %vol(mv)");
myBC20.getCLK(); // Get CLK from BC20
myBC20.loop();
myBC20.publish(pubTopic, ("{"id":"+ClientId+","params":{""+Identifier+"":"+(String)oxygenData+"},"method":"thing.event.property.post"}"));
Serial.println("Data is published to cloud.");
delay(10000);
}[/mw_shl_code]
</font></font> 复制代码
代码框架
代码主要分为几个部分
<font face="微软雅黑"><font face="微软雅黑">[mw_shl_code=cpp,false]
while(!Oxygen.begin(ADDRESS_3)) {
Serial.println("I2c device number error !");
delay(1000);
}
Serial.println("I2c connect success !");
/* Pass in the key value marked on the oxygen sensor */
Oxygen.SetKeys(20.9 / 90);
[/mw_shl_code]</font></font> 复制代码
由于氧气传感器是I2C的,因此只需要在找到合适地址后就可以使用了。
注意,氧气传感器需要进行校准。因此在这里进行了手动的校准。
听产品经理@DFSH_Faith介绍,后续会通过一个按钮简化操作,因此大家也不用在代码中写Oxygen.SetKeys(20.9 / 90)这样的语句了。
然后接下来是屏幕,采用的12864的屏幕,因此直接加载#include "DFRobot_OLED12864.h" 这个库,如果找不到这个库的,可以到DFRobot的wiki里去找
<font face="微软雅黑">[mw_shl_code=cpp,false]
display.init();
display.setContrast(255);
display.flipScreenVertically();
display.clear();
delay(1000);
display.drawString(16,24,"Oxygen:");
display.drawString(96,24,"%");
display.display();
[/mw_shl_code]</font></font> 复制代码
通过这段代码就可以把想要显示的内容显示出来了。
这里需要注意的是,每次需要采用display.display();来显示上面的设置内容。否则可能会和你想象的不一样。
display.drawString(16,24,"Oxygen:");这里的16和24分别代表了行和列,可以根据实际需要进行调整。
display.setContrast(255);可以调整屏幕的对比度,使显示不那么亮或者刺眼。
display.flipScreenVertically();可以翻转屏幕,如果反过来了,那就用这行来翻转过来。
这两部分完成后,只需要把相关的信息给到NB-IoT部分即可,NB-IoT部分的代码也是现成的。
loop()函数中
[mw_shl_code=cpp,false]
float oxygenData = Oxygen.ReadOxygenData();
myBC20.getCLK(); // Get CLK from BC20
myBC20.loop();
myBC20.publish(pubTopic, ("{\"id\":"+ClientId+",\"params\":{\""+Identifier+"\":"+(String)oxygenData+"},\"method\":\"thing.event.property.post\"}"));
Serial.println("Data is published to cloud.");
delay(10000);[/mw_shl_code]
用Oxygen.ReadOxygenData()获取氧气的含量值。用oxygenData来存储。
用myBC20.publish(pubTopic, ("{\"id\":"+ClientId+",\"params\":{\""+Identifier+"\":"+(String)oxygenData+"},\"method\":\"thing.event.property.post\"}"));
将publish函数将相应的数据上传到阿里云。
在测试的时候,可以分别对这些代码进行处理。
然后分别看其效果,比如
myBC20.publish(pubTopic, ("{\"id\":"+ClientId+",\"params\":{\""+Identifier+"\":"+(String)oxygenData+"},\"method\":\"thing.event.property.post\"}"));
可以把其中oxygenData直接改为数字,来检查上传是否正常。
又比如
display.drawString(64,24,String(oxygenData));
可以将oxygenData改为数字来检查显示是否正常。
记得串口监视器是硬件调试的好帮手。
相关的串口打印数据是调试时的重要抓手。
有不确定的时候,放上几个串口打印命令一定会让你事半功倍。
好了,硬件上的这个代码就是非常的简单明了。
报警等功能可以在阿里云上进行设置。
致谢 @DFSH_Faith提供了巨大的支持。
感谢你提供的支持和帮助!