GVKun编程网logo

Wifi设备配网问题(wifi设备配网的原理)

6

对于想了解Wifi设备配网问题的读者,本文将是一篇不可错过的文章,我们将详细介绍wifi设备配网的原理,并且为您提供关于8266station初始化和智能配网问题、Android:设置wifi设备名、

对于想了解Wifi设备配网问题的读者,本文将是一篇不可错过的文章,我们将详细介绍wifi设备配网的原理,并且为您提供关于8266station初始化和智能配网问题、Android: 设置wifi设备名、ESA2GJK1DH1K微信小程序篇: 微信小程序APUConfig给WI-Fi模块配网并绑定设备,并通过MQTT控制设备、Gitee 推荐 | 简单易用 Arduino 配网库 BGWiFiConfig的有价值信息。

本文目录一览:

Wifi设备配网问题(wifi设备配网的原理)

Wifi设备配网问题(wifi设备配网的原理)


今天写个物联网的技术文章——关于Wifi设备为什么配网失败


这相信是很多做过Wifi产品的制造业企业遇到的客诉最多的问题——消费者因Wifi产品配网失败,投诉、申请退货


据我了解,有客户使用2016年的微信硬件airkiss2.0配网,退货率可以达到15%。


今天文章介绍下目前所有的Wifi设备配网技术特点、优劣势、客诉解决方法。重要的是新产品要选什么配网方案,不要再踩坑里了


(以下内容,部分信息收集至阿里云平台)

(技术名词尽量换成中文,方便大家理解)

(技术细节不深究,希望大家看得懂)


进入正题,首先理解几个概念。


——Wifi配网绑定概念——

【Wifi配网概念】:Wifi设备需要连接上路由器(也就是Wifi热点,又称作AP)才能上网,实现数据上报和远程控制。我们将Wifi设备获取Wifi热点的名字和密码的过程称做配网


【Wifi设备绑定概念】:Wifi设备有唯一的标识码MAC地址(类似身份证,一人一个,不重复),用户的账号需要在服务器绑定这个设备的MAC地址后,才有权限在账号下进行控制。我们将手机APP获取设备MAC地址,再将其与用户手机APP账号一起发到服务器绑定的过程称作绑定设备。


只要完成这2个步骤,我们的Wifi设备就可以配网绑定成功,用户就可以正常使用了


相反,如果用户添加设备失败,基本就是在这2个环节上出现问题



——Wifi配网方式介绍——

由于配网失败导致退货的问题一直是Wifi设备的一个痛点,所以各大厂家一直在研究Wifi配网技术。


目前配网技术有以下几种

一键配网(Smartconfig)

设备热点配网(Soft AP)

蓝牙配网(Bleconfig)

零配(Zeroconfig)

手机热点配网(Phone as AP)

路由器配网(WPS)


下面是配网方式的简图:

(以上图片来至阿里云)


相信你一定没看懂,

没关系,我们一一介绍下。



——1.罪魁祸首【一键配网技术】——

(一键配网流程图)


如果你想知道你家或者你的客户家的Wifi设备为什么配不上网,只要了解罪魁祸首——一键配网技术就行


因为目前除了小米米家的产品,这个一键配网的技术基本占据了市面上90%以上的Wifi设备,各大物联网平台像京东微联、阿里小智、阿里飞燕、苏宁智能、华为hilink、微信硬件、 各大第三方物联网平台APP、各大模组厂家都标配一键配网技术,也是制造业企业踩坑的重要原因。


当然很多物联网平台在客户一键配网失败之后,会让客户使用其他配网方式来解决配网成功率问题。但是一键配网依旧是平台让用户首选的配网方式


【技术原理】

一键配网原理是通过手机或路由器发送UDP广播包的形式,将路由器的名字和密码广播出去。Wifi设备在进入配网的时候,其实就是在空中抓取广播包,抓到包之后解析就可以获取到路由器的名字和密码,然后连接上路由器。


Wifi设备连接上路由器之后,会在局域网内广播自己的MAC地址,由于手机也是连接着同一台路由器,所以手机APP可以接收到Wifi设备在局域网下面的广播,进而获取到Wifi设备的MAC地址。然后将MAC地址和用户账号发送到服务器进行绑定。


【问题点】

1.很多路由器不支持UDP广播功能,例如wifi放大器、或者一些默认关闭UDP广播的路由器,会导致发广播包失败,导致WIFI设备无法获取到广播包。

2.当5G和2.4G同频的时候,如果当前手机连接的是5G频段,那发出来的广播包是5G的,而目前所有WIFI设备都只支持2.4G,导致无法获取广播包。

3.如果是2018年以前做的WIFI产品可能还会遇到解包错误等问题,就是WIFI模块获取到数据包了,但是解析出来的密码错误,导致无法链接上路由器。例如微信airkiss就是2016年的产品,跟后面新出的smartconfig对比,成功率还要差上一截。

4.就算经历千辛万险获取到路由器名字和密码,很多路由器由于不支持局域网通讯(例如路由器的访客网络),或者当前环境下面有几个路由器名字都是一样的,导致手机和WIFI设备不是连接在同一个路由器下面,都会导致wifi设备广播的MAC地址无法被手机APP获取到,进而导致绑定失败。


【解决方法】

1.已经出货的产品,配网方式基本是换不了的,因为这涉及到Wifi模块、手机APP、服务器三方的更改,可能性极低。

