質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.52%

  • Arduino

    537questions

    Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

ESP32のWiFi通信

受付中

回答 0

投稿

  • 評価
  • クリップ 0
  • VIEW 515

CyPris

score 3

 前提・実現したいこと

二つのESP32で片方をAPモードでサーバーとして、もう片方をクライアントとしてクライアントから
サーバーにWiFi接続し、データを送信したいと思っています。
それぞれのESP32はデータを送受信したらサーバーはライトスリープ、クライアントはディープスリープはいるようにしてあります。
仕様ソフトはArduino IDEを使用しました。

 発生している問題・エラーメッセージ

起動時は問題なく確実に接続されるのですが、スリープ後にWiFi接続する際に接続されることもあれば、全く接続されないことが起きています。
この問題に周期性がなく、不規則に発生するので解決できない次第です。

 該当のソースコード

/*************クライアント*************/
#include<WiFi.h>
const char *ssid = "ESP32-WiFi"; //サーバーのSSID
const char *pass = "esp32wifi"; //サーバーのパスワード
const IPAddress ip(192, 168, 20, 2); //サーバーのIPアドレス
//const IPAddress ip(192,168,0,9);
static WiFiClient client; //WiFiClient型でclientと宣言

#define TIME 10
#define uS 1000*1000

//WiFiに接続するまでtry つながったらtrue、つながらなかったらfalseを返す
//tryの回数とか、待ち時間は指定する?
bool WiFi_connect_and_try(int try_count, int wait_sec)
{
  Serial.println("now WiFi_connect and try");
  for (int i = 0; i < try_count; i++)
  {
    WiFi.begin(ssid, pass); //接続を試みる
    for (int n = 0; n < wait_sec; n++)
    {
      if (WiFi.status() == WL_CONNECTED)
      {
        Serial.println("WiFi connected");
        return true;
      }
      Serial.print(".");
      Serial.print(WiFi.status());
      delay(1000);
    }
    WiFi.disconnect(1);
    delay(5000);
  }
  Serial.println("WiFi connect error");
  return false;
};

bool Client_connect_and_try(int try_count, int wait_sec, bool error_flag)
{
  Serial.println("now client_connect and try");
  if (error_flag == false)
  {
    return false;
  }
  for (int i = 0; i < try_count; i++)
  {
    client.connect(ip, 80);
    delay(100);
    for (int n = 0; n < wait_sec; n++)
    {
      if (client.connected() == true)
      {
        Serial.println("client connection OK");
        return true;
      }
      Serial.print(".");
      delay(1000);
    }
  }
  Serial.println("client connection false");
  return false;
};


/*-------------server connect-------------*/
/*
  bool status_check()
  {
  int count = 0;
  while (WiFi.status() != WL_CONNECTED && count < 10)
  {
    count++;
    Serial.print(".");
    Serial.print(WiFi.status());
    delay(1000);
  }
  if (WiFi.status() == WL_CONNECTED)
  {
    Serial.println("WiFi Connected");
    client.connect(ip, 80); //IPアドレスとポート番号を指定して接続
    return 1;
  }
  return 0;
  }
  void connect_try()
  {
  WiFi.begin(ssid, pass);
  int try_count = 0;
  while (status_check() != 1 && try_count < 3)
  {
    try_count++;
  //    WiFi.reconnect();
  //    delay(1000);
    WiFi.disconnect(1);
    delay(100);
    WiFi.begin(ssid,pass);
  }
  if (try_count == 3)
  {
    Serial.println("False");
  }
  }
*/
/*-------------メッセージ"Hello"送信-------------*/
bool message_send(bool error_flag)
{
  Serial.println("now message send");
  if (error_flag == false)
    return false;

  if (client.connected() == true)
  {
    Serial.println("Massage Send");
    client.println("Hello");

    /*//ここに入れるか検討
    delay(5000);
    client.stop();
    client.flush();
    delay(1000);
    */
    return true;
  }
  return false;
}


/*------------ディープスリープ関数-------------*/
bool sleep()
{
  Serial.printf("Deep Sleep Start(%d秒)\n",TIME);
  //deep_sleepの時間を設定
  esp_sleep_enable_timer_wakeup(TIME * uS);
  esp_deep_sleep_start();
}
void setup()
{
  bool error_flag = false;
  Serial.begin(115200);
  Serial.println("Program Start");

  error_flag = WiFi_connect_and_try(3, 10); //10秒ごとに3回接続トライ
  //delay(1000);
  Client_connect_and_try(3, 10, error_flag);  //10秒ごとに3回接続トライ
  message_send(error_flag);

  /*
    connect_try();
    message_send();
    WiFi.disconnect(1);
    delay(1000);
  */
}

void loop()
{
  sleep();

}

/*************サーバ*************/
#include<WiFi.h>
const char *ssid = "ESP32-WiFi"; //SSID
const char *pass = "esp32wifi"; //パスワード
const IPAddress ip(192, 168, 20, 2);  //サーバーのIPアドレス

