echo '' ;

Archives

ESP8266 NodeMCU Interface – MCP23008

This Lua script demonstrates how to interface the MCP23008 GPIO expander with an ESP8266 NodeMCU board. The MCP23008 provides an easy way to expand the number of GPIO pins available for use, which can be particularly useful when working with microcontrollers like the ESP8266 that have limited GPIO pins.

Read more: ESP8266 NodeMCU Interface – MCP23008

By using the I2C protocol, the ESP8266 communicates with the MCP23008 to control its GPIO pins. This script sets up the MCP23008, configures its GPIO pins as inputs or outputs, and demonstrates reading the state of input pins (buttons) and controlling the output pins (LEDs).

The script showcases how to initialize the MCP23008, set pin directions, configure pull-up resistors, and read/write GPIO states. Additionally, it periodically reads the state of input pins (buttons) and prints their status, providing a practical example of interfacing with external components using the MCP23008.

Overall, this script serves as a practical guide for implementing GPIO expansion with the MCP23008 on the ESP8266 NodeMCU platform.

Required

  • Required NodeMCU Modules (Firmware) : GPIO Module, I2C Module, Node Module,
  • Required Hardware and Software Tools are ESP8266 with Programmer (or)  NodeMCU Dev Kit, MCP23008, LED,
  • Required software tool is ESPlorer IDE Tool.

MCP23008 with LED Interface