2.遇到客诉除了让客户排除以上各种情况外,可以让客户将设备拉到另一个环境,用手机设置成与要配网的路由器同个名字密码的Wifi热点,将其配网绑定成功之后,再拿回到要使用的地方。

3.新产品不要再用一键配网了。


【很多人会好奇这种有问题的技术是怎么来的?】

那是因为2014年Wifi设备刚开始普及之前,大家都是使用老的AP配网方式,步骤非常复杂,要7个步骤(这里不细说了)。所以当一键配网技术出现的时候,由于其操作只要1个步骤,用户操作简便,优势明显,所以迅速成为Wifi设备配网的主流。


而随后这么多年一键配网技术遇到各种投诉,各大物联网平台也推出了“弥补”方式:


微信硬件在airkiss2.0之后就停掉了微信硬件的发展;京东微联则增加了设备热点配网方式来弥补;阿里智能则增加手机热点配网方式弥补;最新的天猫精灵平台,则用零配的方式来解决配网问题;其他第三方物联网平台的APP则推出的各自的设备热点配网方式给大家选择。


但是一键配网仍是首选方案,因为很多物联网平台都没有将其他配网技术的体验做得很完善,很多销售也不懂技术,不会引导企业使用好的配网方式。


这里要称赞下小米米家物联网平台因为小米米家开始没多久,就把一键配网技术干掉了,所有Wifi设备都是使用设备热点配网或者蓝牙配网,没有一键配网的设备存在。个人觉得小米在物联网的钻研跟其他物联网平台的投入不是一个等级的,这也是小米IOT生态链能发展这么大的原因之一,要不小米智能产品出货量这么大,像其他平台那么高的退货率一定把公司拖垮。



——2.强力推荐【设备热点配网技术】——

(设备热点配网流程图)


如果你要做新的Wifi产品,建议了解下设备热点配网技术,这是保证不增加成本的前提下,保证基本100%成功率的方法。也是小米米家大部分设备的配网方式。而且2019年又有新的技术突破,可以在体验上媲美一键配网技术。


【技术原理】

Wifi设备进入配网状态,实际是变成AP模式,也就是Wifi设备会有一个Wifi热点出来。手机通过连接上Wifi模块的热点,将路由器名字和密码直接发送给Wifi设备,同时从Wifi设备那边拿到MAC地址,然后发送到云端绑定。


【技术点】

1.由于是手机直接连接Wifi模块通讯,这个通讯方式配网绑定的过程都没有路由器参与所以没有路由器兼容性问题,对2.4G/5G同名路由器、同一场景下多个Wifi同名路由器等情况没有影响

2.由于手机直接获取MAC地址,所以绑定设备一定要物联网云平台做外网绑定的方式。否则会出现用户输错密码,Wifi设备绑定成功,但是Wifi设备一直无法上线的情况。

3.所以包括后面讲的其他配网方式,都是需要云服务器配网做绑定接口,否则就不是一个完整的Wifi配网解决方案。

4.苹果IOS11.0系统以下的手机,无法自动切换热点,需要用户进入Wifi列表页面,自动选择新热点。这是设备热点配网没有普及的原因之一,因为没有一键配网方便。

5.没有额外的条件和额外的成本增加



——3.土豪专用【蓝牙配网技术】——

(蓝牙配网流程图)


如果你是土豪,或者你的设备本身就有蓝牙,那可以直接用蓝牙通道来发送和接受配网绑定信息。


【技术原理】

跟设备热点方式一样,只是通讯方式从Wifi连接通讯变成用蓝牙通讯


【技术点】

1.同设备热点配网技术1.2.3点

2.配网成功率还要考虑设备蓝牙模块的手机兼容性。

3.可以直接发现设备,体验方便。

4.增加蓝牙成本

5.有兴趣买个小米的床头灯体验下就知道了~



如果你还想了解其他配网技术,可以接着看看。

——4.天猫精灵【零配技术】——


(零配流程图)


这个代表应用就是天猫精灵的音响了,Wifi设备在进入配网之后,跟天猫精灵说“找队友”或“添加智能设备”,天猫精灵就会将这个Wifi设备配网绑定。


【技术原理】

Wifi设备进入配网状态的时候,会将自己的MAC地址通过Sniffer报文的方式发送出去,这个时候路由器下面支持零配的设备(例如天猫精灵),就可以获取到需要配网设备的MAC地址,同时天猫精灵会将自己保存的路由器名字和密码通过Sniffer报文发给设备。同时等待设备连接上网络,进行外网绑定。


【技术点】

1.前提是路由器下面需要有一台支持零配的设备。如果没有,这个游戏就没的玩了。所以天猫精灵配网是比较合适,纯手机APP配网不太实际。

2.这个方式由于零配设备自己保存了路由器的名字和密码,所以减少了用户输入路由器密码的步骤。

3.总结:除了陪天猫精灵一起玩,手机APP配网目前看应用还不实际。



——5.奇葩【手机热点配网技术】——

(手机热点配网流程图)


这个配网方式我就看过阿里智能做过,叫AHA,部分设备在Smartconfig失败之后60s会进入AHA状态。


【技术原理】

将手机设置成一个特定名字和密码的Wifi热点,然后让设备自己连接手机,再发送和接受配网绑定信息。


【技术点】

1.实际应用过程,很多用户是不知道怎么设置自己手机热点名字,甚至都不知道怎么打开手机Wifi热点。

2.所以不适合消费类大规模推广。



