概述

鉴于ESP32方案的屏幕具有mqtt协议透网远程控制的功能,因此我们可以利用屏的网络语句完成一个远程和家电控制,并可以制作多组定时控制

实体照片

电路原理

使用串口屏的E1扩展端口进行继电器的控制,CN2是接串口屏的插座

代码实现:

这是一个mqtt连接的测试程序,在此界面之前,已经在开机的界面用下面的语句完成了wifi的连接,SNTP互联网时间获取,以及mqtt服务器的连接:

void init()
{    str ssid;
    str pwd;
    ssid=bind_get("wifissid");  //获取存储的wifi AP的SSID
    pwd=bind_get("wifipass");   //获取存储的wifi密码
    wifi_connect(ssid,pwd);     //wifi连接
    gpio_mode(0,1);    //E1端口 设置成输出模式
    app.setio(0); //E1低电平,继电器关闭
}

wifi连接时异步事件,在异步回调之后再依次处理,以下是部分核心代码:

void app.onASYNC(int m){
    if (m==1){
        //已经WIFI连接成功,需要进入下一步:获取互联网时间
        wifi_sntp("ntp.aliyun.com","CST-8");
    }
    if (m==2){
        //获取网络时间OK,在此书写连接服务器的代码
        mqtt_init();    //配置文件初始化
        //mqtt_setv(0,"mqtt://user:pwd@host.com"); //使用自有的mqtt服务器
        mqtt_setv(2,"");//使用SHMICTRL官网提供的免费服务器
        mqtt_connect(); //连接mqtt服务器
    }
    if (m==3){
        //mqtt服务器连接完成
        gopage(2); //直接调整到第2个页面
    }
    super.onASYNC(m);    //调用appbase父类继续处理其他消息
}

可以看到连接mqtt服务器后,会跳转的第二个页面,实际效果如下:

在此界面中,点按钮“开关”可以实现继电器的开关,然后界面处于mqtt协议的连接状态,当收到mqtt消息的时候,会将消息显示在左侧的调试消息显示框中,并且对消息命令进行处理:

同时,界面中生成一个二维码,对应服务器上的一个URL程序,该程序是PHP编制,使用PHP连接mqtt服务器发送相应的消息,用于控制继电器的开关

本页面完整代码如下:

class app=loadcom(appbase);  //加载全局控制控件
class page=loadcom(page);    //加载页面控制控件
class s1=loadcom(skinwindows);  //加载窗体控件
class m1=loadcom(memo); //左侧的大文本显示控件
class s2=loadcom(skinbutton); //按钮"开"
class s3=loadcom(skinbutton); //按钮"测试发布"
class s4=loadcom(skinbutton); //按钮"返回"
class s5=loadcom(skinbutton); //按钮"清空"
class q1=loadcom(QRcode);     //二维码控件

str retstr= "";  //反馈字符串
str maintopic=""; //主topic
io=0;   //端口状态
void app.onASYNC(int m){
    if (m==200){
        //收到消息后,如果有反馈字符串,则发布消息,返回反馈字符串
        if (retstr!=""){
            mqtt_pub(maintopic,0,retstr); //发布一条消息
            retstr="";
        }
    }

}

//mqtt传来的消息命令执行函数
void mqtt_work(str topic,str data){
    if (data=="S1"){
        gpio_out(0,1); //E1端口高电平
        retstr="1";    //返回1
        io=1;
    }
    if (data=="S0"){
        gpio_out(0,0);  //E1端口低电平
        retstr="0";     //返回0
        io=0;
    }
    if (data=="RS"){    //读取继电器状态,也就是E1的端口电平
        retstr=""+io;
    }
    if (retstr!=""){
        async_run(200);  //如果有返回信息,则执行异步反馈发送消息
    }
}


void app.onWIFI32(int m){
    //在此书写有关m对应的wifi异步执行结果的处理代码
    str s;
    int msgnum;
     msgnum=wifi_getinfo(2);
    if (m==7){//m==7 表示收到的是mqtt消息事件
           if (msgnum==6){  //msgnum==6 表示事件是收到mqtt消息
               //收到消息
               str topic;
               str data;
               int qos;
               topic=wifi_getinfo(23); //获取消息的topic
               data=wifi_getinfo(24);  //获取消息的实际内容
               qos=wifi_getinfo(4);    //获取qos,可以不处理
               //---在此书写收到的mqtt消息处理
               s="RECV:"+data+"\r\n";
               m1.text=m1.text+s; //将收到的消息字符串累加到屏幕左侧的大文本控件,用于显示
               mqtt_work(topic,data); //处理传来的消息命令
           }
    }
    super.onWIFI32(m); //调用appbase的父类,继续处理其他的wifi事件
}

void s2.onclick()
{   //返回按钮的点击事件
    gopage(1); //跳到页面1(菜单界面)
}
void s3.onclick()
{   //发布按钮
    mqtt_pub(app.maintopic,0,"testmessage");//发布一条测试消息
}
void s4.onclick()
{   //卡关按钮
    if (s4.text=="开"){
        s4.text="关";  //点击后改变按钮上显示内容
        gpio_out(0,1); //E1输出高电平
        io=1;
    }
    else{
        s4.text="开";
        gpio_out(0,0); //E1输出低电平
        io=0;
    }
}
void s5.onclick()
{   //清空按钮
    m1.text="";  //清空大文本控件的显示内容
}
void init(){
    //刚进入页面时的初始化函数
    q1.text="http://shmictrl.com/wifi/shmi-R1.php?id="+getsn(6); //生成二维码的url
    maintopic="shmi-R1/"+getsn(6); //生成mqtt消息的topic
}
init(); //调用init()函数,初始化一些参数
start(); //进入页面的消息循环,处理页面的显示与触摸事件

内部结构

资源下载:

资源名称 下载
源代码工程 https://gitee.com/shmictrl/demo/tree/master/ESP32_40ATP_MQTT_DEMO
电路图与PCB 电路图与PCB