2赞

2回答

0收藏

【体验】ESP8266使用心得分享

机智云GoKit 机智云GoKit 8064 人阅读 | 2 人回复 | 2018-03-15

本帖最后由 冯俊波 于 2018-3-15 22:13 编辑

       乐鑫生产ESP8266 32位RISC处理器,CPU 时钟速度最高可达 160 MHz,支持实时操作系统 (RTOS) 和 Wi-Fi 协议栈,可将高达 80% 的处理能力留给应用编程和开发。
       本人自接触机智云以来,使用的最多的模组就是ESP8266,已将ESP8266融入到公司的许多产品之中,现将ESP8266一些使用技巧与大家分享。
       一丶开发环境
       ESP8266最常用的开发环境有4个(环境下载可以去官网下载,也可以加群438373554下载,几个环境都上传群文件了的)。
       1.Ardunio(ESP定制版本)与传统Ardunio一样,支持在线更新和下载库,推荐入门级学习,比如开发wifi探针,室内定位,广告机等可以采用Ardunio开发。
       2.lua (运行脚本)和Ardunio开发一样,很好入门,个人觉得用着有一点分散思维。
       3.MicroPython(现在比较流行的),不会Python入门难,开发物联网产品方便。
       4.Eclipse(ESP8266定制版本)比较综合的版本吧,要用RTOS就得用这个环境来开发,个人觉得也是最好的开发环境,C语言编程,会单片机的入门很快。机智云SOC开发也是使用这个环境进行开发。
       二丶硬件的使用技巧
       就拿ESP-12F来说,除开flash引脚之后,留给我们使用的就只有11个可用GPIO口(包括串口),一个ADC口(不可作为GPIO口使用),ADC是一个10位精度的AD口,可以测量0-1V的电压,也就是1/1024。如果用来采集大于1V的电压,要进行分压。可以用来做模拟信号类传感器的接口(注意分压0-1V,切记,高了会烧芯片)。接下来硬件设计的时候应该注意一下几个特殊的GPIO口,

上表中可以看出这3个GPIO在上电的时候不同状态下进入的模式不同。比如你想用GPIO15低电平有效来控制一个继电器,那么在上电的瞬间,由于GPIO15必须要保持低电平才能正常进入正常的运行模式,所以上电瞬间继电器也会伴随着启动,这在实际应用中是绝对要避免的,所以GPIO15应该用作高电平有效的控制,其他2端口使用也需要类似的注意,有很多人设计电路之后说下载之后不能用,比如指示灯一直闪烁(也就是GPIO2)。就是因为电路设计上存在缺陷造成的。进入了其他的模式。
在用ESP-12F设计最小的系统板的时候应该注意按照如下电路图进行设计

SW-2.1可以用一个跳冒代替,那样在下载程序和运行的时候的时候只需要拔插跳冒就行了。本人在使用之中经常作为输入的IO有GPIO0 GPIO2 GPIO4 GPIO5,剩下的用于输出或者传感器。在IO足够的情况下尽量不要先考虑使用GPIO16 GPIO0 GPIO15 GPIO2
三丶软件设计基本的入门
1.Ardunio程序设计,此处我写用几个比较典型的例子说明一下
例子1.基本输入输出GPIO0接 按键GPIO2模块上的灯,按键按下灯亮按键送卡灯灭
#define D3 0  //flash按键
#define D4 2  //板载灯
void setup() {
  pinMode(D4, OUTPUT);
  pinMode(D3, INPUT);
  digitalWrite(D4,HIGH);
}
void loop() {
  int ss;
  ss=digitalRead(D3);
  if(ss==1) digitalWrite(D4,HIGH);
  else digitalWrite(D4,LOW);
}
例子2.串口测试
void setup()
{
  Serial.begin(9600);//设置波特率
  Serial.println("GO GO GO Begin");//打印GOGOGOBegin而且换行
}
void loop()
{
  Serial.printf("hello");//打印hello不换行
  delay(1000);
  Serial.println("   ESP8266学习交流");//打印   ESP8266而且换行
  delay(1000);
}
例子3.热点广告机实验
#include <ESP8266WiFi.h>
extern "C" {
  #include "user_interface.h"
}

