博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(一)基于阿里云的MQTT远程控制(Android 连接MQTT服务器,ESP8266连接MQTT服务器实现远程通信控制----简单的连接通信)...
阅读量:5835 次
发布时间:2019-06-18

本文共 13414 字,大约阅读时间需要 44 分钟。

如果不了解MQTT的可以看这篇文章  

关于钱的问题,其实自己是花钱买的云服务,虽然自己现在能支付的起,但是呢为了尽量减少支出,自已还有好多好多文章要写,好多好多元器件要买,所以哈会在自己的淘宝上卖源码2元价格,一元捐出,一元自己留着当亲们支付云服务的费用了

如果看不懂也没关系,跟着做就可以了,做完以后您会发现原来MQTT这么好用,也如此简单.

对了我要尽量把程序写的烂一些,界面做的烂一些,因为既然是学习用的应该越直观越好.......说一下,自己的服务器因为公开了稳定性上肯定不好,

数据冲突也是可能的,这是第一篇,下面几篇慢慢的来,咱一块慢慢完善哈

实现的功能--手机和WIFI模块都连接MQTT服务器,手机用按钮实现远程控制一个继电器,然后WIFI模块采集的DHT11的温湿度,远程发给手机

不过自己这批贴片的板子要等到后天才到..........................

  

 

 

 

先看一下Android 程序怎么写,首先就是下载个MQTT的jar包

链接: 密码:90vv

新建一个Android 工程就不说了吧...............

将下载的jar包放在一个地方

 

 

我放在了我的Android的源码的根目录

现在在Android 工程导入下载的那个jar包

 

 

 

 

 

 

 

 

 

现在把可能用到的一些权限加上 

 

"

 

现在呢先写个程序获取手机的IMEI号,因为连接的时候每一个客户端的ClientID要求不能一样,咱就用IMEI号代表ClientID

其实就这两句

TelephonyManager mTm = (TelephonyManager)this.getSystemService(TELEPHONY_SERVICE);  TelephonyIMEI = mTm.getDeviceId();

 

现在配置咱的MQTT

 

public class MainActivity extends Activity {        String TelephonyIMEI="";        private MqttClient client;//client    private MqttConnectOptions options;//配置        @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);                TelephonyManager mTm = (TelephonyManager)this.getSystemService(TELEPHONY_SERVICE);          TelephonyIMEI = mTm.getDeviceId();        //Toast.makeText(getApplicationContext(), TelephonyIMEI, 500).show();        MyMqttInit();    }        /*  初始化配置Mqtt  */    private void MyMqttInit()    {                try        {            //(1)主机地址(2)客户端ID,一般以客户端唯一标识符(不能够和其它客户端重名)(3)最后一个参数是指数据保存在内存(具体保存什么数据,以后再说,其实现在我也不是很确定)            client = new MqttClient("tcp://47.93.19.134:1883",TelephonyIMEI,new MemoryPersistence());        } catch (MqttException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }                options = new MqttConnectOptions();//MQTT的连接设置                options.setCleanSession(true);//设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录,这里设置为true表示每次连接到服务器都以新的身份连接                options.setUserName("username");//设置连接的用户名(自己的服务器没有设置用户名)                options.setPassword("password".toCharArray());//设置连接的密码(自己的服务器没有设置密码)                options.setConnectionTimeout(10);// 设置连接超时时间 单位为秒                options.setKeepAliveInterval(20);// 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线,但这个方法并没有重连的机制                client.setCallback(new MqttCallback() {            @Override//获取的消息会执行这里--arg0是主题,arg1是消息            public void messageArrived(String arg0, MqttMessage arg1) throws Exception {                // TODO Auto-generated method stub                            }                        @Override//订阅主题后会执行到这里            public void deliveryComplete(IMqttDeliveryToken arg0) {                // TODO Auto-generated method stub                            }                        @Override//连接丢失后,会执行这里            public void connectionLost(Throwable arg0) {                // TODO Auto-generated method stub                            }        });    }

 