——小众【路由器配网技术】——

(路由器配网流程图)


【技术原理】

有些路由器有WPS的按钮,按下这个按钮,同时触发Wifi设备进入WPS配网模式,就可以让Wifi设备连接上路由器了。至于怎么绑定设备嘛,估计还是得通过局域网发现。


【技术点】

1.有客户在用这种方式,但是都是些工业和商用场合。

2.消费类基本没看到这样用。

3.不是所有的路由器都有WPS功能,不适合消费类大规模推广。


——总结——

1.新产品不要用一键配网(Smartconfig),尽量选用设备热点配网(Soft AP)

2.剩下简单用一个表格总结下,方便大家对比


(各种Wifi配网技术适用场景优劣势对比)


——————

最后关于Wifi设备联网做几点解释和说明:


1.这篇文章讲的Wifi设备,都是使用串口Wifi模块方案的设备,这类设备没有显示屏和多余的按钮来输入Wifi路由器名字和密码,所以只能借助手机来完成Wifi配网工作。那些跑安卓、X86的设备,例如POS机这种设备本身有操作界面可以输入SSID和KEY,他们不存在配网的问题。


2.如果一个物联网方案商只谈Wifi配网的成功率,不谈服务器绑定的成功率,那一定是有问题的。因为实际产品体验是要用户绑定好wifi设备才能算成功,只讲一半的方案,就不是一个完整的物联网方案。所以一个完整的物联网配网方案,是需要云服务器一起参与的。


3.为方便理解,以上配网流程省略了一些信息,实际通讯交互内容会更多。例如发送MAC地址的时候,其实还会包括很多产品ID、产品秘钥等产品信息。这里简化内容,方便大家理解。


4.很多客户会问我有没有5G的Wifi模块,可以这样说,目前市面上暂时还没看到大规模量产的5G串口wifi模块,而且暂时也不建议使用,原因有几个:

a.很多客户找5G的模块的主要原因是国外客户用5G网络,我们2.4G的wifi模块配网失败,导致了客户退货,所以客户希望能找到5G的wifi模块来解决这个问题。但是如上文所说,解决配网问题的本质是要换配网方式,单纯增加5G频段也是解决不了问题的。

b.有5G频段的路由器都具备2.4G频段,而有2.4G频段的路由器不一定具备5G频段。所以单5G频段的模块,问题一定更多。

c.如果选择2.4G和5G双模的Wifi模块,这类模块必定成本增加很多,而且需要同时有两个天线,还要再增加额外的成本。而且2个频段在一起的模块,联网逻辑怎么处理,目前还没有看到量产的案例。

d.5G频段的wifi模块,因为5G的频率高,波长小,衍射能力差,导致5G的Wifi穿墙能力和通讯距离比2.4G要差,所以也不建议使用5G模块。大家如果家里有双频的路由器可以试试看,跟路由器之间隔1-2堵墙,手机可以明显看到5G的热点信号比2.4G要弱。

结论:暂时不建议使用5Gwifi模块



近期活动


RT-Thread线上活动


1、RT-Thread企业人才服务计划:只要加入该人才计划,即可对接睿赛德科技的人才库,得到人才的推荐和人才评估指导,且每年可以接受一次RT-Thread官方提供的OS专业培训。


扫码进入官网


2、6.17 SiFive&RT-Thread趣味开发竞赛,高含金量赛题助你挖掘自身潜能,,参与即得丰厚礼品,还能现场邂逅开发大牛获得指导


扫我参赛


#题外话# 喜欢RT-Thread不要忘了在GitHub上留下你的星哦,你的star对我们来说非常重要!链接地址:https://github.com/RT-Thread/rt-thread



你可以添加微信18917005679为好友,注明:公司+姓名,拉进 RT-Thread 官方微信交流

RT-Thread


让物联网终端的开发变得简单、快速,芯片的价值得到最大化发挥。Apache2.0协议,可免费在商业产品中使用,不需要公布源码,无潜在商业风险。

长按二维码,关注我们

点击“阅读原文”进入RT-Thread官网!

喜欢就点击“在看”

本文分享自微信公众号 - RTThread物联网操作系统(RTThread)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

8266station初始化和智能配网问题

8266station初始化和智能配网问题

代码思路是:

//station
    //Esp8266_Station_mode_init();
    wifi_set_opmode(STATION_MODE); //Station_mode


    //定时器任务创建
    Esp8266_Timer1_init(1000,1);    //1000ms, 1:重复定时
