在一个智能家居系统中,除了各种设备的自动化之外,远程管理和控制也是非常重要的一个功能。想象一下,你在外出的时候可以随时拿出手机检测房间信息。比如有没有煤气泄漏,有没有陌生人闯入等等,是不是很酷!所以在本节课中我们来学习如何做到及时通信与及时报警功能。

知识锦囊

想要实现远程通信功能最方便的方式就是通过电话,短信和移动网络功能了。在Wio LTE主控板背面集成了一块由中移物联网开发的LTE模组,就像我们的手机一样,我们只需要把SIM卡正确插入主控板,然后我们就可以通过程序控制来调用这些功能了。

将SIM卡以图示(下图一)方向插入模组的卡槽中,当SIM卡完全插入卡槽中(如下图二)我们才可以正常使用模组的功能。
image.png
image.png

实践操作

任务一:远程获取房间温湿度数据

在本任务中,我们将通过移动网络来获取安装在房间的温湿度传感器的数据。

它的原理是:将开发板连接到中国移动OneNET平台,然后开发板通过MQTT通信的方式将传感器获取的值远程发送到OneNET网站显示,然后我们就可以在OneNET上远程看到我们开发板传出的数据了。

我们一共将步骤分为3步,首先我们在OneNET注册并创建一个设备,然后将我们的开发板连接到设备,最后我们将数据发送到服务器并在页面上查看结果。

先正确插入SIM卡,连接温湿度传感器,完成硬件的准备工作:
image.png

打开OneNET的网站:https://open.iot.10086.cn/ 在右上角注册并登陆你的账号。
image.png
点击首页的“控制台”进入后台控制页面。
image.png
在控制台点击“全部产品服务”找到“多协议接入”并点击。
image.png
在多协议接入界面点击“添加产品”
image.png
在右侧弹出的界面中填写相关信息。注意红框选择需要和图片中一致,网络运营商需要选择插入Wio LTE开发板的SIM的运营商。
image.png
成功创建产品之后,在网站左侧找到“设备列表”点击右上角的“添加设备”按钮进行添加设备的操作。
image.png
在添加设备的界面正确填写信息并选择当前位置之后点击“添加”按钮,完成设备的添加。
image.png
添加完成设备后进入设备详情页。
image.png
点击“添加APIkey”然后系统会生成一个新的APIkey。此时请记住设备ID和APIkey的值,一会在后面连接设备时会用到。
image.png
然后回到主界面点击“产品概况”同样的查看并记录产品ID,一会会用到。
image.png
在界面左侧找到“数据流模板”然后添加数据流模板。
image.png
添加一个名为“TEST”的数据流名称,然后点击“添加”按钮。
image.png
之后这里会多出一个数据流模板,表示添加成功。
image.png
此时OneNET端的操作已经基本完成,接下来让我们转到代码。