 现在连接咱的服务器,连接成功后打印一下连接成功,连接是阻塞的,所以放在一个任务里面执行连接

 

public class MainActivity extends Activity {        String TelephonyIMEI="";        private MqttClient client;//client    private MqttConnectOptions options;//配置    MqttConnectThread mqttConnectThread = new MqttConnectThread();//连接服务器任务    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);                TelephonyManager mTm = (TelephonyManager)this.getSystemService(TELEPHONY_SERVICE);          TelephonyIMEI = mTm.getDeviceId();        //Toast.makeText(getApplicationContext(), TelephonyIMEI, 500).show();        MyMqttInit();//初始化配置MQTT客户端        mqttConnectThread.start();//执行连接服务器任务    }        /*  初始化配置Mqtt  */    private void MyMqttInit()    {        .........    }            /*连接服务器任务*/    class MqttConnectThread extends Thread    {        public void run()        {            try             {                client.connect(options);//连接服务器,连接不上会阻塞在这                runOnUiThread(new Runnable() {
// public void run() { Toast.makeText(getApplicationContext(), "连接成功", 500).show(); } }); } catch (MqttSecurityException e) { //安全问题连接失败 } catch (MqttException e) { //连接失败原因 } } }

 

 现在下载到手机试一试

 

 现在呢测试一下通信,测试接收消息,用调试助手发信息,然后手机端接收,然后显示出来

 调试助手链接

链接: 密码:exfj

 

 现在先设置一下APP的订阅的主题,和接收到消息之后就显示出来

 

 

public class MainActivity extends Activity {        String TelephonyIMEI="";        private MqttClient client;//client    private MqttConnectOptions options;//配置    MqttConnectThread mqttConnectThread = new MqttConnectThread();//连接服务器任务    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);                TelephonyManager mTm = (TelephonyManager)this.getSystemService(TELEPHONY_SERVICE);          TelephonyIMEI = mTm.getDeviceId();        //Toast.makeText(getApplicationContext(), TelephonyIMEI, 500).show();        MyMqttInit();//初始化配置MQTT客户端        mqttConnectThread.start();//执行连接服务器任务    }        /*  初始化配置Mqtt  */    private void MyMqttInit()    {                try        {            //(1)主机地址(2)客户端ID,一般以客户端唯一标识符(不能够和其它客户端重名)(3)最后一个参数是指数据保存在内存(具体保存什么数据,以后再说,其实现在我也不是很确定)            client = new MqttClient("tcp://47.93.19.134:1883",TelephonyIMEI,new MemoryPersistence());        } catch (MqttException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }                options = new MqttConnectOptions();//MQTT的连接设置                options.setCleanSession(true);//设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录,这里设置为true表示每次连接到服务器都以新的身份连接                options.setUserName("username");//设置连接的用户名(自己的服务器没有设置用户名)                options.setPassword("password".toCharArray());//设置连接的密码(自己的服务器没有设置密码)                options.setConnectionTimeout(10);// 设置连接超时时间 单位为秒                options.setKeepAliveInterval(20);// 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线,但这个方法并没有重连的机制                client.setCallback(new MqttCallback() {            @Override//获取消息会执行这里--arg0是主题,arg1是消息            public void messageArrived(String arg0, MqttMessage arg1) throws Exception {                // TODO Auto-generated method stub                final String topic = arg0;//主题                final String msgString = arg1.toString();//消息                                runOnUiThread(new Runnable() {
// public void run() { Toast.makeText(getApplicationContext(),"主题:"+topic+"消息:"+msgString, 500).show(); } }); } @Override//订阅主题后会执行到这里 public void deliveryComplete(IMqttDeliveryToken arg0) { // TODO Auto-generated method stub } @Override//连接丢失后,会执行这里 public void connectionLost(Throwable arg0) { // TODO Auto-generated method stub } }); } /*连接服务器任务*/ class MqttConnectThread extends Thread { public void run() { try { client.connect(options);//连接服务器,连接不上会阻塞在这 client.subscribe("test",0);//设置(订阅)接收的主题,主题的级别是0 runOnUiThread(new Runnable() {
// public void run() { Toast.makeText(getApplicationContext(), "连接成功", 500).show(); } }); } catch (MqttSecurityException e) { //安全问题连接失败 } catch (MqttException e) { //连接失败原因 } } }

下载到手机 

 