/** timer1 init **/
ICACHE_FLASH_ATTR
void Esp8266_Timer1_init(u32 mstime, u8 mode)
{
    os_timer_disarm(&K_Timer01); //先关闭定时器
    os_timer_setfn(&K_Timer01,(os_timer_func_t *)K_Timer01_cb,NULL);
    os_timer_arm(&K_Timer01, mstime, mode);

}
/* Timer1回调函数 */
ICACHE_FLASH_ATTR
void K_Timer01_cb(void)
{
    u8 K_WIFI_STA_Connect;            //表示wifi当前的连接状态
    struct ip_info ap_ip_info;
    u8 ESP8266_IP[4];
    u8 K_LED_Flash = 0;
    K_WIFI_STA_Connect = wifi_station_get_connect_status();

    if(K_WIFI_STA_Connect == STATION_GOT_IP)    //如果已经连接wifi
    {
        wifi_get_ip_info(STATION_IF,&ap_ip_info);
        ESP8266_IP[0] = ap_ip_info.ip.addr;
        ESP8266_IP[1] = ap_ip_info.ip.addr>>8;
        ESP8266_IP[2] = ap_ip_info.ip.addr>>16;
        ESP8266_IP[3] = ap_ip_info.ip.addr>>24;

        os_printf("ESP8266_IP:%d.%d.%d.%d\n",ESP8266_IP[0],ESP8266_IP[1],ESP8266_IP[2],ESP8266_IP[3]);

        //OLED_SHOW
        for(;K_LED_Flash <=5; K_LED_Flash++)
        {
            GPIO_OUTPUT_SET(GPIO_ID_PIN(4),(K_LED_Flash%2));
            delay_ms(100);
        }
        os_printf(" ESP8266 Connect Wifi success! \n");
        os_timer_disarm(&K_Timer01);//关闭定时器,


        ESP8266_SNTP_Init();        //连接服务器

    }
    else if(K_WIFI_STA_Connect == STATION_NO_AP_FOUND ||        //如果未能连接wifi,进入智能配网模式
            K_WIFI_STA_Connect == STATION_WRONG_PASSWORD ||
            K_WIFI_STA_Connect ==  STATION_CONNECT_FAIL )
    {
        os_timer_disarm(&K_Timer01);//关闭定时器, 进入配网模式

        //wifi_set_opmode(STATION_MODE);
        smartconfig_set_type(SC_TYPE_AIRKISS);
        smartconfig_start(ESP8266_Smartconfig_Cb);

    }
    else
        os_printf("uknow error\n");

    //ESP8266_NetConnect_Init();     //TCP

}

 

8266上电后进入配网模式.

1.先设置成station模式

2.然后进入1秒重复定时器

3.在定时器的回调函数中定义:

  如果flash中保存的wifi 可以连接就自动连接

  如果无法连接就进入配网模式.

 

那么问题来了,在家里测试的时候,很正常,但是在公司测试的时候,

8266的状态都不是 STATION_NO_AP_FOUND, STATION_NO_AP_FOUND, STATION_CONNECT_FAIL

而是IDLE模式. 百度无果. 

 

后来仔细想了想,好像并没有看到扫描wifi结束的提示

于是我有了一个大胆的猜测

1秒定时器,1秒定时器,如果没有进入配网模式,在一秒之后就会重新复位,那么 1秒真的就够了吗?

 

若然,把1秒定时改成3秒(或更多)就不会出现这种情况了.

Android: 设置wifi设备名

Android: 设置wifi设备名

wifi连接AP后,在AP端看到的设备名保存在prop属性

net.hostname 中,可以通过getprop net.hostname查看

通过setprop net.hostname修改

 

默认系统会给一个名字

frameworks/base/services/java/com/android/server/ConnectivityService.java中生成 :
        // setup our unique device name
        String id = Settings.Secure.getString(context.getContentResolver(),
               Settings.Secure.ANDROID_ID);
        if (id != null && id.length() > 0) {
           String name = new String("android_").concat(id);
           SystemProperties.set("net.hostname", name);
        }
 

 

如果需要自己定义,可以注释掉这一段,然后在system.prop中定义 net.hostname=xxxxxx

需要注意的是hostname不能带空格,不然dhcp那边会有问题

 

 


原文链接: http://blog.csdn.net/zmyde2010/article/details/6449785

ESA2GJK1DH1K微信小程序篇: 微信小程序APUConfig给WI-Fi模块配网并绑定设备,并通过MQTT控制设备

ESA2GJK1DH1K微信小程序篇: 微信小程序APUConfig给WI-Fi模块配网并绑定设备,并通过MQTT控制设备

 

 

 

前言(源码使用介绍在最后)

  

  一,微信小程序篇小程序下载(该源码为这节测试源代码)

 

  

 

  二.有多少人一直在期盼着小程序可以实现SmartConfig或者Airkiss的功能? 来吧!我的这种方式包您满意.

    注:APUConfig 是我自己取的名字(哈哈谁让这种方式,我是第一个在微信小程序上实现的),代表着 AP  UDP  Config

    绑定流程详细说明:

    APUConfig小程序端源码

          https://gitee.com/yang456/APUConfig.git

 

    

 

 

实现功能概要

 

  1.小程序使用APUConfig给Wi-Fi模块配网,并获取设备MAC等信息,然后通过MQTT控制绑定的Wi-Fi设备.

 

  2.演示视频:  https://www.bilibili.com/video/av74786875/

 

测试准备工作

一,下载单片机程序(请自行下载)

  

 

 

 二,打开微信小程序软件,导入本节工程

  

 

 

 

  

 

 

 

 

三,把小程序安装到手机运行

 

  

 

 

 四,调整波动开关位置,STM32和Wi-Fi 串口 通信

  

 

 

 

五,短接STM32的PB2和Wi-Fi模块的RST引脚(内部程序使用该引脚硬件复位Wi-Fi)

 

  

 

 

 

 

 

 

开始测试

一,点击小程序下方的添加设备按钮 

  

 

 

 

 

二,选择添加Wi-Fi设备

 

  

 

 

 

 

三,输入路由器密码(注:Wi-Fi名称自动获取,也可自己填写)

 

 

 

 