首先下载安装ArduinoSerialCommand.zip库文件和DHT20温湿度传感器库文件(参考第5课),
然后打开Arduino IDE,新建一个程序文件,编写以下代码:

  1. #include <SerialCommand.h>
  2. #include <SoftwareSerial.h>
  3. #include "DHT.h"
  4. #define DHTTYPE DHT20
  5. DHT dht(DHTTYPE);
  6. #define BAT_ENABLE 19 //Grove端口使能引脚
  7. int newval = 32; //定义变量
  8. #if defined(ARDUINO_ARCH_AVR)
  9. #define debug Serial
  10. #elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM)
  11. #define debug SerialUSB
  12. #else
  13. #define debug Serial
  14. #endif
  15. void setup() {
  16. digitalWrite(BAT_ENABLE, HIGH);//启用Grove端口
  17. pinMode(GROVE_ENABLE,OUTPUT);
  18. digitalWrite(GROVE_ENABLE,HIGH);
  19. delay(100);
  20. SerialUSB.begin(115200);
  21. LTE.begin(115200); //Serial2
  22. Serial1.begin(115200); //Grove
  23. while (!Serial) {
  24. ;
  25. }
  26. Serial.println("SAMD MCU Ready");
  27. Wire.begin();
  28. dht.begin();
  29. pinMode(LTE_PWR,OUTPUT);
  30. pinMode(LTE_RESET,OUTPUT);
  31. pinMode(LTE_WAKEUP,OUTPUT);
  32. pinMode(LTE_ENABLE,OUTPUT);
  33. digitalWrite(LTE_PWR,HIGH);
  34. digitalWrite(LTE_RESET,LOW);
  35. digitalWrite(LTE_WAKEUP,LOW);
  36. digitalWrite(LTE_ENABLE,HIGH);
  37. Serial.println("SAMD21[1] Init OK");
  38. }
  39. void loop() {
  40. String ss = String(newval, DEC);
  41. char buf[9];//>>>>转字符串
  42. ss.toCharArray(buf, 9);
  43. float temp_hum_val[2] = {0}; //将温湿度定义为一个数组
  44. if(SerialUSB.available()){
  45. LTE.write(SerialUSB.read());
  46. }
  47. if(LTE.available()){
  48. SerialUSB.write(LTE.read());
  49. }
  50. if (!dht.readTempAndHumidity(temp_hum_val)) {
  51. SerialUSB.println(temp_hum_val[1]);
  52. }
  53. float temp_val = temp_hum_val[1];
  54. delay(2500);
  55. LTE.write("AT+CGACT=1,1\r\n");
  56. delay(2500);
  57. while(LTE.available()){
  58. SerialUSB.write(LTE.read());
  59. }
  60. LTE.write("AT+CGACT=1,1\r\n");
  61. delay(2000);
  62. while(LTE.available()){
  63. SerialUSB.write(LTE.read());
  64. }
  65. LTE.write("AT+MQTTCFG=\"183.230.40.39\",6002,\"728817855\",600,\"434575\",\"jQMUBpFbzSRe8dstkvMN87HXH70=\",0\r\n");
  66. delay(2500);
  67. while(LTE.available()){
  68. SerialUSB.write(LTE.read());
  69. }
  70. LTE.write("AT+MQTTOPEN=1,1,0,0,0,,\r\n");
  71. delay(2500);
  72. while(LTE.available()){
  73. SerialUSB.write(LTE.read());
  74. }
  75. LTE.write("AT+MQTTSUB=\"TEST\",1\r\n");
  76. delay(2500);
  77. while(LTE.available()){
  78. SerialUSB.write(LTE.read());
  79. }
  80. LTE.write("AT+MQTTPUB=\"$dp\",1,0,0,23\r\n");
  81. delay(2500);
  82. while(LTE.available()){
  83. SerialUSB.write(LTE.read());
  84. }
  85. int a[] = {0x03,0x00,0x14};
  86. for (int i = 0; i < 3; i++){
  87. LTE.write(a[i]);
  88. }
  89. delay(2500);
  90. while(LTE.available()){
  91. SerialUSB.write(LTE.read());
  92. }
  93. LTE.write("{\"TEMP\":\"");
  94. delay(2500);
  95. while(LTE.available()){
  96. SerialUSB.write(LTE.read());
  97. }
  98. LTE.println(temp_val);
  99. delay(2500);
  100. while(LTE.available()){
  101. SerialUSB.write(LTE.read());
  102. }
  103. LTE.write("\"}");
  104. delay(2500);
  105. while(LTE.available()){
  106. SerialUSB.write(LTE.read());
  107. }
  108. LTE.write("1");
  109. delay(1000);
  110. while(LTE.available()){
  111. SerialUSB.write(LTE.read());
  112. }
  113. LTE.write("2");
  114. delay(1000);
  115. while(LTE.available()){
  116. SerialUSB.write(LTE.read());
  117. }
  118. LTE.write("3");
  119. delay(1000);
  120. while(LTE.available()){
  121. SerialUSB.write(LTE.read());
  122. }
  123. LTE.write("4");
  124. delay(1000);
  125. while(LTE.available()){
  126. SerialUSB.write(LTE.read());
  127. }
  128. LTE.write("5");
  129. delay(1000);
  130. while(LTE.available()){
  131. SerialUSB.write(LTE.read());
  132. }
  133. LTE.write("6");
  134. delay(1000);
  135. while(LTE.available()){
  136. SerialUSB.write(LTE.read());
  137. }
  138. LTE.write("7");
  139. delay(1000);
  140. while(LTE.available()){
  141. SerialUSB.write(LTE.read());
  142. }
  143. LTE.write("8");
  144. delay(1000);
  145. while(LTE.available()){
  146. SerialUSB.write(LTE.read());
  147. }
  148. while(1);
  149. }