 现在配置一下软件,对了有些参数现在不明白没关系,后面会介绍一下相关的知识,

软件的主题名称要和APP中订阅的主题一样 都是 test

现在连接

 

 

 现在点击发布消息

 

 

 看手机端

 

 说明已经能通信了

 现在说一下关于主题哈,关于/

 现在把手机端的订阅的主题改为"/#"

 

 然后下载到手机

 

你会发现手机也能接收消息

 

手机都能接收到消息

# 是一个匹配主题中任意层次数的通配符。比如说,如果你订阅了test/device/#,你就可以接收到以下这些主题的消息。

test/device
test/device/后面随便是什么
咱们的设备可以用"/"来进行分类,咱们的APP呢可以指定接收哪一类的产品的数据"XXXX/#"....是不是很方便 对了如果现在接收两个已知主题的设备 假如说是

第一种方式

  

 

 

第二种方式
 

结果和上面一样

 

 现在呢在界面加一个按钮,按下发送消息"1",松开发送消息"0"

然后设置发布的主题是"/test/button"

 

 

 

 

public class MainActivity extends Activity {        String TelephonyIMEI="";        private MqttClient client;//client    private MqttConnectOptions options;//配置    MqttConnectThread mqttConnectThread = new MqttConnectThread();//连接服务器任务        Button button;//发送消息按钮    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);                button = (Button) findViewById(R.id.button1);//获取发送消息按钮        button.setOnTouchListener(buttonTouch);//设置按钮的触摸事件                TelephonyManager mTm = (TelephonyManager)this.getSystemService(TELEPHONY_SERVICE);          TelephonyIMEI = mTm.getDeviceId();        //Toast.makeText(getApplicationContext(), TelephonyIMEI, 500).show();        MyMqttInit();//初始化配置MQTT客户端        mqttConnectThread.start();//执行连接服务器任务    }        /*按钮触摸事件*/    private OnTouchListener buttonTouch = new OnTouchListener() {                @Override        public boolean onTouch(View v, MotionEvent event)         {            MqttMessage msgMessage = null;//Mqtt消息变量            if (event.getAction() == MotionEvent.ACTION_DOWN) //按下            {                msgMessage = new MqttMessage("1".getBytes());            }            else if (event.getAction() == MotionEvent.ACTION_UP) //松开            {                msgMessage = new MqttMessage("0".getBytes());            }                        try             {                client.publish("/test/button",msgMessage);//发送主题为"/test/button"的消息            } catch (MqttPersistenceException e) {                // TODO Auto-generated catch block                e.printStackTrace();            } catch (MqttException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }            catch (Exception e) {                //其余的状态msgMessage = null;所以加了这个catch (Exception e)            }                                    return false;        }    };

 

 现在下载到手机,

调试助手订阅一下主题 "/test/button"

 

 动作一下按钮

 

 

 

 现在把发过来的数据用文本框显示,不让他提示了

 

