サンプルプログラム N446RE_WiFi_TCP_Server の説明
Wi-Fiモジュール ESP-WROOM-02 を使用して、
ST(Station)モードでTCP Serverとして動作する
サンプルプログラムです。
STMicroelectronics社製の
評価用基板、NUCLEO-F446RE と
freeの開発環境、STM32CubeIDE を
使用しています。
目次
サンプルプログラム N446RE_WiFi_TCP_Server のソース
ST(Station)モード接続
Wi-Fiルーターのポートマッピング設定
Wi-Fi選択画面
Wi-Fi接続画面
サンプルプログラム N446RE_WiFi_TCP_Server の説明
N446RE_WiFi_TCP_Server の構成
N446RE_WiFi_TCP_Server の動作パラメータの定義
ユーザープログラムの実行開始位置
N446RE_WiFi_TCP_Server の main() の説明
1) 初期化の部分
2) LED点滅 と TCP通信 の部分
Communicate_TCP_Server の説明
ST(Station)モードの初期化
LED点滅コマンドの送受信
LED点滅コマンドの受信と処理
PCアプリケーション Access_Network_IP
サンプルプログラム N446RE_WiFi_TCP_Server の
動作を確認するためのPCアプリケーションです。
このサンプルプログラムは、えがおのでんし製の試験用基板
Base-N446RE と IF-N446RE-WiFi を使用して動作を確認しています。
動作試験用基板 Base_N446RE の説明
動作試験用基板 IF_N446RE_WiFi の説明
サンプルプログラム N446RE_WiFi_TCP_Server のソース
STMicroelectronics社製のfreeの開発環境 STM32CubeIDE 1.7.0 を使用して作成しました。
ここからサンプルプログラム R_N446RE_WiFi_TCP_Server.zip をダウンロードしてください。
ST(Station)モード接続
PCとESP-WROOM-02をST(Station)モードで接続する場合の様子を
以下に示します。
Wi-Fiルーターのポートマッピング設定
ESP-WROOM-02をST(Station)モードで使用し、PCと接続する場合、
ESP-WROOM-02を特定するためにWi-Fiルータのポートマッピング設定が
必要になります。
ポートマッピング設定の一例を紹介します。
Wi-Fiルーターのポートマッピング設定 を、ご覧ください。
使用しているWi-Fiルーターに合わせて設定してください。
Wi-Fi選択画面
PCの画面の右下のタスクバー上のWi-Fiのアイコンをクリックすると、
Wi-Fi接続のダイアログが開きます。
Wi-Fi接続画面
使用しているWi-Fiルーターに接続していることを確認します。
サンプルプログラム N446RE_WiFi_TCP_Server の説明
TCP Serverとして動作し、PC上などで動作しているTCP Clientからの
通信によるコマンドを受信して、コマンドに従い、LED点滅を行います。
プロジェクトを最初に開いた画面は以下のようになります。
以下、サンプルプログラム N446RE_WiFi_TCP_Server について説明していきます。
サンプルプログラムの構成
STM32CubeIDEの画面左側、Project Explorerの
N446RE_WiFi_TCP_Serverを展開した画面は以下のようになります。
サンプルプログラム N446RE_WiFi_TCP_Server の構成を以下に示します。
N446RE_WiFi_TCP_Server
|
|- Includes
|
|- Access_ESP8266 : Wi-Fiモジュールとのコマンド通信処理
| |- Config_ESP8266.c
| |- Config_ESP8266.h
| |- Handle_ESP8266.c
| |- Handle_ESP8266.h
| |- Net_Data_ESP8266.c
| |- Net_Data_ESP8266.h
|
|- Access_TCP_LED : TCP受信データに対する応答処理
| |- Access_TCP_LED.c
| |- Access_TCP_LED.h
|
|- Blink_LED_Stat : Status LED点滅処理
| |- Blink_LED_Stat.c
| |- Blink_LED_Stat.h
|
|- C_Lib : 共通ライブラリモジュール
| |- Common_Lib.c
| |- Common_Lib.h
|
|- Commu_TCP_Server : TCP通信処理
| |- Commu_TCP_Server.c
| |- Commu_TCP_Server.h
|
|- Core
| |- Inc
| | |- main.h
| | |- stm32f4xx_hal_conf.h
| | |- stm32f4xx_it.h
| |
| |- Src
| | |- main.c
| | |- stm32f4xx_hal_msp.c
| | |- stm32f4xx_it.c
| | |- syscalls.c
| | |- system.c
| | |- system_stm32f4xx.c
| |
| |- Startup
|
|- Drivers
|
|- H_F4_UART4 : UART4のハンドラ
| |- H_F4_UART4.c
| |- H_F4_UART4.h
|
|- N446RE_WiFi_Fix_Config : 動作パラメータの定義
| |- Dev_Conf.h
|
|- Net_Param_ST_Fix : Networkパラメータ
| |- Net_P_IP_ST_Fix : IPアドレス設定
| | |- Net_P_IP_ST_Fix.c
| | |- Net_P_IP_ST_Fix.h
| |
| |- Net_P_WiFi_ST_Fix : WiFi設定パラメータ
| | |- Net_P_WiFi_ST_Fix.c
| | |- Net_P_WiFi_ST_Fix.h
|
|- Net_Utilities : Network処理のためのユーティリティ
| |- Net_Utilities.c
| |- Net_Utilities.h
|
|- Periph_F4 : 周辺インターフェース処理
| |- H_F4_GPIO.c
| |- H_F4_GPIO.h
|
|- Wait_Itvl : 時間待ち処理
| |- Wait_Itvl.c
| |- Wait_Itvl.h
|
|- N446RE_WiFi_TCP_Server.launch
|- STM32F446RETX_FLASH.ld
|- STM32F446RETX_RAM.ld
N446RE_WiFi_TCP_Server の動作パラメータの定義
サンプルプログラム N446RE_WiFi_TCP_Server の動作パラメータの定義を
N446RE_WiFi_Config/Dev_Conf.h に記述しています。
使用する CPU の定義、ヘッダ名の定義、GPIO のポートとピンの定義、動作パラメータの定義、
などを記述しています。
ユーザープログラムの実行開始位置
プログラムは、int main(void) から実行開始します。
int main(void) は、フォルダ Core/Src/main.c にあります。
STM32CubeIDEでビルドされたプログラムは、自動的にCPUの初期化を
行った後、int main(void) を呼び出します。
ユーザーコード(記述したプログラム)は、
int main(void) の先頭から実行されます。
N446RE_WiFi_TCP_Server の main() の説明
サンプルプログラム N446RE_WiFi_TCP_Server の main() の記述は、
以下のとおりです。
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
uint8_t uint8_JobNum_LED = 0; // LED点滅処理番号
uint8_t uint8_JobNum_TCP = 0; // TCP通信処理番号
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
/* USER CODE BEGIN 2 */
//------------------------------------------------
// Status LED(緑) : 点灯1000mSec / 消灯2000mSec
//------------------------------------------------
GLB_uint16_Time_LED_Stat_ON = (uint16_t)1000;
GLB_uint16_Time_LED_Stat_OFF = (uint16_t)2000;
//------------------------------------------------
//------------------------------------------------
// Status LEDのGPIO初期化
//------------------------------------------------
Init_LED_Stat();
//-------------------------------------------------------------
// IP and Portパラメータ設定
//-------------------------------------------------------------
// 戻り値:
// 0 : OK
// 1以上 : NG
//-------------------------------------------------------------
Set_Net_Param_IP();
//-------------------------------------------------------------
// WiFiパラメータ設定
//-------------------------------------------------------------
// 戻り値:
// 0 : OK
// 1以上 : NG
//-------------------------------------------------------------
Set_Net_Param_WiFi();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
//------------------------------------------------------
// Status LED点滅
//------------------------------------------------------
// 引数:
// uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ
// uint16_t uint16_Time_ON : 点灯時間
// uint16_t uint16_Time_OFF : 消灯時間
// 戻り値:
// -1 : 処理中
// 0 : OK終了
// 1 : NG
//------------------------------------------------------
Blk_LED_Stat(&uint8_JobNum_LED,
GLB_uint16_Time_LED_Stat_ON, GLB_uint16_Time_LED_Stat_OFF);
//---------------------------------------------------------
// TCP通信 : Server
//---------------------------------------------------------
// 引数:
// uint8_t *puint8_JobNum : 処理番号が格納された変数のポインタ
// 戻り値:
// -1 : 処理中
// 0 : OK
// 1 : NG
//---------------------------------------------------------
Communicate_TCP_Server(&uint8_JobNum_TCP);
}
/* USER CODE END 3 */
}
1) 初期化の部分
a) CPUとPeripheral初期化
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
により、CPUとPeripheralなどの基本的な初期化を行います。
PeripheralとはCPUの周辺インターフェースなどのことを言います。
HAL_Init はプロジェクト構築時に自動的に組み込まれる、
HAL Drivers(フォルダ Drivers/STM32F4xx_HAL_Drivers) 内に記述されています。
b) CPU動作クロックの設定
/* Configure the system clock */
SystemClock_Config();
CPUの動作クロックとPeripheralの動作クロックを設定します。
SystemClock_Config(); の設定内容は、
int main(void)
{
.
.
.
}
の、すぐ下に記述されています。
c) Status LEDの初期化
初期の点滅時間をセットした後、Init_LED_Stat(); を呼び出して
LEDが接続されているピンを出力に設定しています。
//------------------------------------------------
// Status LED(緑) : 点灯1000mSec / 消灯2000mSec
//------------------------------------------------
GLB_uint16_Time_LED_Stat_ON = (uint16_t)1000;
GLB_uint16_Time_LED_Stat_OFF = (uint16_t)2000;
//------------------------------------------------
//------------------------------------------------
// Status LEDのGPIO初期化
//------------------------------------------------
Init_LED_Stat();
d) Networkパラメータの初期化
IPアドレスとWi-Fiのパラメータを設定します。
//-------------------------------------------------------------
// IP and Portパラメータ設定
//-------------------------------------------------------------
// 戻り値:
// 0 : OK
// 1以上 : NG
//-------------------------------------------------------------
Set_Net_Param_IP();
//-------------------------------------------------------------
// WiFiパラメータ設定
//-------------------------------------------------------------
// 戻り値:
// 0 : OK
// 1以上 : NG
//-------------------------------------------------------------
Set_Net_Param_WiFi();
2) LED点滅 と TCP通信 の部分
永久ループ部分の記述を以下に示します。
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
//------------------------------------------------------
// Status LED点滅
//------------------------------------------------------
// 引数:
// uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ
// uint16_t uint16_Time_ON : 点灯時間
// uint16_t uint16_Time_OFF : 消灯時間
// 戻り値:
// -1 : 処理中
// 0 : OK終了
// 1 : NG
//------------------------------------------------------
Blk_LED_Stat(&uint8_JobNum_LED,
GLB_uint16_Time_LED_Stat_ON, GLB_uint16_Time_LED_Stat_OFF);
//---------------------------------------------------------
// TCP通信 : Server
//---------------------------------------------------------
// 引数:
// uint8_t *puint8_JobNum : 処理番号が格納された変数のポインタ
// 戻り値:
// -1 : 処理中
// 0 : OK
// 1 : NG
//---------------------------------------------------------
Communicate_TCP_Server(&uint8_JobNum_TCP);
}
/* USER CODE END 3 */
Status LED点滅処理 Blk_LED_Stat と
TCP通信 Communicate_TCP_Server を呼び出しています。
Communicate_TCP_Server の説明
1) Communicate_TCP_Serverのソース
モジュール Communicate_TCP_Server は
Commu_TCP_Server/Commu_TCP_Server.c 内に記述されています。
モジュール Communicate_TCP_Server のソースを以下に示します。
//---------------------------------------------------------
// TCP通信 : Server
//---------------------------------------------------------
// 引数:
// uint8_t *puint8_JobNum : 処理番号が格納された変数のポインタ
// 戻り値:
// -1 : 処理中
// 0 : OK終了
// 1 : NG
//---------------------------------------------------------
int16_t Communicate_TCP_Server(uint8_t *puint8_JobNum)
{
static uint8_t STC_uint8_JobNum_TCP; // TCP通信処理番号
static int16_t STC_int16_ID; // ID Number of transmit connection
static int16_t STC_int16_ReceiveLength; // 受信データ数
static int16_t STC_int16_SendLength; // 送信データ数
int16_t int16_Return;
switch(*puint8_JobNum)
{
case 0:
STC_uint8_JobNum_TCP = 0; // TCP通信処理番号初期化
STC_int16_ID = 0; // ID Number of transmit connection : 接続ID初期化
// ESP8266初期化済みフラグを判定する。
if(GLB_int16_Config_Done_ESP8266 == 1){
// ESP8266設定済みなら処理番号 2 に移行する。
*puint8_JobNum = 2; // 処理番号に 2 をセットする。 : case 2: に移行する。
int16_Return = -1; // 処理中
break;
}
// 初期化済みでない場合、ESP8266設定処理に移行する。
(*puint8_JobNum)++; // 次の処理番号に進む。
int16_Return = -1; // 処理中
break;
case 1:
//---------------------------------------------------------
// ESP-WROOM-02 : ESP8266設定 : Webサーバ
//---------------------------------------------------------
// 引数:
// uint8_t *puint8_JobNum : 処理番号が格納された変数のポインタ
// 戻り値:
// -1 : 処理中
// 0 : OK
// 1 : NG
//---------------------------------------------------------
int16_Return = Config_ESP8266_Server(&STC_uint8_JobNum_TCP);
if(int16_Return == -1){
break; // 処理中 : 処理番号維持
}
if(int16_Return != 0){
if(def_UARTx_InitDone == 1){
// UART初期化済みフラグONの場合
HAL_UART_DeInit(&Handle_UART4);
def_UARTx_InitDone = 0; // UART初期化フラグOFF
}
*puint8_JobNum = 0; // 処理番号初期化
int16_Return = 1; // NG
break;
}
(*puint8_JobNum)++; // 次の処理番号に進む。
int16_Return = -1; // 処理中
break;
case 2:
// ESP8266初期化済みフラグの監視
if(GLB_int16_Config_Done_ESP8266 == 0){
if(def_UARTx_InitDone == 1){
HAL_UART_DeInit(&def_Handle_UARTx);
// ESP8266初期化済みフラグがOFFの場合
def_UARTx_InitDone = 0; // UART初期化済みフラグOFF
}
*puint8_JobNum = 0; // 処理番号初期化 : case 0: に戻る。
int16_Return = -1; // 処理中
break;
}
//---------------------------------------------------------
// ESP8266 Network data受信
//---------------------------------------------------------
// Receive network data
//---------------------------------------------------------
//---------------------------------------------------------
// For single connection
// (+CIPMUX=0)
//---------------------------------------------------------
// "+IPD,:" を受信する。
//---------------------------------------------------------
// で指定される受信データ数をチェックして、その数に達するまで受信する。
//---------------------------------------------------------
// 10byteのデータ ABCDE12345 を受信した場合の例:
// +IPD,10:ABCDE12345
//---------------------------------------------------------
//---------------------------------------------------------
//---------------------------------------------------------
//---------------------------------------------------------
// For multiple connection
// (+CIPMUX=1)
//---------------------------------------------------------
// "+IPD,,:" を受信する。
//---------------------------------------------------------
// で指定される受信データ数をチェックして、その数に達するまで受信する。
//---------------------------------------------------------
// 10byteのデータ ABCDE12345 を受信した場合の例:
// +IPD,0,10:ABCDE12345
//---------------------------------------------------------
//---------------------------------------------------------
// 引数:
// uint8_t *puint8_JobNum : 処理番号が格納された変数のポインタ
// uint32_t uint32_Timeout : タイムアウト値
// 0 : Timeoutなし
// 1以上 : Timeout値
// int16_t *pint16_ID : 受信IDを格納する変数のポインタ
// int16_t *pint16_ReceiveLength : 受信データ数を格納する変数のポインタ
// uint8_t *puint8_ReceiveData : 受信データを格納するBufferのポインタ
// 戻り値:
// -1 : 処理中
// 0 : OK
// 1 : NG
//---------------------------------------------------------
//---------------------------------------------------------
int16_Return = ESP8266_Receive_WiFi(&STC_uint8_JobNum_TCP,
(uint32_t)0,
&STC_int16_ID,
&STC_int16_ReceiveLength,
GLB_uint8_ReceiveData_TCP);
if(int16_Return == -1){
break; // 受信中 : 処理番号維持
}
if(int16_Return == 1){
// NG
int16_Return = -1; // 処理継続
break;
}
if(int16_Return == 2){
// WIFI DISCONNECT\r\n
// CONNECT FAIL\r\n
GLB_int16_Config_Done_ESP8266 = 0;
*puint8_JobNum = 0; // 処理番号を 0 にして case 0: に戻る。
break;
}
if(int16_Return == 3){
// CLOSED\r\n
int16_Return = -1; // 処理継続
break;
}
//--------------------------------------------------------------------
// 受信コマンドを実行する。
//--------------------------------------------------------------------
// この例では、受信データの内容を判定してコマンドがOKなら指定に従ってLEDの点滅間隔を変更します。
// また、エコーバックのためのデータを送信Bufferにセットしています。
//--------------------------------------------------------------------
// 引数:
// uint16_t uint16_ReceiveLength : 受信データ数
// uint8_t *puint8_ReceiveData : 受信データが格納されているBufferのポインタ
// uint8_t *puint8_SendData : 応答送信データを格納するBufferのポインタ
// 戻り値: 応答送信データ数
//--------------------------------------------------------------------
STC_int16_SendLength = (int16_t)Execute_Command_TCP(
(uint16_t)STC_int16_ReceiveLength,
GLB_uint8_ReceiveData_TCP,
GLB_uint8_SendData_TCP);
(*puint8_JobNum)++; // 次の処理番号に進む。
int16_Return = -1; // 処理中
break;
case 3:
//---------------------------------------------------------
// ESP8266 Network data送信
//---------------------------------------------------------
// Send data
//---------------------------------------------------------
// For single connection
// (+CIPMUX=0)
//---------------------------------------------------------
// Instruction : Send
// AT+CIPSEND=\r\n
// Echo : Receive
// AT+CIPSEND=\r\r\n
// response: Receive
// OK\r\n
// >[0x20]
// >の次にスペース[0x20]が1個あります。
// データ送信
// で指定したバイト数を送信
// データを16byte送信した場合の応答データの例
// \r\n
// Recv 16 bytes\r\n
// \r\n
// SEND OK\r\n
//---------------------------------------------------------
// データ送信例: データ Blink_LED : OK\r\n を送信する例(16 bytes)
//---------------------------------------------------------
// コマンド送信
// AT+CIPSEND=16\r\n
// Echo受信
// AT+CIPSEND=16\r\r\n
// OK応答受信
// OK\r\n
// >[0x20]
// >の次にスペース[0x20]が1個あります。
// データ送信 : 16bytes
// Blink_LED : OK\r\n
// 応答受信
// \r\n
// Recv 16 bytes\r\n
// \r\n
// SEND OK\r\n
//---------------------------------------------------------
//---------------------------------------------------------
// For multiple connection
// (+CIPMUX=1)
//---------------------------------------------------------
// Instruction : Send
// AT+CIPSEND=,\r\n
// Echo : Receive
// AT+CIPSEND=,\r\r\n
// response: Receive
// OK\r\n
// >[0x20]
// >の次にスペース[0x20]が1個あります。
// データ送信
// で指定したバイト数を送信
// データを16byte送信した場合の応答データの例
// \r\n
// Recv 16 bytes\r\n
// \r\n
// SEND OK\r\n
//---------------------------------------------------------
// データ送信例: データ Blink_LED : OK\r\n を送信する例(16 bytes)
//---------------------------------------------------------
// コマンド送信
// AT+CIPSEND=0,16\r\n
// Echo受信
// AT+CIPSEND=0,16\r\r\n
// OK応答受信
// OK\r\n
// >[0x20]
// >の次にスペース[0x20]が1個あります。
// データ送信 : 16bytes
// Blink_LED : OK\r\n
// 応答受信
// \r\n
// Recv 16 bytes\r\n
// \r\n
// SEND OK\r\n
//---------------------------------------------------------
// 引数:
// uint8_t *puint8_JobNum : 処理番号が格納された変数のポインタ
// int16_t int16_ID : 送信ID
// int16_t int16_SendLength : 送信データ数
// uint8_t *puint8_SendData : 送信データを格納するBufferのポインタ
// 戻り値:
// -1 : 処理中
// 0 : OK
// 1 : NG
// 4 : NG : link is not valid, CONNECT FAIL, SEND FAIL
//---------------------------------------------------------
int16_Return = ESP8266_Send_WiFi(&STC_uint8_JobNum_TCP,
STC_int16_ID,
STC_int16_SendLength,
GLB_uint8_SendData_TCP);
if(int16_Return == -1){
break; // 送信中 : 処理番号維持
}
// ESP8266初期化済みフラグの監視
if(GLB_int16_Config_Done_ESP8266 == 0){
// ESP8266初期化済みフラグがOFFの場合
if(def_UARTx_InitDone == 1){
// UART初期化済みフラグONの場合
HAL_UART_DeInit(&Handle_UART4);
def_UARTx_InitDone = 0; // UART初期化済みフラグOFF
}
}
*puint8_JobNum = 0; // 処理番号を 0 にして case 0: に戻る。
// int16_Return : 処理結果 : 処理終了
break;
default:
*puint8_JobNum = 0; // 処理番号初期化
int16_Return = 1; // NG
break;
}
return(int16_Return);
}
2) Communicate_TCP_Serverの処理内容
a) case 0:
ESP8266初期化済みフラグを判定して移行する処理番号を決定します。
初期化済みでない場合、case 1: に移行します。
初期化済みの場合、case 2: に移行します。
b) case 1:
ESP-WROOM-02 を Webサーバ に設定します。
c) case 2:
モジュール ESP8266_Receive_WiFi を呼び出して、
Networkデータの受信を行います。
Networkデータを受信した場合、モジュール Execute_Command_TCP を
呼び出して、受信データの内容に従って処理を行います。
応答データがバッファ GLB_uint8_SendData_TCP にセットされ、
応答データ数が STC_int16_SendLength 返ります。
d) case 3:
モジュール ESP8266_Send_WiFi を呼びだして、c) でセットされたデータを
Networkに送信します。
送信が終了したら、処理番号を 0 にセットします。
case 0: からの処理を繰り返します。
ST(Station)モードの初期化
ATコマンドによりESP-WROOM-02をST(Station)モードに初期化する
処理について説明します。
ESP-WROOM-02に対するST(Station)モードの初期化は、
以下のモジュール Config_ESP8266_ST_Server で行います。
Access_ESP8266/Config_ESP8266.c内にあります。
//---------------------------------------------------------
// ESP8266設定 : Station Mode : Webサーバ
//---------------------------------------------------------
// 引数:
// uint8_t *puint8_JobNum : 処理番号が格納された変数のポインタ
// 戻り値:
// -1 : 処理中
// 0 : OK
// 1 : NG
//---------------------------------------------------------
int16_t Config_ESP8266_ST_Server(uint8_t *puint8_JobNum)
{
static uint8_t STC_uint8_JobNum_ST; // ST設定処理番号
int16_t int16_Return;
switch(*puint8_JobNum)
{
case 0:
STC_uint8_JobNum_ST = 0; // ST設定処理番号初期化
(*puint8_JobNum)++;
int16_Return = -1;
break;
case 1:
//---------------------------------------------------------
// Access Pointに接続する。
//---------------------------------------------------------
// ESP8266設定 : Station Mode
//---------------------------------------------------------
// 引数:
// uint8_t *puint8_JobNum : 処理番号が格納された変数のポインタ
// 戻り値:
// -1 : 処理中
// 0 : OK
// 1 : NG
//---------------------------------------------------------
int16_Return = Config_ESP8266_Station(&STC_uint8_JobNum_ST);
if(int16_Return == -1){
break;
}
if(int16_Return != 0){
*puint8_JobNum = 0;
int16_Return = 1; // NG
break;
}
(*puint8_JobNum)++;
int16_Return = -1;
break;
case 2:
//---------------------------------------------------------
// Station modeでTCP serverに設定する。
//---------------------------------------------------------
// 引数:
// uint8_t *puint8_JobNum : 処理番号が格納された変数のポインタ
// uint8_t *puint8_IP_Address : IPアドレスが格納されたBufferのポインタ
// 戻り値:
// -1 : 処理中
// 0 : OK
// 1 : NG
//---------------------------------------------------------
int16_Return = Config_Station_TCP_Server(&STC_uint8_JobNum_ST,
GLB_uint8_IP);
if(int16_Return == -1){
break;
}
if(int16_Return != 0){
// NG
int16_Return = -1;
break;
}
*puint8_JobNum = 0; // 処理番号初期化
// int16_Return : 処理結果 : 処理終了
break;
default:
*puint8_JobNum = 0; // 処理番号初期化
int16_Return = -1; // NG
break;
}
return(int16_Return);
}
この処理により、Wi-FiルータのAccess Pointに接続します。
この例では、自分のIPアドレスとPort番号を、
IPアドレス : 192.168.0.100
Port番号 : 30000
に設定しています。
PCから、このIPアドレスとPort番号で、ESP-WROOM-02に接続するためには、
Wi-Fiルータの ポートマッピング設定 または、ポートフォワード設定 で、
IPアドレス : 192.168.0.100
Port番号 : 30000
を設定する必要があります。
IPアドレスとPort番号は、サンプルプログラムの
Net_Param_ST/Net_P_IP_ST/Net_P_IP_ST.h 内で定義しています。
ポートマッピング設定については、
Wi-Fiルーターのポートマッピング設定 を、ご覧ください。
ESP-WROOM-02をST(Station)モードに初期化する場合の、
ATコマンドによる通信の様子を以下に示します。
CPU側から見て、
S: 送信
R: 受信
です。
----------------------------------------
最初に、ESP-WROOM-02にリセットをかける。
----------------------------------------
通信速度が不明のデータがESP-WROOM-02から大量に出力される。
R: \r\n
R: ready\r\n
----------------------------------------
リセット動作後、MACを読み込む。(以下、2行)
----------------------------------------
S: AT+CIPAPMAC_CUR?\r\n
R: AT+CIPAPMAC_CUR?\r\n+CIPAPMAC:\"1a:fe:34:ee:7a:02\"\r\n\r\nOK\r\n
----------------------------------------
Closes the TCP/UDP/SSL Connectionコマンド
----------------------------------------
S: AT+CIPCLOSE\r\n
R: AT+CIPCLOSE\r\n\r\nERROR\r\n
----------------------------------------
ERROR応答でも処理を続行する。
----------------------------------------
----------------------------------------
Disconnects from the APコマンド
----------------------------------------
S: AT+CWQAP\r\n
----------------------------------------
OKの場合
----------------------------------------
R: AT+CWQAP\r\n\r\nOK\r\n
----------------------------------------
ERRORの場合
----------------------------------------
R: AT+CWQAP\r\nQAP fail\r\n\r\nERROR\r\n
----------------------------------------
ERROR応答でも処理を続行する。
----------------------------------------
S: AT+CWMODE_DEF=1\r\n
R: AT+CWMODE_DEF=1\r\n\r\nOK\r\n
S: AT+CWJAP_DEF=\"001D73B3D442\",\"ya0ce6kxnfn1a\"\r\n
R: AT+CWJAP_DEF=\"001D73B3D442\",\"ya0ce6kxnfn1a\"\r\nWIFI CONNECTED\r\nWIFI GOT IP\r\n\r\nOK\r\n
S: AT+CIPSTA_DEF=\"192.168.0.100\"\r\n
R: AT+CIPSTA_DEF=\"192.168.0.100\"\r\n\r\nOK\r\n
S: AT+CIPMODE=0\r\n
R: AT+CIPMODE=0\r\n\r\nOK\r\n
S: AT+CIPMUX=1\r\n
R: AT+CIPMUX=1\r\n\r\nOK\r\n
S: AT+CIPSERVER=1,30000\r\n
R: AT+CIPSERVER=1,30000\r\n\r\nOK\r\n
LED点滅コマンドの送受信
PCからLED点滅コマンドを受信したときの
CPUとESP-WROOM-02との送受信の処理について説明します。
PCからESP-WROOM-02を介してCPUにLED点滅コマンドを送信した場合の、
通信の様子を以下に示します。
CPU側から見て、
S: 送信
R: 受信
です。
R: 0,CONNECT\r\n\r\n
R: +IPD,0,8:LED1 B1\0
------------------------------------------
以下の2行は、なくても構いません。
------------------------------------------
S: AT\r\n
R: AT\r\n\r\nOK\r\n
------------------------------------------
S: AT+CIPSEND=0,8\r\n
R: AT+CIPSEND=0,8\r\n\r\nOK\r\n>
S: LED1 B1\0
R: \r\nRecv 8 bytes\r\n\r\nSEND OK\r\n
R: 0,CLOSED\r\n
1) PCからのコマンド受信
上記の、
R: +IPD,0,8:LED1 B1\0
により、TCPデータを 8bytes 受信して、内容が LED1 B1\0 であることを、
通知されます。
2) 応答送信
受信データがLED点滅コマンドであるので、CPUはLED点滅処理を行い、
応答データ
S: LED1 B1\0
を、エコーバック送信します。
エコーバック送信直前の
S: AT+CIPSEND=0,8\r\n
の部分が、これから 8bytes のTCPデータを送信することを、ESP-WROOM-02に
通知している部分です。
R: AT+CIPSEND=0,8\r\n\r\nOK\r\n>
は、ESP-WROOM-02が了解して、送信データ待ちになったことを示します。
エコーバック送信直後の
R: \r\nRecv 8 bytes\r\n\r\nSEND OK\r\n
は、ESP-WROOM-02が 8bytes のTCPデータを送信したことを示します。
LED点滅コマンドの受信と処理
PCからデータを受信すると、最終的に以下に示す、
Execute_Command_LED が呼び出されます。
モジュール Execute_Command_LED は、
Access_TCP_LED/Access_TCP_LED.c内にあります。
このモジュールでは、受信データを判定して、
LED点滅コマンドなら、指定に従い
LEDの点滅間隔を変更します。
そして、受信データを送信バッファにセットしてエコーバックします。
このモジュール内で、バッファ puint8_SendData に
送信データをセットして、戻り値に送信データ数を返せば、
受信応答データを送信することができます。
以下は、LED点滅コマンドを実行する例です。
この部分に独自のプログラムを記述すれば、希望の動作を実現できます。
//----------------------------------------------------------------------
// 受信コマンドを実行する。 : LED点滅
//----------------------------------------------------------------------
// 引数:
// uint16_t uint16_ReceiveLength : 受信データ数
// uint8_t *puint8_ReceiveData : 受信データが格納されているBufferのポインタ
// uint8_t *puint8_SendData : 応答送信データを格納するBufferのポインタ
// 戻り値: 応答送信データ数
//----------------------------------------------------------------------
uint16_t Execute_Command_LED(uint16_t uint16_ReceiveLength,
uint8_t *puint8_ReceiveData,
uint8_t *puint8_SendData)
{
uint16_t uint16_I;
uint16_t uint16_SendLength = 0;
//----------------------------------------------------------------------
// Command処理
//----------------------------------------------------------------------
//------------------------------------------------------------------
// LED1(緑) 点滅間隔切り替え
//------------------------------------------------------------------
if((memcmp(puint8_ReceiveData, "LED1 B0", 7) == 0)
&& (puint8_ReceiveData[7] == '\0')){
// LED1(緑) : 点灯1000mSec / 消灯2000mSec
GLB_uint16_Time_LED_Stat_ON = (uint16_t)1000;
GLB_uint16_Time_LED_Stat_OFF = (uint16_t)2000;
GLB_int16_Restart_LED_Stat = 1; // Status LED再起動フラグON
}
else if((memcmp(puint8_ReceiveData, "LED1 B1", 7) == 0)
&& (puint8_ReceiveData[7] == '\0')){
// LED1(緑) : 点灯100mSec / 消灯100mSec
GLB_uint16_Time_LED_Stat_ON = (uint16_t)100;
GLB_uint16_Time_LED_Stat_OFF = (uint16_t)100;
GLB_int16_Restart_LED_Stat = 1; // Status LED再起動フラグON
}
else if((memcmp(puint8_ReceiveData, "LED1 B2", 7) == 0)
&& (puint8_ReceiveData[7] == '\0')){
// LED1(緑) : 点灯200mSec / 消灯200mSec
GLB_uint16_Time_LED_Stat_ON = (uint16_t)200;
GLB_uint16_Time_LED_Stat_OFF = (uint16_t)200;
GLB_int16_Restart_LED_Stat = 1; // Status LED再起動フラグON
}
else if((memcmp(puint8_ReceiveData, "LED1 B3", 7) == 0)
&& (puint8_ReceiveData[7] == '\0')){
// LED1(緑) : 点灯300mSec / 消灯300mSec
GLB_uint16_Time_LED_Stat_ON = (uint16_t)300;
GLB_uint16_Time_LED_Stat_OFF = (uint16_t)300;
GLB_int16_Restart_LED_Stat = 1; // Status LED再起動フラグON
}
else if((memcmp(puint8_ReceiveData, "LED1 B4", 7) == 0)
&& (puint8_ReceiveData[7] == '\0')){
// LED1(緑) : 点灯400mSec / 消灯400mSec
GLB_uint16_Time_LED_Stat_ON = (uint16_t)400;
GLB_uint16_Time_LED_Stat_OFF = (uint16_t)400;
GLB_int16_Restart_LED_Stat = 1; // Status LED再起動フラグON
}
else if((memcmp(puint8_ReceiveData, "LED1 B5", 7) == 0)
&& (puint8_ReceiveData[7] == '\0')){
// LED1(緑) : 点灯500mSec / 消灯500mSec
GLB_uint16_Time_LED_Stat_ON = (uint16_t)500;
GLB_uint16_Time_LED_Stat_OFF = (uint16_t)500;
GLB_int16_Restart_LED_Stat = 1; // Status LED再起動フラグON
}
// エコーバック
for(uint16_I = 0; uint16_I < uint16_ReceiveLength; uint16_I++){
puint8_SendData[uint16_I] = puint8_ReceiveData[uint16_I];
}
uint16_SendLength = uint16_ReceiveLength;
return(uint16_SendLength);
}
コマンドとLED点滅間隔との関係は次の通りです。
LED1 B0%00 : 点灯 1000mSec / 消灯 2000mSec
LED1 B1%00 : 点灯 100mSec / 消灯 100mSec
LED1 B2%00 : 点灯 200mSec / 消灯 200mSec
LED1 B3%00 : 点灯 300mSec / 消灯 300mSec
LED1 B4%00 : 点灯 400mSec / 消灯 400mSec
LED1 B5%00 : 点灯 500mSec / 消灯 500mSec
%00 は HEXコードの 0x00 を表します。
モジュール Execute_Command_LED は、同じファイル
Access_TCP_LED/Access_TCP_LED.c 内のすぐ上にあるモジュール、
Execute_Command_TCPから呼び出されています。
サンプルプログラム N446RE_WiFi_TCP_Server では、PCからの受信があった場合、
Execute_Command_TCP という名称で受信処理モジュールを
呼び出すようにしています。
フォルダ Commu_TCP_Server にTCP_Serverのための処理モジュールがあります。
処理が異なる場合でも共通にモジュールを呼び出すために、
ここからExecute_Command_TCPを呼び出すようにしています。
Execute_Command_TCP 内に直接、処理を記述しても構いませんが、
このサンプルプログラムでは、以下のようにして最終的な処理モジュール
Execute_Command_LED を呼び出すようにしています。
以下に、モジュールExecute_Command_TCPのコードを示します。
//-----------------------------------------------------------------------
// uint16_t Execute_Command_TCP は、TCP通信の受信が発生した場合、
// Commu_TCP_Server/Commu_TCP_Server.c 内の
// TCP通信処理 int16_t Commu_TCP_Server の処理により呼び出されます。
//-----------------------------------------------------------------------
// 引数の uint8_t *puint8_SendData にデータをセットして、
// 戻り値に送信データ数を返すと、
// TCP通信処理 int16_t Commu_TCP_Server の処理によりそのデータが送信されます。
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// __weak が先頭に付いていない
// uint16_t Execute_Command_TCP の記述がない場合は、
// Commu_TCP_Server/Commu_TCP_Server.c 内の
// __weak uint16_t Execute_Command_TCP
// を実行します。
//-----------------------------------------------------------------------
// __weak が先頭に付いていない
// uint16_t Execute_Command_TCP の記述が他にある場合は、そちらを実行します。
//-----------------------------------------------------------------------
// よって、この例の場合は、下記の uint16_t Execute_Command_TCP を実行します。
//-----------------------------------------------------------------------
//----------------------------------------------------------------------
// 受信コマンドを実行する。
//----------------------------------------------------------------------
// 引数:
// uint16_t uint16_ReceiveLength : 受信データ数
// uint8_t *puint8_ReceiveData : 受信データが格納されているBufferのポインタ
// uint8_t *puint8_SendData : 応答送信データを格納するBufferのポインタ
// 戻り値: 応答送信データ数
//----------------------------------------------------------------------
uint16_t Execute_Command_TCP(uint16_t uint16_ReceiveLength,
uint8_t *puint8_ReceiveData,
uint8_t *puint8_SendData)
{
uint16_t uint16_SendLength = 0;
//----------------------------------------------------------------------
// Command処理
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// 受信コマンドを実行する。 : LED点滅
//----------------------------------------------------------------------
// 引数:
// uint16_t uint16_ReceiveLength : 受信データ数
// uint8_t *puint8_ReceiveData : 受信データが格納されているBufferのポインタ
// uint8_t *puint8_SendData : 応答送信データを格納するBufferのポインタ
// 戻り値: 応答送信データ数
//----------------------------------------------------------------------
uint16_SendLength = Execute_Command_LED(uint16_ReceiveLength,
puint8_ReceiveData,
puint8_SendData);
return(uint16_SendLength);
}
PCアプリケーション Access_Network_IP
えがおのでんし が提供するWindows10 PCアプリケーション
Access_Network_IP を使用して、サンプルプログラムの動作を確認しています。
PCアプリケーション Access_Network_IP をご覧ください。
このサンプルプログラムは、
えがおのでんし製の試験用基板 Base-N446RE-V1 を使用して動作を確認しています。
動作試験用基板 Base-N446RE の説明
基板については、
Base-N446RE基板 の説明 をご覧ください。
動作試験用基板 IF-N446RE-WiFi の説明
基板については、
IF-N446RE-WiFi基板 の説明 をご覧ください。
A+-2C (ええ加減にC) のページに戻る
メールアドレス: apm2c.sumi@gmail.com
なんでも、気軽に ご相談ください。
担当:おの
えがおのでんし 案内