2025年9月25日木曜日

LEDマトリックス表示装置の設計・製作 3(WiFi・NTP)

 WiFiとNTP

 WiFiとNTPから時間を取得するプログラムは、インターネットから容易に取得できるので、取得して、実行します(この時WiFiのSSIDとPasswordは環境に合わせます)。

 実行結果が右図です。
 WiFiに接続後に、NTPサーバより時間を取得して、1秒ごとに時間を表示しています。




WiFi設定の課題と解決策

 WiFiは便利に使え、FreeWiFiも増えてきています。タブレットやノートPCでは、簡単にWiFiへの接続設定ができますが、マイコンではプログラム中にSSIDとPASSを書き込んでいます。WiFi環境が変わると接続できなくなり、プログラムを書き換えるしかありません。
 この課題は先駆者たちが、WiFiに接続できないときにタブレットと連携して設定する仕組み(WiFi Manager)などを開発しています。

 今回はUSBメモリが利用できるため、以前に紹介した「esp32s3_USB_Drive-main.zip」を使います。USBメモリにWiFi設定ファイルを作成しておき、このファイルを読み込んでWiFi設定をします。

WiFi設定ファイルの構造

 WiFi設定ファイルはメモ帳などで作成できます。
 ただし、文字コードに注意が必要です。近年は、UTFコードが標準になりつつあります。

 WiFi設定ファイルを右図のように作成します。





 名前を付けて保存するときに、ファイル名の下に、エンコードタイプとあります。ここでコードタイプを設定できるのですが、UTF-8に「UTF-8」と「UTF-8(BOM付き)」の2種類あります。
 ここでBOM(Byte Order Mark)は、ファイル形式がUTF-8コードであることを示すため、3バイト「EF BB BF」(16進数)が先頭に付加されるものです。
 これをUSBメモリに保存して、ESP32マイコンから読み込むと、本来「mySSID」の文字列が「???mySSID」のようになってしまいます。このSSIDとPasswordを使ってWiFiに接続しても接続できません。

WiFi設定ファイルを読み込む方法

 SSIDに設定する文字は「ASCIIコード(7ビット)」です。このことから制御コード(00H~1FH、7FH)を除いたコード 20H~7EHの文字を有効な文字として処理します。これによりUTF-8のBOMは除外(削除処理)されることになります。
 この処理はプログラムで処理します。

esp32s3_USB_Driveの改造

 USBメモリを読み込む「esp32s3_USB_Drive」にWiFiに接続する機能を追加します。

 プログラムの先頭で、WiFiに関する定義を追加
#include <WiFi.h>
char ssid[30], pass[30];

 file_operations関数を変更
  読み込むファイルは「/usb/wifi.txt」
  不要なコードを取り除く処理。
 
static void file_operations(void)
{
  const char *file_path = "/usb/wifi.txt";
  FILE *f;
  ESP_LOGI(TAG, "Reading file");
  f = fopen(file_path, "r");
  if (f == NULL) {
    ESP_LOGE(TAG, "Failed to open file for reading");
    return;
  }
  char line[64];
   int ptr;
  // 読み込んだデータをSSIDに格納
  char *pos;
  fgets( line, sizeof(line), f);
  //文字列のクリア
  for ( int i = 0; i < 30; i++) ssid[i] = 0;
  ptr = 0;
  for ( int i = 0; i < strlen(line); i++) {
    if ( 0x20 <= line[i] && line[i] < 0x7f ) {
      ssid[ptr] = line[i];
      ptr++;
    }
  }
  // 読み込んだデータをPASSに格納
  fgets(line, sizeof(line), f);
  //文字列のクリア
  for ( int i = 0; i < 30; i++) pass[i] = 0;
  ptr = 0;
  for ( int i = 0; i < strlen(line); i++) {
    if ( 0x20 <= line[i] && line[i] < 0x7f ) {
      pass[ptr] = line[i];
      ptr++;
    }
  }
  fclose(f);
}

setup関数の終わりでWiFiに接続する処理

 このサンプルは、外部入力スイッチを押すと、USBメモリを取り外す処理をしています。今回スイッチ処理は使わないため、不要な部分をコメントアウトしました。
 
//  do {
    uint8_t device_address = wait_for_msc_device();

    ESP_ERROR_CHECK( msc_host_install_device(device_address, &msc_device) );

    msc_host_print_descriptors(msc_device);

    ESP_ERROR_CHECK( msc_host_get_device_info(msc_device, &info) );
    print_device_info(&info);

    ESP_ERROR_CHECK( msc_host_vfs_register(msc_device, "/usb", &mount_config, &vfs_handle) );

    //while (!wait_for_event(DEVICE_DISCONNECTED, 200)) {
      file_operations();
    //}
//    xEventGroupClearBits(usb_flags, READY_TO_UNINSTALL);
//    ESP_ERROR_CHECK( msc_host_vfs_unregister(vfs_handle) );
//    ESP_ERROR_CHECK( msc_host_uninstall_device(msc_device) );

//  } while (gpio_get_level(USB_DISCONNECT_PIN) != 0);

//  ESP_LOGI(TAG, "Uninitializing USB ...");
//  ESP_ERROR_CHECK( msc_host_uninstall() );
//  wait_for_event(READY_TO_UNINSTALL, portMAX_DELAY);
//  ESP_ERROR_CHECK( usb_host_uninstall() );
//  ESP_LOGI(TAG, "Done");

  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi OK.");

 これで実行させ、USBメモリを認識すると、WiFi接続が完了します。
 また、NTPサーバに接続して、時間表示させるプログラムも追加してm動作させました。






esp32s3_USB_Driveを改良して分かったこと

 USB Driveのサンプルプログラムは、ソースコードを見てわかるように、FreeRTOSを利用し、割り込みにより処理をしています。
 このサンプルでは、USBメモリを認識するまで、処理が進まず待ち続けます。しかし、常にUSBメモリが接続されているわけでなく、処理によってはUSBメモリがない時には、次の処理に移りたい時があります。
 解析の結果、この場合には次の場所を変えることで、一定時間、USBを認識しないと次の処理に移行するように変更できます。

wait_for_msc_device関数内を変更
 プログラムの行末のパラメータ「portMAX_DELAY」のままであると、無制限に待ちます。これを「3000」に変更すると、3秒(3000mS)待ち、ループを抜けるようになります。

event = xEventGroupWaitBits(usb_flags, DEVICE_CONNECTED | DEVICE_ADDRESS_MASK, pdTRUE, pdFALSE, portMAX_DELAY);



0 件のコメント:

コメントを投稿

LEDマトリックス表示装置の設計・製作 9(画像表示)

  LEDマトリックスに画像を表示させるには、いろいろな画像形式を知る必要があります。現在、よく使われるJPG形式やPNG形式は圧縮処理されて保存されています。これに対して、BMP形式やTIFF形式は非圧縮形式で、画像データがそのまま保存されています。このため、ファイルは大きくな...