void setup() {
  delay(500);
  //设置为sta模式
  wifi_set_opmode(STATION_MODE);
  //开启混杂模式
  wifi_promiscuous_enable(1);
}

void loop() {
  //sendBeacon("test"); //sends beacon frames with the SSID 'test'
  //sendRandomBeacon(10); //sends beacon frames with 10 character long random SSID
  //sendFuzzedBeacon("FakeBeacon",10); //sends beacon frames with 10 different SSID all starting with 'test' and ending with whitespaces (spaces and/or tabs)
  RickRoll();
}

void sendFuzzedBeacon(char* baseSsid, int nr) {
  int baseLen = strlen(baseSsid);
  int i=0;
  for(int j=0; j < 32 - baseLen; j++) { //32 is the maximum length of the SSID
    for(int k=0; k < pow(2,j); k++) {
      int kk = k;
      String ssid = baseSsid;
      for(int l=0; l < j; l++) {
        if(kk%2 == 1) ssid += " "; //add a space
        else ssid += "\t"; //add a tab
        kk /= 2;
      }
      char charBufSsid[33];
      ssid.toCharArray(charBufSsid, 33);
      sendBeacon(charBufSsid);
      if(++i >= nr) return;
    }
  }
}

void sendRandomBeacon(int len) {
  char ssid[len+1];
  randomString(len, ssid);
  sendBeacon(ssid);
}

void randomString(int len, char* ssid) {
  String alfa = "1234567890qwertyuiopasdfghjkklzxcvbnm QWERTYUIOPASDFGHJKLZXCVBNM_";
  for(int i = 0; i < len; i++) {
    ssid = alfa[random(65)];
  }
}

void sendBeacon(char* ssid) {
    // Randomize channel //
    byte channel = random(1,12);
    wifi_set_channel(channel);

    uint8_t packet[128] = { 0x80, 0x00, //Frame Control
                        0x00, 0x00, //Duration
                /*4*/   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //Destination address
                /*10*/  0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //Source address - overwritten later
                /*16*/  0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //BSSID - overwritten to the same as the source address
                /*22*/  0xc0, 0x6c, //Seq-ctl
                //Frame body starts here
                /*24*/  0x83, 0x51, 0xf7, 0x8f, 0x0f, 0x00, 0x00, 0x00, //timestamp - the number of microseconds the AP has been active
                /*32*/  0xFF, 0x00, //Beacon interval
                /*34*/  0x01, 0x04, //Capability info
                /* SSID */
                /*36*/  0x00
                };

    int ssidLen = strlen(ssid);
    packet[37] = ssidLen;

    for(int i = 0; i < ssidLen; i++) {
      packet[38+i] = ssid;
    }

    uint8_t postSSID[13] = {0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, //supported rate
                        0x03, 0x01, 0x04 /*DSSS (Current Channel)*/ };

    for(int i = 0; i < 12; i++) {
      packet[38 + ssidLen + i] = postSSID;
    }

    packet[50 + ssidLen] = channel;

    // Randomize SRC MAC
    packet[10] = packet[16] = random(256);
    packet[11] = packet[17] = random(256);
    packet[12] = packet[18] = random(256);
    packet[13] = packet[19] = random(256);
    packet[14] = packet[20] = random(256);
    packet[15] = packet[21] = random(256);

    int packetSize = 51 + ssidLen;

    wifi_send_pkt_freedom(packet, packetSize, 0);
    wifi_send_pkt_freedom(packet, packetSize, 0);
    wifi_send_pkt_freedom(packet, packetSize, 0);
    delay(1);
}

