ESP32をWi-Fiに繋げる
ESP32をWi-Fiに繋げてHello World
これをやりたいが為にESP32をチョイスしたと言っても過言ではないです。
Wi-Fiに繋げて、後はESP32を電池で動かせれば言うことなし。
さっそく自宅のWi-Fiに接続してみます。
Wi-Fi経由でLチカさせましょう。
まずESP32のWi-Fiですが以下のモードがあります。
- ステーション
ESP32からWi-Fiアクセスポイントに接続しに行きます。 - アクセスポイント
ESP32自身がアクセスポイントになって接続を受け付けます。 - ステーション + アクセスポイント
- 近接認識ネットワーク (NAN)
近くにいるデバイスと相互接続できます。Wi-Fi Aware。
上記以外にもWIFI_IF_MAXというモードがあるのですが、こちらは調べてもよくわかりませんでした。
とりあえず ステーション で自宅のWi-Fiに接続してみます。
ソース
Wi-Fiに接続してWebサーバーを起動。
Webサーバーは「Hello World」を表示するだけの簡単なものです。
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_http_server.h"
// Wi-Fiの暗号化モードは WPA2-PSK AES (WPA2ならいいのかも)
#define WIFI_SSID "mySSID" // 自分のWi-FiのSSID
#define WIFI_PASS "myPASS" // 自分のWi-Fiのパスワード
static EventGroupHandle_t wifi_event_group; // イベント
static esp_netif_t *netif_tcpstack; // TCP/IPスタック
static httpd_handle_t server; // Webサーバー
// Wi-Fi接続イベントハンドラ
static void connect_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
{
xEventGroupSetBits(wifi_event_group, BIT0); // FreeRTOSイベントグループ BIT0 をON
}
// Wi-Fi切断イベントハンドラ
static void disconnect_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
{
esp_wifi_connect(); // 切断されたら再接続
xEventGroupClearBits(wifi_event_group, BIT0); // FreeRTOSイベントグループ CONNECTED_BITをOFF
}
// Wi-Fi初期化
void wifi_init_station() {
wifi_event_group = xEventGroupCreate(); // FreeRTOSイベントグループ初期化
// Wi-Fi初期化
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
// Wi-Fi設定/開始
esp_netif_inherent_config_t esp_netif_config = {
.flags = ESP_NETIF_FLAG_GARP | ESP_NETIF_DHCP_CLIENT | ESP_NETIF_FLAG_MLDV6_REPORT | ESP_NETIF_FLAG_EVENT_IP_MODIFIED,
.mac = { },
.ip_info = NULL,
.get_ip_event = IP_EVENT_STA_GOT_IP,
.lost_ip_event = IP_EVENT_STA_LOST_IP,
.if_key = "WIFI_STA_DEF",
.if_desc = "sta",
.route_prio = 128,
.bridge_info = NULL
};
netif_tcpstack = esp_netif_create_wifi(WIFI_IF_STA, &esp_netif_config);
ESP_ERROR_CHECK(esp_wifi_set_default_wifi_sta_handlers());
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_start());
// イベントハンドラ登録
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &connect_handler, NULL)); // Wi-Fiのアクセスポイント(AP)からIPを取得
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &disconnect_handler, NULL)); // Wi-Fiステーション切断
// Wi-Fi APへ接続
wifi_config_t wifi_config = {
.sta = {
.ssid = WIFI_SSID,
.password = WIFI_PASS,
.scan_method = WIFI_ALL_CHANNEL_SCAN,
.sort_method = WIFI_CONNECT_AP_BY_SIGNAL,
.threshold.rssi = -127,
.threshold.authmode = WIFI_AUTH_WPA2_PSK,
}
};
ESP_LOGI("Wi-Fi", "Connecting to %s...", wifi_config.sta.ssid);
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
esp_err_t ret = esp_wifi_connect(); // Wi-Fi APへ接続
if (ret != ESP_OK) {
ESP_LOGE("Wi-Fi", "WiFi connect failed! ret:%x", ret);
ESP_ERROR_CHECK(ret);
}
// Wi-Fi接続待ち ( FreeRTOSのインベントグループ(wifi_event_group) の BIT0 が true になるまで待ちます )
xEventGroupWaitBits(wifi_event_group, BIT0, false, true, portMAX_DELAY);
// Wi-Fi接続完了、IPアドレス取得完了。取得したIPアドレスをログに出力します。
ESP_LOGI("Wi-Fi", "Connected to %s", esp_netif_get_desc(netif_tcpstack));
esp_netif_ip_info_t ip;
ESP_ERROR_CHECK(esp_netif_get_ip_info(netif_tcpstack, &ip));
ESP_LOGI("Wi-Fi", "IP Address: " IPSTR, IP2STR(&ip.ip));
}
// GET "/" ハンドラ
esp_err_t get_root(httpd_req_t *req) {
const char resp[] = "<h1>Hello World</h1>";
httpd_resp_send(req, resp, HTTPD_RESP_USE_STRLEN);
return ESP_OK;
}
// URLマップ "/"
httpd_uri_t root = {
.uri = "/",
.method = HTTP_GET,
.handler = get_root,
.user_ctx = NULL
};
// Webサーバー開始
void start_webserver(void)
{
server = NULL;
httpd_config_t conf = HTTPD_DEFAULT_CONFIG();
// Webサーバー開始
if (httpd_start(&server, &conf) == ESP_OK) {
ESP_LOGI("Web", "Server start");
// URLマップハンドラ登録
httpd_register_uri_handler(server, &root);
}
}
// Webサーバー停止
void stop_webserver() {
if (server) {
httpd_stop(server);
server = NULL;
}
}
// シャットダウンハンドラ
static void app_shutdown(void) {
// Webサーバー停止
stop_webserver();
// イベントハンドラ解放
ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, &connect_handler));
ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &disconnect_handler));
// Wi-Fi切断
esp_wifi_disconnect();
// Wi-Fi停止/設定初期状態
esp_err_t err = esp_wifi_stop();
if (err == ESP_ERR_WIFI_NOT_INIT) {
return;
}
ESP_ERROR_CHECK(err);
ESP_ERROR_CHECK(esp_wifi_deinit());
ESP_ERROR_CHECK(esp_wifi_clear_default_wifi_driver_and_handlers(netif_tcpstack));
esp_netif_destroy(netif_tcpstack);
netif_tcpstack = NULL;
}
void app_main(void)
{
nvs_flash_init(); // Flash初期化 (お約束のようなもの)
// シャットダウンハンドラ, esp_restart関数で再起動される前に呼び出されます
ESP_ERROR_CHECK(esp_register_shutdown_handler(&app_shutdown));
wifi_init_station(); // Wi-Fi初期化
if (xEventGroupGetBits(wifi_event_group) & BIT0) {
// 接続成功ならWebサーバー起動
start_webserver();
}
}
はい、長いですね。
Wi-Fi接続部分が長いだけで特に面倒なところはない気がします。
これでモニタに表示されたIPアドレスで、http://192.168.0.10/ とかでアクセスすれば Hello World と表示されます。
ソースファイルの分割とHTMLのソースをフラッシュに置く方法調べましょう。
コメント
コメントを投稿