UNPKG

cylon-i2c

Version:

Cylon.js drivers for i2c devices

337 lines (288 loc) 7.62 kB
/* * LCD display driver * http://cylonjs.com * * Copyright (c) 2013-2015 The Hybrid Group * Licensed under the Apache 2.0 license. */ "use strict"; var Cylon = require("cylon"); var I2CDriver = require("./i2c-driver"); /** * A LCD Driver * * @constructor lcd */ var LCD = module.exports = function LCD() { LCD.__super__.constructor.apply(this, arguments); this.address = this.address || 0x27; this._backlightVal = LCD.NOBACKLIGHT; this._displayfunction = LCD.FOURBITMODE | LCD.TWOLINE | LCD.FIVExEIGHTDOTS; this._displaycontrol = LCD.DISPLAYON | LCD.CURSOROFF | LCD.BLINKOFF; this._displaymode = LCD.ENTRYLEFT | LCD.ENTRYSHIFTDECREMENT; this.setupCommands([ "clear", "home", "setCursor", "displayOff", "displayOn", "cursorOff", "cursorOn", "blinkOff", "blinkOn", "backlightOff", "backlightOn", "print" ]); }; Cylon.Utils.subclass(LCD, I2CDriver); // i2c commands 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.EIGHTBITMODE = 0x10; LCD.FOURBITMODE = 0x00; LCD.TWOLINE = 0x08; LCD.ONELINE = 0x00; LCD.FIVExTENDOTS = 0x04; LCD.FIVExEIGHTDOTS = 0x00; // flags for backlight control LCD.BACKLIGHT = 0x08; LCD.NOBACKLIGHT = 0x00; LCD.En = 0x04; // Enable bit LCD.Rw = 0x02; // Read/Write bit LCD.Rs = 0x01; // Register select bit /** * Starts the driver * * @param {Function} callback triggered when the driver is started * @return {void} */ LCD.prototype.start = function(callback) { this._init(); this.displayOn(); this.clear(); this.home(); // Turn backlight on by default this.backlightOn(); every(0, function() { this._expanderWrite(this._backlightVal); }.bind(this)); callback(); }; /** * Clears display and returns cursor to the home position (address 0). * * @param {Function} [callback] function to be invoked when done * @return {void} * @publish */ LCD.prototype.clear = function(callback) { this._sendCommand(LCD.CLEARDISPLAY); Cylon.Utils.sleep(2); if (typeof callback === "function") { callback(); } }; /** * Returns cursor to home position. * * @param {Function} [callback] function to be invoked when done * @return {void} * @publish */ LCD.prototype.home = function(callback) { this._sendCommand(LCD.RETURNHOME); Cylon.Utils.sleep(2); if (typeof callback === "function") { callback(); } }; /** * Sets cursor position. * * @param {Number} col cursor column to set * @param {Number} row cursor row to set * @param {Function} [callback] function to be invoked when done * @return {void} * @publish */ LCD.prototype.setCursor = function(col, row, callback) { var rowOffsets = [0x00, 0x40, 0x14, 0x54]; this._sendCommand(LCD.SETDDRAMADDR | (col + rowOffsets[row])); if (typeof callback === "function") { callback(); } }; /** * Sets Off of all display (D), cursor Off (C) and blink of cursor position * character (B). * * @param {Function} [callback] function to be invoked when done * @return {void} * @publish */ LCD.prototype.displayOff = function(callback) { this._displaycontrol &= ~LCD.DISPLAYON; this._sendDisplayCommand(callback); }; /** * Sets On of all display (D), cursor On (C) and blink of cursor position * character (B). * * @param {Function} [callback] function to be invoked when done * @return {void} * @publish */ LCD.prototype.displayOn = function(callback) { this._displaycontrol |= LCD.DISPLAYON; this._sendDisplayCommand(callback); }; /** * Turns off the cursor. * * @param {Function} [callback] function to be invoked when done * @return {void} * @publish */ LCD.prototype.cursorOff = function(callback) { this._displaycontrol &= ~LCD.CURSORON; this._sendDisplayCommand(callback); }; /** * Turns on the cursor. * * @param {Function} [callback] function to be invoked when done * @return {void} * @publish */ LCD.prototype.cursorOn = function(callback) { this._displaycontrol |= LCD.CURSORON; this._sendDisplayCommand(callback); }; /** * Turns off the cursor blinking character. * * @param {Function} [callback] function to be invoked when done * @return {void} * @publish */ LCD.prototype.blinkOff = function(callback) { this._displaycontrol &= ~LCD.BLINKON; this._sendDisplayCommand(callback); }; /** * Turns on the cursor blinking character. * * @param {Function} [callback] function to be invoked when done * @return {void} * @publish */ LCD.prototype.blinkOn = function(callback) { this._displaycontrol |= LCD.BLINKON; this._sendDisplayCommand(callback); }; /** * Turns off the back light. * * @param {Function} [callback] function to be invoked when done * @return {void} * @publish */ LCD.prototype.backlightOff = function(callback) { this._backlightVal = LCD.NOBACKLIGHT; this._expanderWrite(0); if (typeof callback === "function") { callback(); } }; /** * Turns on the back light. * * @param {Function} [callback] function to be invoked when done * @return {void} * @publish */ LCD.prototype.backlightOn = function(callback) { this._backlightVal = LCD.BACKLIGHT; this._expanderWrite(0); if (typeof callback === "function") { callback(); } }; /** * Prints characters on the LCD. * * @param {String} str string to print on the LCD * @param {Function} [callback] function to be invoked when done * @return {void} * @publish */ LCD.prototype.print = function(str, callback) { var chars = str.split(""); for (var i = 0; i < chars.length; i++) { this._writeData(chars[i].charCodeAt(0)); } if (typeof callback === "function") { callback(); } }; LCD.prototype._write4bits = function(val) { this._expanderWrite(val); this._pulseEnable(val); }; LCD.prototype._expanderWrite = function(data) { this.connection.i2cWrite(this.address, (data | this._backlightVal) & 0xFF); }; LCD.prototype._pulseEnable = function(data) { this._expanderWrite(data | LCD.En); Cylon.Utils.sleep(0.0001); this._expanderWrite(data & ~LCD.En); Cylon.Utils.sleep(0.05); }; LCD.prototype._sendCommand = function(value) { this._sendData(value, 0); }; LCD.prototype._writeData = function(value) { this._sendData(value, LCD.Rs); }; LCD.prototype._sendData = function(val, mode) { var highnib = val & 0xf0, lownib = (val << 4) & 0xf0; this._write4bits(highnib | mode); this._write4bits(lownib | mode); }; LCD.prototype._init = function() { Cylon.Utils.sleep(50); this._expanderWrite(this._backlightVal); Cylon.Utils.sleep(100); this._write4bits(0x03 << 4); Cylon.Utils.sleep(4); this._write4bits(0x03 << 4); Cylon.Utils.sleep(4); this._write4bits(0x03 << 4); this._write4bits(0x02 << 4); this._sendCommand(LCD.FUNCTIONSET | this._displayfunction); // Initialize to default text direction (for roman languages), set entry mode this._sendCommand(LCD.ENTRYMODESET | this._displaymode); }; LCD.prototype._sendDisplayCommand = function(callback) { this._sendCommand(LCD.DISPLAYCONTROL | this._displaycontrol); if (typeof callback === "function") { callback(); } };