void RickRoll() {
  sendBeacon("电子技术交流");
  sendBeacon("1083791810");
  sendBeacon("15120205205");
  sendBeacon("物联网");
  sendBeacon("分享快乐");
  sendBeacon("ESP8266");
  sendBeacon("机智云");
  sendBeacon("让您生活更美好");
}
4.云平台测试
#include <ESP8266WiFi.h>
#include <Ticker.h>
#define D0 16
#define D1 5
#define D2 4
#define D3 0  //flash按键
#define D4 2  //板载灯
#define D5 14
// #define D6 12 //DHT11
#define D7 13
#define D8 15
#define D9 3
#define D10 1
//IO方向设置
#define DHT11_IO_IN()  pinMode(12, INPUT)
#define DHT11_IO_OUT() pinMode(12, OUTPUT)
////IO操作函数
#define DHT11_DQ_OUT 12 //数据端口4
#define DHT11_DQ_IN  12  //数据端口4
//*******************
#define u8 unsigned char
Ticker timer;
unsigned long lastTick = 0;
unsigned char SW=15;
uint8_t macAddr[6];
/****************************DHT11部分**********************************/
u8 temperature;
u8 humidity;
u8 t = 0;
//复位DHT11
void DHT11_Rst(void)
{
  DHT11_IO_OUT();   //SET OUTPUT
  digitalWrite(DHT11_DQ_OUT, LOW);   //拉低DQ
  delay(20);     //拉低至少18ms
  digitalWrite(DHT11_DQ_OUT, HIGH);   //DQ=1
  delayMicroseconds(30);       //主机拉高20~40us
}
//等待DHT11的回应
//返回1:未检测到DHT11的存在
//返回0:存在
u8 DHT11_Check(void)
{
  u8 retry = 0;
  DHT11_IO_IN();//SET INPUT
  while (digitalRead(DHT11_DQ_IN) && retry < 100) //DHT11会拉低40~80us
  {
    retry++;
    delayMicroseconds(1);
  };
  if (retry >= 100)return 1;
  else retry = 0;
  while (!digitalRead(DHT11_DQ_IN) && retry < 100) //DHT11拉低后会再次拉高40~80us
  {
    retry++;
    delayMicroseconds(1);
  };
  if (retry >= 100)return 1;
  return 0;
}
//从DHT11读取一个位
//返回值:1/0
u8 DHT11_Read_Bit(void)
{
  u8 retry = 0;
  while (digitalRead(DHT11_DQ_IN) && retry < 100) //等待变为低电平
  {
    retry++;
    delayMicroseconds(1);
  }
  retry = 0;
  while (!digitalRead(DHT11_DQ_IN) && retry < 100) //等待变高电平
  {
    retry++;
    delayMicroseconds(1);
  }
  delayMicroseconds(40);//等待40us
  if (digitalRead(DHT11_DQ_IN))return 1;
  else return 0;
}
//从DHT11读取一个字节
//返回值:读到的数据
u8 DHT11_Read_Byte(void)
{
  u8 i, dat;
  dat = 0;
  for (i = 0; i < 8; i++)
  {
    dat <<= 1;
    dat |= DHT11_Read_Bit();
  }
  return dat;
}
//从DHT11读取一次数据
//temp:温度值(范围:0~50°)
//humi:湿度值(范围:20%~90%)
//返回值:0,正常;1,读取失败
u8 DHT11_Read_Data(u8 *temp, u8 *humi)
{
  u8 buf[5];
  u8 i;
  DHT11_Rst();
  if (DHT11_Check() == 0)
  {
    for (i = 0; i < 5; i++) //读取40位数据
    {
      buf = DHT11_Read_Byte();
    }
    if ((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4])
    {
      *humi = buf[0];
      *temp = buf[2];
    }
  } else return 1;
  return 0;
}
//初始化DHT11的IO口 DQ 同时检测DHT11的存在
//返回1:不存在
//返回0:存在
u8 DHT11_Init(void)
{
  pinMode(4, OUTPUT);
  DHT11_Rst();
  return DHT11_Check();
}
const char* ssid     = "fengshu";//家里面路由器wifi
const char* password = "15120205205";
const char* host = "192.168.1.88";    //服务器地址,此处可更换为云平台,我是局域网测试
const int httpPort = 8810;            //服务器端口
char ser[64];
char str[512];
WiFiClient client;// 使用WiFi客户端类创建TCP连接
//反向控制:
unsigned long MS_TIMER = 0;
char flag = false;
void sensor_init()
{
  pinMode(D0, OUTPUT);
  digitalWrite(D0, HIGH);
  pinMode(D1, OUTPUT);
  digitalWrite(D1, HIGH);
  pinMode(D2, OUTPUT);
  digitalWrite(D2, HIGH);
  pinMode(D3, OUTPUT);
  digitalWrite(D3, HIGH);
  pinMode(D4, OUTPUT);
  digitalWrite(D4, HIGH);
}
void setup()
{
  Serial.begin(115200);
  MS_TIMER = millis();
  sensor_init();
  delay(10);
  if (DHT11_Init()) //DHT11初始化
  {
    delay(200);
  }
  WiFi.disconnect();/////////////////
  // 首先,我们连接到WiFi网络
  Serial.println();
  Serial.println();
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println(WiFi.localIP());
  delay(50);
  Serial.println(host);
  // 使用WiFi客户端类创建TCP连接
  // 使用WiFi客户端类创建TCP连接
  if (!client.connect(host, httpPort))
  {
  //  Serial.println(hz[3]);
    return;
  }
}
int timerun=0;
void loop()
{
  if (millis() - lastTick > 10000)  //10s读一次
  {
    lastTick = millis();
    //读传感器并发送
    DHT11_Read_Data(&temperature, &humidity);   //读取温湿度值
    WiFi.softAPmacAddress(macAddr);
    sprintf(str, "b%02x%02x%02x%02x%02x%02x%01x%d%d\r\n", macAddr[0],macAddr[1],macAddr[2],macAddr[3],macAddr[4],macAddr[5],SW, humidity, temperature);
    Serial.printf("MAC:%02x%02x%02x%02x%02x%02x Temp:%d'C,Humi:%d%. \n", macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5], temperature, humidity);
    client.print(str);
    delay(1000);
    String recDataStr1 = client.readStringUntil('\n');
    if(recDataStr1=="#") timerun=0;
    else
    {
      if(timerun<=6)
      {
        timerun++;
      }
      else
      {
   //     WiFi.begin(ssid, password);
        client.connect(host, httpPort);
        Serial.printf("TCP ERROW");
      }
    }
   }
  if (client.available())
  {
    //读并处理
    // R读取服务器的应答的所有行,并把它们打印到串口
    String recDataStr = client.readStringUntil('\n');
    Serial.println(recDataStr);
    if ((recDataStr == "#se")||(recDataStr == "#sc")||(recDataStr == "#sa")||(recDataStr == "#s8")||(recDataStr == "#s6")||(recDataStr == "#s4")||(recDataStr == "#s2")||(recDataStr == "#s0"))  //BS ECA86420
    {
      digitalWrite(D0, LOW);
      if((SW&1)==1) SW=SW-1;
      else SW=SW;
    }
    if ((recDataStr == "#sf")||(recDataStr == "#sd")||(recDataStr == "#sb")||(recDataStr == "#s9")||(recDataStr == "#s7")||(recDataStr == "#s5")||(recDataStr == "#s3")||(recDataStr == "#s1"))
    {
      digitalWrite(D0, HIGH);
      if((SW&1)==0) SW=SW+1;
      else SW=SW;
    }

    if ((recDataStr == "#sd")||(recDataStr == "#sc")||(recDataStr == "#s9")||(recDataStr == "#s8")||(recDataStr == "#s5")||(recDataStr == "#s4")||(recDataStr == "#s1")||(recDataStr == "#s0"))
    {
      digitalWrite(D1, LOW);
      if((SW&2)==2) SW=SW-2;
      else SW=SW;
    }
    if ((recDataStr == "#sf")||(recDataStr == "#se")||(recDataStr == "#sb")||(recDataStr == "#sa")||(recDataStr == "#s7")||(recDataStr == "#s6")||(recDataStr == "#s3")||(recDataStr == "#s2"))
    {
      digitalWrite(D1, HIGH);
      if((SW&2)==0) SW=SW+2;
      else SW=SW;
    }

    if ((recDataStr == "#sb")||(recDataStr == "#sa")||(recDataStr == "#s9")||(recDataStr == "#s8")||(recDataStr == "#s3")||(recDataStr == "#s2")||(recDataStr == "#s1")||(recDataStr == "#s0"))
    {
      digitalWrite(D2, LOW);
      if((SW&4)==4) SW=SW-4;
      else SW=SW;
    }
    if ((recDataStr == "#sf")||(recDataStr == "#se")||(recDataStr == "#sd")||(recDataStr == "#sc")||(recDataStr == "#s7")||(recDataStr == "#s6")||(recDataStr == "#s5")||(recDataStr == "#s4"))
    {
      digitalWrite(D2, HIGH);
      if((SW&4)==0) SW=SW+4;
      else SW=SW;
    }

    if ((recDataStr == "#s7")||(recDataStr == "#s6")||(recDataStr == "#s5")||(recDataStr == "#s4")||(recDataStr == "#s3")||(recDataStr == "#s2")||(recDataStr == "#s1")||(recDataStr == "#s0"))
    {
      digitalWrite(D3, LOW);
      if((SW&8)==8) SW=SW-8;
      else SW=SW;
    }
    if ((recDataStr == "#sf")||(recDataStr == "#se")||(recDataStr == "#sd")||(recDataStr == "#sc")||(recDataStr == "#sb")||(recDataStr == "#sa")||(recDataStr == "#s9")||(recDataStr == "#s8"))
    {
      digitalWrite(D3, HIGH);
      if((SW&8)==0) SW=SW+8;
      else SW=SW;
    }
    Serial.println(SW);
//   Serial.println(ser);
    WiFi.softAPmacAddress(macAddr);
    sprintf(str, "b%02x%02x%02x%02x%02x%02x%01x%d%d\r\n", macAddr[0],macAddr[1],macAddr[2],macAddr[3],macAddr[4],macAddr[5],SW, humidity, temperature);
    client.print(str);
  }
}
可以用串口助手开个端口进行调试,结合VB可以实现自动应答,界面如下