     接收显示的换一下

 

 

runOnUiThread(new Runnable() {
//因为操作的是主界面的控件所以用刷新UI的线程,最好用handle哈,我这里怎么简单怎么写 public void run() { //Toast.makeText(getApplicationContext(),"主题:"+topic+"消息:"+msgString, 500).show(); textView.setText("主题:"+topic+"\n消息:"+msgString); } });

 

 现在试一下

 

 

 

好了,现在咱开始控制咱的WIFI模块了....用咱的手机控制WIFI板子上的继电器,WIFI模块呢采集温湿度,然后显示在手机的文本框中

自己更倾向于用lua开发,所以要刷入lua的固件哈

关于刷固件可以参考

自己已经下载好的固件

链接: 密码:9zns

 

如果亲们自己下载的话别忘了,把mqtt和dht选择上哈

 

 

程序--init.lua

wifi.setmode(wifi.STATION)RelayPin = 2;--RelayPingpio.mode(RelayPin,gpio.OUTPUT)--RelayPingpio.write(RelayPin,0)--RelayPinLedPin = 4;--LedPingpio.mode(LedPin,gpio.OUTPUT)--LedPingpio.write(LedPin,0)--LedPinDHT11pin = 5--DHT11 GPIOTemperature = "0";--Storage temperatureHumidity = "0";--Store humidityapcfg={}apcfg.ssid="qqqqq"apcfg.pwd="11223344"wifi.sta.config(apcfg)--wifi.sta.connect()wifi.sta.autoconnect(1)clientid = wifi.sta.getmac()mqttClient=nilmqttConnectedFlage = 0;Mymqtt = mqtt.Client(clientid, 120,"user", "password");--[[The connection serve]]tmr.alarm(0, 1000, 1, function()    Mymqtt:connect("47.93.19.134", 1883, 0,ConnectSuccess,ConnectFailed)end)--[[The connection Success]]function ConnectSuccess(client)     client:subscribe("/test/button", 0, subscribeSuccess)                                              print("connected")     mqttClient = client;     tmr.stop(0);     mqttConnectedFlage = 1;end--[[The connection fails]]function mqttConnectFailed(client,reason)   mqttConnectedFlage = 0;   print("failed reason: " .. reason)   tmr.start(0);end--[[The subscribe Success]]function subscribeSuccess(client)    print("subscribe success") end--[[The Receive Msg]]Mymqtt:on("message", function(client, topic, data)     if  string.find(data,"1") ~= nil then        gpio.write(RelayPin,1)    end    if  string.find(data,"0") ~= nil then        gpio.write(RelayPin,0)    end   end)--[[The Send Msg]]tmr.alarm(1, 1000, 1, function()    if mqttClient ~= nil and mqttConnectedFlage == 1 then        mqttClient:publish("/test/yang","Temperature="..Temperature..";".."Humidity="..Humidity, 0, 0,           function(client)             gpio.write(4,1-gpio.read(4))          end)    end      end)--[[The gather humiture data]]tmr.alarm(5, 2000, 1, function()--Every other 1S    local status, temp, humi, temp_dec, humi_dec = dht.read11(DHT11pin)--Gathering temperature and humidity                     if status == dht.OK or status == dht.ERROR_CHECKSUM then        Temperature = temp;        Humidity = humi;        --print("DHT Temperature:"..temp..";".."Humidity:"..humi)    endend)printip = 0wifi.eventmon.register(wifi.eventmon.STA_DISCONNECTED, function(T)    printip = 0end)wifi.eventmon.register(wifi.eventmon.STA_GOT_IP, function(T)   if printip == 0 then      ip,netmask,gateway = wifi.sta.getip()      print(gateway)   end   printip = 1end)

 

现在说一下个个部分的功能,对了关于语法问题和其余的问题就请大家参考我的,其实上面的代码就是参考的官方给的API函数,

我希望亲们最重要的是有自学的能力,而不是需要别人灌输东西的机器.

 

 

 

 

 

 好了亲们可以自己去测试了

源码链接

wifi的就是上面的,直接复制粘贴过去就好啦

自己淘宝店的链接呢在最上面

 

转载地址:http://liycx.baihongyu.com/

你可能感兴趣的文章
verilog语法实例学习(8)
查看>>
如何使用istream_iterator將文字檔轉到vector? (C/C++) (STL)
查看>>
艾伟也谈项目管理,创建敏捷团队
查看>>
Linux服务器access_log日志分析及配置详解(一)
查看>>
Pad本蓝牙模块检测
查看>>
QT QDateTime类、QTimer类
查看>>
小程序https Android 安卓可以发request请求,IOS 苹果 发请求失败问题
查看>>
LiteORM学习五:实体类验证
查看>>
xp 网页 flash swf 无法调用 摄像头 问题解决
查看>>
看成功学·谈成功
查看>>
java.io.CharConversionException: isHexDigit
查看>>
Asp.Net在IIS上运行不了,就试下下面方法应该可以你的问题
查看>>
iOS开发中捕获Crash 发送Bug邮件
查看>>
BMP图片转换为JPEG图片
查看>>
codeforces B. Design Tutorial: Learn from Life
查看>>
haproxy配置直接重定向url
查看>>
第三方支付集成
查看>>
anything vs everything
查看>>
N-gram统计语言模型(总结)
查看>>
SQL - 分页存储过程
查看>>