四.长按PB5大约4S,等待指示灯快闪,松开PB5,Wi-Fi模块进入配网状态

  

 

 

 五.点击小程序上的 "绑定设备"按钮,开始搜索设备,绑定成功,将自动跳转到主页面,显示绑定的Wi-Fi设备

  5.1 正在尝试连接Wi-Fi模块的热点

  

 

 

  5.2 连接上热点,正在和模块通信

 

  

 

 

  5.3 成功绑定设备

 

  

 

 

 

 

六.点击设备,进入控制页面,控制设备

 

  6.1 点击设备

 

  

 

 

  6.2 控制继电器吸合

 

      

 

 

 

 

  6.2 控制继电器断开

 

      

 

 

 

 

 

结语

希望能够为在用小程序做物联网开发的大家解决当前最大的烦心事!

知识是死的,人是活的!

希望大家不仅要有超强的学习能力,还需要有灵活运用知识的能力.

现在想想我挺感谢我的高中班主任 (朱兆同老师),是他让我开始了自学生涯,培养了这种能力.

师者,传道受业解惑者也.   传道:应该是首当其冲的吧!

 

绑定部分小程序端源码

 

https://gitee.com/yang456/APUConfig.git   (下载最新版本请在git下载)

 

小程序端APUConfig源码:

APUConfig.js

 

// pages/APUConfig/APUConfig.js
var util = require("../../utils/util.js");

var APUConfigStart = false;//是否在配网

var APUConfigconnectAPCount = 0;//连接热点的次数

var APUConfigSendUDPDataIntervalNumber = 0;//发送UDP数据的定时器编号

var APUConfigSendUDPDataCount = 0;//发送UDP数据的次数

var udp;

Page({

  /**
   * 页面的初始数据
   */
  data: {
    ssid: '''',
    password: ''''
  },
  // 获取路由器名称
  ssidInput: function (e) {
    this.data.ssid = e.detail.value;
  },
  // 获取输入密码 
  passwordInput: function (e) {
    this.data.password = e.detail.value;
  }, 
    /**
   * 成功连接热点
   */
  connectWifiSuccess: function(res)
  {
    var _this = this;
    udp = wx.createUDPSocket()//启用UDP
    udp.bind()

    wx.hideLoading();
    wx.showLoading({
      title: ''正在绑定''
    })

    udp.onListening(function (res) {
      console.log(''监听中...'')
      console.log(res)
    })


    //定时1S发送一次UDP数据
    try { clearInterval(APUConfigSendUDPDataIntervalNumber); } catch (e) { }

    APUConfigSendUDPDataIntervalNumber = setInterval(
      function () {
        udp.send
          ({
            address: ''192.168.4.1'',
            port: 5556,
            message: "{\"ssid\":" + "\"" + _this.data.ssid + "\"" + "\"pwd\":" + "\"" + _this.data.password + "\"" + "}"
          })
        APUConfigSendUDPDataCount = APUConfigSendUDPDataCount + 1;
        console.log(''发送数据: '' + "{\"ssid\":" + "\"" + _this.data.ssid + "\"" + "\"pwd\":" + "\"" + _this.data.password + "\"" + "}");

        if (APUConfigSendUDPDataCount>20)//发送了20次,还没绑定上
        {
          try { clearInterval(APUConfigSendUDPDataIntervalNumber); } catch (e) { }
          APUConfigSendUDPDataCount = 0;
          APUConfigconnectAPCount = 0;
          APUConfigStart = false;//
          udp.close();
          wx.hideLoading();
          wx.showModal({//弹出对话框
            title: ''绑定失败'',
            content: ''请重新尝试''
          })
        }
      },
      1000,
      "null");//启动定时器



    //UDP接收到消息
    udp.onMessage(function (res) {
      console.log(res)
      let str = util.newAb2Str(res.message);//接收消息
      console.log(''str==='' + str)

      //{ "mac": "dc:4f:22:10:b0:ce", "ip": "192.168.0.101" }

      try { clearInterval(APUConfigSendUDPDataIntervalNumber); } catch (e) { }
      try { udp.close(); } catch (e) { }//关闭UDP
      APUConfigSendUDPDataCount = 0;
      APUConfigconnectAPCount = 0;
      APUConfigStart = false;//复位所有变量
      wx.hideLoading();//关闭提示框


      if (str!=null)
      {
        let json = JSON.parse(str);//解析JSON数据
        if (json != null)
        {
          let mac = json.mac;
          let ip = json.ip;
          if (mac != null)
          {
            wx.reLaunch({
              url: ''../index/index?ClientID='' + mac + "&" + "IP=" + ip
            })
          }
        }
      }
    })

  },
    /**
  * 连接无线失败
  */
  connectWifiFail: function (res) 
  {
    var _this = this;
    
    if (APUConfigconnectAPCount<6)//尝试连接热点的次数
    {
      APUConfigconnectAPCount = APUConfigconnectAPCount + 1;
      console.log(''连接Wi-Fi: wifi_8266_bind'');
      wx.connectWifi//控制连接Wi-Fi无线信号
      ({
          SSID: "wifi_8266_bind",
        password: "11223344",
        success: _this.connectWifiSuccess,
        fail: _this.connectWifiFail
      })
    }
    else
    {
      APUConfigconnectAPCount = 0;
      APUConfigStart = false;//
      wx.hideLoading();
      wx.showModal({//弹出对话框
        title: ''绑定失败'',
        content: ''请重新尝试''
      })
    }

  },
  //点击绑定按钮
  BindClick: function () {

    var _this = this;

    if (_this.data.ssid.length == 0 || _this.data.password.length == 0) {
      wx.showModal({//弹出对话框
        title: ''提示'',
        content: ''Wi-Fi名称和密码不能为空''
      })
    } 
    else 
    {
      APUConfigStart = true;//开始配网
     
      //控制连接Wi-Fi无线信号
      wx.connectWifi
      ({
          SSID: "wifi_8266_bind",
        password: "11223344",
        success: _this.connectWifiSuccess,
        fail: _this.connectWifiFail
      })

    }
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    var _this = this;

    _this.GetWiFiSSID();//显示当前连接的Wi-Fi名称

    //启动网络状态监听
    wx.onNetworkStatusChange(function (res) 
    {
      console.log("绑定设备:网络改变" + res.isConnected + " " + res.networkType);
      if (res.networkType == "wifi")//当前连接的网络类型是WIFI
      {
        console.log("绑定设备:当前连接的网络类型是WIFI");
        if (!APUConfigStart)//没在配网状态
        {
          _this.GetWiFiSSID();
        }
      }
      else//其它网络
      {
        if (!APUConfigStart)//没在配网状态
        {
          _this.setData({//清空显示的wifi名称
            ssidValue: ""
          }) 
        }
      }
    })
  },
  /**
  * 获取链接的WIFI名称
  */
  GetWiFiSSID: function () {
    var _this = this;
    wx.startWifi({//启用WIFI功能
      success(res) {
        wx.getConnectedWifi//获取链接的Wi-Fi信息
          ({
            success(res) //获取到信息
            {
              _this.data.ssid = res.wifi.SSID;

              console.log("绑定设备:连接的Wi-Fi名称 " + _this.data.ssid);

              _this.setData({
                ssidValue: _this.data.ssid
              })
            },
            fail(res) {
            }
          })
      }
    })
  },
  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {
    this.GetWiFiSSID();//显示当前连接的Wi-Fi名称
  },
  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {
    try { clearInterval(APUConfigSendUDPDataIntervalNumber); } catch (e) { }
    try { udp.close(); } catch (e) { }
    APUConfigSendUDPDataCount = 0;
    APUConfigconnectAPCount = 0;
    APUConfigStart = false;//
    wx.hideLoading();
  },
  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },
  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  }
})
View Code

 

 

 APUConfig.json

