ESP8266 NodeMCU Interface 7 Segment Display
In this “ESP8266 NodeMCU Interface 7 Segment Display” project, we’re interfacing using an MCP23017 GPIO expander. The MCP23017 expands GPIO capabilities, allowing us to control the display efficiently. This setup enables us to display numeric digits on the 7-segment display through the NodeMCU board.
The NodeMCU is programmed using Lua scripting language, leveraging the I²C communication protocol to communicate with the MCP23017. We utilize the GPIO pins of the MCP23017 to control the segments of the 7-segment display, achieving the desired numerical output.
This interface offers a versatile platform for displaying numeric data in various projects, such as digital clocks, temperature monitors, or any application requiring numerical output. With the flexibility and power of the ESP8266 NodeMCU and the MCP23017 GPIO expander, this interface provides a robust solution for integrating 7-segment displays into IoT and embedded systems projects.
Required
- NodeMCU Modules (Firmware) :Â Bit Module, GPIO Module, I2C Module, Timer Module,
- hardware :Â ESP8266 with Programmer (or)Â NodeMCU Dev Kit, 7-Segment Display,
- software tools : ESPlorer IDE Tool.
Code
This script initializes the necessary constants, sets up functions for reading from and writing to the MCP23017, initializes the MCP23017, and then starts a loop to blink the 7-segment display. Make sure you have the appropriate libraries and hardware connections set up. ESP8266 NodeMCU Interface 7 Segment Display
-- https://www.aruneworld.com/embedded/espressif/esp8266/esp8266_nodemcu/
-- Tested By: Arun(20170219)
-- Example Name: AEW_7-Segment Display_MCP23017.lua
------------------------------------------------------------------------------------------
-- i2c setup
local id = 0 -- always 0
local pinSDA = 2 -- 1~12, IO index
local pinSCL = 1 -- 1~12, IO index
local speed = i2c.SLOW -- only i2c.SLOW supported
-- CONSTANTS
local MCP23017_ADDRESS = 0x21 -- you can change this id, I used 0x21
local Numbers = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}
-- MCP23017 registers (everything except direction defaults to 0)
local IODIRA = 0x00 -- I/O DIRECTION REGISTER (0 = output, 1 = input (Default))
local IODIRB = 0x01
local IPOLA = 0x02 -- INPUT POLARITY REGISTER (0 = normal, 1 = inverse)
local IPOLB = 0x03
local GPINTENA = 0x04 -- INTERRUPT-ON-CHANGE PINS
local GPINTENB = 0x05
local DEFVALA = 0x06 -- Default comparison for interrupt on change (interrupts on opposite)
local DEFVALB = 0x07
local INTCONA = 0x08 -- Interrupt control (0 = interrupt on change from previous, 1 = interrupt on change from DEFVAL)
local INTCONB = 0x09
local IOCON = 0x0A -- IO Configuration: bank/mirror/seqop/disslw/haen/odr/intpol/notimp
--IOCON = 0x0B -- same as = 0x0A
local GPPUA = 0x0C -- GPIO PULL-UP RESISTOR REGISTER (0 = disabled, 1 = enabled)
local GPPUB = 0x0D
local INFTFA = 0x0E -- Interrupt flag (read only) : (0 = no interrupt, 1 = pin caused interrupt)
local INFTFB = 0x0F
local INTCAPA = 0x10 -- Interrupt capture (read only) : value of GPIO at time of last interrupt
local INTCAPB = 0x11
local GPIOA = 0x12 -- Port value. Write to change, read to obtain value
local GPIOB = 0x13
local OLLATA = 0x14 -- Output latch. Write to latch output.
local OLLATB = 0x15
local chip1 = 0x20 -- MCP23017 is on I2C address = 0x20
local chip2 = 0x21 -- MCP23017 is on I2C address = 0x21
-- user-defined function: read from reg_addr content of dev_addr --write MCP23017 start
function read_reg(MCP23017_ADDRESS, reg_addr)
i2c.start(id)
i2c.address(id, MCP23017_ADDRESS, i2c.TRANSMITTER)
i2c.write(id, reg_addr)
i2c.stop(id)
i2c.start(id)
i2c.address(id, MCP23017_ADDRESS, i2c.RECEIVER)
local c = string.byte(i2c.read(id, 1))
i2c.stop(id)
return c
end --read MCP23017 end
--write MCP23017 start
function write_reg(MCP23017_ADDRESS, reg_addr, reg_val)
i2c.start(id)
i2c.address(id, MCP23017_ADDRESS, i2c.TRANSMITTER)
i2c.write(id, reg_addr)
i2c.write(id, reg_val)
i2c.stop(id)
end --write MCP23017 end
--MCP Initialize start
function init(MCP23017_ADDRESS)
write_reg(MCP23017_ADDRESS, IOCON, 0x60) -- BANK=0, MIRROR=1, SEQOP=1, DISSLW=0, HAEN=0, ODR=0, INTPO=0, bit0=nil
write_reg(MCP23017_ADDRESS, IODIRA, 0x00) -- Port A as Output
write_reg(MCP23017_ADDRESS, GPIOA, 0xFF) -- Set All port A pins High
end --MCP Initialize end
-----------Main Program start------------------
i2c_speed = i2c.setup(id, pinSDA, pinSCL, speed) -- Initialize the I²C module.
print("i2c_Speed : "..i2c_speed)
if i2c_speed ~= nil then
print("i2c Speed : "..i2c_speed)
print("i2c init done")
else
print("i2c init not done!!")
end
--init MCP23017
init(MCP23017_ADDRESS)
--Blink 7segment Display
write_reg(0x21, GPIOA, 0xFF)
tmr.delay(100000)
write_reg(0x21, GPIOA, 0x00)
print("7-Segment is Ready")
--Loop
function Display()
for Num = 1, 12 do
print(Numbers[Num])
if 11 == Num then
Display()
else
write_reg(0x21, GPIOA, Numbers[Num])
end
tmr.delay(1000000)
end
end
tmr.alarm(0, 1000, 0, Display)
Code Explanation
| Line(s) | Explanation |
|---|---|
| 1-9 | Header comments providing information about the code, including its source, author, and example name. |
| 11-14 | Declaration of variables for configuring the I²C communication, including the I²C ID, SDA pin, SCL pin, and speed. |
| 17-33 | Definition of constant values, including the address of the MCP23017, and an array of numbers for the 7-segment display. |
| 36-60 | Definition of MCP23017 register addresses and their corresponding functions. These functions handle reading from and writing to the MCP23017 registers. |
| 63-72 | Function to initialize the MCP23017. It sets the IO configuration and configures Port A as an output with all pins set to high. |
| 75-89 | Main program logic, including the initialization of the I²C module, printing the I²C speed, and handling initialization of the MCP23017. |
| 92-100 | Blinking of the 7-segment display. It sets all pins of Port A to high, delays, then sets them to low. |
| 103-116 | Loop function Display() to display the numbers on the 7-segment display. It iterates through the Numbers array, setting the appropriate value on Port A, and then delays. |
| 118 | Setting up a timer to call the Display() function every second. |