ESP8266 TCP to Serial

Make a transparent TCP to Serial (UART) bridge using the ESP8266

ESP8266 TCP to Serial

This page explains how to program the ESP-01 module to become a WiFi to Serial Transparent Bridge.

Materials needed:
- ESP-01 WiFi module
- 8-pin socket for the ESP-01 module
- 1x 470R resistor
- 2x 220R resistors
- 2x 47uF capacitors
- 3.3V 250mA LDO voltage regulator MCP1702T3302ECB
- 2-pin jumper + jumper header
- wires
- protoboard
- soldering iron + solder

Introduction

A WiFi to Serial transparent bridge is very useful, it can replace the BlueSMiRF Bluetooth module to use WiFi instead of Bluetooth. It works as Serial passthrough:
The data received from TCP client goes to Tx pin,
The data from Rx pin goes to TCP client.
Both LUA and Arduino IDE code available!

Steps:

Using LUA and NodeMCU:

1.
Build the circuit according to the schematic.

2.
Flash NodeMCU Firmware to ESP8266 (Here is how).

3.
Upload this init.lua script to the ESP:

wifi.setmode(wifi.SOFTAP)

cfg={}
cfg.ssid="mywifi"
cfg.pwd="qwerty123"

cfg.ip="192.168.0.1"
cfg.netmask="255.255.255.0"
cfg.gateway="192.168.0.1"

port = 9876

wifi.ap.setip(cfg)
wifi.ap.config(cfg)

print("ESP8266 TCP to Serial Bridge v1.0 by RoboRemo")
print("SSID: " .. cfg.ssid .. "  PASS: " .. cfg.pwd)
print("RoboRemo app must connect to " .. cfg.ip .. ":" .. port)
print("BaudRate will change now to 115200")

tmr.alarm(0,200,0,function() -- run after a delay

    uart.setup(0, 115200, 8, 0, 1, 1)

    srv=net.createServer(net.TCP, 28800) 
    srv:listen(port,function(conn)
     
        uart.on("data", 0, function(data)
            conn:send(data)
        end, 0)
        
        conn:on("receive",function(conn,payload) 
            uart.write(0, payload)
        end)  
        
        conn:on("disconnection",function(c) 
            uart.on("data")
        end)
        
    end)
end)

4.
Connect the adapter you just built to your project, as you would conect a Bluetooth Serial module.

5.
Power ON your project.

6.
Open Android WiFi settings and connect to SSID "mywifi" with password "qwerty123".

7.
Open RoboRemo and connect to TCP 192.168.0.1:9876

8.
Enjoy controlling your project using RoboRemo :)


Using Arduino IDE:

1.
Configure the settings in this Arduino sketch according to your needs:
(SSID, password, IP, port, mode (AP/STATION))

// ESP8266 WiFi <-> UART Bridge
// by RoboRemo
// www.roboremo.com

// Disclaimer: Don't use RoboRemo for life support systems
// or any other situations where system failure may affect
// user or environmental safety.

#include <ESP8266WiFi.h>


// config: ////////////////////////////////////////////////////////////

#define UART_BAUD 9600
#define packTimeout 5 // ms (if nothing more on UART, then send packet)
#define bufferSize 8192

//#define MODE_AP // phone connects directly to ESP
#define MODE_STA // ESP connects to WiFi router

#define PROTOCOL_TCP
//#define PROTOCOL_UDP


#ifdef MODE_AP
// For AP mode:
const char *ssid = "mywifi";  // You will connect your phone to this Access Point
const char *pw = "qwerty123"; // and this is the password
IPAddress ip(192, 168, 0, 1); // From RoboRemo app, connect to this IP
IPAddress netmask(255, 255, 255, 0);
const int port = 9876; // and this port
// You must connect the phone to this AP, then:
// menu -> connect -> Internet(TCP) -> 192.168.0.1:9876
#endif


#ifdef MODE_STA
// For STATION mode:
const char *ssid = "myrouter";  // Your ROUTER SSID
const char *pw = "password"; // and WiFi PASSWORD
const int port = 9876;
// You must connect the phone to the same router,
// Then somehow find the IP that the ESP got from router, then:
// menu -> connect -> Internet(TCP) -> [ESP_IP]:9876
#endif

//////////////////////////////////////////////////////////////////////////




#ifdef PROTOCOL_TCP
#include <WiFiClient.h>
WiFiServer server(port);
WiFiClient client;
#endif

#ifdef PROTOCOL_UDP
#include <WiFiUdp.h>
WiFiUDP udp;
IPAddress remoteIp;
#endif


