WiFi - ESP8266


For this week I revisited the ESP8266 chip after trying it out in the HTMAA class. My previous impression was that the chip is unstable and unexpected - the wifi connection seemed to drop now and then and the occasional TCP request would timeout which required significant management overhead.

I'm interested in having the ESP8266 chip act as a bridge node in my machine to the daisy chain of action nodes. The chip would act as a server, receiving requests through an attached (single) client and relay responses from the chain back to the client.

In this assignment I built a simple echo program to measure the return trip of a byte with the following path:

Illustration

A core problem of my previous experience is that due to my background with web applications I immediately view servers as HTTP servers. HTTP is a communication protocol in the application layer built on top of TCP. HTTP requests are originated by client, (mostly) short lived, have lengthy headers and initiate a new TCP socket stream per request.

However, It is much more efficient to open a single long-lived TCP socket with the server which is what I did in this experiment.

Another problem I had in the past was managing the serial communication between the controller and the ESP8266. There are various different responses from the ESP8266 which sometimes succeeds and fails in various ways and the response needs to be parsed accordingly. There is a also a matter of retrying failed commands.

In this experiment I used an open-source 3rd party library that abstracts the ESP8266 serial protocol with a convenient C api and seems to be well maintained: WeeESP8266

CONTROLLER Code (link)

uint8_t mux_id;
    
void loop(void)
{
    uint8_t buffer[128] = {0};

    uint32_t len = wifi.recv(&mux_id, buffer, sizeof(buffer), 100);

    if (len > 0) {
        Serial.print("Status:[");
        Serial.print(wifi.getIPStatus().c_str());
        Serial.println("]");
        
        Serial.print("Received from :");
        Serial.print(mux_id);
        Serial.print("[");
        for(uint32_t i = 0; i < len; i++) {
            Serial.print((char)buffer[i]);
            sSerial.print((char)buffer[i]);
        }
        Serial.print("]\r\n");
        
        Serial.print("Status:[");
        Serial.print(wifi.getIPStatus().c_str());
        Serial.println("]");
    }
  
  
    if (sSerial.available()) {
        int i=0;
        Serial.print("Incoming: ");
        while (sSerial.available()){
          buffer[i] = sSerial.read();
          Serial.print((char)buffer[i]);          
          i++;
        }
        Serial.print("\n");
        
        if(wifi.send(mux_id, buffer, i)) {
            Serial.print("send back ok\r\n");
        } else {
            Serial.print("send back err\r\n");
        }             
    }
    
    
}

NODE Simulation Code (serial echo)

import serial
import time

ser = serial.Serial("/dev/tty.usbserial-FTGO1C75", 9600)
while True:
  msg = ser.read(1)
  if len(msg) > 0:
    print "echoing", ord(msg)
    ser.write(msg)

TCP Test Code

import socket
import time

TCP_IP = '10.0.1.34'
TCP_PORT = 8090
BUFFER_SIZE = 1024

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))

print "packet number, response time"
for i in range(128):
  start = time.time() 
  s.send(unichr(i));
  data = s.recv(BUFFER_SIZE)
  print i, time.time()-start


s.close()
Results

Median response time is 0.553s which can be fine or bad depending on how much logic is in the computer vs. the machine itself. These results can vary significantly in different spaces with different wireless connectivity.