在代码的77行中,将728817855替换为你的设备ID;
将434575替换为你的产品ID;
将jQMUBpFbzSRe8dstkvMN87HXH70=\替换为你的APIkey。


然后上传代码,接下来打开串口监视器查看程序运行状态:


为了防止程序运行过快出错,所以程序中加了很多2.5秒的延时,所以打开串口监视器之后需要等待几秒才可以看到数据持续输出。


image.png
如果在串口监视器中发现下图的报错,那么代表网络初始化出错。
image.png
解决方法:保持串口监视器打开的情况下,断开Wio LTE开发板的数据线,然后再重新连接数据线;之后关闭串口监视器再重新打开串口监视器,等待串口监视器中返回ok。

程序运行成功之后打开OneNET网站,在设备列表中点击数据流,进入数据流展示界面。
image.png
如果发送成功的话,你会在这里看到来自传感器的数值。
image.png

如果你想要在OneNET平台上看到其他传感器的数值,你可以先在程序中加入获取传感器数值的代码,然后将示例代码的第109行中的“TEMP”改为你的传感器数值名称, 在第115行中把“LTE.println(temp_val)”的“temp_val”改为你的传感器数值。

任务二:向手机自动报警异常信息

除了像任务一一样主动获取数据的方式之外,我们还可以被动获取一些关键信息,比如有人闯入房间,煤气泄漏或者发生火灾。在本任务中,我们将制作一个自动报警装置,当检测到危险信息,则开发板自动发短信到指定手机号提醒我们。
首先是硬件部分,按照图示正确连接PIR人体红外传感器。
image.png
然后打开Arduino IDE,新建一个程序文件,编写以下代码:

#include <SerialCommand.h>
#include <SoftwareSerial.h> 
#define BAT_ENABLE 19 //Grove端口使能引脚
#define PIR_SENSOR 0 //PIR传感器连接到D0接口
 int newval = 32; //定义变量
void setup() {
    SerialUSB.begin(115200);
    LTE.begin(115200);      //Serial2
    Serial1.begin(115200);  //Grove
    SerialUSB.println("SAMD MCU Ready");

    digitalWrite(BAT_ENABLE, HIGH);//启用Grove端口
    pinMode(PIR_SENSOR, INPUT);//设置PIR传感器为输入模式
    pinMode(GROVE_ENABLE,OUTPUT);
    digitalWrite(GROVE_ENABLE,HIGH);
    pinMode(LTE_PWR,OUTPUT);
    pinMode(LTE_RESET,OUTPUT);
    pinMode(LTE_WAKEUP,OUTPUT);
    pinMode(LTE_ENABLE,OUTPUT);

    digitalWrite(LTE_PWR,HIGH);
    digitalWrite(LTE_RESET,LOW);
    digitalWrite(LTE_WAKEUP,LOW);
    digitalWrite(LTE_ENABLE,HIGH);
    SerialUSB.println("SAMD21[1] Init OK");
}

