NodeMCU and HD 44780 – part 1

Another post about ESP8266!. This time we will attach a char display based on HD44780, something we already done for Raspberry Pi.
It will require some wiring and writing.
This time I’m also using NodeMCU v3 board because it has 5V on VU pin and we gonna power our display from it.
As for the display I have a nice 16×2 lcd.

Wiring

To connect lcd to board we are using 6 data pins, one (or more) ground pin(s) and VU pin. For now we have a nice mess with wires:) but later we will made a small board to clean up this.

  LCD                      NodeMCU
1 VSS ------------- GND
2 VDD ----------------------- VU 
3 V0 ------/\/\/\-
              \---- GND
4 RS ------------------------ D6
5 R/W ------------- GND
6 E ------------------------- D7
11 D4 ----------------------- D5
12 D5 ----------------------- D3
13 D6 ----------------------- D1
14 D7 ----------------------- D2
15 A ------/\/\/\-
              \---- VU
16 K -------------- GND

Two potentiometers are used, one to adjust screen brightness and second to adjust text strength.

Software

What we need to do? First setup data pins:

pins = {
    RS= 7,
    E= 6,
    DB4= 5,
    DB5= 3,
    DB6= 1,
    DB7= 2,
}

for k,v in pairs(pins) do 
    gpio.mode(v, gpio.OUTPUT)
    gpio.write(v, gpio.LOW)
end

To initialize display in 4 bit mode we need to send command 0x02. But what is 4 bit mode?
Its nice trick that allow us to send 8 bites in two parts. First we send four higher bits and next we send four lower bits. That is why we are using only 4 data lines.
After we set pins we need to tell HD44870 to read them. Its done by setting E high for 5 ms.
This imply that we need function send:

function send()    
    gpio.write(pins['E'], gpio.HIGH)
    tmr.delay(5)
    gpio.write(pins['E'], gpio.LOW)
end

Next function will set our four data pins correctly. My first problem was that I didn’t compile firmware with bit library. Quickly reflashed and I could do a bit operations 🙂 Thanks to this function write4 looks like this:

function write4(ch)
    if bit.isset(ch, 0) then gpio.write(pins['DB4'], gpio.HIGH) else gpio.write(pins['DB4'], gpio.LOW) end        
    if bit.isset(ch, 1) then gpio.write(pins['DB5'], gpio.HIGH) else gpio.write(pins['DB5'], gpio.LOW) end        
    if bit.isset(ch, 2) then gpio.write(pins['DB6'], gpio.HIGH) else gpio.write(pins['DB6'], gpio.LOW) end       
    if bit.isset(ch, 3) then gpio.write(pins['DB7'], gpio.HIGH) else gpio.write(pins['DB7'], gpio.LOW) end

    send()
end

How to send 8 bits ? Just like that:

function write(ch)
    print ("write "..ch)
    write4(bit.rshift(ch, 4))
    write4(bit.band(ch, 0x0F))    
end

We can now initialize display, first RS to low and then send commands:

print ("core ready")
gpio.write(pins['RS'], gpio.LOW)

write4(3)
tmr.delay(50)
write4(3)
tmr.delay(50)
write4(3)
tmr.delay(50)
write4(2)
write8(0x28)
write8(0x08)
write8(0x01)
write8(0x06)
write8(15)

What is going on there?
We do some pinging and then send 2 command. From now on we are in 4 bit mode. Next we set some other options.
Setup complete, we may now display Hello message:

gpio.write(pins['RS'], gpio.HIGH)
write(string.byte('H'))
write(string.byte('e'))
write(string.byte('l'))
write(string.byte('l'))
write(string.byte('o'))

Summary

We made it – our lcd is alive and can display any text. But using it this way? Very inconvenient. But do not worry, there is a way to fix this problem 🙂 New shiny lcd_hd44870 class. Stay tuned !

Advertisements

2 comments

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s