ESP8266 WiFi – Universal I/O bridge Firmware

iobridge logo

Espressif logo vol



This is a project that attempts to make all (or at least most) of the I/O on the ESP8266 available over the network. Currently this includes GPIO’s (as GPIO or PWM), I2C, the UART and external displays (currently only SAA1064).

The GPIOs can be selected to work as “normal” input, “normal” output, “timer” mode (this means trigger once, either manually or at startup, or “blink” continuously) or “pwm” mode (16 bits PWM mode, running at 330 Hz, suitable for driving lighting).

The “normal” UART lines (TXD/RXD) are available and are bridged to the ESP8266’s ip address at port 25. This is unless the UART lines are re-assigned as GPIOs, which is also possible.

GPIOs can also be selected to work as i2c lines (sda, scl). You can use the “raw” i2c send and receive commands to send/receive arbitrary commands/data to arbitrary slaves. For a number of i2c sensors there is built-in support, which allows you to read them out directly, where a temperature etc. is given as result.

The firmware also listens at tcp port 24, and that is where the configuration and commands go to. Type telnet <ip_address> 24 and type ? for help.

The project is still in development, expect more features in the future.

About the UART bridge

The UART bridge accepts connections on tcp port 23, gets all data from it, sends it to the UART (serial port) and the other way around. This is the way to go to make your non-networking microcontroller WiFi-ready. If you add an RS-232C buffer (something like a MAX232 or similar), you can even make your non-networking peripherals like printers etc. available over the wireless lan.

The UART driver is heavily optimised and is completely interrupt driven, no polling, which makes it very efficient.

This code is very loosely based on the work of beckdac, which I used as a starting point, although there hasn’t been any original code left for some time 😉

This is how it works:

  • Attach your microcontroller’s UART lines or RS232C’s line driver lines to the ESP8266, I think enough has been written about how to do that.
  • Load a generic “AT-command” style firmware into the ESP8266. Exactly how to do that should be on the page you’re downloading the firmware from.
  • Setup the wlan parameters (SSID and password) from this firmware, using a terminal emulator. Check it’s working and write to flash (if the firmware doesn’t do that automatically).
  • Now flash this firmware, for example with the command, something like this: --port /dev/pl2303 --baud 460800 write_flash 0x00000 fw-0x00000.bin 0x40000 fw-0x40000.bin. Replace /dev/pl2303 by the proper device node. The ESP8266 can indeed be flashed at this high speed, it’s autoprobing the baud rate. If it doesn’t succeed immediately, try again, sometimes the ESP8266 gets the baud rate wrong initially. If it still doesn’t work, try a lower baud rate.
  • After flashing restart. In theory this is not necessary, but I found the UART won’t start if you leave out the reset.
  • Start a telnet session to port 24 of the ip address, type help and <enter>.
  • You will now see all commands.
  • Use the commands starting with baud to setup the UART. After that, issue the config-write command to save and use the reset command to restart.
  • After restart you will have a transparent connection between tcp port 23 and the UART, tcp port 24 is always available for control.

About i2c

To work with i2c, first select two GPIO’s as sda and scl lines using the gm .. mode sda and gm .. mode scl commands. Besides the “normal” GPIOs, it should be possible to use GPIO0 and GPIO2 for i2c (boot selection), just as GPIO1 andGPIO3 (normally connected to the UART) using a proper pull-up resistor, but I didn’t try it myself.

The selected GPIO’s are set to open drain mode without pull-up, so you will have to add them yourself. The proper value of the resistors should be calculated but 4.7 kOhm usually works just fine.

Use the i2c-address, i2c-read and i2c-write commands to read/write raw data to/from i2c slaves.

For a selection of well-known i2c sensors, there is built-in support. Use the i2c-sensor-dump and i2c-sensor-readcommands for these.

Currently supported i2c sensors are:

  • digipicco (temperature and humidity)
  • lm75 (and compatible sensors) (temperature)
  • ds1621/ds1631/ds1731 (temperature)
  • bmp085 (temperature and pressure) (untested for now)
  • htu21 (temperature and humdity) (untested for now)
  • am2321 (temperature and humidity)
  • tsl2560 (light intensity)
  • bh1750 (light intensity).

About external displays

Currently only the SAA1064 is supported, it’s a 4×7 led display multiplexer, controlled over i2c.

In the future I plan to add “bare” LCD text displays using the well-known Hitachi LCD controller and Orbital Matrix i2c-controlled VFD/LCD screens.

The system consists of multiple “slots” of messages that will be shown one at a time. You can set a timeout on a message and it will be deleted automatically after that time. If no slots are left, it show the current time (rtc). Use 0 as timeout to not auto-expire slots.

All displays have 8 slots for messages that can be set using the ds (display-set) command: ds . Use dd (display-dump) to show all detected displays, add a verbosity value (0-2) to see more detail. Finally the db (display-bright) command controls the brightness of the display. Valid values are 0 (off), 1, 2, 3, 4 (max). Use: db

