2016-07-14 24 views
1

私はarduino unoとESP8266exをwifiモジュールとして使用しているプロジェクトに取り組んでいます。ケーブルの接続:Arduino ESP8266 HTTP取得要求にバッファ不足のソフトウエアがあります

Arduino 5V - > 3.3Vレギュレータ - > ESP:CH_PD(10k抵抗付き)およびVCC Arduino GND - > 3.3Vレギュレータ - > ESP:GNDおよびRST(リセットが接続されています。 Arduino RX - > ESP TX Arduino TX - >分圧器(2k 1k抵抗) - > ESP RX 5uFコンデンサ - ESPがリセットされないようにする電圧レギュレータ。

ここで私が抱えている問題について説明しましょう。私はarduino uno用のWiFiモジュールとしてESP8266を使用している2つのコードを持っています。私は長い(600以上の文字)を持つGETリクエストを送信するために、サーバとのTCP接続をオープンし、SoftwareSerialが読ん経由ですべての長い応答を処理することに成功した

#define ard_rx_esp_tx 2 
#define ard_tx_esp_rx 3 

#include <SoftwareSerial.h> 

SoftwareSerial ESPserial(ard_rx_esp_tx, ard_tx_esp_rx); // RX | TX 

void setup() 
{ 
    int i = 0; 
    Serial.begin(9600);  // communication with the host computer 
    while (!Serial); 

    // Start the software serial for communication with the ESP8266 
    ESPserial.begin(9600); 
    Serial.println(""); 
    Serial.println(F("Remember to to set Both NL & CR in the serial monitor.")); 
    Serial.println(F("Ready")); 
    Serial.println(F("")); 
    Serial.println(F("start")); 
    delay(1000); 
} 
void loop() 
{ 

    if (ESPserial.available()) { 
    char c = ESPserial.read(); 
    Serial.print(c); 
    } 

    if (Serial.available()) { 
    ESPserial.write(Serial.read()); 
    } 
} 

:私の最初のプログラムでは、私は手でコマンドを送りました()関数を呼び出してシリアルモニタにすべて出力します。

enter image description here

目的は、「SoftwareSerial.print()」を経由してこれらのATコマンドを送信し、文字全体の応答を置くことです:一言で言えば、このコードは、サーバーの600以上のchar型の応答を処理することができますAPI-KEYを解析する配列。私がこれまでに書いたコード:

#define ard_rx_esp_tx 2 
#define ard_tx_esp_rx 3 
char response[625]; 
#include <SoftwareSerial.h> 
SoftwareSerial ESPserial(ard_rx_esp_tx, ard_tx_esp_rx); // RX | TX 
int i; 

void setup() 
{ 

    Serial.begin(9600);  // communication with the host computer 
    while (!Serial); 

    // Start the software serial for communication with the ESP8266 
    ESPserial.begin(9600); 

    Serial.println(""); 
    Serial.println(F("Remember to to set Both NL & CR in the serial monitor.")); 
    Serial.println(F("Ready")); 
    Serial.println(F("")); 
    Serial.println(F("start")); 
    delay(1000); 

    ESPserial.println("AT+CIPSTART=\"TCP\",\"domainname\",80"); 
    delay(5000); 

    i = 0; 
    while (ESPserial.available()) { 
     response[i] = ESPserial.read(); 
     i++; 
    } 
    response[i++] = '\0'; 
    Serial.println(response); 
    for (i = 0; i < 625; i++) { 
     response[i] = '\0'; 
    } 

    ESPserial.println("AT+CIPSEND=107"); 
    delay(5000); 

    i = 0; 
    while (ESPserial.available()) { 
     response[i] = ESPserial.read(); 
     i++; 
    } 
    response[i++] = '\0'; 
    Serial.println(response); 
    for (i = 0; i < 625; i++) { 
     response[i] = '\0'; 
    } 

    ESPserial.println("GET request to the server which has length 107 as indicated"); 
    delay(5000); 

    i = 0; 
    while (ESPserial.available()) { 
     response[i] = ESPserial.read(); 
     i++; 
    } 
    response[i++] = '\0'; 
    Serial.println(response); 
    for (i = 0; i < 625; i++) { 
     response[i] = '\0'; 
    } 
} 
void loop() { 
    // put your main code here, to run repeatedly: 

} 

"setup()"スコープの最後にレスポンスを表示します。私はまた、出力の写真を入れてみましょう:結論

enter image description here

問題があることである:SoftwareSerialは256のバイトまで増加させることができる64バイトのバッファを持っており、私はそれを増やしたときにプログラムが印刷することができますしかし、今度は256文字で、ATコマンドを手動で送信した私の最初のコードでは、64バイトバッファにもかかわらず応答全体を処理でき、シリアルモニタにそれを印刷することができます。 2番目の方法では、応答全体をchar配列に格納して格納することができませんでした。

私は自分の問題を説明することができ、正確に自分のプロセスのどこに詳細があるのか​​を指摘したいと思います。

私に何をすることをお勧めしますか?この大きなレスポンスを処理し、それを文字配列に入れていくうちに私は何ができますか?どのようにしてESP8266exのバッファに最初から残っているレスポンスを処理することができますか?また、関数read()が64バイト配列を持ち、256まで増やすことができるSoftwareSerialクラスを介してArduino RXピンで読み込みます。

答えて

4

ここで問題となるのはタイミングです。あなたは、9600ビット/秒のボーレートで、256バイトであるソフトウェアシリアル(いずれのハードウェアUARTでも当てはまります)のバッファサイズに制限があることをご存知でしょうか。

スタートビット、8データビット、ストップビットがあるため(ここでは9600 8N1を使用すると仮定します)、1/9600 * 10 - 秒、または1.04ミリ秒です。したがって、256バイトを受信するには、約266ミリ秒かかるはずです。これは、266ミリ秒後にバッファが完全にいっぱいになり、後で受け取ったものが以前に受信したデータの削除を開始することを意味します。

あなたの問題の要点 - サーバーからデータを受信するコマンドをESPに送信してから、5秒間スリープ状態に入ると、バッファからデータを取得していないことを意味するので、データ損失の原因となります。シリアルバッファのポイントは、1つのポイントで受け取るデータセット全体を保持するのではなく、読めるようになるまで十分な長さに保持することです。

コマンドを送信してArduinoにコードを実行させて、期待される終了またはタイムアウトが見つかるまでバッファからできるだけ早くデータを取得させるようにしてください。

char espBuffer[1024] = {0}; 
int readCount = 0; 
long startTime = millis(); 

ESPserial.println("AT+CIPSTART=\"TCP\",\"domainname\",80"); 

while (millis() - startTime < 5000) { // Run for at least 5 seconds 
    // Check to make sure we don't exceed espBuffer's boundaries 
    if (ESPserial.available() > readCount + sizeof espBuffer - 1) 
    break; 
    readCount += ESPserial.readBytes(espBuffer + readCount, ESPserial.available()); 
} 

Serial.println(espBuffer); 

は今、あなたはそれが期待するすべてのデータを受信したときに終了するには、このコードを変更したいと思います。このような基本的な

何かがあなたが軌道に乗るだろう。さらに、このシンプルなセットアップでは、レスポンスの最大サイズは1023バイトに制限されていますが、あまり役に立ちません。理想的には、HTTPボディを見つけてすべてを破棄するまで、データを見つけるためのバッファが小さく、実際にボディを格納するバッファがはるかに大きくなることを意味するまで、読書を続けておくのが理想的です。

+0

ありがとうございます – 4JaoDeka

関連する問題