システムの開発を進めていく際のデバッグ用、もしくは開発完了後のアクセスポイントの動作確認用として、表示デバイスがあると非常に利便性が高くなる。このセンサネットワークでは、小型有機LEDのSSD1306をI2C通信により駆動する。

以下は、GPIOのピン番号設定と表示関連の関数である。特に説明の必要はないと思うが、SSD1306をスリープさせる関数も用意されているので、省電力化は容易である。

// OLED関連定義
#define OLED_Address  0x3C
#define OLED_SDAPin   21
#define OLED_SCLPin   22
#define OLED_Font24   ArialMT_Plain_24
#define OLED_Font16   ArialMT_Plain_16
SSD1306 display(OLED_Address, OLED_SDAPin, OLED_SCLPin);

// 動作状態出力ピン
#define STATPin       19

// OLED初期化
void displayInit() {
  display.init();                 // SSD1306初期化
  display.clear();                // 表示エリアクリア
  display.flipScreenVertically(); // 180度回転表示
  display.display();              // 表示更新
}

// 経過時間の文字列変換(最大表示 99時間59分59秒 = 359,999秒)
void timeConvert(unsigned long counter, char time[9]) {
  unsigned int limit = 360000, n;
  uint16_t h;
  uint8_t m, s;
  if (counter > limit) n = limit - 1;
  else n = counter;
  s = n % 60;
  m = ((n - s) / 60) % 60;
  h = (n - s - m * 60) / 3600;
  time[0] = h / 10 + 0x30;
  time[1] = h % 10 + 0x30;
  time[2] = ':';
  time[3] = m / 10 + 0x30;
  time[4] = m % 10 + 0x30;
  time[5] = ':';
  time[6] = s / 10 + 0x30;
  time[7] = s % 10 + 0x30;
  time[8] = 0x00; // 経過時間文字列終端
}

// インターバル文字列変換(最大表示99)
void intervalConvert(uint16_t interval, char base[3]) {
  uint8_t n;
  if (interval > 100) n = 99;
  else n = interval;
  base[0] = n / 10 + 0x30;
  base[1] = n % 10 + 0x30;
  base[2] = 0x00; // インターバル文字列終端

}

// データサイズ文字列変換(1024の倍数, 例外0:1byte)
void datasizeConvert(uint8_t data, char size[3]) {
  uint8_t n;
  if (data > 100) n = 99;
  else n = data;
  size[0] = n / 10 + 0x30;
  size[1] = n % 10 + 0x30; 
  size[2] = 0x00; // データサイズ文字列終端
}

// クライアント接続状態の文字列変換
void clientConvert(client c, char stat[6]) {
  uint8_t n = 0, w = 0;
  for (uint8_t num = 0; num < CLIENT_MAX; num++) {
    if (c.Connect[num]) {
      n++; // 接続クライアント数
      if (c.Station[num] == 1) w++; // 接続ウェブブラウザ数
    }
  }
  stat[0] = w / 10 + 0x30;
  stat[1] = w % 10 + 0x30;
  stat[2] = '/';
  stat[3] = n / 10 + 0x30;
  stat[4] = n % 10 + 0x30;
  stat[5] = 0x00; // クライアント状態文字列終端
}

// APモード表示更新
void displayAPMode() {
  char time[9], base[3], size[3], stat[6];
  display.clear();                     // 表示エリアクリア
  display.setFont(OLED_Font24);        // フォント24使用
  display.drawString(  0,  0, ssid);   // SSID表示設定
  timeConvert(setupCounter, time);     // 経過時間の文字列変換
  display.drawString(  0, 20, time);   // 経過時間表示設定
  intervalConvert(intervalBase, base); // インターバル文字列変換
  display.drawString(101, 20, base);   // インターバル表示設定
  datasizeConvert(datasizeBase, size); // データサイズ文字列変換
  display.drawString(101, 40, size);   // データサイズ表示設定
  clientConvert(clientSTAT, stat);     // クライアント接続状態の文字列変換 
  display.drawString(  0, 40, stat);   // クライアント表示設定
  display.display();                   // 表示更新
}

以下に表示例を示す。上段のAP-ESP32は、アクセスポイントのSSIDである。

中段左は、アクセスポイントを起動してからの時間(時:分:秒)を示している。秒単位で更新されるので、ネットワークの不具合などのデバッグに活用できる。中段右は100msec単位のインターバル係数。この例では、300msec間隔でセンサデバイスから情報を受け取っている。

下段左は接続中のクライアント数(分子がブラウザ数、分母が総数)を示す。1つのブラウザ、2つのセンサデバイスが接続し、総数は3である。下段右は1024byte単位のデータサイズ係数。8x1024=8192byteのデータをセンサデバイスから受け取っている。例外として、係数0の場合は1byteのデータサイズとしている。