開発ボード購入リンク
https://item.taobao.com/item.htm?spm=a2oq0.12575281.0.0.50111deb2Ij1As&ft=t&id=626366733674
はじめに開発ボード用に
開発環境構築ウィンドウへ
:基本ルーチン
0_Helloバグ(ESP_LOGXとprintfのは) プロジェクトテンプレート/印刷出力のデバッグ
1_LED コントロールのオンとオフLEDを
2_LED_Task タスクモード使用して制御LED
3_LEDC_PWM 制御するために使用LEDCを光効果呼吸達成するために、LED
4_ADC_LightRの 読み取りに使用するADCをフォトレジスター、光センシング達成する
5_KEY_Short_Longを 達成するためにボタンを長押し、短押しを
6_TouchPad_Interrupt 達成するために、割り込み静電容量式タッチを
7_WS2812_RMTを RGB_LED虹色の例達成するために、RMTを使用
する8_DHT11_RMT DHT11温度を読み取るためにRMTを使用する湿度センサ
9_SPI_SDCard SPIバスTFカードファイルシステムを使用する例示的な実施
10_IIC_ADXL345を 角度ADXL345加速度を読み取るためのIICバスを使用してセンサー
11_IIC_AT24C02は 小容量データストレージを実現するためにIICバステストを用い
12_IR_Rev_RMT 赤外線リモコン受信機デコーダを使用しては、RMT(NEC符号化)実施
13_IR_Send_RMTを 赤外線データ伝送を使用しては、RMTを実装しました(NECコード)
14_WIFI_Scan WIFI信号走査例近く
15_WIFI_AP ソフトAP例作成
16_WIFI_AP_TCP_Server TCPサーバを実現する ソフトAPモードでは
17_WIFI_AP_TCP_Clientは TCPクライアントを実現するソフトAPモードで
18_WIFI_AP_UDP ソフトAPモードUDP通信で達成
19_WIFI_STA ルータに接続されたSTAスレーブモード作成
20_WIFI_STA_TCP_Server スレーブモードSTAでTCPサーバを実装
21_WIFI_STA_TCP_Client スレーブモードSTA TCPクライアントに実装
22_WIFI_STA_UDP UDP通信モードSTAスレーブ実装
23_LCD_TestをLCD液晶タッチスクリーンディスプレイ・テストを
24_LVGL_Test LVGLグラフィックライブラリの簡単な例
APモードの紹介
アクセスポイント(AP)は、Wi-Fiネットワークアクセスを提供し、有線ネットワークに接続するデバイスです。有線ネットワークとのインターフェースがないことに加えて、ESP32は同様の機能を提供できます。この動作モードは、ソフトアクセスポイント(soft-AP)と呼ばれます。ソフトAPに同時に接続できるステーションの最大数は4に設定でき、デフォルトは4です。
ESP32がAPモードのみの場合、外部ネットワークにアクセスできないLAN WiFiルーターノードと見なすことができ、さまざまなデバイスからの接続要求を受け入れることができます。また、TCPおよびUDPを介して接続デバイスと接続して、データフローを実現できます。ローカルのモノのインターネットの設計において、データ受信ノードおよび送信ノードの役割を果たすことができます。
UDPプロトコルの概要
UDP(ユーザーデータグラムプロトコル、ユーザーデータグラムプロトコル)
UDPはトランスポート層プロトコルであり、その機能は、IPデータグラムサービスに最も基本的なサービス(多重化と逆多重化、およびエラー検出)を追加することです。
UDPは信頼性の低いサービスを提供し、TCPにはない利点があります。
UDPには接続がなく、接続を確立するために必要な時間遅延はありません。空間的には、TCPはエンドシステムの接続状態を維持する必要があるため、ある程度のオーバーヘッドが必要です。この接続は、受信バッファーと送信バッファー、輻輳制御パラメーター、シーケンス番号と確認番号などのパラメーターをロードします。UCPは接続状態を維持せず、これらのパラメーターも追跡しないため、オーバーヘッドは小さくなります。空間と時間の両方に利点があります。
例えば:
DNSがUDPではなくTCPで実行されている場合、DNSの速度ははるかに遅くなります。
HTTPはUDPではなくTCPを使用します。これは、テキストデータに基づくWebページでは信頼性が非常に重要であるためです。
同じ種類の専用アプリケーションサーバーがUDPをサポートする場合、よりアクティブなクライアントをサポートできる必要があります。
パケットヘッダーのオーバーヘッドは小さい**、TCPヘッダーは20バイト、UDPヘッダーは8バイトです。
UDPには輻輳制御がありません。アプリケーション層は、送信するデータと送信時間をより適切に制御できます。ネットワークの輻輳制御は、ホストの送信速度に影響しません。特定のリアルタイムアプリケーションは、安定した速度での送信を必要とします。これにより、ある程度のデータ損失は許容できますが、大きな遅延は許されません(リアルタイムビデオ、ライブブロードキャストなど)。
UDPはベストエフォート型の配信を提供し、信頼できる配信を保証するものではありません。伝送の信頼性を維持するためのすべての作業では、ユーザーがアプリケーション層で完了する必要があります。TCP確認メカニズムまたは再送信メカニズムはありません。ネットワーク上の理由で相手側に送信されない場合、UDPはアプリケーション層にエラーメッセージを返しません。
UDPはメッセージ指向です。アプリケーション層から受け渡されるメッセージの場合、ヘッダーが追加され、直接IP層に配信されます。ヘッダーはマージも分割もされず、これらのメッセージの境界を保持します。IP層に配信されたUDPユーザーデータグラムは、ヘッダーが削除された後もそのまま上位のアプリケーションプロセスに配信され、メッセージは分割できず、UDPデータグラム処理の最小単位です。
このため、UDPはデータの読み取りと書き込みの頻度と量を制御するのに十分な柔軟性を備えていません。たとえば、100バイトのメッセージを送信する場合、sendto関数を1回呼び出して100バイトを送信し、反対側の端もrecvfrom関数を使用して一度に100バイトを受信する必要があります。ループを使用して毎回10バイトを取得することはできません。これを10回繰り返します。
UDPは、DNS、SNMPなど、一度に比較的少量のデータを送信するネットワークアプリケーションで一般的に使用されます。これらのアプリケーションでは、TCPを使用すると、接続の作成、メンテナンス、および破棄に多くのオーバーヘッドが発生するためです。UDPは、マルチメディアアプリケーション(IPテレフォニー、リアルタイムビデオ会議、ストリーミングメディアなど)でもよく使用されます。データの信頼性の高い伝送は、それらにとって重要ではありません。TCPの輻輳制御は、それらに大きな遅延を生じさせ、これも耐えられません。
実験プロセス
1. ESP32でAPを作成します
2. UDPリスナーを作成する
3.コンピュータ/携帯電話がこのESP32によって作成されたAPに接続するのを待ちます
4.コンピューター/携帯電話のUDPがメッセージを送信するのを待ち、そのままメッセージを返します。
1つは、コードを書く
最初に必要なヘッダーファイルを引用します
#include <stdio.h>
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_err.h"
#include "nvs_flash.h"
#include "esp_event.h"
#include <string.h>
#include <sys/socket.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
メイン関数を書く
// 主函数
void app_main(void)
{
ESP_LOGI(TAG, "APP Start......");
//初始化flash
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES){
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
wifi_init_softap();
//新建一个udp连接任务
xTaskCreate(&udp_connect, "udp_connect", 4096, NULL, 5, NULL);
}
AP機能を作成
// WIFI作为AP的初始化
void wifi_init_softap()
{
udp_event_group = xEventGroupCreate();
tcpip_adapter_init();
ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
wifi_config_t wifi_config = {
.ap = {
.ssid = SOFT_AP_SSID,
.password = SOFT_AP_PAS,
.ssid_len = 0,
.max_connection = SOFT_AP_MAX_CONNECT,
.authmode = WIFI_AUTH_WPA_WPA2_PSK,
},
};
if (strlen(SOFT_AP_PAS) == 0){
wifi_config.ap.authmode = WIFI_AUTH_OPEN;
}
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP) );
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(TAG, "SoftAP set finish,SSID:%s password:%s \n",wifi_config.ap.ssid, wifi_config.ap.password);
}
UDP接続タスク
// 建立UDP连接并从UDP接收数据
static void udp_connect(void *pvParameters)
{
//等待WIFI连接成功事件,死等
xEventGroupWaitBits(udp_event_group, WIFI_CONNECTED_BIT, false, true, portMAX_DELAY);
ESP_LOGI(TAG, "start udp connected");
vTaskDelay(3000 / portTICK_RATE_MS);
ESP_LOGI(TAG, "create udp Client");
int socket_ret = create_udp_client();
if (socket_ret == ESP_FAIL){
ESP_LOGI(TAG, "create udp socket error,stop...");
vTaskDelete(NULL);
}else{
ESP_LOGI(TAG, "create udp socket succeed...");
//建立UDP接收数据任务
if (pdPASS != xTaskCreate(&recv_data, "recv_data", 4096, NULL, 4, NULL)){
ESP_LOGI(TAG, "Recv task create fail!");
vTaskDelete(NULL);
}else{
ESP_LOGI(TAG, "Recv task create succeed!");
}
}
vTaskDelete(NULL);
}
UDP関数を作成する
// 建立udp client
esp_err_t create_udp_client()
{
ESP_LOGI(TAG, "will connect gateway ssid : %s port:%d",UDP_ADRESS, UDP_PORT);
//新建socket
connect_socket = socket(AF_INET, SOCK_DGRAM, 0); /*参数和TCP不同*/
if (connect_socket < 0){
//打印报错信息
show_socket_error_reason("create client", connect_socket);
//新建失败后,关闭新建的socket,等待下次新建
close(connect_socket);
return ESP_FAIL;
}
//配置连接服务器信息
client_addr.sin_family = AF_INET;
client_addr.sin_port = htons(UDP_PORT);
client_addr.sin_addr.s_addr = inet_addr(UDP_ADRESS);
struct sockaddr_in Loacl_addr;
Loacl_addr.sin_addr.s_addr = htonl(INADDR_ANY);
Loacl_addr.sin_family = AF_INET;
Loacl_addr.sin_port = htons(UDP_PORT); //设置本地端口
uint8_t res = 0;
res = bind(connect_socket,(struct sockaddr *)&Loacl_addr,sizeof(Loacl_addr));
if(res != 0){
printf("bind error\n");
}
int len = 0; //长度
char databuff[1024] = "Hello Server,Please ack!!"; //缓存
//测试udp server
len = sendto(connect_socket, databuff, 1024, 0, (struct sockaddr *) &client_addr,sizeof(client_addr));
if (len > 0) {
ESP_LOGI(TAG, "Transfer data to %s:%u,ssucceed\n",inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
} else {
show_socket_error_reason("recv_data", connect_socket);
close(connect_socket);
return ESP_FAIL;
}
return ESP_OK;
}
データタスクの受信と処理
// 接收数据任务
void recv_data(void *pvParameters)
{
int len = 0; //长度
char databuff[1024]; //缓存
while (1){
memset(databuff, 0x00, sizeof(databuff));//清空缓存
//读取接收数据
len = recvfrom(connect_socket, databuff, sizeof(databuff), 0,(struct sockaddr *) &client_addr, &socklen);
if (len > 0){
//打印接收到的数组
ESP_LOGI(TAG, "UDP Client recvData: %s", databuff);
//接收数据回发
sendto(connect_socket, databuff, strlen(databuff), 0,(struct sockaddr *) &client_addr, sizeof(client_addr));
}else{
//打印错误信息
show_socket_error_reason("UDP Client recv_data", connect_socket);
break;
}
}
close_socket();
vTaskDelete(NULL);
}
WIFIイベント処理
// wifi 事件
static esp_err_t event_handler(void *ctx, system_event_t *event)
{
switch (event->event_id)
{
case SYSTEM_EVENT_AP_STACONNECTED: //AP模式-有STA连接成功
//作为ap,有sta连接
ESP_LOGI(TAG, "station:" MACSTR " join,AID=%d\n",MAC2STR(event->event_info.sta_connected.mac),event->event_info.sta_connected.aid);
xEventGroupSetBits(udp_event_group, WIFI_CONNECTED_BIT);
break;
case SYSTEM_EVENT_AP_STADISCONNECTED://AP模式-有STA断线
ESP_LOGI(TAG, "station:" MACSTR "leave,AID=%d\n",MAC2STR(event->event_info.sta_disconnected.mac),event->event_info.sta_disconnected.aid);
xEventGroupClearBits(udp_event_group, WIFI_CONNECTED_BIT);
break;
default:
break;
}
return ESP_OK;
}
2、ダウンロードテスト
ESP-IDFコマンドプロンプトを開く
このプロジェクトディレクトリに入るcdコマンド
cd F:\ESP32_DevBoard_File\18_WIFI_AP_UDP
コンピューターのデバイスマネージャーで開発ボードのシリアルポート番号を表示する
idf.py -p COM9フラッシュモニターを実行してシリアルポート9からダウンロードして実行し、ポートを開いてデバイスのデバッグ情報を表示しますCtrl + cで終了します
テストプロセス
コードをダウンロードした後、コンピューターは "HelloBug" WIFIが表示されるのを待ち、それに接続します。パスワードは12345678です(コードで変更できます)。
接続が成功したら、コンピューター側でネットワークデバッグアシスタントを開きます。
接続方法を「UDP」に選択
ローカルホストアドレス:192.168.4.2(開発ボードの印刷情報/コンピューターのローカル接続ステータスにあります)
ローカルホストポート:1257(何気なく9527にすることはできません。開発ボードのポートは9527です)
接続をクリックします
リモートホスト入力192.168.4.1:9527または255.255.255.255:9527
データを送信すると、開発ボードは同じデータを返します。詳細については、シリアルポート情報を確認してください。
テスト結果は次のとおりです。