Please note the saa1064 runs at 5V or higher. It cannot be connected to the esp8266 directly. It must have it’s own 5V power supply and may or may not need i2c level shifters. I am using level shifters, but it may not be necessary in the end. YMMV.

Needless to say it will only work if i2c is up and running.

Commands concerning the UART bridge:

short long parameters description
ub uart-baud baud rate Any baud rate you like, forget the 300-600-1200-2400-etc. list, the ESP8266 can freely use any baud rate you like. Don’t forget to config-write and reset.
ud uart-data 5, 6, 7, or 8 The number of data bits, usually 8.
us uart-stop 1 or 2 The number of stop bits, usually 1.
up uart-parity none, evenor odd The parity, usually none. Don’t forget to set data bits to 7 if you want to use any parity.

Commands concerning configuration:

short long parameters description
cd config-dump none Shows the complete configuration as stored in non volatile memory.
cw config-write none Writes config to non volatile memory.

Commands concerning GPIO:

short long parameters description
gd gpio-dump none Dump GPIO configuration and current status.
gg gpio-get gpio Read GPIO. For example gg 2 reads the GPIO 2 as input.
gs gpio-set gpio [value] Set the GPIO if it’s set as output, if set as timer, trigger the timer, if it’s set as pwm, set the duty cycle (default startup value is taken if it’s missing).
gm gpio-mode mode[mode parameters] Without mode/parameters: dump all GPIOs and their mode. See the table below for available modes and their syntax when parameters are supplied. After making changes, use reset to enable the changes.
command:gm gpiomode parameters: description:
disable none Dont’ use the GPIO (leave completely untouched).
input none Set GPIO to input.
counter [reset_on_get[debounce_time]] Set GPIO to counter. Set reset_on_get to 1 to have the counter reset when read. Set debounce to set debounce time in milliseconds (default is 100 ms).
output startup-state Set GPIO to output. Set startup-state to 0 or 1 to configure the state of the output directly after start.
timer direction delayrepeatautotrigger
Set direction to either up or down, specifying whether to start the timer output from “off” or “on”.
Set delay to a value in milliseconds between triggered state and resuming normal output state.
Set repeat to 0 or 1. 0 means run once, 1 means repeat until stopped manually.
Set autotrigger to 0 or 1. 0 means leave the output alone after start, you need to trigger manually then (using gpio-set), 1 means trigger automatically after start.
pwm [startup-duty-cycle] startup duty cycle is the duty cycle after boot, default 0. The duty cycle can be 0 (off) to 65535 (continuously on).
i2c sda or scl configure this GPIO for i2c operation. Specify two GPIOs to assign to sda and scl.

I2C related commands

short long parameters description
ia i2c-address address set i2c slave’s client address for subsequent read and write commands.
ir i2c-read bytes Read (raw) this amount of bytes from the i2c slave. The bytes returned are in hex.
iw i2c_write byte [byte …] Write (raw) bytes to i2c slave. Format is hex bytes separated by a space, e.g. 1 2 a b cc.
irst i2c-reset none Reset the i2c bus. Required whenever a read or write failed.
isd i2c-sensor-dump [verbose] Dump all detected sensors on the i2c bus. Set verbose to 1 to list all known sensors, including those that are not detected, set verbose to 2 to get even more verbose output, including i2c bus errors.
isr i2c-sensor-read sensor-id Get the value of the sensor with id sensor id. Obtain sensor id’s with i2c-sensor-dump.
isc i2c-sensor-calibrate sensor-idscale offset Set calibration of the sensor with id sensor id. The result from the sensor is multiplied by scale and then offset is added. Both values may be negative and are floating point types. Don’t forget to write the config afterwards.

Display commands:

display idslottimeouttext

short long parameters description
db display-brightness brightness Sets display brightness. Use brightness = 0 (off), 1,2,3,4
dd display-dump Dumps all detected displays.
ds display-set Displays text on display. Slots with text are shown in turn, after timeout (in seconds) the slot is discarded, 0 for permanent, need to replace manually.

Other commands:

short long parameters description
? help none Shows list of commands.
s or u set/unset [option] Sets / unset options. Add option to set/unset option, leave out the option to list all options.

Currently known options are:

print-debug, shows debug info on the UART (wlan, dhcp etc).

strip-telnet, disable / enable stripping initial “garbage” from telnet at the UART bridge.

tsl-high-sens, set tsl2550 and tsl2561 sensors to “high sensitivity mode”, recommended unless operated outdoors in sunlight.

bh-high-sens, set bh1750 sensor to “high sensitivity mode”, recommended unless operated outdoors in sunlight.

To activate, write config and restart.

q quit none Disconnect from the control channel.
r reset none Reset the ESP8266, required if you make changes to the UART parameters or to the GPIOs mode.
S stats none Shows some statistics (timers, wlan, memory). These may change over time.
rs rtc-set hoursminutesseconds Set “real time clock”. It’s a real time clock in the sense that it counts hours, minutes, seconds. It may not be that precise. YMMV.
wl wlan-list none View results of access point / ssid scan from wlan-list
ws wlan-scan none Initiate access point / ssid scan. Use wlan-list to view the results

Download universal i/o bridge @