From 02e150314ad7d47b9c36cfce20d857e73bd3f08c Mon Sep 17 00:00:00 2001 From: Nathaniel Wesley Filardo Date: Sun, 22 Jan 2017 19:59:18 -0500 Subject: [PATCH] Fork dvv-nodemcu-things lcd1602 Improve initialization sequence, remove buggy 'run' method. This file and all changes to it retain the original (MIT) license, independent of the rest of this project. --- _external/lcd1602.lua | 110 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 _external/lcd1602.lua diff --git a/_external/lcd1602.lua b/_external/lcd1602.lua new file mode 100644 index 0000000..5c846cb --- /dev/null +++ b/_external/lcd1602.lua @@ -0,0 +1,110 @@ +------------------------------------------------------------------------------ +-- LCD 1602 module +-- +-- LICENSE: http://opensource.org/licenses/MIT +-- Vladimir Dronnikov +-- Compiled from various sources inc. +-- http://www.avrfreaks.net/forum/lcd-display-iic-1602-atmega328p +-- http://www.avrfreaks.net/sites/default/files/lcd_22.h +-- https://github.com/nekromant/esp8266-frankenstein/blob/4880a04452ab745b1d99c0aedbb69cc2ba7fd5cb/include/driver/i2c_hd44780.h +-- +-- Originally from +-- https://github.com/dvv/nodemcu-thingies/blob/master/lcd1602.lua . +-- Modified by nwf to improve comm reliability and remove buggy 'run' +-- function. This file retains its original license, as above, and is +-- not subject to the license of the containing project. +-- +-- Example: +-- i2c.setup(0, 3, 4, i2c.SLOW) +-- lcd = dofile("lcd1602.lua")() +-- lcd:put(lcd:locate(0, 5), "Hello, dvv!") +-- lcd:clear() +-- lcd:define_char(0, { 10, 0, 14, 17, 17, 17, 14, 0 }) -- custom char o umlaut +-- lcd:put(lcd:locate(0, 0), "\000!"); lcd:put(lcd:locate(0, 14), "!\000") +------------------------------------------------------------------------------ + +local _offsets = { [0] = 0x80, 0xC0, 0x94, 0xD4 } -- 20x4 +-- local _offsets = { [0] = 0x80, 0xC0, 0x90, 0xD0 } -- 16x4 + +-- write byte helper +local w = function(self, b, mode) + i2c.start(0) + i2c.address(0, self._adr, i2c.TRANSMITTER) + local bh = bit.band(b, 0xF0) + self._ctl + mode + local bl = bit.lshift(bit.band(b, 0x0F), 4) + self._ctl + mode + i2c.write(0, bh + 4, bh, bl + 4, bl) + i2c.stop(0) + tmr.delay(40) +end + +-- backlight on/off +local light = function(self, on) + self._ctl = on and 0x08 or 0x00 + w(self, 0x00, 0) +end + +-- clear screen +local clear = function(self) + w(self, 0x01, 0) +end + +-- return command to set cursor at row/col +local locate = function(self, row, col) + return col + _offsets[row] +end + +-- define custom char 0-7 +-- NB: e.g. use "\003" in argument to .put to display custom char 3 +local define_char = function(self, index, bytes) + w(self, 0x40 + 8 * bit.band(index, 0x07), 0) + for i = 1, #bytes do w(self, bytes[i], 1) end +end + +-- write to lcd +local put = function(self, ...) + for _, x in ipairs({...}) do + -- number? + if type(x) == "number" then + -- direct command + w(self, x, 0) + -- string? + elseif type(x) == "string" then + -- treat as data + for i = 1, #x do w(self, x:byte(i), 1) end + end + end +end + +-- start lcd +local init = function(self) + w(self, 0x33, 0) -- move to 8 bit data mode + w(self, 0x32, 0) -- move to 4 bit data mode + w(self, 0x28, 0) -- 2 lines, 5x8 dots + w(self, 0x0C, 0) -- display on, cursor and cursor blink off + w(self, 0x06, 0) -- position increment, no display shift + w(self, 0x02, 0) -- cursor home + w(self, 0x01, 0) -- clear display +end + +-- instance metatable +local meta = { + __index = { + clear = clear, + define_char = define_char, + init = init, + light = light, + locate = locate, + put = put, + run = run, + }, +} + +-- create new LCD1602 instance +return function(adr) + local self = setmetatable({ + _adr = adr or 0x27, + _ctl = 0x08, + }, meta) + self:init() + return self +end -- 2.50.1