From d1e279ae6cd1e2b37050a5022b0d0c8a4faf605d Mon Sep 17 00:00:00 2001 From: Rhys Williams Date: Mon, 13 May 2019 21:16:12 +1200 Subject: [PATCH 1/4] Add driver for HD44780 character LCD with i2c interface --- examples/drivers/HD44780i-i2c/main.js | 81 +++++++++ examples/drivers/HD44780i-i2c/manifest.json | 12 ++ modules/drivers/HD44780-i2c/HD44780.js | 172 ++++++++++++++++++++ 3 files changed, 265 insertions(+) create mode 100644 examples/drivers/HD44780i-i2c/main.js create mode 100644 examples/drivers/HD44780i-i2c/manifest.json create mode 100644 modules/drivers/HD44780-i2c/HD44780.js diff --git a/examples/drivers/HD44780i-i2c/main.js b/examples/drivers/HD44780i-i2c/main.js new file mode 100644 index 0000000000..6c469a26ec --- /dev/null +++ b/examples/drivers/HD44780i-i2c/main.js @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2016-2017 Moddable Tech, Inc. + * Copyright (c) 2019 Wilberforce + * + * This file is part of the Moddable SDK. + * + * This work is licensed under the + * Creative Commons Attribution 4.0 International License. + * To view a copy of this license, visit + * . + * or send a letter to Creative Commons, PO Box 1866, + * Mountain View, CA 94042, USA. + * + */ + +import Timer from "timer"; +import HD44780 from "HD44780"; + +let lcd = new HD44780({ + sda: 12, + scl: 13, + address: 0x27, +}); + +// Degree symbol +lcd.createChar( 2,[ 0x0C,0x12,0x12,0x0C,0x00,0x00,0x00,0x00] ); + +lcd.setCursor(0, 0); +lcd.cursor(true); + +// Moddable logo Left and Right parts, 6x8 matrix +lcd.createChar( 0, +[ + 0b00001110, + 0b00010000, + 0b00010000, + 0b00010000, + 0b00010000, + 0b00010000, + 0b00010000, + 0b00001110, +] ); +lcd.createChar( 1, + [ + 0b00000000, + 0b00111100, + 0b00000010, + 0b00000010, + 0b00000010, + 0b00000010, + 0b00111100, + 0b00000000, + ] ); + +lcd.blink(true); +lcd.blink(false); +lcd.blink(true); +lcd.cursor(false); +lcd.cursor(true); +lcd.setCursor(0, 0); +lcd.setCursor(5, 1); +lcd.setCursor(0, 0); + +lcd.print('Moddable '+String.fromCharCode(0)+String.fromCharCode(1)); + +Timer.repeat(() => { + let date = new Date(); + let hours = String(date.getHours()); + let minutes = String(date.getMinutes()); + let seconds = String(date.getSeconds()); + let ampm = (hours > 11 ? ' pm' : ' am'); + if (hours > 12) + hours -= 12; + if (1 == minutes.length) + minutes = '0' + minutes; + if (1 == seconds.length) + seconds = '0' + seconds; + let time = hours + ':' + minutes + ':' + seconds + ampm; + lcd.setCursor(0,1).print(time); + lcd.print( ' 20'+String.fromCharCode(2)+'c'); +}, 1000); \ No newline at end of file diff --git a/examples/drivers/HD44780i-i2c/manifest.json b/examples/drivers/HD44780i-i2c/manifest.json new file mode 100644 index 0000000000..1df0c46c0c --- /dev/null +++ b/examples/drivers/HD44780i-i2c/manifest.json @@ -0,0 +1,12 @@ +{ + "include": [ + "$(MODDABLE)/examples/manifest_base.json", + "$(MODULES)/pins/i2c/manifest.json", + ], + "modules": { + "*": "./main", + "pins/i2c": "$(MODULES)/pins/i2c/i2c", + "HD44780": "$(MODULES)/drivers/HD44780-i2c/HD44780" + }, + "preload": "HD44780", +} \ No newline at end of file diff --git a/modules/drivers/HD44780-i2c/HD44780.js b/modules/drivers/HD44780-i2c/HD44780.js new file mode 100644 index 0000000000..cf7e0d49a5 --- /dev/null +++ b/modules/drivers/HD44780-i2c/HD44780.js @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2016-2017 Moddable Tech, Inc. + * Copyright (c) 2019 Wilberforce + * + * This file is part of the Moddable SDK Runtime. + * + * The Moddable SDK Runtime is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Moddable SDK Runtime is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the Moddable SDK Runtime. If not, see . + * + */ + +/* + HD44780 - LCD i2c module using PCF8574P i2c expander in 4 Bit mode +*/ + +import I2C from "pins/i2c"; +import Timer from "timer"; + +let displayPorts = { + RS: 0x01, + E: 0x04, + D4: 0x10, + D5: 0x20, + D6: 0x40, + D7: 0x80, + + CHR: 1, + CMD: 0, + + backlight: 0x08, + RW: 0x20 // not used +}; + +var LCD = {}; + +LCD.CLEARDISPLAY = 0x01; +LCD.RETURNHOME = 0x02; +LCD.ENTRYMODESET = 0x04; +LCD.DISPLAYCONTROL = 0x08; +LCD.CURSORSHIFT = 0x10; +LCD.FUNCTIONSET = 0x20; +LCD.SETCGRAMADDR = 0x40; +LCD.SETDDRAMADDR = 0x80; + +//# flags for display entry mode +LCD.ENTRYRIGHT = 0x00; +LCD.ENTRYLEFT = 0x02; +LCD.ENTRYSHIFTINCREMENT = 0x01; +LCD.ENTRYSHIFTDECREMENT = 0x00; + +//# flags for display on/off control +LCD.DISPLAYON = 0x04; +LCD.DISPLAYOFF = 0x00; +LCD.CURSORON = 0x02; +LCD.CURSOROFF = 0x00; +LCD.BLINKON = 0x01; +LCD.BLINKOFF = 0x00; + +//# flags for display/cursor shift +LCD.DISPLAYMOVE = 0x08; +LCD.CURSORMOVE = 0x00; +LCD.MOVERIGHT = 0x04; +LCD.MOVELEFT = 0x00; + +//# flags for function set +LCD._8BITMODE = 0x10; +LCD._4BITMODE = 0x00; +LCD._2LINE = 0x08; +LCD._1LINE = 0x00; +LCD._5x10DOTS = 0x04; +LCD._5x8DOTS = 0x00; + +class HD44780 extends I2C { + constructor(dictionary) { + + super(Object.assign({ + address: 0x27 + }, dictionary)); + + // Backlight state - default on + this.backlight=displayPorts.backlight; + + this.write4(0x30, displayPorts.CMD); //initialization + Timer.delay(200); + this.write4(0x30, displayPorts.CMD); //initialization + Timer.delay(100); + this.write4(0x30, displayPorts.CMD); //initialization + Timer.delay(100); + this.write4(LCD.FUNCTIONSET | LCD._4BITMODE | LCD._2LINE | LCD._5x10DOTS, displayPorts.CMD); //4 bit - 2 line 5x7 matrix + + Timer.delay(10); + this.write8(LCD.DISPLAYCONTROL | LCD.DISPLAYON, displayPorts.CMD); //turn cursor off 0x0E to enable cursor + Timer.delay(10); + this.write8(LCD.ENTRYMODESET | LCD.ENTRYLEFT, displayPorts.CMD); //shift cursor right + Timer.delay(10); + this.write8(LCD.CLEARDISPLAY, displayPorts.CMD); // LCD clear + Timer.delay(10); + } + + write4(nibble, cmd) { + var msb = (nibble & 0xF0) | this.backlight; // Use upper 4 bit nibble + this.write(msb | cmd); + Timer.delay(1); + this.write(msb | displayPorts.E | cmd); + Timer.delay(1); + this.write(msb | cmd ); + Timer.delay(1); + } + + write8(byte, cmd) { + this.write4(byte, cmd); + this.write4(byte << 4, cmd); + return this; + } + // print text + print(str) { + for (var i = 0; i < str.length; i++) { + this.write8(str.charCodeAt(i), displayPorts.CHR); + } + return this; + } + // clear screen + clear() { + return this.write8(LCD.CLEARDISPLAY, displayPorts.CMD); + } + + // flashing block for the current cursor, or underline + cursor(block) { + return this.write8(block ? 0x0F : 0x0E, displayPorts.CMD); + } + // set cursor pos, top left = 0,0 + setCursor(x, y) { + var l = [0x00, 0x40, 0x14, 0x54]; + let bits = (l[y] + x); + return this.write8(LCD.SETDDRAMADDR | bits, displayPorts.CMD); + } + // set special character 0..7, data is an array(8) of bytes, and then return to home addr + createChar(ch, data) { + this.write8(LCD.SETCGRAMADDR | ((ch & 7) << 3), displayPorts.CMD); + for (var i = 0; i < 8; i++) + this.write8(data[i], displayPorts.CHR); + return this; + } + + blink(state) { + return this.write8(LCD.DISPLAYCONTROL | LCD.DISPLAYON | LCD.CURSORON | state ? LCD.BLINKON : LCD.BLINKOFF, displayPorts.CMD); + } + + setBacklight(val) { + if (val > 0) { + this.backlight = displayPorts.backlight; + } else { + this.backlight = 0x00; + } + return this.write8(LCD.DISPLAYCONTROL, displayPorts.CMD); + } +} + +export { + HD44780 as + default, HD44780 +}; \ No newline at end of file From a343f62e201326e78814c2a398993584c25088bb Mon Sep 17 00:00:00 2001 From: Rhys Williams Date: Fri, 17 May 2019 18:21:32 +1200 Subject: [PATCH 2/4] freeze constants and class --- modules/drivers/HD44780-i2c/HD44780.js | 130 +++++++++++++------------ 1 file changed, 68 insertions(+), 62 deletions(-) diff --git a/modules/drivers/HD44780-i2c/HD44780.js b/modules/drivers/HD44780-i2c/HD44780.js index cf7e0d49a5..77a4364edb 100644 --- a/modules/drivers/HD44780-i2c/HD44780.js +++ b/modules/drivers/HD44780-i2c/HD44780.js @@ -26,59 +26,64 @@ import I2C from "pins/i2c"; import Timer from "timer"; -let displayPorts = { +const displayPorts = { RS: 0x01, E: 0x04, D4: 0x10, D5: 0x20, D6: 0x40, D7: 0x80, + backlight: 0x08, + //RW: 0x20 not used +}; + +Object.freeze(displayPorts); + +const LCD = { CHR: 1, CMD: 0, - - backlight: 0x08, - RW: 0x20 // not used + + CLEARDISPLAY: 0x01, + RETURNHOME: 0x02, + ENTRYMODESET: 0x04, + DISPLAYCONTROL: 0x08, + CURSORSHIFT: 0x10, + FUNCTIONSET: 0x20, + SETCGRAMADDR: 0x40, + SETDDRAMADDR: 0x80, + + //# flags for display entry mode + ENTRYRIGHT: 0x00, + ENTRYLEFT: 0x02, + ENTRYSHIFTINCREMENT: 0x01, + ENTRYSHIFTDECREMENT: 0x00, + + //# flags for display on/off control + DISPLAYON: 0x04, + DISPLAYOFF: 0x00, + CURSORON: 0x02, + CURSOROFF: 0x00, + BLINKON: 0x01, + BLINKOFF: 0x00, + + //# flags for display/cursor shift + DISPLAYMOVE: 0x08, + CURSORMOVE: 0x00, + MOVERIGHT: 0x04, + MOVELEFT: 0x00, + + //# flags for function set + _8BITMODE: 0x10, + _4BITMODE: 0x00, + _2LINE: 0x08, + _1LINE: 0x00, + _5x10DOTS: 0x04, + _5x8DOTS: 0x00, }; -var LCD = {}; - -LCD.CLEARDISPLAY = 0x01; -LCD.RETURNHOME = 0x02; -LCD.ENTRYMODESET = 0x04; -LCD.DISPLAYCONTROL = 0x08; -LCD.CURSORSHIFT = 0x10; -LCD.FUNCTIONSET = 0x20; -LCD.SETCGRAMADDR = 0x40; -LCD.SETDDRAMADDR = 0x80; - -//# flags for display entry mode -LCD.ENTRYRIGHT = 0x00; -LCD.ENTRYLEFT = 0x02; -LCD.ENTRYSHIFTINCREMENT = 0x01; -LCD.ENTRYSHIFTDECREMENT = 0x00; - -//# flags for display on/off control -LCD.DISPLAYON = 0x04; -LCD.DISPLAYOFF = 0x00; -LCD.CURSORON = 0x02; -LCD.CURSOROFF = 0x00; -LCD.BLINKON = 0x01; -LCD.BLINKOFF = 0x00; - -//# flags for display/cursor shift -LCD.DISPLAYMOVE = 0x08; -LCD.CURSORMOVE = 0x00; -LCD.MOVERIGHT = 0x04; -LCD.MOVELEFT = 0x00; - -//# flags for function set -LCD._8BITMODE = 0x10; -LCD._4BITMODE = 0x00; -LCD._2LINE = 0x08; -LCD._1LINE = 0x00; -LCD._5x10DOTS = 0x04; -LCD._5x8DOTS = 0x00; +Object.freeze(LCD); + class HD44780 extends I2C { constructor(dictionary) { @@ -86,24 +91,24 @@ class HD44780 extends I2C { super(Object.assign({ address: 0x27 }, dictionary)); - + // Backlight state - default on - this.backlight=displayPorts.backlight; + this.backlight = displayPorts.backlight; - this.write4(0x30, displayPorts.CMD); //initialization + this.write4(0x30, LCD.CMD); //initialization Timer.delay(200); - this.write4(0x30, displayPorts.CMD); //initialization + this.write4(0x30, LCD.CMD); //initialization Timer.delay(100); - this.write4(0x30, displayPorts.CMD); //initialization + this.write4(0x30, LCD.CMD); //initialization Timer.delay(100); - this.write4(LCD.FUNCTIONSET | LCD._4BITMODE | LCD._2LINE | LCD._5x10DOTS, displayPorts.CMD); //4 bit - 2 line 5x7 matrix + this.write4(LCD.FUNCTIONSET | LCD._4BITMODE | LCD._2LINE | LCD._5x10DOTS, LCD.CMD); //4 bit - 2 line 5x7 matrix Timer.delay(10); - this.write8(LCD.DISPLAYCONTROL | LCD.DISPLAYON, displayPorts.CMD); //turn cursor off 0x0E to enable cursor + this.write8(LCD.DISPLAYCONTROL | LCD.DISPLAYON, LCD.CMD); //turn cursor off 0x0E to enable cursor Timer.delay(10); - this.write8(LCD.ENTRYMODESET | LCD.ENTRYLEFT, displayPorts.CMD); //shift cursor right + this.write8(LCD.ENTRYMODESET | LCD.ENTRYLEFT, LCD.CMD); //shift cursor right Timer.delay(10); - this.write8(LCD.CLEARDISPLAY, displayPorts.CMD); // LCD clear + this.write8(LCD.CLEARDISPLAY, LCD.CMD); // LCD clear Timer.delay(10); } @@ -113,7 +118,7 @@ class HD44780 extends I2C { Timer.delay(1); this.write(msb | displayPorts.E | cmd); Timer.delay(1); - this.write(msb | cmd ); + this.write(msb | cmd); Timer.delay(1); } @@ -125,35 +130,35 @@ class HD44780 extends I2C { // print text print(str) { for (var i = 0; i < str.length; i++) { - this.write8(str.charCodeAt(i), displayPorts.CHR); + this.write8(str.charCodeAt(i), LCD.CHR); } return this; } // clear screen clear() { - return this.write8(LCD.CLEARDISPLAY, displayPorts.CMD); + return this.write8(LCD.CLEARDISPLAY, LCD.CMD); } // flashing block for the current cursor, or underline cursor(block) { - return this.write8(block ? 0x0F : 0x0E, displayPorts.CMD); + return this.write8(block ? 0x0F : 0x0E, LCD.CMD); } // set cursor pos, top left = 0,0 setCursor(x, y) { var l = [0x00, 0x40, 0x14, 0x54]; let bits = (l[y] + x); - return this.write8(LCD.SETDDRAMADDR | bits, displayPorts.CMD); + return this.write8(LCD.SETDDRAMADDR | bits, LCD.CMD); } // set special character 0..7, data is an array(8) of bytes, and then return to home addr createChar(ch, data) { - this.write8(LCD.SETCGRAMADDR | ((ch & 7) << 3), displayPorts.CMD); - for (var i = 0; i < 8; i++) - this.write8(data[i], displayPorts.CHR); + this.write8(LCD.SETCGRAMADDR | ((ch & 7) << 3), LCD.CMD); + for (var i = 0; i < 8; i++) + this.write8(data[i], LCD.CHR); return this; } blink(state) { - return this.write8(LCD.DISPLAYCONTROL | LCD.DISPLAYON | LCD.CURSORON | state ? LCD.BLINKON : LCD.BLINKOFF, displayPorts.CMD); + return this.write8(LCD.DISPLAYCONTROL | LCD.DISPLAYON | LCD.CURSORON | state ? LCD.BLINKON : LCD.BLINKOFF, LCD.CMD); } setBacklight(val) { @@ -162,11 +167,12 @@ class HD44780 extends I2C { } else { this.backlight = 0x00; } - return this.write8(LCD.DISPLAYCONTROL, displayPorts.CMD); + return this.write8(LCD.DISPLAYCONTROL, LCD.CMD); } } +Object.freeze(HD44780.prototype); export { HD44780 as - default, HD44780 + default, HD44780, LCD }; \ No newline at end of file From 17fa1c13bfc71aad572816d32a095cc2e99e361b Mon Sep 17 00:00:00 2001 From: Rhys Williams Date: Sat, 18 May 2019 09:01:40 +1200 Subject: [PATCH 3/4] block cursor --- modules/drivers/HD44780-i2c/HD44780.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/drivers/HD44780-i2c/HD44780.js b/modules/drivers/HD44780-i2c/HD44780.js index 77a4364edb..becea3f17a 100644 --- a/modules/drivers/HD44780-i2c/HD44780.js +++ b/modules/drivers/HD44780-i2c/HD44780.js @@ -66,6 +66,10 @@ const LCD = { CURSOROFF: 0x00, BLINKON: 0x01, BLINKOFF: 0x00, + //BLOCKON: 0x80 + //BLOCKOFF: 0x00 + + //# flags for display/cursor shift DISPLAYMOVE: 0x08, From bd7235a049c24c135182331ee34f3207dda860f2 Mon Sep 17 00:00:00 2001 From: Rhys Williams Date: Sat, 18 May 2019 09:08:38 +1200 Subject: [PATCH 4/4] fix folder name --- examples/drivers/{HD44780i-i2c => HD44780-i2c}/main.js | 0 examples/drivers/{HD44780i-i2c => HD44780-i2c}/manifest.json | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename examples/drivers/{HD44780i-i2c => HD44780-i2c}/main.js (100%) rename examples/drivers/{HD44780i-i2c => HD44780-i2c}/manifest.json (100%) diff --git a/examples/drivers/HD44780i-i2c/main.js b/examples/drivers/HD44780-i2c/main.js similarity index 100% rename from examples/drivers/HD44780i-i2c/main.js rename to examples/drivers/HD44780-i2c/main.js diff --git a/examples/drivers/HD44780i-i2c/manifest.json b/examples/drivers/HD44780-i2c/manifest.json similarity index 100% rename from examples/drivers/HD44780i-i2c/manifest.json rename to examples/drivers/HD44780-i2c/manifest.json