サンプルプログラム 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)モードで接続する場合の様子を
 以下に示します。

Connect_WiFi_ST



Wi-Fiルーターのポートマッピング設定
  ESP-WROOM-02をST(Station)モードで使用し、PCと接続する場合、
 ESP-WROOM-02を特定するためにWi-Fiルータのポートマッピング設定が
 必要になります。

  ポートマッピング設定の一例を紹介します。

 Wi-Fiルーターのポートマッピング設定 を、ご覧ください。

  使用しているWi-Fiルーターに合わせて設定してください。



Wi-Fi選択画面
icon_WiFi

  PCの画面の右下のタスクバー上のWi-Fiのアイコンをクリックすると、
 Wi-Fi接続のダイアログが開きます。

Dialog_WiFi_ST



Wi-Fi接続画面
  使用しているWi-Fiルーターに接続していることを確認します。

Connect_WiFi_router



サンプルプログラム N446RE_WiFi_TCP_Server の説明
  TCP Serverとして動作し、PC上などで動作しているTCP Clientからの
 通信によるコマンドを受信して、コマンドに従い、LED点滅を行います。

 プロジェクトを最初に開いた画面は以下のようになります。

N446RE_WiFi_TCP_Server_Scrn_First

 以下、サンプルプログラム N446RE_WiFi_TCP_Server について説明していきます。



サンプルプログラムの構成
  STM32CubeIDEの画面左側、Project Explorerの
 N446RE_WiFi_TCP_Serverを展開した画面は以下のようになります。

N446RE_WiFi_TCP_Server_Tree

  サンプルプログラム 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 にあります。

N446RE_WiFi_TCP_Server_main

  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-V1_Dim

  基板については、
 Base-N446RE基板 の説明 をご覧ください。



動作試験用基板 IF-N446RE-WiFi の説明

IF-N446RE-WiFi-V1_Dim

  基板については、
 IF-N446RE-WiFi基板 の説明 をご覧ください。



A+-2C (ええ加減にC) のページに戻る




 メールアドレス: apm2c.sumi@gmail.com

 なんでも、気軽に ご相談ください。
 担当:おの

マスコット
  えがおのでんし 案内