ESP8266 WiFi Module - Sample TCP Client-Server Application

Overview

At this page you can find general information in terms of how to build basic ESP TCP Client-Server application. It includes few practical examples showing how data packages can be transferred between ESP Client and ESP Server nodes. Full source code with comments is also included at the bottom of this page.

The following topics can be explored at this section (and within application's source code):

•   How to open ESP server-side TCP socket under certain IP address
•   How to setup server DHCP config with client-assignment addresses range
•   How to accept connections on ESP server-side under specific port
•   How to manage WiFi sessions (to set target WiFi session name, WiFi security mode and WiFi password)
•   How to handle\log current WiFi connection state
•   How to configure target server IP address to connect to (and port number)
•   How to transmit sample data over to server node
•   How to configure certain ESP GPIOs to input\output mode
•   How to poll GPIOs pins state using timer

Youtube Video

At the second part of this video you can find sample application demo (starting at 27:09). Which shows interaction between TCP Client and TCP Server nodes.




Sample TCP Client - Server application. Implementation details.

Application data transmission and processing pipeline

This demo application is designed to make single-byte transfer from client side to server side. At the initial stage source byte of data is composed from GPIOs input values and encoded into single byte using 3 less-significant bits. Source bits composition is made from GPIO12, GPIO13, GPIO14 inputs correspondingly. Table below represents possible states of push-buttons converted into byte for transfer:

Push buttons state is polled by timer event each 100ms. And composed input byte is checked against changes with previous state. This way, byte of data will be transmitted only in case of buttons state is updated. Besides that, the current buttons state will be transferred each 30 seconds in order to maintain heartbeat logic to keep TCP connection opened (as ESP server side has corresponding TCP socket timeout set)

 // If connected - transmits buttons state (transmits changes only) - check is triggered each 100 ms
 if (connection_state == STATE_CLIENT_SOCKET_CONNECTED)
 {
  uint8 current_buttons_state = get_buttons_state();
  if (current_buttons_state != buttons_state)
  {
   buttons_state = current_buttons_state;
   tx_buttons_state();
  }
 }

 // Each 30 seconds - send heartbeat message (heartbeat presented as conventional 'buttons state update' message)
 if (tick_index % TIMER_PERIOD_HEARTBEAT_SEND == 0)
 {
  if (connection_state == STATE_CLIENT_SOCKET_CONNECTED)
  {
   buttons_state = get_buttons_state();
   tx_buttons_state();
  }
 }

At ESP server node, corresponding 'data received' callback handler is responsible to accepts and process input byte of data by setting output GPIOs 12, 13 and 14 accordingly.

// Method is used to set LEDs state according to the last 3 bits of input digit (e.g '7' - all LEDs are on, '5' - only the first and last LEDs are on, etc)
void process_digit_key(char digit)
{
 uint8 num = (digit - CHAR_DIGITS_START) & 0x07;
 OS_UART_LOG("[INFO] Processing digit-key: %d\n", num);
 // Sets 3 LED pins in bulk
 gpio_output_set(0x07 << GPIO_PIN_LED_1, (num ^ 0x07) << GPIO_PIN_LED_1, 0, 0);
}

// This callback method is triggered when server receives data from client
LOCAL void ICACHE_FLASH_ATTR on_tcp_server_receive(void* arg, char* pusrdata, unsigned short length)
{
 OS_UART_LOG("[INFO] TCP Server 'on data received' event. Received %d bytes.\n", length);
 // In case of logs are enabled - will try to print received package content to UART
 if (length)
 {
  char last_char = 0;
  unsigned short idx;
  for (idx = length; idx > 0 && !last_char; --idx)
  {
   last_char = pusrdata[idx - 1];
   if (last_char >= CHAR_DIGITS_START && last_char <= CHAR_DIGITS_END)
   {
    process_digit_key(last_char);
   }
   else
   {
    last_char = 0;
   }
  }
 }
}


WiFi session configuration. Host IP-address and port settings.

Each ESP Server and ESP Client nodes are supposed to be configured on the same WiFi session. This way, WiFi SSID setup by server AP automatically will be recognised by client node. Besides that, ESP Client node should know which target IP address and port it should be connecting to. This way, ESP Server node should open TCP socket under corresponding IP address and port, which should match expected values on the client side. The following configuration currently is set in ESP sample application:

•   WiFi Session ID - ESP8266_AP_LED
•   WiFi Session Passphrase - ap_test5
•   WiFi Session Authentication Mode - WPA, WPA2_PSK
•   TCP Server IP-Address - 10.0.0.1
•   TCP Server Listening Port - 1010
•   TCP Server DHCP Addresses Range - 10.0.0.100 to 10.0.0.110

These configuration values are presented within client\server source code as corresponding macro definitions:

// Establishes ESP access point WiFi session ID. Session ID which should be visible to other devices.
#define WIFI_ACCESS_POINT_SSID               "ESP8266_AP_LED"
// Establishes ESP access point WiFi passphrase
#define WIFI_ACCESS_POINT_PASSPHRASE         "ap_test5"
// Establishes maximum allowed clients to connect
#define WIFI_ACCESS_POINT_MAX_CONNECTIONS    3
// TCP Server socket port number
#define SERVER_SOCKET_PORT                   1010


Debugging and testing. Enabling UART logs.

Sample firmware quite often needs to be tested and debugged under different conditions. Presented ESP8266 TCP Client-Server application has detailed logging mechanisms for these purposes. And it is considered a good practice to constantly monitor output UART logs at initial stages of ESP application testing. On a standard Debian distribution (or other Linux) minicom tool can be used to monitor ESP UART output while running the application. Below the typical shell command is shown to open UART terminal and display logs output from sample TCP Server application:

minicom -D /dev/serial/esp8266 -b 115200

bcn 100
[INFO] AP config is set
[INFO] AP DHCP Started
[INFO] AP Host IP: 10.0.0.1
[INFO] ESP Access Point initialization is completed
[INFO] TCP Server accepts connections on port 1010
add 1
aid 1
station: f8:c3:9e:ed:11:f2 join, AID = 1
[INFO] Number of connected WiFi sessions: 1
[INFO] TCP Server 'on client connection accepted' event
[INFO] TCP Server 'on data received' event. Received 3 bytes.
[INFO] Received package content:
4
[INFO] Processing digit-key: 4
[INFO] TCP Server 'on data received' event. Received 3 bytes.
[INFO] Received package content:
1
[INFO] Processing digit-key: 1
[INFO] TCP Server 10.0.0.100:46494 'on disconnect' event

These logs snapshot will contain general information about ESP Server WiFi connection, TCP Socket state and the content of received data from ESP client. So this logging information will be quite useful at the initial testing stage, and when application will be started the first time. The following macro OS_UART_LOG(...) is used within application to print output logs to UART. In order to build the sample with UART logs enabled you have to use special UART_DEBUG_LOGS directive:

make COMPILE=gcc BOOT=none APP=0 SPI_SPEED=20 SPI_MODE=DIO SPI_SIZE_MAP=4 FLAVOR=release UNIVERSAL_TARGET_DEFINES=-DUART_DEBUG_LOGS

Within Eclipse workspace it will be possible to define additional Makefile target configuration to have a build with logs enabled (how to make initial Eclipse IDE setup with ESP module please refer the ESP8266 Introduction video). ESP12-E onboarded LED also might help to understand what is the current WiFi session and TCP connection state. Current sample applications will use the following indication: LED Blinking mode indicates that ESP WiFi session is active already - but TCP connection is not established yet, and once LED is constantly On - it means client-server TCP socket connection has been established successfully. In case of LED does not have any indication - it means there are no active WiFi sessions.

Server node connection schema

Typical connection schema is presented below for TCP Server ESP application with LEDs used as received byte indication mechanism:


Client node connection schema

Typical connection schema is presented below for TCP Client ESP application with push-buttons used to compose byte for transmission:



Sample source code

This section represents main-modules source code. Full source code is also available at following git-hub repositories:
[ ESP8266: Sample TCP Server Application ]
[ ESP8266: Sample TCP Client Application ]

A. TCP Server main-module source code

 user/user_main.c

B. TCP Client main-module source code

 user/user_main.c