在上一个教程中,介绍了TCP/IP协议虽然TCP/IP并不最适合物联网应用,因为数据包开销仍然是互联网上最常见的协议栈,但它提供了无处不在的连接。物联网设备可以使用TCP/IP协议与云或服务器进行通信,而无需任何网络编程和网络管理的麻烦。在本文中该项目将设计一种物联网设备,使用TCP/IP协议将传感器数据传输到ThingSpeak平台。
本项目设计的物联网设备使用Arduino UNO搭建。Arduino只是一个微控制器板,不能自己连接到互联网网络。为了连接互联网,Arduino UNO与ESP8266模块接口。ESP8266 Wi-Fi模块是一个独立的SOC,集成了TCP/IP协议栈,可以访问Wi-Fi网络。ESP模块实现Arduino板与路由器连接,接入互联网。Arduino通过TCP/IP协议与云平台ThingSpeak进行通信。Arduino通过将AT命令串行传递给ESP8266模块来实现TCP/IP协议。
物联网设备设计为访客计数器以及温度和湿度监视器。作为访客计数器,红外传感器和光电二极管与Arduino板连接。作为温度和湿度监测器,DHT-11传感器与Arduino板连接。Arduino从传感器读取数据并将其发送到ThingSpeak平台。0.6英寸128 X 64 OLED还与Arduino接口,Arduino通过I2C协议从电路板接收串行数据,并显示当前温度和湿度读数。用户可以访问ThingSpeak平台,从任何地方监控房屋内的居住人数、温度和湿度值。
Arduino板控制物联网设备的所有功能,如访客计数、从DHT-11传感器读取温湿度值、在OLED上显示温湿度数据、实现TCP/IP协议、连接ThingSpeak平台并将数据发送到云服务器。为此,Arduino代码是使用Arduino IDE编写和编译的。
所需组件-
图1:与Thingspeak服务器进行基于TCP/IP的物联网通信所需的组件列表
所需软件-
•ThingSpeak服务器
•Arduino IDE
方框图-
图2:Arduino和Thingspeak服务器之间基于TCP/IP的物联网通信框图
电路连接-
与ThingSpeak云通信的物联网设备是建立在Arduino UNO上的。通过DHT-11 Sensor、IR Sensor、Photodiodes、ESP8266模块和OLED模块与Arduino板进行接口,实现物联网设备。
基于ESP8266的TCP-IP连接的ThingSpeak Arduino温度监控电路
物联网设备具有以下电路连接-
Arduino UNO–Arduino UNO是最流行的原型板之一。它是基于Atmega 328的控制器板,具有14个GPIO引脚、6个PWM引脚、6个模拟输入和板载UART、SPI和TWI接口。Atmega 328是Arduino板上的嵌入式MCU。控制器具有以下引脚配置-
图3:Arduino Uno引脚配置表
Arduino板有两个GPIO引脚(外部中断引脚INT0和INT1)用于连接光电二极管,TX和RX引脚(分别为引脚3和引脚2)用于连接ESP模块,SDA和SCL引脚(分别为引脚27和28)用于连接OLED模块。
OLED模块–OLED模块用于显示室内的温度和湿度信息以及访客(居住者)数量。该模块使用I2C协议与Arduino板通信。这是一个双线协议。该模块有四个引脚–SDA、SCL、VCC和GND。VCC和接地分别连接到5V DC和公共接地。5V DC可通过7805电压调节器IC通过蓄电池供电。OLED模块的SDA和SCL引脚连接到Arduino板的SDA和SCL引脚(分别为引脚27和28)。OLED由碳基有机材料制成。因此与LCD显示器不同,它们不需要背光和滤波器。
图4:显示OLED显示屏上闪烁的初始消息的图像
ESP8266 Module - ESP8266 Wi-Fi Module是一个独立的SOC,集成了TCP/IP协议栈,可以访问Wi-Fi网络。ESP8266既可以承载一个应用程序,也可以从另一个应用程序处理器卸载所有Wi-Fi网络功能。每个ESP8266模块都带有预编程的AT命令集固件。该模块有ESP-01和ESP-12两种型号。ESP-12接口有16个引脚,ESP-01接口只有8个引脚。ESP-12的引脚配置如下:-
图5 ESP8266 ESP-12模块引脚配置表
本项目采用ESP-01型。ESP-01型号具有以下引脚配置-
图6:ESP8266 ESP-01模块引脚配置列表
模块的芯片启用和VCC引脚连接至3.3 V DC,而接地引脚连接至公共接地。芯片启用引脚通过10K上拉电阻器连接到VCC。复位引脚未连接。模块的Tx和Rx引脚连接至Arduino UNO的Rx和Tx引脚。模块的GPIO-0引脚通过10K上拉电阻器连接至VCC。
ESP模块允许Arduino通过Wi-Fi连接到路由器访问互联网。
图7:ESP8266 ESP-01 Wi-Fi调制解调器的典型图像
红外传感器–电路中使用两个红外LED阵列来检测任何访客的进入。这些红外发光二极管安装在房子的入口处。红外LED是一种在红外频率范围内发光的LED。红外辐射是人眼看不见的,但可以通过照相机的镜头看到。在操作上,红外LED与普通LED差别不大。他们还需要一个3V直流偏压和消耗20毫安电流。它们还需要与电路中的上拉电阻器连接。在阵列中,IR LED与220欧姆上拉电阻器相连。
光电二极管–光电二极管用作电路中的红外接收器。光电二极管是一种二极管,当光入射到它上面时,它会受到正向偏置。当没有光线照射时,它的电阻很高。当入射到它上面的光的强度增加时,它开始向前偏置,电流开始流过它。所以,当光入射到它上面时,它的电阻减小,通过它的电压降也更小。当光没有入射到它上面时,它的电阻增加,并且在它上面有更高的电压降。光电二极管看起来完全像LED,外壳上可能有深蓝色或黑色薄膜。光电二极管用于电路中的反向偏置配置。电路中使用了两个光电二极管阵列,安装在红外发射器上。光电二极管与Arduino板的外部中断引脚INT0和INT1连接。
图8:用于计数访客的红外发射器和光电二极管阵列的图像
DHT-11 Sensor DHT-11是一款温湿度传感器。DHT11传感器由两个主要组件组成,一个是湿度传感器组件,另一个是NTC温度传感器(或热敏电阻)。热敏电阻实际上是一个可变电阻,它的电阻随着温度的变化而变化。它们都能感知该区域的温度和湿度,并将输出给IC(放置在传感器的背面)。该传感器有四个引脚- VCC,接地,数据输出和NC。VCC和Ground引脚分别连接到普通VCC和Ground上。传感器的Data Out引脚通过10K上拉电阻连接到Arduino板的PD7引脚。
图9:DHT-11温湿度传感器引脚图
ThingSpeak服务器–ThingSpeak服务器用于可视化从物联网设备接收的数据。数据以图形的形式显示在平台上。ThingSpeak生成读写API密钥。写入API密钥用于将数据写入通道,读取API通道用于允许其他人查看专用通道提要和图表。数据也可以保存在平台上以备将来参考。
为了配置ThingSpeak平台来访问上面的数据,首先需要一个账户必须在平台上创建。然后必须为该帐户上的数据创建一个通道。它可以通过导航来实现通道窗口以及创建一个新频道。必须在网站上的给定表单中填写所需信息,以便创建所需字段。对于此项目,必须创建三个字段–总人数、温度和湿度。然后可以在服务器上实时检查这些字段。保存频道设置后,将创建一个写入API密钥必须记下的额定值。此写入API密钥用于Arduino的固件代码中,以访问ThingSpeak帐户上创建的专用通道。
图10:基于ESP8266的TCP-IP连接Thingspeak Arduino访客计数器原型
电路如何工作——
电路通电后,Arduino板开始从红外接收器和DHT-11传感器读取数据。红外接收器以反向偏置配置在VCC和接地之间串联可变电阻器,形成分压器电路。红外接收器(光电二极管)的输出从红外接收器阴极端子的连接处引出。在正常条件下,红外发射器发射的光由光电二极管连续接收。这将使光电二极管的数字逻辑输出保持高。当有人进入房间时,红外发射器发出的光被阻挡,光电二极管的逻辑输出被切换到低电平。红外接收器连接在Arduino的外部中断引脚上,因此当人员进入或离开房间时,会在Arduino的INT0和INT1引脚上产生中断。使用两对或红外发射器和接收器。在INT0和INT1引脚上产生中断的顺序表示一个人是否已进入或离开房屋。相应地,房屋的当前居住者数量增加或减少。
DHT11温湿度传感器是一款内置电容式湿度传感器和热敏电阻的数字传感器。它每2秒继电器实时温度和湿度读数。传感器工作在3.5 ~ 5.5 V电源下,可以读取0°C ~ 50°C的温度和20% ~ 95%的相对湿度。DHT11通过测量两个电极之间的电阻来检测水蒸气。湿度传感组件是带有电极的持湿基板。当水蒸汽被衬底吸收时,离子被衬底释放,这增加了电极之间的电导率。两个电极之间电阻的变化与相对湿度成正比。较高的相对湿度会降低电极之间的电阻,而较低的相对湿度会增加电极之间的电阻。
DHT11通过内置在装置中的表面安装NTC温度传感器(热敏电阻)测量温度。DHT 11传感器通过单线协议以数字形式向Arduino板发送数据,该协议必须在固件端实现。首先,将数据引脚配置为输入,并向其发送启动信号。启动信号包括18毫秒的低电平,20至40微秒的高电平,80微秒的低电平和80微秒的高电平。发送启动信号后,引脚被配置为数字输出,包括温度和湿度读数的40位数据被锁存。在5字节数据中,前两个字节分别为相对湿度读数的整数和小数部分,第三和第四个字节为温度读数的整数和小数部分,最后一个字节为校验和字节。单线协议使用Arduino可用的开源库在固件上实现。Arduino还使用开源库与以太网连接。读取的温度和湿度值以及乘员编号显示在OLED模块上。
图11:Thingspeak服务器上访客数量的屏幕截图
通过写入API密钥访问ThingSpeak服务器,每三秒向ThingSpeak服务器传递一次相同的数据。通过串行通信向ESP模块发送AT命令,通过TCP/IP协议传递数据。每三秒更新一次所有三个字段传递的数据,并在serv上以图形的形式显示呃。访客数量显示如下-
图11:Thingspeak服务器上访客数量的屏幕截图
同样,服务器上显示的温度如下-
图12:Thingspeak服务器上显示温度的图形截图
服务器上的湿度也以图形方式显示,如下图所示
图13:Thingspeak服务器上湿度的屏幕截图
编程指南-
Arduino板加载了一个草图,用于计数访客、读取DHT-11传感器的温度和湿度值、在OLED上显示温度和湿度数据、实现TCP/IP协议、连接ThingSpeak平台并将数据发送到云服务器。Arduino代码加载用于连接OLED模块和DHT-11传感器的标准库。声明变量和对象以存储温度、湿度和访客计数信息。
定义timer1_init()函数来初始化计时器。调用OLED_欢迎_消息(void)来显示OLED上的初始消息。
Arduino使用ESP模块与本地网络以及ThingSpeak服务器连接。以下代码用于初始化与Wi-Fi接入点的连接,并定义用于访问ThingSpeak服务器的写入API密钥。
//ESP866-01无线网络连接
#定义SSID“编写您的SSID”/“SSID WiFiname”
#定义PASS“password/”password
#定义IP“184.106.153.149”//thingspeak.com IP
String msg=“获取/更新?密钥=写入API密钥”//我们频道的API密钥
调用connectWiFi()函数以连接Wi-Fi接入点。AT命令–AT+CWMODE=1被传递到ESP模块,以将Wi-Fi设置为电台模式。AT命令–AT+CWJAP被传递到ESP模块以连接到Wi-Fi接入点。
当与本地网络和ThingSpeak服务器建立连接后,Arduino读取传感器的数据。PERSONIN()和PERSONOUT()函数用于增加和减少访问者计数。函数的作用是:读取DHT-11传感器的温度和湿度值,格式化成字符串。函数的作用是:显示OLED模块上的数据。
调用update_Data_To_Server()函数将传感器数据更新到ThingSpeak服务器。在函数中,AT命令–AT+CIPSTART被传递到ESP模块以启动TCP连接,然后AT命令–AT+CIPSEND被传递到服务器以发送数据。通过向ESP模块传递AT命令–AT+CIPCLOSE关闭TCP连接。
查看代码部分完整的Arduino草图,以便更好地理解。
在下一个教程中UDP协议将进行讨论。
项目源代码
###//计划/**文件名-基于IR的访客计数器和DHT11测试。ino*创建日期:2017年2月14日11:02:11 AM*基于IR的Visior couter和DHT11测试的主要源代码*在基于ATmega328的Arduino板上测试,在Arduino Baord*A5的内部振荡器上以16MHz*/**输入/输出引脚运行。*OLED SCL引脚*A4-OLED SDA引脚*Tx-ESP8266-01 Rx*Rx-ESP8266-01 Tx*D2-IR1(PERSONIN)输出*D3-IR2(PERSONOUT)输出*D7-DHT11输出(pin2)*///Oled通用图形库(128x64)显示#包括“U8glib.h”//DHT11或DHT22温度传感器库#包括“DHT.h”//Setup u8g对象U8glib SSD1306(u128x64 u8g(u8g I2C-OPT-NONE | u8g I2C-DEV-0)//声明所有全局变量const int PersonIn=2//保存person const int PersonOut=3的传入条目的变量//用于保存person volatile unsigned int count=0的传出条目的变量//变量,用于保持温度内的计数值//保持温度和湿度的变量//变量以保持湿度字符串tempC//变量来保存字符值char str[10]//数组初始化以保存字符串//DHT11或DHT22引脚和类型声明#定义连接到数字引脚7的DHTPIN 7//DHT11输出#定义DHTTYPE DHT11//DHT Type-DHT 11或22 DHT DHT(DHTPIN,DHTTYPE)//DHTPIN和类型声明//ESP866-01 WIFI连接#定义SSID“非您的WIFI”/“SSID WiFiname”#定义PASS“营销”/“密码”#定义IP“184.106.153.149”//thingspeak.com IP字符串msg=“获取/更新?密钥=03JHV63FG27FYL3R”//通道的API键//初始化设置函数void setup()中的变量{Serial.begin(115200);//以115200 bps Serial.println(“at”);初始化串行通信//波特率匹配时,以串行监视器延迟(5000)打印;//检查串行是否从ESP8266找到Ok响应的条件//如果找到Ok响应,则调用connectWifi()函数If(Serial.find(“Ok”){connectWifi();}pinMode(PersonIn,INPUT);//将数字Pin-2初始化为输入Pin模式(PersonOut,INPUT);//将数字Pin-3初始化为输入附件中断(digitalPinToInterrupt(2),PERSONIN,FALLING);//附加D2附加中断处理程序(digitalPinToInterrupt(3),PERSONOUT,FALLING);//附加D3中断处理程序//初始化Timer1函数Timer1_init();//在OLED上显示欢迎消息()///循环函数void Loop(){//检查标志位是否已设置//如果已设置,则表示存在比较匹配//且计时器已清除//利用此机会更新OLED和Thingspeak上的数据(TIFR1&(1<" if(Serial.find(">")) { //Serial monitor prints the Get command with the API key and fields speacified Serial.print(cmd); } else { //close the TCP connection Serial.println("AT+CIPCLOSE"); Temperature_and_Humidity_Test(); count; } } /* *Function Name- connectWifi() *It establishes the connection between the ESP8266 and Wifi *Input paramerter-void *Return type- boolean */ boolean connectWiFi() { //Enable the module to act as both Station and an access point Serial.println("AT+CWMODE=1"); delay(2000); //Join the WIFI access point String cmd="AT+CWJAP=""; cmd+=SSID; cmd+="",""; cmd+=PASS; cmd+="""; //Print the Wifi SSID and Password on Serial monitor Serial.println(cmd); delay(5000); if(Serial.find("OK")) { return true; } else { return false; } } /* *Function Name- timer1_init() Timer1(16bit) creates the delay time period in order to display the data on OLED and Server(Thingpeak) */ void timer1_init() { //Initialize registers TCCR1A = 0; //set entire TCCR1A register to 0 TCCR1B = 0; //set entire TCCR1B register to 0 //Initialize counter TCNT1 = 0; // Set the Compare value equal to count_value_for_Delay_time that // was calculated for generating a Delay Time period // This updates the temperature, Humidity and Total person after every Delay Time Period OCR1A = 46874; //Start timer1 //Set up timer with prescaler = 1024 and CTC mode TCCR1B |= (1 << WGM12)|(1 << CS12)|(1 << CS10); } ###