ESP-WROOM-32の環境構築
用意したもの
ブレッドボード(ESP-WROOM32にはちょっと狭い)
ESP-WROOM32
いつも使っている無線LANルータ
コードの概要
Kconfig.projbuild
WiFiを繋ぐためにはSSIDとパスワードが必要なので、Kconfig.projbuildでビルド時にSSIDとパスワードを指定するようにした。
menu "Config" config WIFI_SSID string "WiFi SSID" default "myssid" help SSID (network name) for the example to connect to. config WIFI_PASSWORD string "WiFi Password" default "mypassword" help WiFi password (WPA or WPA2) for the example to use. endmenu
WiFiの準備
- TCP/IPアダプタの初期化
- イベントハンドラの準備
- WiFiコンフィグ関連の準備
- WiFiドライバの起動
- WiFi接続
- Webへのアクセスタスクの実行
- アクセスタスクの削除
- 接続解除
- WiFiドライバの停止
void app_main() { ESP_ERROR_CHECK( nvs_flash_init() ); ESP_LOGI(TAG, "WAKE UP!"); //TCP/IPアダプタの初期化 tcpip_adapter_init(); //イベントハンドラの準備 wifi_event_group = xEventGroupCreate(); ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); //WiFiコンフィグ関連の準備 wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&cfg)); wifi_config_t wifi_config = { .sta = { .ssid = DEFAULT_SSID, .password = DEFAULT_PWD }, }; ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); //WiFiドライバの起動 ESP_LOGI(TAG, "WIFI_START"); ESP_ERROR_CHECK(esp_wifi_start()); vTaskDelay(1000 / portTICK_PERIOD_MS); //WiFi接続 ESP_LOGI(TAG, "WIFI_CONNECT"); ESP_ERROR_CHECK(esp_wifi_connect()); //Webへアクセスタスクの実行 xTaskHandle xHandle; xTaskCreate(&http_get_task, "http_get_task", 4096, NULL, 5, &xHandle); vTaskDelay(30000 / portTICK_PERIOD_MS); //アクセスタスクの削除 vTaskDelete( xHandle ); //接続解除 ESP_LOGI(TAG, "DISCONNECT"); ESP_ERROR_CHECK(esp_wifi_disconnect()); vTaskDelay(1000 / portTICK_PERIOD_MS); //WiFiドライバの停止 ESP_LOGI(TAG, "STOP"); ESP_ERROR_CHECK(esp_wifi_stop()); }
Webへのアクセスタスク
- 接続済BITの確認
- 接続先IPの確認
- ソケット作成
- サーバへ接続
- リクエスト実行
- レスポンスの表示
static void http_get_task(void *pvParameters) { const struct addrinfo hints = { .ai_family = AF_INET, .ai_socktype = SOCK_STREAM, }; struct addrinfo *res; struct in_addr *addr; int s, r; char recv_buf[64]; while(1) { //接続済BITの確認 xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); ESP_LOGI(TAG, "Connected to AP"); int err = getaddrinfo(WEB_SERVER, "80", &hints, &res); if(err != 0 || res == NULL) { ESP_LOGE(TAG, "DNS lookup failed err=%d res=%p", err, res); vTaskDelay(1000 / portTICK_PERIOD_MS); continue; } //接続先IPの確認 addr = &((struct sockaddr_in *)res->ai_addr)->sin_addr; ESP_LOGI(TAG, "DNS lookup succeeded. IP=%s", inet_ntoa(*addr)); //ソケット作成 s = socket(res->ai_family, res->ai_socktype, 0); if(s < 0) { ESP_LOGE(TAG, "... Failed to allocate socket."); freeaddrinfo(res); vTaskDelay(1000 / portTICK_PERIOD_MS); continue; } ESP_LOGI(TAG, "... allocated socket\r\n"); //サーバへ接続 if(connect(s, res->ai_addr, res->ai_addrlen) != 0) { ESP_LOGE(TAG, "... socket connect failed errno=%d", errno); close(s); freeaddrinfo(res); vTaskDelay(4000 / portTICK_PERIOD_MS); continue; } ESP_LOGI(TAG, "... connected"); freeaddrinfo(res); //リクエスト実行 if (write(s, REQUEST, strlen(REQUEST)) < 0) { ESP_LOGE(TAG, "... socket send failed"); close(s); vTaskDelay(4000 / portTICK_PERIOD_MS); continue; } ESP_LOGI(TAG, "... socket send success"); //レスポンスの表示 do { bzero(recv_buf, sizeof(recv_buf)); r = read(s, recv_buf, sizeof(recv_buf)-1); for(int i = 0; i < r; i++) { putchar(recv_buf[i]); } } while(r > 0); ESP_LOGI(TAG, "... done reading from socket. Last read return=%d errno=%d\r\n", r, errno); close(s); ESP_LOGI(TAG, "Success!"); for(int countdown = 10; countdown >= 0; countdown--) { ESP_LOGI(TAG, "%d... ", countdown); vTaskDelay(1000 / portTICK_PERIOD_MS); } ESP_LOGI(TAG, "Starting again!"); } }
書いたコード
僕のブログにGETリクエストできました!
cd esp_trial/pwm make menuconfig
で接続先の設定を行って
make flash monitor
で実行する。
つらつらとブログのHTMLが流れた。
今日はここまで!
APIを叩けるようになればだいぶ世界が広がりそう。