カテゴリー
Arduino

Ethernet3ライブラリの不具合を修正しました

自宅状況モニタの作成にあたって、奇妙な不具合に遭遇しました。

修正コードは、GitHubにコミットしています。

事象

  • InfluxDBサーバにアップロードする際、WIFI接続時は問題ないがEthernet接続時にエラーとなってしまう。
  • 送信データのサイズが小さい場合は、Ethernet接続時でもエラーとならない。

原因

  • Ethernet3ライブラリ内のデータ送信を行うsend()メソッド内で、サイズが2048byteを超える場合に超過分を削除しているため。(utility/socket.cpp)
  • 結果、InfuluxDBのREST API側としては続きが送られてこないため、(約30秒の)タイムアウトエラーが発生してしまう。
uint16_t send(SOCKET s, const uint8_t * buf, uint16_t len)
{
  uint8_t status=0;
  uint16_t ret=0;
  uint16_t freesize=0;

  if (len > w5500.SSIZE) 
    ret = w5500.SSIZE; // check size not to exceed MAX size.
  else 
    ret = len;

  // if freebuf is available, start.
  do 
  {
    freesize = w5500.getTXFreeSize(s);
    status = w5500.readSnSR(s);
    if ((status != SnSR::ESTABLISHED) && (status != SnSR::CLOSE_WAIT))
    {
      ret = 0; 
      break;
    }
  } 
  while (freesize < ret);

  // copy data
  w5500.send_data_processing(s, (uint8_t *)buf, ret);
  w5500.execCmdSn(s, Sock_SEND);

  /* +2008.01 bj */
  while ( (w5500.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK ) 
  {
    /* m2008.01 [bj] : reduce code */
    if ( w5500.readSnSR(s) == SnSR::CLOSED )
    {
      close(s);
      return 0;
    }
  }
  /* +2008.01 bj */
  w5500.writeSnIR(s, SnIR::SEND_OK);
  return ret;
}

修正内容

  • 上記のsend()メソッドを呼び出す側で、2048byte以下(1536byte)となるように区切って、複数回のメソッド呼び出しとなるようにした。(コードは、リンク先のGitHubを参照)

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA