ESP8266/Arduino IDE: Communicating with TCP

Today’s goal is to transmit and receive TCP packets with my ESP-01, building on yesterday’s post, ESP8266/Arduino IDE: Connecting to a Network with WIFI.

To make this process a little easier, I will be communicating with an Echo server so I only need to focus on the code for the ESP8266. Whatever you transmit to an Echo server, it echos back exactly to you.

I’ve covered setting up an Echo server on a Raspberry Pi in the past in Using the Echo Service on Raspberry Pi for Network Testing.

I will use all of the hardware as I setup previously in ESP8266 and Using the Arduino IDE.

What’s the Plan, Stan?

My goal, to start, is very modest. I want to transmit a packet to the echo server, receive the echo, and display both strings. That way I know I am communicating properly.

Using TCPDUMP to Monitor the Network

Since I’m using an echo server on a linux system, I can easily monitor network traffic to the echo port using TCPDUMP. Using TCPDUMP is outside the scope of this post, but you can find lots of info on it elsewhere.

To monitor the echo service, in a terminal window on my RPI I just type:

sudo tcpdump 'port 7' -X

The WiFiClient Library

Since the ESP8266 is making the connection, I need to use the WiFiClient library. The header for this library can be found in

C:\Users\<user>\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src

From what I can tell, this library follows the Arduino WiFiClient library pretty close, so their documentation should largely be correct:

https://www.arduino.cc/en/Reference/WiFi

The Program

Now I have everything necessary to write some code.

I took my last program and just added a little more code at the end of the setup function.

First, I connect to the echo server:

if (!client.connect("rpi", 7)) {
    Serial.println("Connection to echo server failed");
    while (true) {}
    }

Then I transmit a string to the echo server:

client.println(testStr);

You cannot directly receive a string, so I use a look to assemble characters into a string until the Newline character is received (skipping the return character):

i = 0;
while (true) {
    while (client.available() == 0) {}
    s[i] = client.read();
    if (s[i] == '\n') {
        s[i] = '\0';
        break; // while
        }
    else if (s[i] == '\r')
        ; // do nothing additional on return character - it will be overwritten by next char
    else {
        if (i == sizeof(s)) {
            Serial.println("buffer overflow");
            while (true) {}
            }
        else
            i = i + 1;
        }
    } // while

Lastly, I display the two strings:

Serial.print("String Xmitted: ");
Serial.println(testStr);
Serial.print("String Recvd:   ");
Serial.println(s);

On the ESP8266 serial monitor, I see:

Trying to connect to AP101
Connected.
MAC Addr: 18:FE:34:9F:F9:85
IP Addr:  192.8.50.249
Subnet:   255.255.255.0
Gateway:  192.8.50.1
DNS Addr: 192.8.50.15
Channel:  9
Status: 3
String Xmitted: The Quick Brown Fox Jumps Over the Lazy Dog
String Recvd:   The Quick Brown Fox Jumps Over the Lazy Dog
on
off

and within the TCPDUMP’s output you can see the string transmitted and received as well (I’ve omitted all packets except for the 2 I’m interested in here):

12:13:05.296650 IP 192.8.50.249.4097 > 192.8.50.106.echo: Flags [P.], seq 1:44, ack 1, win 5840, length 43
        0x0000:  4500 0053 0006 0000 ff06 d62a c008 32f9  E..S.......*..2.
        0x0010:  c008 326a 1001 0007 0000 1996 6595 39a9  ..2j........e.9.
        0x0020:  5018 16d0 1d46 0000 5468 6520 5175 6963  P....F..The.Quic
        0x0030:  6b20 4272 6f77 6e20 466f 7820 4a75 6d70  k.Brown.Fox.Jump
        0x0040:  7320 4f76 6572 2074 6865 204c 617a 7920  s.Over.the.Lazy.
        0x0050:  446f 67                                  Dog
12:13:05.298192 IP 192.8.50.106.echo > 192.8.50.249.4097: Flags [P.], seq 1:44, ack 44, win 29200, length 43
        0x0000:  4500 0053 c353 4000 4006 91dd c008 326a  E..S.S@.@.....2j
        0x0010:  c008 32f9 0007 1001 6595 39a9 0000 19c1  ..2.....e.9.....
        0x0020:  5018 7210 e5b9 0000 5468 6520 5175 6963  P.r.....The.Quic
        0x0030:  6b20 4272 6f77 6e20 466f 7820 4a75 6d70  k.Brown.Fox.Jump
        0x0040:  7320 4f76 6572 2074 6865 204c 617a 7920  s.Over.the.Lazy.
        0x0050:  446f 67                                  Dog

The entire program is here (note: the code for the LED is still here as I still plan to use it a little further on).

#include             <ESP8266WiFi.h>
#include            <WiFiClient.h>

const int             ledPin                 = 0;

// ---------------------------------------------------------------------------
void setup() {

WiFiClient            client;
int                    i;
char                pass[]                = "1234";
char                ssid[]                = "AP101";
char                s[100];
int                 status;
char                testStr[]            = "The Quick Brown Fox Jumps Over the Lazy Dog";

Serial.begin(9600);
pinMode(ledPin, OUTPUT);

Serial.print("Trying to connect to ");
Serial.println(ssid);

// attempt to connect to Wifi network:
status = WiFi.begin(ssid, pass);

status = WiFi.waitForConnectResult();
if (status != WL_CONNECTED) {
    Serial.println("Connection Failed");
    while (true) {}
    }

Serial.println("Connected.");
Serial.print("MAC Addr: ");
Serial.println(WiFi.macAddress());
Serial.print("IP Addr:  ");
Serial.println(WiFi.localIP());
Serial.print("Subnet:   ");
Serial.println(WiFi.subnetMask());
Serial.print("Gateway:  ");
Serial.println(WiFi.gatewayIP());
Serial.print("DNS Addr: ");
Serial.println(WiFi.dnsIP());
Serial.print("Channel:  ");
Serial.println(WiFi.channel());
Serial.print("Status: ");
Serial.println(WiFi.status());

if (!client.connect("rpi", 7)) {
    Serial.println("Connection to echo server failed");
    while (true) {}
    }

client.println(testStr);

i = 0;
while (true) {
    while (client.available() == 0) {}
    s[i] = client.read();
    if (s[i] == '\n') {
        s[i] = '\0';
        break; // while
        }
    else if (s[i] == '\r')
        ; // do nothing additional on return character - it will be overwritten by next char
    else {
        if (i == sizeof(s)) {
            Serial.println("buffer overflow");
            while (true) {}
            }
        else
            i = i + 1;
        }
    } // while

Serial.print("String Xmitted: ");
Serial.println(testStr);
Serial.print("String Recvd:   ");
Serial.println(s);

} // setup

// ---------------------------------------------------------------------------
void loop() {

int                    k;

for (k = 0; k <= 100; k = k + 1) {

    Serial.println("on");
    digitalWrite(ledPin, HIGH);
    delay(500);

    Serial.println("off");
    digitalWrite(ledPin, LOW);
    delay(500);
    }

WiFi.disconnect(true);

while (true) {}

}

 

Advertisements
This entry was posted in c-arduino and tagged . Bookmark the permalink.

2 Responses to ESP8266/Arduino IDE: Communicating with TCP

  1. Pingback: ESP8266/Arduino IDE: Further TCP Exploration | Big Dan the Blogging Man

  2. Pingback: ESP8266/Arduino IDE: Further TCP Exploration | Big Dan the Blogging Man

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s