VB代码
Option Explicit
Dim UserCookie() As Long

Private Sub Form_Load()
    ReDim UserCookie(0)
    wskListen.Bind 8810
    wskListen.Listen                            '监听网络连接
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Dim i As Long

    On Error Resume Next
    Erase UserCookie
    For i = wskServer.UBound To 1 Step -1
        wskServer(i).Close
        Unload wskServer(i)
    Next
    wskListen.Close
End Sub

Private Sub btnSend_Click()
    Dim i As Integer
    For i = 1 To wskServer.UBound
        If wskServer(i).Tag = UCase(Text2.Text) Then
            wskServer(i).SendData Text1.Text
            Exit Sub
        End If
    Next
End Sub

Private Sub btnClose_Click()
    Unload Me
End Sub

Private Sub List1_DblClick()
Text2.Text = Mid(List1.Text, 1, 12)
End Sub

Private Sub wskListen_ConnectionRequest(ByVal requestID As Long)
    Dim i As Long
    For i = 1 To wskServer.UBound
        If wskServer(i).State = sckClosed Then
            UserCookie(i) = requestID
            wskServer(i).Accept requestID
            Exit Sub
        End If
    Next
    Load wskServer(i)
    wskServer(i).Accept requestID
    ReDim Preserve UserCookie(i)
    UserCookie(i) = requestID
