<noscript id="mmkmi"><source id="mmkmi"></source></noscript>
  • <noscript id="mmkmi"><kbd id="mmkmi"></kbd></noscript>
  • <table id="mmkmi"><source id="mmkmi"></source></table>
  • ESP8266使用arduino開發時遇到的IO讀寫延遲的問題及解決方案

    作者:cwb_tfx | 更新時間:2018-12-13 | 瀏覽量:1773

    最近在使用ESP8266連接BIGIOT服務器做開發時遇到了一個很奇怪的問題

    由于本人也是第一次玩arduino和esp8266,不知道arduino 里面的io讀寫會有這么大的坑

    在使用client類調用readstring等系列(只要是讀一大串字符串的api)接口都會發生延遲的現象,手機發送的數據經過服務器傳

    到板子,延遲有四五秒左右。起初我以為跟網絡延遲有關系,但是經過測試發現,與此無關。

    后面我想是否跟io讀取string 數據的實現有關系,也就是說,底層讀取函數并不知道從服務器發來的數據已經讀取完成了,因此

    會一直等待完整的數據到來(這種情況下,我們發送多次數據后,在停止發送后會一次性把所有的數據讀取出來),于是我想是否

    可以人為的區分服務器發來的每一條信息,在查閱arduino函數后,發現有readBytes()方法,但是我在使用這個函數一次性讀取多個

    字符串時也存在延遲現象,因此我改成一個字符一個字符去讀(只有每次讀一個字符才能解決,其他方式都不行,讀者可以自行測試),

    讀到\n就算拿到一幀完整的數據。使用int recvData(char* buff, int len) 這個函數解決了延遲的問題。

    下面貼出源碼,在此之前,先簡單介紹一下:

    該源碼實現了WIFI斷開自動重啟,連接超時自動重連,離線自動重連等功能,意思就是說,無論在哪個環節掉線了,都會重新去連接。

    代碼只是一段測試,有需要的朋友可以自行修改測試。

    另外值得注意的地方是,這里使用的是8282端口,被動在線(客戶端不主動給服務器發心跳包,而是等服務器先發心跳包過來,然后再發心跳包給服務器)

    源碼如下:

    ============================================================================================

    #include
    WiFiClient client;

    #define RCV_BUFF_LEN 512

    #define SND_HEART_JUMP_PKG     "{\"M\":\"b\"}\n"
    #define SND_CONNECT_PKG        "{\"M\":\"checkin\",\"ID\":\"1234\",\"K\":\"1212121\"}\n"
    #define MSG_CONNECT_TO_BIGIOT  "{\"M\":\"WELCOME TO BIGIOT\"}\n"
    #define LED1 16 //LED連接在8266的GPIO16上
    #define LED2 2 //LED連接在8266的GPIO2上
    const char *ssid     = "cwbtest";//"360WiFi-3C7943";
    const char *password = "1234567891";//"112233445566";
    const char *host = www.eqytg.org;
    const int httpPort = 8282;
    static char recvBuff[RCV_BUFF_LEN] = {0};
    int len = 0;

    int recvData(char* buff, int len)
    {
         if(len <= 0)
         {
               Serial.print("Len value error ");
               return -1;
         }
         char str;
         int count = 0;
         while(client.readBytes(&str,1) > 0)
         {
              recvBuff[count++] = str;
              if(str == '\n')
              {
                  recvBuff[count++] = '\0';
                  break; 
              }
              if(count >= len)
              {
                  return -1; 
              }
         }
         return count;
    }

    bool ConnectToWIFI(const char* ssid, const char* passwd)
    {
        if(WiFi.status() == WL_CONNECTED)
        {
            return true; 
        }
        WiFi.mode(WIFI_STA);
        WiFi.begin(ssid, passwd);
        int timeCount = 0;
        while(WiFi.status() != WL_CONNECTED)
        {
            delay(500);
            Serial.print(".");
            timeCount++;
            if(timeCount >= 20)
            {
                Serial.print("Connect to ");
                Serial.print(WiFi.SSID());
                Serial.println("failer, time out!");
                return false;
            }
        }
        Serial.println("");
        return true;
    }
    bool ConnectToServer(const char* host, const int port)
    {
        int timeCount = 0;
        client.flush();
        while(!client.connect(host, port))
        {
            Serial.println("connection to Server failed,retry...");
            delay(4000);
            timeCount++;
            if(timeCount >= 5)
            {
                Serial.print("Connect to ");
                Serial.print(host);
                Serial.println(" failer, time out!");
                return false;
            }
        }
        timeCount = 0;
        while(true)
        {
            if(( len = client.readBytesUntil('\0',recvBuff,RCV_BUFF_LEN)) > 0)
            {
                recvBuff[len] = '\0';
                Serial.print(recvBuff);
                String line = String(recvBuff);
                if(line.compareTo(MSG_CONNECT_TO_BIGIOT) == 0)
                {
                    Serial.print("connected to ");
                    Serial.println(host);
                }
                break;
            }
            delay(10);
            timeCount++;
            if(timeCount >= 1000)
            {
                Serial.println("GET Connect Message time out!");
                return false; 
            }
        }
        return true;
    }
    bool LogInToServer()
    {
        int timeCount = 0;
        while(true)
        {
            int count = 0;
            bool isConnect = false;
            client.write(SND_CONNECT_PKG);//登陸設備,修改成自己的ID和key
            while(true)
            {
                if(( len = client.readBytesUntil('\0',recvBuff,RCV_BUFF_LEN)) > 0)
                {
                    Serial.println(recvBuff);
                    String line = String(recvBuff);
                    if(line.compareTo("checkinok") > 0)
                    {
                        //Serial.println("connect ok");
                        return true;
                    }
                }
                delay(3000);
                count++;
                if(count >= 5)
                {
                    Serial.println ("time out>>> retry");
                    timeCount++;
                    break;
                }
            }
            if(timeCount >= 3)
            {
                return false;
            }
        }
        return true; 
    }
    bool IsWifiConnect()
    {
        if(WiFi.status() != WL_CONNECTED)
        {
            return false;
        }
        return true; 
    }

    void setup()
    {
        Serial.begin(115200);
        Serial.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        delay(10);
        pinMode(LED1, OUTPUT);
        pinMode(LED2, OUTPUT);
    }

    void loop()
    {
        unsigned int timeStart = 0;
        unsigned int timeEnd = 0;
        static int ledctrl = LOW;
        while(1)
        {
            Serial.println("Welcom to use this ESP8266 device");
            Serial.print("Step1: Connecting to ");
            Serial.println(ssid);
       
            if(!ConnectToWIFI(ssid, password))
            {
                continue ;
            }
            Serial.println("WiFi connected");
            Serial.print("IP address: ");
            Serial.println(WiFi.localIP());
            Serial.println("");

            Serial.println("Step2: ConnectTo Server>>");
            if(!ConnectToServer(host, httpPort))
            {
                delay(3000);
                continue;
            }
            Serial.println("Connect to server successful!");
            Serial.println("");
            Serial.println("Step3: Login to Server>>");
            if(!LogInToServer())
            {
                client.stop();
                delay(3000);
                continue;
            }
            Serial.println("Login to Server successful!");
            Serial.println("Now you can control your device by ethernet!");
            timeStart = millis();
            while(1)
            {
                 if(( len = recvData(recvBuff,RCV_BUFF_LEN)) > 0)
                {
                    digitalWrite(LED1,ledctrl);
                    digitalWrite(LED2,ledctrl);
                    if(ledctrl == LOW)
                    {
                        ledctrl = HIGH; 
                    }
                    else
                    {
                        ledctrl = LOW;
                    }
                    timeStart = millis();
                    String line = String(recvBuff);
                    if(line.compareTo(SND_HEART_JUMP_PKG) == 0)
                    {
                        Serial.println("this is heart jump package");
                        client.write(SND_HEART_JUMP_PKG);
                    }
                    Serial.print(line);
                }
                timeEnd = millis();
                if((IsWifiConnect() == false) || ((timeEnd - timeStart) > 180000))
                {
                    Serial.println(timeEnd - timeStart);
                    Serial.println("Error Message: Wifi Disconnect!\n");
                    Serial.println("Retry to connect to WIFI");
                    break;
                }
            }
        }
    }

     


    評論:共2條

    xbk 評論于:2018-12-13 14:03:28
    厲害了!
    799243768 評論于:2019-04-13 13:28:23
    用readStringUntil()方法沒有延時
    返回頂部
    <noscript id="mmkmi"><source id="mmkmi"></source></noscript>
  • <noscript id="mmkmi"><kbd id="mmkmi"></kbd></noscript>
  • <table id="mmkmi"><source id="mmkmi"></source></table>
  • 三上悠亚在线观看