{
  "usingComponents": {}
}

 

APUConfig.wxml

 

<!--pages/APUConfig/APUConfig.wxml-->


<view class="container"> 
  <!--提示-->


  <view class="hint"> 
    <text style="color: #545454; font-size:35rpx;">绑定设备前请确定完成以下步骤</text>

    <view> 
      <text style="color:#09bb07; font-size:35rpx;">①</text>
      <text style="font-size:35rpx;" space=''nbsp''>  请先连接自家路由器热点</text>
    </view>

    <view> 
      <text style="color:#09bb07; font-size:35rpx;">②</text>
      <text style="font-size:35rpx;" space=''nbsp''>  给设备上电</text>
    </view>
    
    <view> 
      <text style="color:#09bb07; font-size:35rpx;">③</text>
      <text style="font-size:35rpx;" space=''nbsp''>  长按"配置按键"大约3S,直至指示灯快闪</text>
    </view>
    
    <view> 
      <text style="color:#09bb07; font-size:35rpx;">④</text>
      <text style="font-size:35rpx;" space=''nbsp''>  输入路由器密码,点击“添加设备”按钮</text>
    </view>
    
    <view> 
      <text style="color:#09bb07; font-size:35rpx;" >⑥</text>
      <text style="font-size:35rpx;" space=''nbsp''>  绑定成功后,软件自动跳转到设备页面</text>
    </view>

  </view> 


  <view class="login-from"> 
    <!--WiFi名称-->
    <view class="inputView"> 
      <label class="loginLab">WiFi名称:</label> 
      <input class="inputText" placeholder="请输入路由器热点" bindinput="ssidInput" value="{{ssidValue}}"/> 
    </view> 
    <view class="line"></view> 
    
    <!--WiFi密码-->
    <view class="inputView"> 
      <label class="loginLab">WiFi密码:</label> 
      <input class="inputText" placeholder="请输入密码" bindinput="passwordInput"/> 
    </view> 
    
    <!--按钮-->
    <view class="BindClickView"> 
      <button class="BindClick" type="primary"  bindtap="BindClick">绑定设备</button> 
    </view> 
  </view> 
</view>
View Code

 

 

 

 

 APUConfig.WXSS

 

/* pages/APUConfig/APUConfig.wxss */
page{ 
 height: 100%; 
} 
  
.container { 
 height: 100%; 
 display: flex; 
 flex-direction: column; 
 padding: 0; 
 box-sizing: border-box; 
 background-color: #f2f2f2
} 
  
/*提示信息*/
.hint {
  display: flex; 
  flex-direction:  column;
  margin-top: 10rpx
}

/*表单内容*/
.login-from { 
 margin-top: 50px; 
 width: 90%;
 flex: auto; 
 height:100%; 
} 
  
.inputView { 
 display: flex; 
 flex-direction:  row; 
 background-color: #fff; 
} 
  
/*Wi-Fi名称和密码两个字*/
.loginLab { 
  margin-left: 10px;
  margin-top: 15px;
  margin-bottom: 15px;
  color: #545454; 
  font-size: 16px
} 

.inputText { 
 margin-left: 10px;
 text-align: left; 
 margin-top: 15px; 
 color:  black; 
 font-size: 16px
} 
  