`lua
----------------------------------------
-- https://www.aruneworld.com/embedded/espressif/esp32/esp32_nodemcu/
-- Tested By : Arun(20170212)
-- Example Name : AEW_MCP23008_LEDs.lua
----------------------------------------

-- Constant device address.
local MCP23008_ADDRESS = 0x20

-- Registers' address as defined in the MCP23008's datasheet
local MCP23008_IODIR = 0x00
local MCP23008_IPOL = 0x01
local MCP23008_GPINTEN = 0x02
local MCP23008_DEFVAL = 0x03
local MCP23008_INTCON = 0x04
local MCP23008_IOCON = 0x05
local MCP23008_GPPU = 0x06
local MCP23008_INTF = 0x07
local MCP23008_INTCAP = 0x08
local MCP23008_GPIO = 0x09
local MCP23008_OLAT = 0x0A

-- Default value for i2c communication
local id = 0

-- pin modes for I/O direction
M.INPUT = 1
M.OUTPUT = 0

-- pin states for I/O i.e. on/off
M.HIGH = 1
M.LOW = 0

-- Weak pull-up resistor state
M.ENABLE = 1
M.DISABLE = 0

-- Write function: Writes one byte to a register
local function write(registerAddress, data)
    i2c.start(id)
    i2c.address(id, MCP23008_ADDRESS, i2c.TRANSMITTER)
    i2c.write(id, registerAddress)
    i2c.write(id, data)
    i2c.stop(id)
end

-- Read function: Reads the value of a register
local function read(registerAddress)
    i2c.start(id)
    i2c.address(id, MCP23008_ADDRESS, i2c.TRANSMITTER)
    i2c.write(id, registerAddress)
    i2c.stop(id)
    i2c.start(id)
    i2c.address(id, MCP23008_ADDRESS, i2c.RECEIVER)
    local data = 0x00
    data = i2c.read(id, 1) -- we expect only one byte of data
    i2c.stop(id)
    return string.byte(data) -- i2c.read returns a string so we convert to its int value
end

-- Begin function: Sets the MCP23008 device address's last three bits
function M.begin(address, pinSDA, pinSCL, speed)
    MCP23008_ADDRESS = bit.bor(MCP23008_ADDRESS, address)
    i2c.setup(id, pinSDA, pinSCL, speed)
end

-- Write GPIO function: Writes a byte of data to the GPIO register
function M.writeGPIO(dataByte)
    write(MCP23008_GPIO, dataByte)
end

-- Read GPIO function: Reads a byte of data from the GPIO register
function M.readGPIO()
    return read(MCP23008_GPIO)
end

-- Write IODIR function: Writes one byte of data to the IODIR register
function M.writeIODIR(dataByte)
    write(MCP23008_IODIR, dataByte)
end

-- Read IODIR function: Reads a byte from the IODIR register
function M.readIODIR()
    return read(MCP23008_IODIR)
end

-- Write GPPU function: Writes a byte of data to the GPPU register
function M.writeGPPU(dataByte)
    write(MCP23008_GPPU, dataByte)
end

-- Read GPPU function: Reads the GPPU (Pull-UP resistors register) byte
function M.readGPPU()
    return read(MCP23008_GPPU)
end

-- ESP-01 GPIO Mapping as per GPIO Table in https://github.com/nodemcu/nodemcu-firmware
local gpio0, gpio2 = 3, 4

-- Setup MCP23008
M.begin(0x0, gpio2, gpio0, i2c.SLOW)
M.writeIODIR(0x00) -- make all GPIO pins as outputs
M.writeGPIO(0x00) -- make all GPIO pins off/low

-- Count function: Reads the value from the GPIO register, increases the read value by 1,
-- and writes it back so the LEDs will display a binary count up to 255 or 0xFF in hex.
local function count()
    local gpio = 0x00
    gpio = mcp23008.readGPIO()
    if gpio < 0xff then
        mcp23008.writeGPIO(gpio + 1)
    else
        mcp23008.writeGPIO(0x00)
    end
end

-- Run count() every 100ms
tmr.alarm(0,100,1,count)

Explanation

SectionDescription for ESP8266 NodeMCU Interface MCP23008
Header CommentsContains information about the source, author, and example name.
ConstantsDefines constant values for the MCP23008’s device address and various register addresses.
Global VariablesInitializes the id variable to represent the I2C interface index.
Pin Modes and StatesDefines constants for input and output modes, as well as pin states for I/O operations.
Write and Read FunctionsFunctions to write data to and read data from MCP23008 registers via I2C communication.
Initialization FunctionSets up the MCP23008 device address and initializes I2C communication.
GPIO Control FunctionsFunctions to write to and read from the GPIO register of the MCP23008.
I/O Direction Control FunctionsFunctions to control the input/output direction register (IODIR) of the MCP23008.
Pull-Up Resistor Configuration FunctionsFunctions to control the pull-up resistor configuration register (GPPU) of the MCP23008.
Main SetupMaps GPIO pins for SDA and SCL, and initializes the MCP23008 with specific configurations.
LED Counting FunctionReads the current value from the GPIO register, increments it by 1, and writes it back to create a binary count pattern on the LEDs.
Timer SetupSets up a timer to execute the LED counting function (count) every 100ms.

MCP23008 with Buttons Interface

This Lua code sets up communication between an ESP8266 NodeMCU and an MCP23008 I/O expander via the I2C protocol. It defines functions to write and read from the MCP23008’s registers, as well as functions to control the GPIO pins and their states. Finally, it continuously monitors the state of the GPIO pins connected to buttons and prints the state every 2 seconds.

----------------------------------------
-- https://www.aruneworld.com/embedded/espressif/esp8266/esp8266_nodemcu/
-- Tested By : Arun(20170212)
-- Example Name : AEW_MCP23008_Buttons.lua
----------------------------------------

-- Constant device address.
local MCP23008_ADDRESS = 0x20

-- Registers' address as defined in the MCP23008's datasheet
local MCP23008_IODIR = 0x00
local MCP23008_IPOL = 0x01
local MCP23008_GPINTEN = 0x02
local MCP23008_DEFVAL = 0x03
local MCP23008_INTCON = 0x04
local MCP23008_IOCON = 0x05
local MCP23008_GPPU = 0x06
local MCP23008_INTF = 0x07
local MCP23008_INTCAP = 0x08
local MCP23008_GPIO = 0x09
local MCP23008_OLAT = 0x0A

-- Default value for i2c communication
local id = 0

-- pin modes for I/O direction
M.INPUT = 1
M.OUTPUT = 0

-- pin states for I/O i.e. on/off
M.HIGH = 1
M.LOW = 0

-- Weak pull-up resistor state
M.ENABLE = 1
M.DISABLE = 0

-- Write function: Writes one byte to a register
local function write(registerAddress, data)
    i2c.start(id)
    i2c.address(id, MCP23008_ADDRESS, i2c.TRANSMITTER)
    i2c.write(id, registerAddress)
    i2c.write(id, data)
    i2c.stop(id)
end

-- Read function: Reads the value of a register
local function read(registerAddress)
    i2c.start(id)
    i2c.address(id, MCP23008_ADDRESS, i2c.TRANSMITTER)
    i2c.write(id, registerAddress)
    i2c.stop(id)
    i2c.start(id)
    i2c.address(id, MCP23008_ADDRESS, i2c.RECEIVER)
    local data = i2c.read(id, 1)
    i2c.stop(id)
    return string.byte(data)
end

-- Begin function: Sets the MCP23008 device address's last three bits
function M.begin(address, pinSDA, pinSCL, speed)
    MCP23008_ADDRESS = bit.bor(MCP23008_ADDRESS, address)
    i2c.setup(id, pinSDA, pinSCL, speed)
end

-- Write GPIO function: Writes a byte of data to the GPIO register
function M.writeGPIO(dataByte)
    write(MCP23008_GPIO, dataByte)
end

-- Read GPIO function: Reads a byte of data from the GPIO register
function M.readGPIO()
    return read(MCP23008_GPIO)
end

-- Write IODIR function: Writes one byte of data to the IODIR register
function M.writeIODIR(dataByte)
    write(MCP23008_IODIR, dataByte)
end

-- Read IODIR function: Reads a byte from the IODIR register
function M.readIODIR()
    return read(MCP23008_IODIR)
end

-- Write GPPU function: Writes a byte of data to the GPPU register
function M.writeGPPU(dataByte)
    write(MCP23008_GPPU, dataByte)
end

-- Read GPPU function: Reads the GPPU (Pull-UP resistors register) byte
function M.readGPPU()
    return read(MCP23008_GPPU)
end

-- ESP-01 GPIO Mapping as per GPIO Table in https://github.com/nodemcu/nodemcu-firmware
local gpio0, gpio2 = 3, 4

-- Setup the MCP23008
M.begin(0x0, gpio2, gpio0, i2c.SLOW)
M.writeIODIR(0xff)
M.writeGPPU(0xff)

-- Show buttons state function
function showButtons()
    local gpio = M.readGPIO()
    for pin = 0, 7 do
        local pinState = bit.band(bit.rshift(gpio, pin), 0x1)
        if pinState == M.HIGH then
            pinState = "HIGH"
        else
            pinState = "LOW"
        end
        print("Pin " .. pin .. ": " .. pinState)
    end
    print("\r\n")
end

tmr.alarm(0, 2000, 1, showButtons) -- run showButtons() every 2 seconds

Explanation

SectionDescription
Header CommentsContains information about the source, author, and example name.
ConstantsDefines constant values for the MCP23008’s device address and various register addresses.
Global VariablesInitializes the id variable to represent the I2C interface index.
Pin Modes and StatesDefines constants for input and output modes, as well as pin states for I/O operations.
Write and Read FunctionsFunctions to write data to and read data from MCP23008 registers via I2C communication.
Initialization FunctionSets up the MCP23008 device address and initializes I2C communication.
GPIO Control FunctionsFunctions to write to and read from the GPIO register of the MCP23008.
I/O Direction Control FunctionsFunctions to control the input/output direction register (IODIR) of the MCP23008.
Pull-Up Resistor ConfigurationFunctions to control the pull-up resistor configuration register (GPPU) of the MCP23008.
Main SetupMaps GPIO pins for SDA and SCL, and initializes the MCP23008 with specific configurations.
Show Buttons State FunctionReads the state of each GPIO pin (button), prints the state, and repeats every 2 seconds.

Next

NodeMCU Get Start
NodeMCU Build Firmware
NodeMCU Flash Firmware
NodeMCU IDE
ESP8266 NodeMCU Modules
NodeMCU Module–Firmware Info
NodeMCU Module – GPIO
NodeMCU Module – Node
NodeMCU Module – WiFi
NodeMCU Module – Timer
NodeMCU Module – I2C
NodeMCU Module – File
NodeMCU Module – NET
NodeMCU Module – HTTP
NodeMCU Module – MQTT
ESP8266 NodeMCU Interface
NodeMCU Interface LED
NodeMCU Interface Button
NodeMCU Interface 7 Seg
NodeMCU Interface LCD
NodeMCU Interface ADC
NodeMCU Interface DHT11
NodeMCU Interface MCP23008
NodeMCU Interface MCP23017
NodeMCU Interface ADXL345
NodeMCU Interface DS18B20
ESP8266 NodeMCU Tutorials
NodeMCU Tutorials Google Time
NodeMCU Tutorials WebServer
ESP8266 NodeMCU Projects
Imperial March Ringtone Play
WiFi Router Status Indicator
ESP8266 Home Automation
Others
NodeMCU All Post
Sitemap