ESP8266 under MicroPython : using th MOD-IO2 board (UEXT connector)

Ce n'est pas l'habitude sur ce blog mais pour une fois, je vais offrir une traduction anglaise pour nos amis d'Olimex.
We are not use to publish paper un english but this time we will offer a translation for our friend at Olimex.
15 days before, we did published the paper "MicroPython running on the Olimex's ESP8266-EVB" followed by a paper on the "Olimex MOD-IO" expansion board and how to manipulate relais, opto-isolated input (24v) and analog input (3.3v).

This time, we will explore a new UEXT expansion board, the Olimex's MO-IO2.
Olimex's ESP8266-EVB
The UEXT Connector and expansion boards
What make the ESP8266-EVB so great it is the UEXT connector. The UEXT is an 10 Pins IDC standard connector  carrying an I2C bus, SPI bus and asynchronous serial connection (sort of Serial port).
Mapping UEXT sur ESP8266
Thank to the pin mapping between the UEXT and ESP8266-DEV, we can consider to take control over UEXT expansion board with MicroPyhton. What's make it so great is that you can use the board & expansion without wiring hardness :-)

The code will be compatible with all other 3.3v MicroPython micro controller. You just need to wire the I2C bus properly on the UEXT connector.

MOD-IO2 expansion board

Carte MOD-IO2
MOD-IO2 is a development board allowing you to append relais, analog & digital inputs, PWM output on any board having an UEXT or I2C bus. So, if you need extra Input/Ouput under 3.3V logic then this board is the product of your needs.

Carte MOD-IO2
The MOD-IO2 boards can be daisy chained and are adressables. This means that you can have several board connected together as long each one have distinct address!
Thank to the UEXT connector, wiring the board is child's play!
Very kind for school learning purpose.
Brancher la carte MOD-IO2, UEXT Splitter et ESP8266-EVB ensembles
MOD-IO2 Library
We did wrote the modio2 library to ease the control of the board under MicroPython.
This library is available on the GitHub page dedicated to the MODIO-2 under MicroPython.

Upload the file on your MicroPython micro controler and you are ready.

Test the MOD-IO2 board under MicroPython
# Using the Olimex's MOD-IO2 board with an ESP8266-EVB under MicroPython
# Shop: [UEXT Expandable Input/Output board (MOD-IO2)](
# GitHub:

from machine import I2C, Pin
from time import sleep_ms
from modio2 import MODIO2

i2c = I2C( sda=Pin(2), scl=Pin(4) )
brd = MODIO2( i2c ) # Adresse par défaut=0x21

# === Handle the GPIOs =============================
print( "Display the pin modes")
print( brd.gpios.pin_modes )
# Should return: ['IN', 'IN', 'IN', 'IN', 'IN', 'IN', 'IN']

print( "GPIO 5 - analod read")
brd.gpios.pin_mode( 5, Pin.IN )
for i in range(10):
    volt = brd.gpios.analog(5)
    print( "GPIO 5 (AN7) = %s v" % volt )
    val  = brd.gpios.analog(5, raw=True )
    print( "GPIO 5 (AN7) = %s / 1023" % val )
    sleep_ms( 1000 )

print( "GPIO 0 - as output (OUT) switched On then Off" )
brd.gpios.pin_mode( 0, Pin.OUT )
brd.gpios[0] = True
sleep_ms( 2000 )
brd.gpios[0] = False

print( "GPIO 1,2,3 - as input (IN)" )
brd.gpios.pin_mode( 1, Pin.IN )
brd.gpios.pin_mode( 2, Pin.IN )
brd.gpios.pin_mode( 3, Pin.IN, Pin.PULL_UP ) # pull up is mandatory on GPIO 3
print( "Display the pin modes")
print( brd.gpios.pin_modes )
# Should display ['OUT', 'IN', 'IN', 'IN', 'IN', 'IN', 'IN']

print( "Display the state of every I/O (1/0)" )
print( brd.gpios.states )
# Should display [False, False, True, False, False, True, False]

# === RELAYS ======================================
# Change the states of relay REL1 & REL2.
# The relays are counted from 0
print( 'Modif. relais par index' )
brd.relais[0] = True
brd.relais[1] = False
print( 'Relays[0..1] states : %s' % brd.relais.states )
# Should display: [True, False]  
sleep_ms( 2000 )

# Switch off all the relays
brd.relais.states = False 

print( 'Change the relays (one at the time)')
for irelay in range( 2 ):
    print( '   relay %s' % (irelay+1) )
    brd.relais[irelay] = True # ON
    sleep_ms( 1000 )
    brd.relais[irelay] = False # OFF
    sleep_ms( 500 )

print( 'Update several relays at once' )
brd.relais.states = [False, True]
sleep_ms( 2000 )
print( 'Activate all relays' )
brd.relais.states = True
sleep_ms( 2000 )
print( 'Switch off all relays' )
brd.relais.states = False

print( "That's the end folks")

Generate a PWM output on MOD-IO2
We can generate a PWM output on the GPIO 5 & GPIO 6 of the MOD-IO2 board. The following exemple read the analog input on GPIO 5 then use th value to set the PWM Duty Cycle on the GPIO 6.

# PWM Test on Olimex's MOD-IO2 with an ESP8266 under MicroPython
# Shop:
# GitHub:

from machine import I2C, Pin
from time import sleep_ms
from modio2 import MODIO2

i2c = I2C( sda=Pin(2), scl=Pin(4) )
brd = MODIO2( i2c ) # default address=0x21

print( "GPIO 5 - IN")
brd.gpios.pin_mode( 5, Pin.IN )

print( "GPIO 6 - PWM" )
brd.gpios.pwm( gpio=6, cycle=0 )

while cycle<255:
    val = brd.gpios.analog( 5, raw = True )
    cycle = val // 4   # from 0..1023 to 0..254
    if cycle >= 254:   # encure 100% of duty cycle
        cycle = 255
    brd.gpios.pwm( 6, cycle )
    print( "val=%s -> cycle=%s" %(val,cycle) )
    sleep_ms( 1000 )

print( "That's the end folks")

Which produce the following result on the serial connexion:

MicroPython v1.9.4-8-ga9a3caad0 on 2018-05-11; ESP module with ESP8266
Type "help()" for more information.
>>> import test2pwm
val=698 -> cycle=174
val=698 -> cycle=174
val=620 -> cycle=155
val=614 -> cycle=153
val=597 -> cycle=149
val=496 -> cycle=124
val=494 -> cycle=123
val=701 -> cycle=175
val=880 -> cycle=220
val=978 -> cycle=244
val=979 -> cycle=244
val=982 -> cycle=245
val=1023 -> cycle=255
That's the end folks

Connect several MOD-IO2
You can connect several MOD-IO2 board together. You just need to change the board's address before connecting them (otherwise I2C address conflict will appears between the board). The MOD-IO2 retains the I2C address inside the EEPROM. This address can be changed with a function call. The following sample change the MOD-IO2 address from 0x21 to 0x22.

# Change the Olimex's MOD-IO2 address to 0x22
# Shop:
# GitHub:

from machine import I2C, Pin
from modio2 import MODIO2

i2c = I2C( sda=Pin(2), scl=Pin(4) )
brd = MODIO2( i2c, addr=0x21 )
brd.change_address( 0x22 )

Please note that address change is immediate, so the ACK is not retuned by 0x21 but 0x22 (which is causing transmission error under MicroPython... by the way , this new address is accepted and applied inside the board).

Tutorials and GitHub
You may find numerous information in the french tutorial and products listed here under.
Where to buy