【PT+Arduino+OneNET基础教程9】Arduino上云OneNET(TCP透传)信息接收与发送教程ESP8266-01(s)
教程1.PacketTracer中MCU芯片编程入门教程 教程2.全部智能设备连接MCU使用方法 教程3.读卡器与红外探测器连接MCU使用方法 教程4.常用传感器使用方法 教程5.几种按钮与开关的使用方法 教程6.执行器使用方法 教程7.上云教程 教程8.多设备上云教程 教程9.Arduino+OneNET TCP透传上云教程(发+收)
关于拓扑连线大家可以参照这位博主的博客,【小白入门】超详细Arduino uno接入onenet云平台教程(TCP透传) 我也是通过这篇文章进行的入门学习,但是遇到了一些困难,无法正常使用上云部分的代码。所以我又进行了一些学习,掌握了一些串口与软串口通信的知识,与发送消息到onenet以及从onenet接收消息的方法(tcp透传)。
芯片:ArduinoMega2560 或 ArduinoUno
注:我的ESP8266 RX接了11 TX接了10 大家可以根据需要改变接口 EN引脚也要接5V或3.3V
那么我们连线完成后,从配网开始讲解
大家可以先打开手机热点,设置热点名称(手机名称)与热点密码(二者都不要含有中文,越简单越好)
烧录以下代码
SoftwareSerial mySerial(10,11);//如果无法正常使用大家可以把10和11换一下,可能大家把RX和TX接反了,是很常见也很好解决的错误
void setup()
{
Serial.begin(115200);//打开硬串口
while(!Serial){//有没有其实基本无所谓
;
}
Serial.println("hard");//硬串口输出hard表示硬串口打开成功了
mySerial.begin(115200);//打开软串口
mySerial.println("soft");//软串口输出soft表示软串口打开成功了
}
void loop()
{
if(mySerial.available()){//如果软串口检测到信息
Serial.write(mySerial.read());//硬串口输出软串口读到的信息
}
if(Serial.available()){//如果硬串口检测到信息
mySerial.write(Serial.read());//软串口输出硬串口的信息
}
}
硬串口是我们在串口监视器可以看到的信息 软串口不能通过串口监视器看到 所以我们要在硬串口输出软串口接收到的信息
烧录运行之后点击右上角串口监视器 可以看到以下信息(如果波特率不正确可能看不到如图,往下跟就好了) 然后我们下方选择波特率 在这里选择NL和CR
由于大家切换了波特率所以可能会重新显示几条信息如下图,如果波特率本来就正确就不需要重新选了 然后在上方输入AT并回车 显示OK 再输入AT+RST 按回车 再输入AT+CWMODE=1回车 然后输入AT+CWJAP=“wifi账号”,“wifi密码” 大家请一定注意自己的热点没有被手机自动关闭 此时我们可以看一下手机是不是有ESP设备连接上了热点 若有则说明连接成功 如果没有大家可以多试几次,我当时也是失败了很多次,然后就不停地烧录运行,终于成功了。
那么接下来就可以进行上云代码了 第一部分:发送消息至云平台 这位博主采用了芯片每次运行都自动再次连接wifi并先连接服务器的策略 但是esp8266会自动连接先前连接的热点,只要我们没有修改热点密码即可,所以我们不需要再setup里重新连接 下面博主连接了onenet服务器,这样的话我们芯片就只能连接一个设备,而不能断开。 博主使用了Serial.print的方法,使用硬串口输出指令信息,但我不知道为什么,使用硬串口没有反应,但使用软串口可以。 而且博主检测串口是否接收到OK信息,但是有时我好像收不到OK信息 经过摸索,我总结出以下代码 (与那位博主不同的是我全部使用了软串口)
#include<SoftwareSerial.h>
SoftwareSerial mySerial(10,11);
void setup() {
Serial.begin(115200);
Serial.println("hard!");
mySerial.begin(115200);
mySerial.println("soft");
delay(500);
}
void loop() {
mySerial.println("AT+CIPSTART=\"TCP\",\"183.230.40.40\",1811");
delay(50);
mySerial.print("AT+CIPMODE=1\r\n");
delay(50);
mySerial.print("AT+CIPSEND\r\n");
delay(50);
mySerial.print("*513529#tem#jiaoben*");
delay(50);
mySerial.print("succ");
delay(50);
mySerial.print("+++");
delay(50);
mySerial.print("\r\n");
delay(50);
mySerial.print("AT+CIPCLOSE\r\n");
delay(50);
}
把代码中的产品ID 鉴权信息 脚本名修改为自己的信息 修改完毕后烧录运行 之后查看onenet设备 大家可能看到有时离线,有时在线,是因为我们每次连接发送后都断开了连接,以方便连接其他设备,所以出现这个情况。 在数据流可以发现成功接收信息 我们看一下代码 分为四部分 大家只需要修改2 3 部分即可
第二部分 接收信息 接收信息其实也不是很复杂 利用tcp协议接收信息效果并不是特别理想 所以我们需要采取一些手段进行优化
#include<SoftwareSerial.h>
SoftwareSerial mySerial(10,11);
String c="";
int con=1;
void setup() {
Serial.begin(115200);
Serial.println("hard!");
mySerial.begin(115200);
mySerial.println("soft");
delay(500);
}
void loop() {
if(con==1){
mySerial.println("AT+CIPSTART=\"TCP\",\"183.230.40.40\",1811");
delay(50);
mySerial.print("AT+CIPMODE=1\r\n");
delay(50);
mySerial.print("AT+CIPSEND\r\n");
delay(50);
mySerial.print("*513529#tem#jiaoben*");
delay(2000);
while(true){
c="";
while (mySerial.available() > 0)
{
char cc=mySerial.read();
Serial.write(cc);
c += cc;
}
if(c=="finish"){
con=0;
mySerial.print("+++");
delay(50);
mySerial.print("\r\n");
delay(50);
mySerial.print("AT+CIPCLOSE\r\n");
delay(50);
break;
}
}
}
}
烧录以上代码运行 并打开串口监视器(不是一定要打开 方便我们看而已) 发现设备在线 此时芯片已经和这一个设备建立了连接 正在循环等待字符串 我们下发命令 串口显示这个信息 此时我们的字符串c就是hello 成功接收到信息 我们可以发送finish断开连接 设备已经离线,我们已经掌握了基本的接发信息的方法 那么接下来我们进行接收信息的深入解读
mySerial.println("AT+CIPSTART=\"TCP\",\"183.230.40.40\",1811");
delay(50);
mySerial.print("AT+CIPMODE=1\r\n");
delay(50);
mySerial.print("AT+CIPSEND\r\n");
delay(50);
mySerial.print("*513529#tem#jiaoben*");
while(true){
不断检测字符并累加为字符串并保存这个字符串
可以自己编写需要的逻辑跳出循环
比如接收到信息就跳出、接收到finish就跳出、按下按钮就跳出等等
if(需要跳出){
mySerial.print("+++");
delay(50);
mySerial.print("\r\n");
delay(50);
mySerial.print("AT+CIPCLOSE\r\n");
delay(50);
}
}
但是当我们连接的设备很多(上云的设备或物联网模块),逻辑复杂 可能导致芯片算力跟不上(接触不良也可能导致) 起码在我的mega2560芯片上发生了这个状况 那么就可能串口通信卡顿导致连接或断开连接失败,经过我的摸索,我发现了一种还算好用的方法,可以提高稳定性
问题主要可能出在建立连接与断开连接上 只要连接建立成功,一般信息都能成功发送过去,所以我们可以尝试连续建立两次连接并发送两次断开请求如下
mySerial.println("AT+CIPSTART=\"TCP\",\"183.230.40.40\",1811");
delay(50);
mySerial.print("AT+CIPMODE=1\r\n");
delay(50);
mySerial.print("AT+CIPSEND\r\n");
delay(50);
mySerial.print("*513529#tem#jiaoben*");
mySerial.println("AT+CIPSTART=\"TCP\",\"183.230.40.40\",1811");
delay(50);
mySerial.print("AT+CIPMODE=1\r\n");
delay(50);
mySerial.print("AT+CIPSEND\r\n");
delay(50);
mySerial.print("*513529#tem#jiaoben*");
while(true){
不断检测字符并累加为字符串并保存这个字符串
可以自己编写需要的逻辑跳出循环
比如接收到信息就跳出、接收到finish就跳出、按下按钮就跳出等等
if(需要跳出){
mySerial.print("+++");
delay(50);
mySerial.print("\r\n");
delay(50);
mySerial.print("AT+CIPCLOSE\r\n");
delay(50);
mySerial.print("+++");
delay(50);
mySerial.print("\r\n");
delay(50);
mySerial.print("AT+CIPCLOSE\r\n");
delay(50);
}
}
当然这样也有一定的弊端,虽然稳定性提高了,但是可能会把操作指令被当作信息发送给云平台,大家可以根据需要自行取舍。
|