.line { 
 width: 100%; 
 height: 1px; 
 background-color: #cccccc; 
 margin-top: 1px; 
} 
/*按钮*/
.BindClickView { 
 width: 100%; 
 height: auto; 
 background-color: #f2f2f2; 
 margin-top: 0px; 
 margin-bottom: 0px; 
 padding-bottom: 0px; 
} 
  
.BindClick { 
 width: 95%; 
 margin-top: 35px; 
}
View Code

 

util.js
const formatTime = date => {
  const year = date.getFullYear()
  const month = date.getMonth() + 1
  const day = date.getDate()
  const hour = date.getHours()
  const minute = date.getMinutes()
  const second = date.getSeconds()

  return [year, month, day].map(formatNumber).join(''/'') + '' '' + [hour, minute, second].map(formatNumber).join('':'')
}

const formatNumber = n => {
  n = n.toString()
  return n[1] ? n : ''0'' + n
}


// util.newAb2Str代码
var newAb2Str =   function newAb2Str(arrayBuffer) {
  let unit8Arr = new Uint8Array(arrayBuffer);
  let encodedString = String.fromCharCode.apply(null, unit8Arr),
    decodedString = decodeURIComponent(escape((encodedString)));//没有这一步中文会乱码
  return decodedString;
}


module.exports = {
  formatTime: formatTime,
  newAb2Str: newAb2Str
}
View Code

 

单片机端APUConfig,Wi-Fi配置流程

/**
  ******************************************************************************
  * @author  yang feng wu 
  * @version V1.0.0
  * @date    2019/10/12
  * @brief   配置8266
  ******************************************************************************
    一,使用说明:指示灯(PC13)
        1,把以下程序放在1ms定时器中断中
            SmartConfigCnt++;
            if(SmartConfigFlage)//配网状态,指示灯闪耀
            {
                Config8266LedDelay++;
                if(Config8266LedDelay>100)
                {
                    Config8266LedDelay=0;
                    SmartConfigPinOut = ~SmartConfigPinOut;
                }
            }
            else
            {
                Config8266LedDelay=0;
            }
        
        2,调用使用,建议使用一个按钮控制
            
            if(SmartConfig())//配网成功
            {
                //执行操作
            }
  ******************************************************************************
    APUConfig配网绑定流程
    设备端
    1.获取设备MAC XX:XX:XX:XX:XX:XX
    2.控制WIFI发出固定无线网  名称:wifi_8266_bind    密码:11223344  
    3.UDP 监听固定端口5556
    4.等待接收客户端的消息. 消息格式{"ssid":"qqqqq","pwd":"11223344"} 
    5.提取路由器名称和密码,连接路由器
    6.获取链接路由器后分的的IP. 假设是192.168.10.2 以防后期实现局域网通信备用 
    7.UDP发送数据,{"mac":"XX:XX:XX:XX:XX:XX","ip":"192.168.10.2"}
    
    APP/小程序/上位机
    1.提示用户连接自己的路由器,长按设备按钮使得设备进入UDP监听状态,提示用户输入路由器密码
    2.用户点击绑定设备 , 控制手机尝试连接 名称为 wifi_8266_bind 的无线 (内部控制)
    3.成功连接无线,往192.168.4.1:5556 UDP发送路由器信息,1S 1次
    4.接收到 {"mac":"XX:XX:XX:XX:XX:XX","ip":"192.168.10.2"}
    5.绑定成功
    8.完
  */

#define CONFIG8266_C_
#include "include.h"

char SmartConfigFlage = 0;//是不是在配网
u32  SmartConfigCnt = 0;//配网连接路由器延时使用
char SmartConfigSuccess = 0;//是否配网成功
u32  Config8266Delay=0;//执行Config8266函数内部所需延时
u32  Config8266LedDelay=0;//配置8266指示灯闪耀


char ThisSSID[32]="";//记录路由器名称
char ThisPWD[64]="";//记录密码
char ThisMAC[18]="";//记录设备MAC
char ThisIP[21]="";//记录设备连接路由器分得的IP