End Sub

Private Sub wskServer_Close(Index As Integer)
    wskServer(Index).Close
    wskServer(Index).Tag = ""
    'cmbClient.RemoveItem Index
    'cmbClient.ListIndex = cmbClient.ListCount - 1
    'cmbClient.Tag = cmbClient.Text
    'btnSend.Enabled = (cmbClient.ListCount > 0)
End Sub

Private Sub wskServer_DataArrival(Index As Integer, ByVal bytesTotal As Long)
    Dim strData As String

    wskServer(Index).GetData strData, vbString

    If Mid(strData, 1, 1) = "b" Then
        wskServer(Index).SendData "b"
        wskServer(Index).Tag = UCase(Mid(strData, 2, 12))
        strData = Mid(strData, 14)
        List1.AddItem wskServer(Index).Tag & ":" & Index & ":" & Mid(strData, 1, 1) & "|" & Mid(strData, 2), 0
    End If

End Sub

Private Sub wskServer_SendComplete(Index As Integer)
    'MsgBox "给[" & cmbClient.Tag & "]的内容已发送完毕!", vbInformation, "提示"
End Sub
Private Sub cmbClient_Click()
'    btnSend.Enabled = (.ListCount > 0)
'End SubcmbClient
End Sub
Private Function FindUser(ByVal lCookie As Long) As String
    Dim i As Long

   ' For i = 0 To cmbClient.ListCount - 1
      '  If InStr(cmbClient.List(i), "-" & lCookie) > 0 Then Exit For
   ' Next
