国内综合精彩aⅤ无码不卡_日本少妇做爰全过程_欧美性爱在线播放免费_午夜?V日韩一区二区_免费a级毛片无码免费播放_成在人线av无码喷水_亚洲精品网站色视频_国产婷婷精品成人_老师撩起裙子让我桶的视频_秋霞影院国产

ESP8266使用arduino開發(fā)時遇到的IO讀寫延遲的問題及解決方案

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

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

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

在使用client類調(diào)用readstring等系列(只要是讀一大串字符串的api)接口都會發(fā)生延遲的現(xiàn)象,手機發(fā)送的數(shù)據(jù)經(jīng)過服務(wù)器傳

到板子,延遲有四五秒左右。起初我以為跟網(wǎng)絡(luò)延遲有關(guān)系,但是經(jīng)過測試發(fā)現(xiàn),與此無關(guān)。

后面我想是否跟io讀取string 數(shù)據(jù)的實現(xiàn)有關(guān)系,也就是說,底層讀取函數(shù)并不知道從服務(wù)器發(fā)來的數(shù)據(jù)已經(jīng)讀取完成了,因此

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

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

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

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

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

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

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

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

源碼如下:

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

#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 = m.placeboworld.cn;
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);//登陸設(shè)備,修改成自己的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()方法沒有延時
返回頂部