查看: 2973|回复: 1

ESP8266学习笔记更新--电子灭蚊器

[复制链接]
  • TA的每日心情
    慵懒
    2017-3-10 15:15
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    发表于 2017-3-13 16:05:31 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 开发快 于 2017-3-13 16:11 编辑

    其实技术这东西很多时候是互通的,这一个小制作其实就是简单的IO口输入输出实验;我把模块放在这个灭蚊器上面就能远程控制灭蚊器,如果我把它放在插座上面,就是远程智能插座,给它一个通用点的名字,就是远程开关;
        代码上面是很简单的,虽然后面写的有点多,不过是为了让大家知道我做了些什么,总结起来就是IO输入输出,然后一些简单的判断语句,看的头疼的朋友其实也没必要细究,直接拿固件用就是了;
        内容的话,ESP的底层固件+上位机的更新+安卓APP的编写;虽然是个简单的东西,但毕竟我是学习用的,所以尽可能的多加点东西,对自己有好处。

    本制作提供视频材料,大家可以去优酷看我的使用视频。http://v.youku.com/v_show/id_XMjUyNTcxNjg2OA==.html

    1.1材料准备(声明:本人不打广告,所给全部链接只是我的淘宝记录,大家没必要跟我一样,开心就好)
       电子灭蚊器:(没什么特别的要求,就是大一点,毕竟要加点东西到里面去,空间小了不好.蛮便宜的,22块钱)
      供电方式是USB供电,这种很适合我,因为直接插在电脑上就能使用,方便我调试,就算不是也没事,用万用表找到一个5V的电压出口就好了,主要是给芯片供电;
      继电器模块(只要一路就好了,小一点)



    整个成本其实很低的,我买的灭蚊器是比较便宜的,高级一点的其实也无所谓,一样可以用这种方式(继电器控制电源通断);



      小e体验板(只要这三个就好了,没什么其他的东西了)


    当然也可以直接用开发板搞起,不过我就这么一个,舍不得。
    之前一直有人问这体验板和开发板有什么不同,这要我怎么回答。。。长得不同呗,其实这两主要部分就是一个玩意;不过使用开发板上面的模块需要买个降压模块,3.3V的,电路上出来的是5V,不能直接用,如果是体验板就不要了,直接用。如果有的朋友比较浪,直接一个开发板搭上去,我也无话可说了,跟体验板一样,直接使用就好了。
    1.2硬件搭建
    啥也不说,把灭蚊器拆开看一下;
    看一下电路部分吧

    恩,好简单的玩意,就是点个灯转个风扇的事,啥也不说了,直接把电路搭好吧;
    可能大家看电路图容易理解一点,好吧,我花几分钟画个简单的原理图;
    可以看到,原理其实很简单就是把电源引出到继电器上面,然后让体验板能够直接控制电源的通断,说的再直白一点,就是给产品引出一个新的开关,只不过这个开关我能使用软件控制而已。

    最后来一张做完的图片,里面都看不到了,跟买来的时候一模一样,但是却能让我自由控制了;

    这就是基本的硬件结构了,下面介绍软件的处理

    1.3 ESP8266固件编写
    首先确定一下我需要什么功能:
    1.定时开关设备,健忘症必备,少不了的东西;
    2.局域网控制,虽然是在家里,走两步就可以了,但是我比较懒,有时候在床上,懒得动;
    3.开关状态反馈,**作之前好歹要知道现在设备是工作还是休息的吧,少不了;
    4.微信控制,反正有现成的东西,不要我白不要,搞起;
    5.APP控制,我是不太喜欢微信点来点去的,做个APP,果断直接,必须支持广域网,局域网随便了,反正网上那么多UDP/TCP的APP,看心情吧;
    6.上位机控制,我的老本行,少不了,局域网和广域网都要做,作为一个程序员,离不开电脑,手机我还没那么依赖;
    7.一键配置网络肯定不能少,恩,airkiss和smartconfig少不了;
    差不多就这些了,现在可以搞起了。图个快捷简单,直接在开发快源码上做手脚。

    1.3.1 IO口的驱动
    避免冲突,找个开发板没使用的IO口来搞事情,就GPIO8了,没有为什么。改代码其实蛮简单了,就把一些不要的函数直接干掉,加上自己的就好了;
    先做个无关紧要的事情,改下版本号:
    #define SOFTWARE_VERSION                                  "小白-电子灭蚊器源码"

    第一个函数:本来是获取工作模式的,**作个继电器而已,不需要那么多东西,直接删掉,使用WORK_MODE_RGB模式
    user_get_work_mode(et_uint32 *mode)
    {
            *mode = WORK_MODE_RGB;

            return RETURN_OK;
    }
    第二个函数:user_init_work_mode(et_uint32 mode, et_uchar fac_norm_mode)
                    虽然原本函数删了再说
    user_init_work_mode(et_uint32 mode, et_uchar fac_norm_mode)
    {
            PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U,FUNC_GPIO12);

            return RETURN_OK;
    }

    看过我之前的文章的朋友都知道,我习惯一边写代码,一边写文档;所以里面会有一些测试的东西,大家忽略不计,我做了注释;

    初始化就这么完了,定义一下对GPIO的操作;
    /*开关继电器的操作*/
    #define my_gpio  GPIO_INPUT_GET(GPIO_ID_PIN(8))
    #define MY_ON    GPIO_OUTPUT_SET(GPIO_ID_PIN(8), 1)
    #define MY_OFF   GPIO_OUTPUT_SET(GPIO_ID_PIN(8), 0)

    这里我要处理下串口的内容,做个数据透传,不然我数据发没发,发了些啥玩意都不知道,官方源码里面有现成的,不过我用的不是很顺手,改一下,反正我自己写过
    /********************************************
    * 函数名:uart0_tx_buffer(uint8 *buf, uint16 len)
    * 函数用途:发送数组
    * 参数1:buf
    * 参数1作用:数组指针
    * 参数1:len
    * 参数1作用:数组长度
    * 修改时间:2017-1-14
    * 修改人:小白
    ********************************************/
    void ICACHE_FLASH_ATTR
    uart0_tx_buffer(uint8 *buf, uint16 len)
    {
      uint16 i;

      for (i = 0; i < len; i++)
      {
        uart_tx_one_char(UART0, buf);
      }
    }

    /********************************************
    * 函数名:uart0_tx_SendStr(uint8 *buf)
    * 函数用途:发送字符串
    * 参数:buf
    * 参数作用:数组指针
    * 修改时间:2017-1-14
    * 修改人:小白
    ********************************************/
    void ICACHE_FLASH_ATTR
    uart0_tx_SendStr(uint8 *buf)
    {
       while(*buf!='\0')
       {
              uart0_tx_buffer(buf++,1);
       }
    }

    /********************************************
    * 函数名:uart0_tx_SendNum(uint32 num)
    * 函数用途:发送整型数
    * 参数:num
    * 参数作用:要发送的数
    * 修改时间:2017-1-14
    * 修改人:小白
    ********************************************/
    void ICACHE_FLASH_ATTR
    uart0_tx_SendNum(uint32 num)
    {
            uint8   buf[10];
            uint32  numTmp = num;
            int8   i=0;
            while(numTmp)
            {
              numTmp=numTmp/10;
              i++;
            }
            buf[i--]='\0';
            for(;i>=0;i--)
            {
              buf=num%10 + '0';
              num/=10;
            }
            uart0_tx_SendStr(buf);
    }
    这一段大家看不明白可以看我的学习笔记串口发送的内容,或者干脆别理,反正跟正常功能不挂钩,至于串口调试怎么做的,我就不说了,直接上ILINK远程控制的代码,这一部分是通用的,手机、上位机、微信远程控制都是这一段控制代码,很简单的if判断;
    对ILINK接收回调函数的处理,这里面东西蛮多不要的,删了删了~~~,然后改一下,具体的我就不说了,上源码。目的是实现微信、app、上位机的远程控制.
    et_int32 parse_msg_from_mqtt(et_uchar *msg_buf, et_int32 data_len)
    {
            et_int32 i, pos=0, rc = -1;
            et_uchar cmd, type, bcc;
            et_int32 len, seq;
            et_uint16 gb_code=0;
            WORK_MODE_T mode;
            os_printf("\r\n数据内容:\r\n");
            uart0_tx_SendStr(msg_buf);
            char *my_OFF="OFF";
            char *my_ON="ON";
            if(strcmp(msg_buf,my_OFF)==0) MY_OFF;
            else if(strcmp(msg_buf,my_ON)==0) MY_ON;
            else
            {
                    if(msg_buf[pos] != 0xFF ||msg_buf[pos + 1] != 0xFF)
                    {
                            os_printf("parse packet head error\n");
                            return rc;
                    }
                    pos += 2;
                    len = (msg_buf[pos] << 8) | msg_buf[pos + 1];
                    if(len < 3 || len != data_len - 2 - 2)
                    {
                            os_printf("parse packet length error\n");
                            return rc;
                    }
                    bcc = check_sum(&msg_buf[pos], len + 2 - 1);
                    if(bcc != msg_buf[data_len - 1])
                    {
                            msg.len = ack_to_mqtt(msg_buf, msg.buf, ACK_BCC_ERROR);
                            os_printf("bcc error\n");
                            rc = et_chat_to(g_cloud_handle,msg.buf, msg.len, g_user_id, SEND_TO_ALL);
                            return rc;
                    }
                    pos += 2;
                    cmd = msg_buf[pos];
                    pos += 1;
                    seq += msg_buf[pos];
                    pos += 1;
                    type = msg_buf[pos];
                    pos += 1;
                    mode = user_get_run_mode();    //get board mode from adc
                    switch(cmd)
                    {
                            case CMD_CONTROL:
                            {
                                    switch(type)
                                    {
                                            case TYPE_RGB_LIGHT_DEV:
                                            {
                                                    if(mode == WORK_MODE_RGB)
                                                    {   //code undefine
                                                            et_uchar red;
                                                            et_uchar gre;
                                                            et_uchar blu;
                                                            red = msg_buf[pos];
                                                            pos += 1;
                                                            gre = msg_buf[pos];
                                                            pos += 1;
                                                            blu = msg_buf[pos];
                                                            if(red==0&&gre==0&&blu==0)
                                                            {
                                                                     MY_ON    ;
                                                            }
                                                            else{
                                                                     MY_OFF   ;
                                                            }
                                                             RGB_light_set_color(red, gre, blu);      //set rgb color
                                                            msg.len = ack_to_mqtt(msg_buf, msg.buf, ACK_SUCCESS);
                                                            rc = msg.len;
                                                    }
                                                    else
                                                    {
                                                            printf("mode error, mode = %u\n", mode);
                                                            msg.len = ack_to_mqtt(msg_buf, msg.buf, ACK_MODE_ERR);
                                                            rc = msg.len;
                                                    }
                                            }
                                                    break;
                                            default:
                                                    break;
                                    }
                            }
                                    break;
                            default:
                                    msg.len = ack_to_mqtt(msg_buf, msg.buf, ACK_CMD_ILLIGAL);
                                    rc = msg.len;
                                    break;
                    }
            }
            bzero(msg_buf,sizeof(msg_buf));
    //        rc = et_chat_to(g_cloud_handle,msg.buf, msg.len, g_user_id, SEND_TO_CLOUD_FIRST);
            return rc;
    }
    好像还是蛮多,稍微说两句,不想看的朋友跳过吧,这里首先判断是不是我自己定义的操作OFF/ON。是的话,就操作继电器,不是的话,就判断是不是微信来的数据,不是的话就啥也不干,是的话就操作继电器,思路还是蛮简单的吧。

    这里提供官方的局域网传输控制代码,没做什么改动,就是在这个函数里面加上判断函数,就可以了:

    #include "driver/gpio.h"
    /*开关继电器的操作*/
    #define my_gpio  GPIO_INPUT_GET(GPIO_ID_PIN(12))
    #define MY_ON    GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 1)
    #define MY_OFF   GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 0)
    extern et_cloud_handle g_cloud_handle;

    et_int32 et_socket_recv_from(et_socket_t socket, et_uint8 *recv_buf, et_uint32 buf_len, et_addr_info_t *remote_info,
                                        et_uint32 time_out_ms)
    {
            et_int32 rc;
            struct sockaddr_in addr;
            et_int32 addr_len = sizeof(struct sockaddr_in);
            fd_set read_set;
            struct timeval timer = {0, 0};

            time_out_ms = 200;
            timer.tv_sec = time_out_ms/1000;
            timer.tv_usec = time_out_ms%1000*1000;

            FD_ZERO(&read_set);
            FD_SET(socket, &read_set);
            if((rc = select(socket+1, &read_set, NULL, NULL, &timer)) > 0)
            {
                    rc = recvfrom(socket, recv_buf, buf_len, 0, (struct sockaddr*)&addr,&addr_len);
                    et_strncpy(remote_info->ip_str, inet_ntoa(addr.sin_addr.s_addr), sizeof(remote_info->ip_str));
                    remote_info->port = ntohs(addr.sin_port);
                    printf("broadcast 0x%x:0x%x\n", addr.sin_addr.s_addr, addr.sin_port);
                    uart0_tx_SendStr(recv_buf);
                    char *my_OFF="OFF";
                    char *my_ON="ON";
                    char *my_get="GET";

                    if(strcmp(recv_buf,my_OFF)==0)
                    {
                            MY_OFF;
                            rc = et_chat_to(g_cloud_handle,"设备正在运行", 10, 0, SEND_TO_LOCAL);
                    }
                    else if(strcmp(recv_buf,my_ON)==0)
                    {
                            MY_ON;
                            rc = et_chat_to(g_cloud_handle,"设备已经关闭", 10, 0, SEND_TO_LOCAL);
                    }
                    else if(strcmp(recv_buf,my_get)==0)
                    {
                            if(my_gpio==0)
                                    rc = et_chat_to(g_cloud_handle,"设备正在运行", 10, 0, SEND_TO_LOCAL);
                            else if(my_gpio==1)
                                    rc = et_chat_to(g_cloud_handle,"设备已经关闭", 10, 0, SEND_TO_LOCAL);
                    }

            }
            else if(rc < 0 && !(errno == 0 || errno == EINTR || errno == EAGAIN || errno == EINPROGRESS || errno == EWOULDBLOCK))        ///< Socket error
            {
                    printf("recv from failed\n");
                    return ET_FAILURE;
            }
            bzero(recv_buf,sizeof(recv_buf));
            return rc;
    }
    #define ET_LISTEN_PORT_UDP_BROAD  2073  ///< UDP广播端口

    当然也可以用自己的,如下:
    if (wifi_station_get_connect_status() == STATION_GOT_IP && ipconfig.ip.addr != 0)
            {
                    os_printf("got ip !!! \r\n");
                    InterNet_InitUDP("192.168.31.225",8888,8033);
                    if (user_main_start_flag == 0)
                    {
                            user_main_start_flag = 1;
                            xTaskCreate(et_user_main, "et_user_main", 1024, NULL, 2, NULL);
                    }
                    wifi_reconnect_start_flag = 1;
            }
    static void ICACHE_FLASH_ATTR
    InterNet_Receive(void *arg, char *pdata, unsigned short len)
    {
            char *my_OFF="OFF";
            char *my_ON="ON";
            char *my_get="GET";
            if(strcmp(pdata,my_OFF)==0)
            {
                    MY_OFF;
                    InterNet_UDP_SendData("192.168.31.199", 8266,"开关已打开",10);
            }
            else if(strcmp(pdata,my_ON)==0)
            {
                    MY_ON;
                    InterNet_UDP_SendData("192.168.31.199", 8266,"开关已关闭",10);
            }
            else if(strcmp(pdata,my_get)==0)
            {
                    if(my_gpio==0)
                                    InterNet_UDP_SendData("192.168.31.199", 8266,"OFF",3);
                    else if(my_gpio==1)
                                    InterNet_UDP_SendData("192.168.31.199", 8266,"ON",2);
            }
    }
    那么esp这边的代码就可以了,剩下的就是手机APP和上位机软件的设计了,大家可以直接下我的这个代码做测试,使用步骤如下:
    1.首先下载一下固件:关于环境搭建,大家可以参考我之前的内容或者在官网找一下
    这里说个小技巧,打英文是不是很烦,大家可以使用tab键,直接自动补全
    成功编译了,更新固件就好了;
    注意:不知道大家有没有遇到过这个情况,不管怎么样都进入不了工厂模式;我后来发现是我把flash size选错了,尴尬癌都有了
    考虑到是作为一个实际的制作,我把代码更新的具体步骤写一下,如果大家感觉说的不清楚,可以去官网找官方的烧录步骤,一样的,或者QQ群留言我也行,随意啦,搞过一两次,以后都是分分钟的事情了。
    1.首先是保证板子有个正确的UID/APPKEY,这里可以使用fac.bin文件,我的附件里面提供了这些文件;
    时间是2017/2/22,,防止大家搞错,我把Bin文件拿出来改了个名字叫电子灭蚊器,下图是大家可能用到的 所有文件
    虽然有几个固件可以不要,但是也还是下载一次,反正不费事;
    下载完了,用串口打印,看一下是不是正常进入工厂模式
    可能不清楚,最后那个字符串是:
    run in factory mode
    有这个字符串就对了,因为我刷了工厂模式,然后刷UID/APPKEY。
    1.使用开发快提供的UID烧写软件,把自己的UID什么的烧进去,我就不涂掉这里面的UID/APPKEY信息了,方便大家理解,大家最好用自己的UID/APPKEY信息,这是相当于你的QQ账号和密码的东西,我反正是DIY玩家,告诉你们也无所谓,各位自己搞还是不要泄露这个信息的好;

    先连接好串口,然后输入自己的信息;
    这种软件使用应该是蛮简单的,之前有个事情,就是好多朋友连接微信的时候,或者输入UID的时候,填的100;这是错误的,正确的UID是有34位的,大家可以看看我学习笔记的第六章第二节,或者官方论坛找UID烧录的帖子看看。
    2.然后断电重启看串口打印的情况
    数据内容
    software version:小白-电子灭蚊器源码
    run in normal mode

    Local_port:8033ssid=2.4G鐨刉IFI锛堟瘮杈冨揩锛?
    mode : sta(5c:cf:7f:d0:e2:cf)
    add if0
    f r0, scandone
    state: 0 -> 2 (b0)
    state: 2 -> 3 (0)
    state: 3 -> 5 (10)
    add 0
    aid 4
    pm open phy_2,type:2 0 0
    cnt

    connected with 2.4G鐨刉IFI锛堟瘮杈冨揩锛? channel 3
    dhcp client start...
    et connect to ssid 2.4G鐨刉IFI锛堟瘮杈冨揩锛? channel 3
    ip:192.168.31.225,mask:255.255.255.0,gw:192.168.31.1
    got ip !!!

    ET U-SDK var3.0.0.6
    uid : Fc5wGsTuvumomVom6wSQTwUVj3eWa5oUQq
    appkey : 4d66c9c0-8082-444637
    secretkey : 3c2cd461698ed83099630174f5ddf340
    server information lb.kaifakuai.com : 8085
    Local Ip 192.168.31.225
    You are connect:0x1

    数据包括,现在已经连接上我的WIFI,显示这个代码的版本号,显示ESP8266在局域网的IP,显示主机的IP.....

    1.4上位机测试
    1.上位机也修改下,让它按个按键就能控制我的设备。不做太细致的优化,只实现需要的功能;
    打开我的上位机(广域网通信的设置)

    图片对应信息:

    1.ESP上面的UID信息
    2.进开发快申请一个自己的UID/APPKEY
    3.登录
    登录成功如下所示:此时可以对体验版进行远程控制(广域网);

    2.局域网设置
    确定好端口和IP地址,通信方式是UDP。代码设置服务端端口:8266,ESP端口:8033。需要根据本机IP修改代码里面的IP信息,推荐一个软件;



    file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps28EE.tmp.jpg
    [size=10.5000pt][size=10.5000pt]file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps28FF.tmp.jpg
    IP获取方式很多,我就不一一说了,实在不会就问度娘吧;现在局域网也配置好了
    [size=10.5000pt][size=10.5000pt]
    3.上位机使用
    局域网控制:在上面第二步设置好以后,可实现局域网控制。
    [size=10.5000pt][size=10.5000pt]
    [size=10.5000pt][size=10.5000pt]广域网控制:在上面第一步成功之后,可实现广域网控制

    定时开关设置:
    需要设置定时的时间,然后启动定时功能,如果要远程控制就控制方式选择远程控制,软件更新时间是10s一个周期

    1.5 安卓APP测试
    这个小项目支持smartconfigairkiss两种配网方式
    Smartconfig软件:

    或者官网下载也行:
    file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2913.tmp.jpg

    首先来试试安卓的局域网控制:一般的UDP/TCP安卓软件,网上一大堆,直接搞一个就好了,这没什么好讲的
    [size=10.5000pt][size=10.5000pt]
    [size=10.5000pt][size=10.5000pt]
    file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2914.tmp.jpg
    [size=10.5000pt]介绍一下我修改好的远程控制的APP,连接服务器的东西必须有,然后就是三个按键,控制我的设备。

    在连接之前,我要去申请一个APPKEY/UID;
    [size=10.5000pt][size=10.5000pt][size=10.5000pt]
    [size=10.5000pt][size=10.5000pt][size=10.5000pt]
    file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2915.tmp.jpg
    注意看我的平台类型是安卓,上位机也有它的平台类型
    [size=10.5000pt][size=10.5000pt][size=10.5000pt]
    然后手机端登录上去
    [size=10.5000pt][size=10.5000pt][size=10.5000pt]
    [size=10.5000pt][size=10.5000pt][size=10.5000pt]
    file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2926.tmp.jpg
    [size=10.5000pt]登陆成功是这样的
    [size=10.5000pt][size=10.5000pt][size=10.5000pt]
    [size=10.5000pt][size=10.5000pt][size=10.5000pt]
    file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2927.tmp.jpg
    [size=10.5000pt]我比较懒,大家如果用我提供的软件,应该可以直接就用,因为我把这些UID什么的直接做到了初始化上面;

    现在还有一个问题,字符编码格式不对,我也懒得搞了,随他吧,以后再说;
    file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2928.tmp.jpg
    修改的内容不多,就加点按键而已。(电脑太卡,我实在没有写下去的心情了)

    1.6 微信远程测试
    网络配置跟小E开发板是一个套路,我就不说了。我也懒得自己搭建微信公众号,直接用小E官方有的东西;
    [size=10.5000pt][size=10.5000pt][size=10.5000pt]
    file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2948.tmp.jpg
    [size=10.5000pt]使用指令控制
    [size=10.5000pt][size=10.5000pt][size=10.5000pt]
    [size=10.5000pt][size=10.5000pt][size=10.5000pt]
    file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2949.tmp.jpg
    多彩灯光模式
    [size=10.5000pt][size=10.5000pt][size=10.5000pt]
    [size=10.5000pt][size=10.5000pt][size=10.5000pt]
    file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps294A.tmp.jpg
    关灯就是关闭设备,其他的都是打开设备,玩多了,没什么好说的。
    [size=10.5000pt][size=10.5000pt][size=10.5000pt]
    [size=10.5000pt][size=10.5000pt][size=10.5000pt]
    代码好像有点问题,不过我要吃饭了,不管了。
    [size=10.5000pt][size=10.5000pt][size=10.5000pt]视频链接:http://v.youku.com/v_show/id_XMjUyNTcxNjg2OA==.html
    [size=10.5000pt][size=10.5000pt][size=10.5000pt]学习笔记介绍:http://bbs.kaifakuai.com/forum.php?mod=viewthread&tid=3756&extra=page%3D1
    [size=10.5000pt][size=10.5000pt][size=10.5000pt]百度云资料链接:链接:http://pan.baidu.com/s/1mhVJOAs 密码:m132
    [size=10.5000pt][size=10.5000pt][size=10.5000pt]码云:https://git.oschina.net/changsha_qianrushi_xiaobai/electronic-mosquito-killer/tree/master
    开发快官网咨询:http://www.kaifakuai.com[size=10.5000pt][size=10.5000pt][size=10.5000pt]
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2021-3-13 10:11
  • 签到天数: 1088 天

    连续签到: 2 天

    [LV.10]以坛为家III

    发表于 2017-3-14 09:20:16 | 显示全部楼层
    这个灭蚊器什么原理。
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-11-20 13:22 , Processed in 0.137214 second(s), 17 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.