//const IPAddress ip(192,168,0,9);

const IPAddress subnet(255, 255, 255, 0); //サブネットマスク
static WiFiServer server(80);
static WiFiClient client;
#define TIME 10
#define uS 1000*1000
void wifi_AP_mode_start()
{
  int flag=0;
  Serial.println("Configuring access point...");
  flag=WiFi.softAP(ssid, pass); //SSIDとパスの設定
  WiFi.softAPConfig(ip, ip, subnet); //IPアドレス、ゲートウェイ、サブネットマスクの設定

  //delay(100); //接続失敗防止
  //delay(500);
  //delay(200);
  IPAddress myIP = WiFi.softAPIP(); //WiFi.softAPIP()でWiFi起動
  //delay(100);
  /*各種情報を表示*/
  Serial.printf("softAP condition %d\n", flag);
  Serial.println("Access Point Information");
  Serial.print("SSID:");
  Serial.print(ssid);
  Serial.print(" ");
  Serial.print("AP IP Address:");
  Serial.println(myIP);
  Serial.println("Server Begin");
  server.begin(); //サーバーを起動(htmlを表示させるため)
}
/*bool Client_connect_and_try(WiFiServer* server, int try_count, int wait_sec)
{
  Serial.println("now Client_connect and try");
  for (int i = 0; i < try_count; i++)
  {
    wifi_AP_mode_start();
    for (int n = 0; n < wait_sec; n++)
    {
      //接続してきたクライアントの情報を得る
      client = server->available(); //WiFiClient client = sever.available();と同じ意味
      //接続されるとclientがNULLでなくなる
      if (client)
      {
        Serial.println("New Client");
        while (client.connected())
        {
          //Serial.println("client.connected");
          if (int data_size = client.available())
          {
            Serial.println("client.available");
            String line = client.readStringUntil('\n');
            Serial.println(line);
            Serial.print("client.available()_size:");
            Serial.println(data_size);
            //client.stop();  //ここでもあまり変わらないかも?
            return true;
          }
        }
      }
      client.stop(); //ここが一番接続しやすいかも?
      Serial.print(".");
      delay(1000);
    }
    WiFi.softAPdisconnect(1);
  }
  Serial.println("Client connect error");
  return false;
};
*/
bool wait_client_communication(WiFiServer * server, int wait_time)
{
  Serial.printf("wait client_communication(%d秒)\n", wait_time);
  for (int i = 0; i < wait_time; i++)
  {
    //接続してきたクライアントの情報を得る
    client = server->available(); //WiFiClient client = sever.available();と同じ意味
    //接続されるとclientがNULLでなくなる
    if (client)
    {
      Serial.println("New Client");
      while (client.connected())
      {
        //Serial.println("client.connected");
        if (int data_size = client.available())
        {
          Serial.println("client.available");
          String line = client.readStringUntil('\n');
          Serial.println(line);
          Serial.print("client.available()_size:");
          Serial.println(data_size);
          //client.stop();  //ここでもあまり変わらないかも?
          return true;
        }

      }
      //if(!client.connected()){client.stop();}
      //client.stop();

    }

    client.stop(); //ここが一番接続しやすいかも?
    Serial.print(".");
    delay(1000);
  }
  Serial.println("client connection false");
  return false;
};
void light_sleep()
{
  esp_sleep_enable_timer_wakeup(TIME * uS);
  Serial.printf("light Sleep Start(%d秒)\n", TIME);
  esp_light_sleep_start();
  //delay(5000);
  Serial.println("Wake Up");
};
/*bool message_recive()
  {
  //接続したクライアントの情報を得る。
  WiFiClient client = server.available();
  if(client){
    Serial.println("New Client");
    while(client.connected()){
      if(client.available()){
        String line = client.readStringUntil('\n');
        //client.stop();
        Serial.println(line);

        return true;
      }
    }
  }

  }*/
void setup()
{
  Serial.begin(115200);
  Serial.println("Program Start");
}

void loop()
{
  /*3,10);
  Serial.println("softAPdisconnec
  Client_connect_and_try(&server,
  delay(1000);t");
  WiFi.softAPdisconnect();
  */
  wifi_AP_mode_start();
  wait_client_communication(&server, 40);
  Serial.println("softAPdisconnect");
  WiFi.softAPdisconnect(1);
  WiFi.disconnect(1);
  //delay(1000);
  light_sleep();


  /*if(message_recive()==true)
    {
    delay(500);
    Serial.println("AP Mode Shutdown");
    WiFi.softAPdisconnect(1);
    delay(100);
    wifi_ap();
    } 
    */
}

 試したこと

ESP32の動作よりWiFi接続の動作の方が重いようなので、
適当なもの場所にdelayをかけてみましたが改善されませんでした。

 補足情報(FW/ツールのバージョンなど)

サーバー・クライアント:ESP32 DevKit
仕様ソフト:Arduino IDE ver1.8.5

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.52%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Arduino

    537questions

    Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。