'   FindUser = cmbClient.List(i)
End Function

温湿度会上传到VB端,发送控制命令过去可以控制端口VB程序在这儿我就不仔细说明了,需要生成的可执行程序可以私聊我发给你
2.lua脚本,此处由于本人用的不多,所以我就写几个基本的
串口打印hello word!
tmr.alarm(0, 1000, tmr.ALARM_AUTO, function()
    print("Hello word!\n")
    end
)
基本的控制,控制模块板载灯串口打印按键状态
pin = 2
gpio.mode(pin,gpio.OUTPUT)
gpio.write(pin,gpio.HIGH)
gpio.mode(pin,gpio.INPUT)
print(gpio.read(pin))
ESP8266连接到路由器
print(wifi.sta.getip())
wifi.setmode(wifi.STATION)
wifi.sta.config("fengshu","15120205205")
print(wifi.sta.getip())
连接服务器
wifi.setmode(wifi.STATIONAP)
cfg = {}
cfg.ssid = "fengshu"
cfg.pwd = "15120205205"
wifi.ap.config(cfg)
stacfg = {}
stacfg.ssid = "hyx"
stacfg.pwd = "15597700228"
wifi.sta.config(stacfg)
wifi.sta.autoconnect(1)
ClientConnectFlag = 0
TcpClient = nil  
tmr.alarm(2, 1000, 1, function() --定时器的妙用,当没连接上就一直打印Error,连接上就OK
    if ClientConnectFlag == 0 then
        Client = net.createConnection(net.TCP, 0) --创建一个TCP Client
        Client:connect(8000, "192.168.0.117") --连接服务器的IP以及端口(下面会介绍怎么看IP)
        Clientn("receive", function(sck, data) --Client接收到数据,打印到串口
            print(data)
          --uart.write(0, data) 两者都可以
        end)
        Clientn("connection", function(sck, c) --当连接上的时候
            ClientConnectFlag = 1 --标志位
            TcpClient = sck --记录当前的socket,以供串口向网络发送数据。
            print("Link OK")
            tmr.stop(2) --连上就停止定时器
            --特别注意connection和disconnection的嵌套关系,不然会有意外情况
            Clientn("disconnection", function(sck, c) --没有连上
                ClientConnectFlag = 0 --清0标志位
                TcpClient = nil
                tmr.start(2) --重启定时器
            end)
        end)
        if ClientConnectFlag == 0 then
            print("Link Error")  
        end
    end  
end)
uart.on("data", 0, function(data) --串口要发送数据到网口
    if TcpClient~=nil then
        TcpClient:send(data)
    end
end,0)
printip = 0  
wifi.eventmon.register(wifi.eventmon.STA_DISCONNECTED, function(T)
    printip = 0
end)
wifi.eventmon.register(wifi.eventmon.STA_GOT_IP, function(T)
    if printip==0 then
        print("IP: "..T.IP)
    end
    printip = 1
end)  

3. MicroPython  MicroPython是一个基于Python 3的、精简和高效的编程语言,其包括Python标准库的一个小子集,并针对微控制器及受限的环境优化以可以运行。python本人今年才开始学的,所以有问题可以一起讨论
Python开发环境可以问我要,此处我不再写环境的搭建
常用命令help()可用于打印信息
编辑器最好使用Notepad++编写。比较方便,下面开始写几个例子
上电自动连接wifi
# main.py
import network
import webrepl
SSID = "fengshu"
PASSWORD = "15120205205"
def do_connect():
    import network
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    if not wlan.isconnected():
        print('connecting to network...')
        wlan.connect(SSID, PASSWORD)
    start = utime.time()
    while not wlan.isconnected():
        utime.sleep(1)
        if utime.time()-start > 5:
            print("connect timeout!")
            break
    if wlan.isconnected():
        print('network config:', wlan.ifconfig())
do_connect()

分享到:
回复

使用道具 举报

回答|共 2 个

倒序浏览

沙发

nndada

发表于 2018-3-15 23:31:19 | 只看该作者

萌新虫虫前来学习
板凳

qpwurqwrmuew

发表于 2018-3-17 11:00:28 | 只看该作者

小辉前来学习
您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

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