uint8_t buf1[bufferSize];
uint16_t i1=0;

uint8_t buf2[bufferSize];
uint16_t i2=0;



void setup() {

  delay(500);
  
  Serial.begin(UART_BAUD);

  #ifdef MODE_AP 
  //AP mode (phone connects directly to ESP) (no router)
  WiFi.mode(WIFI_AP);
  WiFi.softAPConfig(ip, ip, netmask); // configure ip address for softAP 
  WiFi.softAP(ssid, pw); // configure ssid and password for softAP
  #endif

  
  #ifdef MODE_STA
  // STATION mode (ESP connects to router and gets an IP)
  // Assuming phone is also connected to that router
  // from RoboRemo you must connect to the IP of the ESP
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, pw);
  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
  }
  #endif

  #ifdef PROTOCOL_TCP
  Serial.println("Starting TCP Server");
  server.begin(); // start TCP server 
  #endif

  #ifdef PROTOCOL_UDP
  Serial.println("Starting UDP Server");
  udp.begin(port); // start UDP server 
  #endif
}


void loop() {

  #ifdef PROTOCOL_TCP
  if(!client.connected()) { // if client not connected
    client = server.available(); // wait for it to connect
    return;
  }

  // here we have a connected client

  if(client.available()) {
    while(client.available()) {
      buf1[i1] = (uint8_t)client.read(); // read char from client (RoboRemo app)
      if(i1<bufferSize-1) i1++;
    }
    // now send to UART:
    Serial.write(buf1, i1);
    i1 = 0;
  }

  if(Serial.available()) {

    // read the data until pause:
    
    while(1) {
      if(Serial.available()) {
        buf2[i2] = (char)Serial.read(); // read char from UART
        if(i2<bufferSize-1) i2++;
      } else {
        //delayMicroseconds(packTimeoutMicros);
        delay(packTimeout);
        if(!Serial.available()) {
          break;
        }
      }
    }
    
    // now send to WiFi:
    client.write((char*)buf2, i2);
    i2 = 0;
  }
  #endif



  #ifdef PROTOCOL_UDP
  // if there‚Äôs data available, read a packet
  int packetSize = udp.parsePacket();
  if(packetSize>0) {
    remoteIp = udp.remoteIP(); // store the ip of the remote device
    udp.read(buf1, bufferSize);
    // now send to UART:
    Serial.write(buf1, packetSize);
  }

  if(Serial.available()) {

    // read the data until pause:
    //Serial.println("sa");
    
    while(1) {
      if(Serial.available()) {
        buf2[i2] = (char)Serial.read(); // read char from UART
        if(i2<bufferSize-1) {
          i2++;
        }
      } else {
        //delayMicroseconds(packTimeoutMicros);
        //Serial.println("dl");
        delay(packTimeout);
        if(!Serial.available()) {
          //Serial.println("bk");
          break;
        }
      }
    }

    // now send to WiFi:  
    udp.beginPacket(remoteIp, port); // remote IP and port
    udp.write(buf2, i2);
    udp.endPacket();
    i2 = 0;
  }
    
  #endif
  
  
}

2.
Build the circuit according to the schematic.

3.
Connect the Firmware Update jumper.

4.
Connect the circuit to PC using an USB to Serial adapter like FTDI.

5.
Upload the Arduino sketch to your ESP

6.
Disconnect the circuit fromt PC and connect it to your project, as you would conect a Bluetooth Serial module.

7.
Power ON your project.

8.
Connect phone to the ESP WiFi with the SSID you configured in the code (AP mode) or to the same router where ESP connected (STATION mode)

9.
Open RoboRemo and select menu -> connect -> Internet(TCP) -> enter IP:port of the ESP

10.
Enjoy controlling your project using RoboRemo :)


Note:
For normal operation of ESP8266, GPIO0 and GPIO2 must be floating or HIGH at power on.

Note2:
The ESP8266 will switch BaudRate to 115200 after power on. If you want to put it back in the state as it was before writing init.lua file, open a terminal with BaudRate 115200 and enter file.remove("init.lua"), then enter node.restart(), then close terminal and open again with BaudRate 9600.

Update 2015-09-08
For LUA code: There seems to be a problem when sending large amount of data from UART to TCP. Part of the data is skipped. Probably the code can not process fast enough all that data. Changing the BaudRate to a lower value (tested with 19200) seems to fix that.

Update 2016-10-29
Arduino IDE code available: https://github.com/roboremo/ESP8266-WiFi-UART-Bridge
Can be configured to work in AP mode (phone connects directly to the ESP)
or STATION mode (ESP connects to router)
Enjoy :)