void loop() {
String ss = String(newval, DEC); 
char buf[9];//>>>>转字符串
ss.toCharArray(buf, 9);

if(SerialUSB.available()){
   LTE.write(SerialUSB.read());
}
if(LTE.available()){     
   SerialUSB.write(LTE.read());     
}

  delay(2500);
     if(digitalRead(PIR_SENSOR)){          //如果检测到有人靠近
      LTE.write("AT+CMGF=1\r\n");
        delay(2500);
        while(LTE.available()){
        SerialUSB.write(LTE.read());     
    } 

    LTE.write("AT+CMGS=\"10086\"\r\n");
    delay(2500);   
    while(LTE.available()){
        SerialUSB.write(LTE.read());     
    } 

 // LTE.write(buf);//发送变量
    LTE.write("Someone broke into the room!");//发送字符串
    LTE.write(0x1A);
    delay(2500);
    while(LTE.available()){
        SerialUSB.write(LTE.read());     
    } 
while(1);
   } 
}

注意需要将代码第48行中的“10086”改为接收信息的手机号。你也可以在第55行更改要发送的字符串,或者取消54行的注释来发送变量。


上传成功程序之后,你可以在串口监视器中看到信息发送状态。
image.png
指定手机号收到的信息:
image.png

思维拓展

Wio LTE除了短信与移动网络通信的功能之外,我们还可以利用该开发板来实现打电话的功能。让我们来看看怎么做吧!

首先将套件中的喇叭安装在开发板上,注意Wio LTE有2个JST接口,分别是Speaker和电池接口,仔细观察接口旁边的丝印,不要接错在电池接口。
image.png
然后编写以下程序:

#include <SerialCommand.h>
#include <SoftwareSerial.h> 
#define BAT_ENABLE 19 //Grove端口使能引脚
int a = 10;
void setup() {
    SerialUSB.begin(115200);
    LTE.begin(115200);      //Serial2
    Serial1.begin(115200);  //Grove
    SerialUSB.println("SAMD MCU Ready");

    digitalWrite(BAT_ENABLE, HIGH);//启用Grove端口
    pinMode(GROVE_ENABLE,OUTPUT);
    digitalWrite(GROVE_ENABLE,HIGH);
    pinMode(LTE_PWR,OUTPUT);
    pinMode(LTE_RESET,OUTPUT);
    pinMode(LTE_WAKEUP,OUTPUT);
    pinMode(LTE_ENABLE,OUTPUT);

    digitalWrite(LTE_PWR,HIGH);
    digitalWrite(LTE_RESET,LOW);
    digitalWrite(LTE_WAKEUP,LOW);
    digitalWrite(LTE_ENABLE,HIGH);
    SerialUSB.println("SAMD21[1] Init OK");
}

void loop() {
if(SerialUSB.available()){
   LTE.write(SerialUSB.read());
}
if(LTE.available()){     
   SerialUSB.write(LTE.read());     
}

  delay(2500);

    LTE.write("AT+CGACT=1,1\r\n");
    delay(2500);
    while(LTE.available()){
        SerialUSB.write(LTE.read());     
    } 

    LTE.write("AT+SETVOLTE=1\r\n");
    delay(2500);   
    while(LTE.available()){
        SerialUSB.write(LTE.read());     
    } 

     LTE.write("AT+CLIP=1\r\n");
    delay(2500);   
    while(LTE.available()){
        SerialUSB.write(LTE.read());     
    } 

    LTE.write("ATD 10086\r\n");
    delay(2500);   
    while(LTE.available()){
        SerialUSB.write(LTE.read());     
    } 

while(1);
}

注意将代码中第54行的“10086”改为接收的手机号码。上传成功之后打开串口监视器观察返回信息是否正常,如果返回ok则电话成功拨出,如果没有返回信息或者返回错误,那么在打开串口监视器的情况下断开数据线,然后重新连接数据线,再关闭串口监视器并重新打开串口监视器即可解决。


image.png