/**
* @brief  启用APUConfig 给WIFI配网
* @ warn  None
* @param  None
* @param  None
* @param  None
* @param  None
* @retval 1:成功
* @example 
**/
char APUConfig(void)
{
  u32 delay=0,Flage=0;
    SmartConfigPinOut = 1;
    SmartConfigSuccess = 0;
    Rst8266();
    
    if(ConfigModuleBlock("+++","+++",NULL))//退出透传
    {
        if(ConfigModuleBlock("AT+RESTORE\r\n","ready",NULL))//恢复出厂设置
        {
            if(ConfigModuleBlock("AT+CWMODE_DEF=3\r\n","OK",NULL))//模式3
            {
                if(ConfigModuleBlock("AT+CIPSTAMAC_CUR?\r\n","MAC_CUR",NULL))//MAC
                {
                    MainString = StrBetwString(Usart1ReadBuff,"MAC_CUR:\"","\"");//得到MAC
    
                    if(strlen(MainString) ==17)
                    {
                        memset(ThisMAC,0,sizeof(ThisMAC));
                        memcpy(ThisMAC,MainString,17);
                    }
                    else {goto end;}
                    cStringRestore();
                    
                    if(ConfigModuleBlock("AT+CWSAP_DEF=\"wifi_8266_bind\",\"11223344\",11,4,4\r\n","OK",NULL))//配置发出的无线
                    {
                        if(ConfigModuleBlock("AT+CIPSTART=\"UDP\",\"192.168.4.2\",5555,5556,2\r\n","OK",NULL))//配置UDP
                        {
                            SmartConfigCnt = 0;
                            while(1)
                            {
                                //{"ssid":"qqqqq","pwd":"11223344"}
                                //{"mac":"XX:XX:XX:XX:XX:XX","ip":"192.168.10.2"}
                                //*StrBetwString(char *Str,char *StrBegin,char *StrEnd)
                                IWDG_Feed();//喂狗
                                if(Usart1ReadFlage==1)
                                {
                                    Usart1ReadFlage=0;
                                    
                                    MainString = StrBetwString(Usart1ReadBuff,"\"ssid\":\"","\"");//获取ssid
                                    if(MainString!=NULL) 
                                    {
                                        memset(ThisSSID,0,sizeof(ThisSSID));
                                        sprintf(ThisSSID,"%s",MainString);
                                        cStringRestore();
                                        
                                        MainString = StrBetwString(Usart1ReadBuff,"\"pwd\":\"","\"");//获取pwd
                                        if(MainString!=NULL) 
                                        {
                                            memset(ThisPWD,0,sizeof(ThisPWD));
                                            sprintf(ThisPWD,"%s",MainString);
                                            cStringRestore();
                                            break;
                                        }
                                        else {goto end;}
                                    }
                                    else {goto end;}
                                }
                                
                                if(SmartConfigCnt>60000) {goto end;}//60S超时
                            }

                            if(ConfigModuleBlock("AT+CWAUTOCONN=1\r\n","OK",NULL))//自动连接路由器
                            {
                                memset(MainBuffer,0,sizeof(MainBuffer));
                                sprintf(MainBuffer,"AT+CWJAP_DEF=\"%s\",\"%s\"\r\n",ThisSSID,ThisPWD);
                                if(ConfigModuleBlock(MainBuffer,"WIFI GOT IP",NULL))//设置连接的路由器
                                {
                                    Flage = 1;//配网成功
                                    SmartConfigSuccess=1;
                                    
                                    if(ConfigModuleBlock("AT+CIPSTA_CUR?\r\n","CIPSTA_CUR:ip",NULL))//获取路由器分得的IP
                                    {
                                        MainString = StrBetwString(Usart1ReadBuff,"CUR:ip:\"","\"");//得到路由器分得的IP
                                        if(MainString != NULL)
                                        {
                                            memset(ThisIP,0,sizeof(ThisIP));
                                            memcpy(ThisIP,MainString,strlen(MainString));
                                            
                                            split(MainString,".",NULL,&MainLen);//XXX.XXX.XXX.XXX
                                            
                                            if(MainLen == 4)
                                            {
                                                MainLen = sprintf(MainBuffer,"{\"mac\":\"%s\",\"ip\":\"%s\"}",ThisMAC,ThisIP);
                                                MainLen = sprintf(MainBuffer,"AT+CIPSEND=%d\r\n",MainLen);

                                                if(ConfigModuleBlock(MainBuffer,">",NULL))//准备向UDP客户端发送消息
                                                {
                                                    memset(MainBuffer,0,sizeof(MainBuffer));
                                                    MainLen = sprintf(MainBuffer,"{\"mac\":\"%s\",\"ip\":\"%s\"}",ThisMAC,ThisIP);
                                                    printf("%s",MainBuffer);
                                                    
                                                    SmartConfigCnt = 0;
                                                    while(SmartConfigCnt<3000)
                                                    {
                                                        IWDG_Feed();//喂狗
                                                    }
                                                    
                                                }else {goto end;}
                                            }else {goto end;}
                                        }else {goto end;}
                                        cStringRestore();
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    end:
    if(ConfigModuleBlock("AT+CWMODE_DEF=1\r\n","OK",NULL))//模式1
    {}
    Rst8266();//复位
    SmartConfigFlage = 0;
    return Flage;
}
View Code

 

 

 

1.把文件导入工程

     

 

 

 

 

2.请在util.js添加如下代码

  

 

 

 

 

使用
1.跳转到 APUConfig 函数,请在自己需要的地方自行填写

  

 

 

 

 

2.绑定完成,跳转到的页面(请根据自己的设置跳转路径)

  

 

 

 

 

3.在跳转的页面获取绑定的数据

  

 

Gitee 推荐 | 简单易用 Arduino 配网库 BGWiFiConfig

Gitee 推荐 | 简单易用 Arduino 配网库 BGWiFiConfig

一个为esp8266和esp32设计的简单易用Arduino配网库,可通过api配置WiFi网络,支持GET和POST请求配置;可通过微信小程序配网(小程序名:配网库);可通过默认网页配置WiFi网络;可自定义配网页面。

 

今天关于Wifi设备配网问题wifi设备配网的原理的讲解已经结束,谢谢您的阅读,如果想了解更多关于8266station初始化和智能配网问题、Android: 设置wifi设备名、ESA2GJK1DH1K微信小程序篇: 微信小程序APUConfig给WI-Fi模块配网并绑定设备,并通过MQTT控制设备、Gitee 推荐 | 简单易用 Arduino 配网库 BGWiFiConfig的相关知识,请在本站搜索。

本文标签:

上一篇直播预告:WiFi 配网的N种姿势(wifi配网过程)

下一篇基于RT-Thread在STM32H7上移植LWIP(一)(rtthread移植到stm32)