WiFi 送信出力を調整する

いつも使っているWiFi接続用のコード

wifi.ino

#include <WiFi.h>
const char* ssid = "xxxxxxxxx";
const char* password = "yyyyyyyy";

void setup(){
    Serial.begin(115200);
    delay(100);
    
    // Connect WiF 
    WiFi.disconnect();
    WiFi.softAPdisconnect(true);
    delay(500);

    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED)
    {
      Serial.println("...Connecting to WiFi");
      delay(500);
    }
    Serial.println("Connected");
}

void loop(){
  delay(10);
}

を使って、ESP32S3ボードでWiFiに繋ごうとしたらなかなか繋がらない。

同じスケッチをESP32で試すと問題無く繋がる。ネットで原因を調べたらWiFi送信出力に問題が有る事が分かりました。

WiFi 送信出力を調整する

ESP32にはWiFi 送信出力設定関数として bool setTxPower(wifi_power_t power);、設定値読み込関数として wifi_power_t getTxPower(); があります。

設定関数setTxPower() は

bool WiFiGenericClass::setTxPower(wifi_power_t power){
if((getStatusBits() & (STA_STARTED_BIT | AP_STARTED_BIT)) == 0){
log_w(“Neither AP or STA has been started”);
return false;
}
return esp_wifi_set_max_tx_power(power) == ESP_OK;
}
と定義されていて、ログのメッセージからAPかSTAの開始後に使用する必要があります。

また引数の型 wifi_power_t は、WiFiGeneric.h に
typedef enum {
WIFI_POWER_19_5dBm = 78,// 19.5dBm
WIFI_POWER_19dBm = 76,// 19dBm
WIFI_POWER_18_5dBm = 74,// 18.5dBm
WIFI_POWER_17dBm = 68,// 17dBm
WIFI_POWER_15dBm = 60,// 15dBm
WIFI_POWER_13dBm = 52,// 13dBm
WIFI_POWER_11dBm = 44,// 11dBm
WIFI_POWER_8_5dBm = 34,// 8.5dBm
WIFI_POWER_7dBm = 28,// 7dBm
WIFI_POWER_5dBm = 20,// 5dBm
WIFI_POWER_2dBm = 8,// 2dBm
WIFI_POWER_MINUS_1dBm = -4// -1dBm
} wifi_power_t;

となっています。これらを考慮して以下にスケッチを書いて見ました。

TX_Power00.ino

#include <WiFi.h>

const char* ssid = "xxxxxxxx";
const char* password = "yyyyyyyy";

void setup() {
  int a;
  
  Serial.begin(115200);
  measure_TX();
}

void loop() {
  
  delay(10);
  
}

void measure_TX(){
  int a, b; 
  bool flg;  
  wifi_power_t db_data[] = {
    WIFI_POWER_19_5dBm,     // 78:  19.5dBm
    WIFI_POWER_19dBm,       // 76:  19dBm
    WIFI_POWER_18_5dBm,     // 74:  18.5dBm
    WIFI_POWER_17dBm,       // 68:  17dBm
    WIFI_POWER_15dBm,       // 60:  15dBm
    WIFI_POWER_13dBm,       // 52:  13dBm
    WIFI_POWER_11dBm,       // 44:  11dBm
    WIFI_POWER_8_5dBm,      // 34:  8.5dBm
    WIFI_POWER_7dBm,        // 28:  7dBm
    WIFI_POWER_5dBm,        // 20:  5dBm
    WIFI_POWER_2dBm,        // 8 :  2dBm
    WIFI_POWER_MINUS_1dBm,  // -4:  -1dBm
  };

    delay(100);
    Serial.println("\nTxPower: " + String(WiFi.getTxPower()));
    
    for(b = 0; b < 12; b ++){                    
      WiFi.disconnect();
      delay(100);
      
      WiFi.begin(ssid, password);
      flg = WiFi.setTxPower(db_data[b]); 
      Serial.print("Set TX:" + String(db_data[b]));
      if(flg) Serial.print(",  OK ");
      else Serial.print(",  NG "); 
      Serial.print(",  GetTX: " + String(WiFi.getTxPower()));
      
      a = 3;    // wait 3sec
      while (WiFi.status() != WL_CONNECTED) {
        delay(1000);
        a --;
        if (!a) break;               
      }
      if (!a) Serial.println(" ,  Fail!");
      else  Serial.println(" ,  Success!");
    }
    Serial.println("OK");
}

スケッチの内容は

  • トップに現在の送信出力(TXの値)を表示
  • 予め設定してある、wifi_power_tの値(12個)を順番に設定して行く。
  • setTxPowerの戻り値がTrueなら”OK”。Falseなら”NG”。
  • 接続の判断は3秒内に接続出来れば、”Success!”。出来なければ、”Fail!”
  • 設定値、setTxPowerの戻り値、読み取り値、接続結果の順に結果を表示。

実行結果は以下の通り

初期設置値は78。 これはMAX値の様です。設定は78(WIFI_POWER_19_5dBm)から行い、78,76,74,68と Failし、60からつながる様です。

setTxPower(); 引数は、wifi_power_t 型の数で有れば良い様に思えるので、コードを下記の様に変えて見ました。設定値の最小値と減少値を引数にしています。

TX_Power00.ino

#include <WiFi.h>

const char* ssid = "xxxxxxxx";
const char* password = "yyyyyyyy";

void setup() {
  int a;
  
  Serial.begin(115200);
  measure_TX(20, 10);
}

void loop() {
  
  delay(10);
  
}

void measure_TX(int TX_min, int skip){
  int a, tx_data;   
  
    delay(50);
    tx_data = WiFi.getTxPower();         
    Serial.println("\nTxPower: " + String(tx_data));
    
    while(tx_data >= TX_min){                    
      WiFi.begin(ssid, password);
      WiFi.setTxPower((wifi_power_t)tx_data);  
    delay(50);
      Serial.print("WiFi connection at " + String(WiFi.getTxPower()));
      a = 3;    // wait 3sec
      while (WiFi.status() != WL_CONNECTED) {
        delay(1000);
        a --;
        if (!a) break;               
      }
      if (!a) Serial.println("  Fail!");
      else  Serial.println("  Success!");
      WiFi.disconnect();
      tx_data -= skip;
    }
    Serial.println("OK");
}

設定最小値を50。 減少値を2と指定た場合お実行結果は以下の通り。

前回より設定値を細かく指定しています。今回は72でFail。70でSuccessとなりました。この2つの結果から出力を60(WIFI_POWER_15dBm)位にセットするのが良さそうです。そこで、WiFi.setTxPower(WIFI_POWER_15dBm);をWiFi.begin(ssid, password);の後に入れて実行すると、嘘の様に簡単に接続しました。

wifi01.ino

#include <WiFi.h>
const char* ssid = "xxxxxxxxx";
const char* password = "yyyyyyyy";

void setup(){
    Serial.begin(115200);
    delay(100);
    
    // Connect WiF 
    WiFi.disconnect();
    WiFi.softAPdisconnect(true);
    delay(500);

    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);

    WiFi.setTxPower(WIFI_POWER_15dBm);

    while (WiFi.status() != WL_CONNECTED)
    {
      Serial.println("...Connecting to WiFi");
      delay(500);
    }
    Serial.println("Connected");
}

void loop(){
  delay(10);
}

問題無くWiFiに繋がる様になったので結果的には良いのですが、送信出力を下げると繋がるとはどういう理由なのでしょうか。