一直想试试远程控制设备,τ 宝成品还是小贵,之前买的ESP8266-01(IO口太少,而且机智云、腾讯云等感觉又太麻烦)
这几天接触到巴法云,感觉挺简单的,试了官方的示例(用的是MCU的ESP8266-12E+Arduino)但感觉浪费IO口
然后继续百度搜资料,找到了巴法云-简书,发现了这个ESP8266-01+STC89C52的示例(官方代码备注详细,简单易懂)
后经摸索修改成了能同时控制二个设备的代码,能用控制台控制,也能用天猫精灵控制(APP控制还没有时间测试)
还需低成本远程控制多个设备的,可以添加NRF24L01当主机, 从机用NRF24L01+单片机实现
以下是巴法云的控制台,我添加了二个设备,跟代码里的一致
以下是附件内容,大家按顺序操作即可,工具和引脚接线统统有图有说明
- /*********************************************************************
- 题目:STC89C51/52+ESP8266-01/01S实现在线远程控制多个设备
- 代码:以下为利用巴法云2个订阅主题分别控制2个IO口的代码(方便新手理解及扩展)
- 注意:晶振一定是11.0592MHz。
- 关于UID:在巴法云注册登陆,即可看到自己UID,推送微信消息,需要手机绑定微信,bemfa.com在控制台进行绑定即可。
- 注意:新买的ESP8266-01默认是115200波特率,需要利用串口调试助手更改esp8266波特率为9600
- 更改方法:USB转串口板连接到ESP8266,波特率115200,发送 AT+UART=9600,8,1,0,0 //末尾有回车换行
- USB转串口板接线方法:tx--rx ,rx--tx,gnd-gnd,3.3v--3.3v,EN--3.3v //esp8266--USB转串口板
- 官方文档见官网:www点cloud.bemfa点com/docs/#/?id=_51-tcp%e5%88%9b%e5%ae%a2%e4%ba%91
- 注册、登陆页面:cloud.bemfa点com/u_login.php
- STC89C51/52与ESP8266-01/01S的接线方式(注意-需要先将本程序烧录到单片机后断电,接上ESP8226-01/01S,然后上电):
- STC89C51/52 ESP8266-01
- P30----------------TX
- P31----------------RX
- 以下代码只有几处需要根据你的实际情况修改, 已注明"需要修改此部分", 其它地方不需要修改
- ********************************************************************/
- #include <reg52.h>
- #include <stdio.h>
- #include <string.h> //包含头文件
- #define uint unsigned int
- #define uchar unsigned char
- //************ 需要修改以下部分 ************
- #define Ssid "wifi名称" //WIFI名称,,修改为自己路由器的WIFI名称,好像不支持中文
- #define PassWord "wifi密码" //WIFI密码,修改为自己路由器的
- #define Uid "密钥" //巴法云UID密钥,控制台获取
- #define TopicLed1 "LedA002" //巴法云控制台创建,名称自定义,app订阅主题要和这个推送主题一致(如需控制多个主题,只要填其中一个即可)
- #define TopicLed2 "LedB002" //巴法云控制台创建,名称自定义,app订阅主题要和这个推送主题一致(如需控制多个主题,只要填其中一个即可)
- sbit LED1 = P2^0; //灯1, 对应订阅主题LedA002
- sbit LED2 = P2^1; //灯2, 对应订阅主题LedB002
- //************ 需要修改以上部分 ************
- /*****************相关变量**************/
- uchar Receive; //接收到的字节
- uchar i,i2,count; //定时器所用变量
- uint n; //接收到字节的个数
- uchar flag=0; //标志位,检查是否有数据通过串口发到MCU
- uchar connected = 0; //标志位,检查是否已连接服务器
- uchar Recive_table[100]; //用于接收wifi模块反馈到MCU上的数据
- /*******************************************************************
- 名称:延时函数
- 作用:毫秒级延时,微妙级延时函数,为数据收发完成作等待.......
- ********************************************************************/
- void ms_delay(uint t)
- {
- uint i,j;
- for(i=t;i>0;i--)
- for(j=110;j>0;j--);
- }
- void us_delay(uchar t)
- {
- while(t--);
- }
- /********************************************************************
- 名称:波特率发生器函数
- 作用:波特率发生器可以是T1定时器实现,也可以是MCU内部独立的波特率发生器,
- 各自不同的载入值计算式,具体根据寄存器相关设置来参考计算,以实现
- 异步串行通讯。(经测试,两种设置方式均可用,可任选一种。)
- ********************************************************************/
- void Uart_Init()//使用定时器1作为波特率发生器(STC89C52、STC89C51、AT89C51或者STC12C560S2等均可)
- {
- SCON=0x50; //设置为串行口以方式1工作,8位异步通讯,允许接收中断。
- //一帧信息为10位,1位起始位,8位数据位(低位在先),1位停止位。
- PCON=0x80; //SMOD波特率选择位为1,SMOD=1.
- TMOD=0x21; //设置定时器1为波特率发生器,工作在模式2,8位自动装载
- TH1=0xFA ;//波特率9600 ,TH1=256-FOSC/16/12/波特率
- TL1=TH1;
- EA=1; //总中断打开
- ES=0; //关闭串口中断
- TR1=1; //启动定时器1
- TH0=0xD8; //定时10ms
- TL0=0xF0;
- ET0=1;
- TR0=1;
- }
- /********************************************************************
- 名称:串口发送函数
- 功能:MCU向其他与其连接的设备发送数据(此处是无线WIFI模块ESP8266)
- ********************************************************************/
- void Send_Uart(uchar value)
- {
- ES=0; //关闭串口中断
- TI=0; //清发送完毕中断请求标志位
- SBUF=value; //发送
- while(TI==0); //等待发送完毕
- TI=0; //清发送完毕中断请求标志位
- ES=1; //允许串口中断
- }
- /********************************************************************
- 名称:串口发送数据
- 作用: 通过串口发送指令到WIFI模块,以便可以实现无线接入和控制,带回车换行
- ********************************************************************/
- void SerialSend(uchar *puf) // 数组指针*puf指向字符串数组
- {
- while(*puf!='\0') //遇到空格跳出循环
- {
- Send_Uart(*puf); //向WIFI模块发送控制指令。
- us_delay(5);
- puf++;
- }
- us_delay(5);
- Send_Uart('\r');//回车
- us_delay(5);
- Send_Uart('\n'); //换行
- }
- /********************************************************************
- 名称:串口发送数据
- 作用: 通过串口发送指令到WIFI模块,不带回车换行
- ********************************************************************/
- void SerialSend_byte(uchar *puf) // 数组指针*puf指向字符串数组
- {
- while(*puf!='\0') //遇到空格跳出循环
- {
- Send_Uart(*puf); //向WIFI模块发送控制指令。
- us_delay(5);
- puf++;
- }
- }
- /********************************************************************
- 名称:心跳函数
- 作用:发送心跳。如果一分钟不发送心跳,服务器就会认为设备掉线,故建议30s发送一次心跳
- 在中断1中调用,和发送数据函数,留一个就行,发送数据也相当于心跳
- ********************************************************************/
- void Ping(void)
- {
- SerialSend("cmd=0&msg=ping"); //发送心跳
- }
- void connect_topic(uchar x){
- //发送订阅指令,原格式为:cmd=1&uid=***UID***&topic=***Topic***
- SerialSend_byte("cmd=1&uid=");
- SerialSend_byte(Uid);
- SerialSend_byte("&topic=");
-
- //************ 需要修改以下部分 ************
- if(x==1){
- SerialSend_byte(TopicLed1);
- } else if(x==2){
- SerialSend_byte(TopicLed2);
- }
- //************ 需要修改以上部分 ************
-
- us_delay(5);
- Send_Uart('\r');//回车
- us_delay(5);
- Send_Uart('\n'); //换行
- }
- void connect_bemfa(void){
- connected = 1;
- SerialSend("AT+CIPMODE=1"); //开启透明传输模式
- ms_delay(1000);
- SerialSend("AT+CIPSTART=\"TCP\",\"bemfa.com\",8344"); // 连接服务器和端口
- ms_delay(1000);
- SerialSend("AT+CIPSEND"); //进入透传模式,下面发的都会无条件传输
- ms_delay(1000);
-
- //************ 需要修改以下部分 ************
- connect_topic(1); //连接第1个订阅主题
- ms_delay(1000);
- connect_topic(2); //连接第2个订阅主题
- ms_delay(1000);
- //************ 需要修改以上部分 ************
-
- connected = 1; //表示连接成功,可以发送数据了
- }
- /********************************************************************
- 名称:主函数
- 作用:程序的执行入口
- ********************************************************************/
- void main()
- {
- memset(Recive_table,'\0',sizeof Recive_table);//重置数组
- Uart_Init();//使用独立的波特率发生器
- ms_delay(1000);
- SerialSend("AT+RST"); //重新启动wifi模块
- ms_delay(1000);
- SerialSend("AT"); //重新启动wifi模块
- ms_delay(1000);
- SerialSend("AT+CWMODE=3"); //设置路由器模式 1 station模式 2 AP路由器模式 3 station+AP混合模式
- ms_delay(1000);
- SerialSend("AT+CWJAP=\""Ssid"\",\""PassWord"\"");//设置模块SSID:WIFI, PWD:密码 及安全类型加密模式(WPA2-PSK)
- ms_delay(8000);
- connect_bemfa(); //连接巴法云服务器
- while(1)
- {
- if(flag == 1){
- //************ 需要修改以下部分 ************
- //实际收到到指令:cmd=2&uid=4d9ec352e0376f2110a0c601a2857225&topic=light002&msg=on
- //字符串匹配,当检测到字符串msg=on时,执行开灯
- //如果有多个主题,可以加上主题名字以区分不同设备控制命令,如: if(strstr(Recive_table,"light002&msg=on"))
- if(strstr(Recive_table,"LedA002&msg=on")){ //当检测到字符串msg=on时,执行开灯
- LED1=0; //引脚置高电平
- } else if(strstr(Recive_table,"LedA002&msg=off")){ //当检测到字符串msg=off时,执行关灯
- LED1=1; //引脚置低电平
- } else if(strstr(Recive_table,"LedB002&msg=on")){
- LED2=0;
- } else if(strstr(Recive_table,"LedB002&msg=off")){
- LED2=1;
- }
- //************ 需要修改以上部分 ************
- else if(strstr(Recive_table,"ERROR")){ //如果掉线或网络故障,重新连接
- connect_bemfa(); //连接巴法云服务器
- }
- memset(Recive_table,'\0',sizeof Recive_table);//重置数组
- flag=0;
- }
- }
- }
- /********************************************************************************
- 名称:串行通讯中断
- 作用:发送或接收结束后进入该函数,对相应的标志位清零, 实现模块对数据正常的收发
- *********************************************************************************/
- void Uart_Interrupt() interrupt 4
- {
- if(RI==1)
- {
- RI=0;
- Receive=SBUF; //MCU接收wifi模块反馈回来的数据
- Recive_table[i]=Receive;
- i++;
- if((Receive =='\n')){
- i=0;
- flag = 1;
- }
- }
- else TI=0;
- }
- //定时发送心跳,或发送传感器数据
- //心跳建议30s发一次,一分钟不发数据,服务器会认为设备掉线
- void timer0isr(void) interrupt 1
- {
- TH0=0xD8;
- TL0=0xF0;
- i2++;
- if(i2==100)
- {
- i2=0;
- count++;
- if(count>=40) //40秒,可自行修改
- {
- if(connected == 1){
- Ping(); //发送心跳
- }
- count=0;
- }
- }
- }
复制代码
附件在2楼
|