diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..5f76bc3 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Suz Hinton + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 866c0d2..00d14fe 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,8 @@ OLED JS Pi ## What is this? -A NodeJS driver for I2C/SPI compatible monochrome OLED screens; to be used on the Raspberry Pi! Works with 128 x 32, 128 x 64 and 96 x 16 sized screens, of the SSD1306 OLED/PLED Controller (read the [datasheet here](http://www.adafruit.com/datasheets/SSD1306.pdf)). +A NodeJS driver for I2C/SPI compatible monochrome OLED screens. Only I2C is supported at this time. +Compatible with Raspberry Pi, Works with 128 x 32, 128 x 64, 96 x 16 and 64x48 sized screens, of the SSD1306 OLED/PLED Controller (read the [datasheet here](http://www.adafruit.com/datasheets/SSD1306.pdf)). This based on the Blog Post and code by Suz Hinton - [Read her blog post about how OLED screens work](http://meow.noopkat.com/oled-js/)! @@ -17,30 +18,67 @@ OLED screens are really cool - now you can control them with JavaScript! If you haven't already, install [NodeJS](http://nodejs.org/). -`npm install oled-js-pi` +`npm install oled-ssd1306-i2c` ## I2C screens -Hook up I2C compatible oled to the Raspberry Pi. Pins: SDL and SCL + +Hook up I2C compatible oled to the Raspberry Pi. Pins: SDL and SCL. ### I2C example ```javascript -var oled = require('oled-js-pi'); +var oled = require('oled-ssd1306-i2c'); var opts = { width: 128, height: 64, - address: 0x3D }; var oled = new oled(opts); // do cool oled things here +``` + +The above code uses the default I2C address of 0x3C and the I2C device /dev/i2c-1 (default on newer Raspberry Pi boards). +Additional options that can be passed, with default values shown: + +```javascript +var opts = { + width: 128, // screen width + height; 32, // screen height + address: 0x3C, // Pass I2C address of screen if it is not the default of 0x3C + device: '/dev/i2c-1', // Pass your i2c device here if it is not /dev/i2c-1 + microview: true, // set to true if you have a microview display +}; ``` +Allowable combinations for screen width and height are: +128x32, 128x64, 96x16 and 64x48. + ### Wait, how do I find out the I2C address of my OLED screen? -Check your screen's documentation... + +You can use the i2c npm library for this. Make sure the display is connected to the I2C bus with pull-ups and run the +following: + +``` +npm install i2c +``` + +Then run the following script: + +```javascript +var i2c = require('i2c'); +var address = 0x3C; +var wire = new i2c(address, {device: '/dev/i2c-1'}); + +wire.scan(function(err, data) { + // result contains an array of addresses +}); +``` + +This will return the I2C addresses of any I2C devices connected to the bus at /dev/i2c-1. If you have other devices +than the screen attached, you will need to manually filter those out. ## Available methods @@ -136,6 +174,40 @@ Usage: oled.fillRect(1, 1, 10, 20, 1); ``` +### drawRect +Draws an empty rectangle. + +Arguments: ++ int **x0, y0** - top left corner of rectangle ++ int **x1, y1** - bottom right corner of rectangle ++ int **color** - can be specified as either 0 for 'off' or black, and 1 or 255 for 'on' or white. + +Optional bool as last argument specifies whether screen updates immediately with result. Default is true. + +Usage: +```javascript +// args: (x0, y0, x1, y1, color) +oled.drawRect(1, 1, 10, 20, 1); +``` + +### drawCircle +Draws an empty circle. + +Arguments: ++ int **x** - x of circle's center ++ int **y** - y of circle's center ++ int **r** - radius of circle ++ int **color** - can be specified as either 0 for 'off' or black, and 1 or 255 for 'on' or white. + +Optional bool as last argument specifies whether screen updates immediately with result. Default is true. + +Usage: +```javascript +// args: (x, y, r, color) +oled.drawCircle(30, 10, 5, 1); +``` + + ### drawBitmap Draws a bitmap using raw pixel data returned from an image parser. The image sourced must be monochrome, and indexed to only 2 colors. Resize the bitmap to your screen dimensions first. Using an image editor or ImageMagick might be required. @@ -214,6 +286,7 @@ Arguments: + string **text** - the actual text you want to show on the display. + int **color** - color of text. Can be specified as either 0 for 'off' or black, and 1 or 255 for 'on' or white. + bool **wrapping** - true applies word wrapping at the screen limit, false for no wrapping. If a long string without spaces is supplied as the text, just letter wrapping will apply instead. ++ int **linespacing** - amount of spacing between lines of text on the screen. Negative numbers are also ok. Optional bool as last argument specifies whether screen updates immediately with result. Default is true. @@ -239,3 +312,6 @@ Usage: ```javascript oled.update(); ``` + +Forked from https://github.com/kd7yva/oled-js-pi + diff --git a/oled.js b/oled.js index c8fbf17..2b8e2bd 100644 --- a/oled.js +++ b/oled.js @@ -2,10 +2,15 @@ var i2c = require('i2c'); var Oled = function(opts) { + if (opts == null) { + opts = {} + } + this.HEIGHT = opts.height || 32; this.WIDTH = opts.width || 128; this.ADDRESS = opts.address || 0x3C; - this.PROTOCOL = 'I2C'; + this.DEVICE = opts.device || '/dev/i2c-1'; + this.MICROVIEW = opts.microview || false; // create command buffers this.DISPLAY_OFF = 0xAE; @@ -15,7 +20,6 @@ var Oled = function(opts) { this.SET_DISPLAY_OFFSET = 0xD3; this.SET_START_LINE = 0x00; this.CHARGE_PUMP = 0x8D; - this.EXTERNAL_VCC = false; this.MEMORY_MODE = 0x20; this.SEG_REMAP = 0xA1; // using 0xA0 will flip screen this.COM_SCAN_DEC = 0xC8; @@ -61,18 +65,23 @@ var Oled = function(opts) { 'multiplex': 0x0F, 'compins': 0x2, 'coloffset': 0, - } - }; + }, + // this is blended microview / normal 64 x 48, currently wip + '64x48': { + 'multiplex': 0x2F, + 'compins': 0x12, + 'coloffset': (this.MICROVIEW) ? 32 : 0 + }, +}; // Setup i2c - console.log('this.ADDRESS: ' + this.ADDRESS); - this.wire = new i2c(this.ADDRESS, {device: '/dev/i2c-0'}); // point to your i2c address, debug provides REPL interface + this.wire = new i2c(this.ADDRESS, {device: this.DEVICE}); var screenSize = this.WIDTH + 'x' + this.HEIGHT; this.screenConfig = config[screenSize]; this._initialise(); -} +}; Oled.prototype._initialise = function() { @@ -102,10 +111,10 @@ Oled.prototype._initialise = function() { for (i = 0; i < initSeqLen; i ++) { this._transfer('cmd', initSeq[i]); } -} +}; // writes both commands and data buffers to this device -Oled.prototype._transfer = function(type, val, fn) { +Oled.prototype._transfer = function(type, val) { var control; if (type === 'data') { control = 0x40; @@ -115,22 +124,15 @@ Oled.prototype._transfer = function(type, val, fn) { return; } - // send control and actual val - // this.board.io.i2cWrite(this.ADDRESS, [control, val]); - this.wire.writeByte(control, function(err) { - this.wire.writeByte(val, function(err) { - fn(); - }); - }); -} + this.wire.writeBytes(control, [val], function () {}); +}; // read a byte from the oled Oled.prototype._readI2C = function(fn) { this.wire.readByte(function(err, data) { - // result is single byte fn(data); }); -} +}; // sometimes the oled gets a bit busy with lots of bytes. // Read the response byte to see if this is the case @@ -146,29 +148,29 @@ Oled.prototype._waitUntilReady = function(callback) { // if not busy, it's ready for callback callback(); } else { - console.log('I\'m busy!'); setTimeout(tick, 0); } }); - }; + } setTimeout(tick(callback), 0); -} +}; // set starting position of a text string on the oled Oled.prototype.setCursor = function(x, y) { this.cursor_x = x; this.cursor_y = y; -} +}; // write text to the oled -Oled.prototype.writeString = function(font, size, string, color, wrap, sync) { +Oled.prototype.writeString = function(font, size, string, color, wrap, linespacing, sync) { var immed = (typeof sync === 'undefined') ? true : sync; var wordArr = string.split(' '), len = wordArr.length, // start x offset at cursor pos offset = this.cursor_x, - padding = 0, letspace = 1, leading = 2; + padding = 0, letspace = 1; + var leading = linespacing || 2; // loop through words for (var w = 0; w < len; w += 1) { @@ -192,7 +194,7 @@ Oled.prototype.writeString = function(font, size, string, color, wrap, sync) { // read the bits in the bytes that make up the char var charBytes = this._readCharBytes(charBuf); // draw the entire character - this._drawChar(charBytes, size, false); + this._drawChar(font, charBytes, size, false); // calc new x position for the next char, add a touch of padding too if it's a non space char padding = (stringArr[i] === ' ') ? 0 : size + letspace; @@ -210,24 +212,27 @@ Oled.prototype.writeString = function(font, size, string, color, wrap, sync) { if (immed) { this._updateDirtyBytes(this.dirtyBytes); } -} +}; // draw an individual character to the screen -Oled.prototype._drawChar = function(byteArray, size, sync) { +Oled.prototype._drawChar = function(font, byteArray, size, sync) { // take your positions... var x = this.cursor_x, y = this.cursor_y; + var pagePos = 0; + var c = 0; // loop through the byte array containing the hexes for the char for (var i = 0; i < byteArray.length; i += 1) { + pagePos = Math.floor(i / font.width) * 8; for (var j = 0; j < 8; j += 1) { // pull color out var color = byteArray[i][j], xpos, ypos; // standard font size if (size === 1) { - xpos = x + i; - ypos = y + j; + xpos = x + c; + ypos = y + j + pagePos; this.drawPixel([xpos, ypos, color], false); } else { // MATH! Calculating pixel size multiplier to primitively scale the font @@ -236,8 +241,9 @@ Oled.prototype._drawChar = function(byteArray, size, sync) { this.fillRect(xpos, ypos, size, size, color, false); } } + c = (c < font.width -1) ? c += 1 : 0; } -} +}; // get character bytes from the supplied font object in order to send to framebuffer Oled.prototype._readCharBytes = function(byteArray) { @@ -259,7 +265,7 @@ Oled.prototype._readCharBytes = function(byteArray) { bitArr = []; } return bitCharArr; -} +}; // find where the character exists within the font object Oled.prototype._findCharBuf = function(font, c) { @@ -268,7 +274,7 @@ Oled.prototype._findCharBuf = function(font, c) { // slice just the current char's bytes out of the fontData array and return var cBuf = font.fontData.slice(cBufPos, cBufPos + font.width); return cBuf; -} +}; // send the entire framebuffer to the oled Oled.prototype.update = function() { @@ -297,7 +303,10 @@ Oled.prototype.update = function() { } }.bind(this)); -} + + // now that all bytes are synced, reset dirty state + this.dirtyBytes = []; +}; // send dim display command to oled Oled.prototype.dimDisplay = function(bool) { @@ -311,17 +320,17 @@ Oled.prototype.dimDisplay = function(bool) { this._transfer('cmd', this.SET_CONTRAST); this._transfer('cmd', contrast); -} +}; // turn oled off Oled.prototype.turnOffDisplay = function() { this._transfer('cmd', this.DISPLAY_OFF); -} +}; // turn oled on Oled.prototype.turnOnDisplay = function() { this._transfer('cmd', this.DISPLAY_ON); -} +}; // clear all pixels currently on the display Oled.prototype.clearDisplay = function(sync) { @@ -339,7 +348,7 @@ Oled.prototype.clearDisplay = function(sync) { if (immed) { this._updateDirtyBytes(this.dirtyBytes); } -} +}; // invert pixels on oled Oled.prototype.invertDisplay = function(bool) { @@ -348,7 +357,7 @@ Oled.prototype.invertDisplay = function(bool) { } else { this._transfer('cmd', this.NORMAL_DISPLAY); // non inverted } -} +}; // draw an image pixel array on the screen Oled.prototype.drawBitmap = function(pixels, sync) { @@ -366,7 +375,7 @@ Oled.prototype.drawBitmap = function(pixels, sync) { if (immed) { this._updateDirtyBytes(this.dirtyBytes); } -} +}; // draw one or many pixels on oled Oled.prototype.drawPixel = function(pixels, sync) { @@ -408,50 +417,56 @@ Oled.prototype.drawPixel = function(pixels, sync) { if (immed) { this._updateDirtyBytes(this.dirtyBytes); } -} +}; // looks at dirty bytes, and sends the updated bytes to the display Oled.prototype._updateDirtyBytes = function(byteArray) { var blen = byteArray.length, i, displaySeq = []; - // check to see if this will even save time - if (blen > (this.buffer.length / 7)) { - // just call regular update at this stage, saves on bytes sent - this.update(); - // now that all bytes are synced, reset dirty state - this.dirtyBytes = []; + this._waitUntilReady(function() { + var pageStart = Infinity, pageEnd = 0; + var colStart = Infinity, colEnd = 0, any = false; + + // iterate through dirty bytes + for (var i = 0; i < blen; i += 1) { + var b = byteArray[i]; + if ((b >= 0) && (b < this.buffer.length)) { + var page = b / this.WIDTH | 0; + if (page < pageStart) pageStart = page; + if (page > pageEnd) pageEnd = page; + var col = b % this.WIDTH; + if (col < colStart) colStart = col; + if (col > colEnd) colEnd = col; + any = true; + } + } - } else { + if (!any) return; - this._waitUntilReady(function() { - // iterate through dirty bytes - for (var i = 0; i < blen; i += 1) { + displaySeq = [ + this.COLUMN_ADDR, colStart, colEnd, // column start and end address + this.PAGE_ADDR, pageStart, pageEnd // page start and end address + ]; - var byte = byteArray[i]; - var page = Math.floor(byte / this.WIDTH); - var col = Math.floor(byte % this.WIDTH); + var displaySeqLen = displaySeq.length, v, vp, vc; - var displaySeq = [ - this.COLUMN_ADDR, col, col, // column start and end address - this.PAGE_ADDR, page, page // page start and end address - ]; + // send intro seq + for (v = 0; v < displaySeqLen; v += 1) { + this._transfer('cmd', displaySeq[v]); + } + // send byte, then move on to next byte + for (vp = pageStart; vp <= pageEnd; vp += 1) { + for (vc = colStart; vc <= colEnd; vc += 1) { + this._transfer('data', this.buffer[this.WIDTH * vp + vc]); + } + } - var displaySeqLen = displaySeq.length, v; + }.bind(this)); - // send intro seq - for (v = 0; v < displaySeqLen; v += 1) { - this._transfer('cmd', displaySeq[v]); - } - // send byte, then move on to next byte - this._transfer('data', this.buffer[byte]); - this.buffer[byte]; - } - }.bind(this)); - } // now that all bytes are synced, reset dirty state this.dirtyBytes = []; -} +}; // using Bresenham's line algorithm Oled.prototype.drawLine = function(x0, y0, x1, y1, color, sync) { @@ -477,6 +492,26 @@ Oled.prototype.drawLine = function(x0, y0, x1, y1, color, sync) { } } +// Draw an outlined rectangle +Oled.prototype.drawRect = function(x, y, w, h, color, sync){ + var immed = (typeof sync === 'undefined') ? true : sync; + //top + this.drawLine(x, y, x + w, y,color,false); + + //left + this.drawLine(x, y + 1, x, y + h - 1, color, false); + + //right + this.drawLine(x + w, y + 1, x + w, y + h - 1, color, false); + + //bottom + this.drawLine(x, y + h - 1, x + w, y + h - 1, color, false); + + if (immed) { + this._updateDirtyBytes(this.dirtyBytes); + } +}; + // draw a filled rectangle on the oled Oled.prototype.fillRect = function(x, y, w, h, color, sync) { var immed = (typeof sync === 'undefined') ? true : sync; @@ -488,7 +523,59 @@ Oled.prototype.fillRect = function(x, y, w, h, color, sync) { if (immed) { this._updateDirtyBytes(this.dirtyBytes); } -} +}; + +/** + * Draw a circle outline + * + * This method is ad verbatim translation from the corresponding + * method on the Adafruit GFX library + * https://github.com/adafruit/Adafruit-GFX-Library + */ +Oled.prototype.drawCircle = function(x0, y0, r, color, sync) { + var immed = (typeof sync === 'undefined') ? true : sync; + + var f = 1 - r; + var ddF_x = 1; + var ddF_y = -2 * r; + var x = 0; + var y = r; + + this.drawPixel( + [[x0, y0 + r, color], + [x0, y0 - r, color], + [x0 + r, y0, color], + [x0 - r, y0, color]], + false + ); + + while(x < y) { + if (f >=0) { + y--; + ddF_y += 2; + f += ddF_y; + } + x++; + ddF_x += 2; + f += ddF_x; + + this.drawPixel( + [[x0 + x, y0 + y, color], + [x0 - x, y0 + y, color], + [x0 + x, y0 - y, color], + [x0 - x, y0 - y, color], + [x0 + y, y0 + x, color], + [x0 - y, y0 + x, color], + [x0 + y, y0 - x, color], + [x0 - y, y0 - x, color]], + false + ); + } + + if (immed) { + this._updateDirtyBytes(this.dirtyBytes); + } +}; // activate scrolling for rows start through stop Oled.prototype.startScroll = function(dir, start, stop) { @@ -500,32 +587,45 @@ Oled.prototype.startScroll = function(dir, start, stop) { cmdSeq.push(this.RIGHT_HORIZONTAL_SCROLL); break; case 'left': cmdSeq.push(this.LEFT_HORIZONTAL_SCROLL); break; - // TODO: left diag and right diag not working yet case 'left diagonal': cmdSeq.push( - this.SET_VERTICAL_SCROLL_AREA, 0x00, + this.SET_VERTICAL_SCROLL_AREA, + 0x00, + this.HEIGHT, this.VERTICAL_AND_LEFT_HORIZONTAL_SCROLL, - this.HEIGHT + 0x00, + start, + 0x00, + stop, + 0x01, + this.ACTIVATE_SCROLL ); break; - // TODO: left diag and right diag not working yet case 'right diagonal': cmdSeq.push( - this.SET_VERTICAL_SCROLL_AREA, 0x00, + this.SET_VERTICAL_SCROLL_AREA, + 0x00, + this.HEIGHT, this.VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL, - this.HEIGHT + 0x00, + start, + 0x00, + stop, + 0x01, + this.ACTIVATE_SCROLL ); break; } this._waitUntilReady(function() { - cmdSeq.push( - 0x00, start, - 0x00, stop, - // TODO: these need to change when diagonal - 0x00, 0xFF, - this.ACTIVATE_SCROLL - ); + if(dir === 'right' || dir === 'left'){ + cmdSeq.push( + 0x00, start, + 0x00, stop, + 0x00, 0xFF, + this.ACTIVATE_SCROLL + ); + } var i, cmdSeqLen = cmdSeq.length; @@ -533,11 +633,11 @@ Oled.prototype.startScroll = function(dir, start, stop) { this._transfer('cmd', cmdSeq[i]); } }.bind(this)); -} +}; // stop scrolling display contents Oled.prototype.stopScroll = function() { this._transfer('cmd', this.DEACTIVATE_SCROLL); // stahp -} +}; module.exports = Oled; diff --git a/package.json b/package.json index 6b43e40..de1df9d 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,19 @@ { - "name": "oled-js-pi", - "version": "1.0.5", + "name": "oled-ssd1306-i2c", + "version": "1.0.6", "description": "NodeJS module for controlling oled devices on the Raspbery Pi (including the SSD1306 OLED screens)", "main": "oled.js", - "dependencies": {"i2c": "~0.2.1"}, + "dependencies": { + "i2c": "0.2.3", + "oled-font-5x7": "1.0.0", + "png-to-lcd": "1.0.3", + "pngparse": "2.0.1" + }, "devDependencies": { "oled-font-5x7": "~1.0.0", "png-to-lcd": "~1.0.2", "pngparse": "~2.0.1", + "q": "1.4.1", "temporal": "^0.3.8" }, "scripts": { @@ -15,7 +21,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/kd7yva/oled-js-pi.git" + "url": "https://github.com/perjg/oled_ssd1306_i2c.git" }, "keywords": [ "Raspbery Pi", @@ -24,10 +30,14 @@ "oled", "SSD1306" ], - "author": ["Judd Flamm", "Suz Hinton"], + "author": [ + "Judd Flamm", + "Suz Hinton", + "Per Johan Groland" + ], "license": "MIT", "bugs": { - "url": "https://github.com/kd7yva/oled-js-pi/issues" + "url": "https://github.com/perjg/oled_ssd1306_i2c/issues" }, "homepage": "https://github.com/kd7yva/oled-js-pi" } diff --git a/tests/buffers/adafruitLogoBuf.js b/tests/buffers/adafruitLogoBuf.js new file mode 100644 index 0000000..d29e174 --- /dev/null +++ b/tests/buffers/adafruitLogoBuf.js @@ -0,0 +1,37 @@ +// example picture using just pixels, in the framebuffer size allowed (512) +var adafruitLogo = [ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, +0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x80, 0x80, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xF8, 0xE0, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, +0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xFF, +0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, +0x80, 0xFF, 0xFF, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x80, +0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x8C, 0x8E, 0x84, 0x00, 0x00, 0x80, 0xF8, +0xF8, 0xF8, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xE0, 0xE0, 0xC0, 0x80, +0x00, 0xE0, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xC7, 0x01, 0x01, +0x01, 0x01, 0x83, 0xFF, 0xFF, 0x00, 0x00, 0x7C, 0xFE, 0xC7, 0x01, 0x01, 0x01, 0x01, 0x83, 0xFF, +0xFF, 0xFF, 0x00, 0x38, 0xFE, 0xC7, 0x83, 0x01, 0x01, 0x01, 0x83, 0xC7, 0xFF, 0xFF, 0x00, 0x00, +0x01, 0xFF, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0xFF, 0x07, 0x01, 0x01, 0x01, 0x00, 0x00, 0x7F, 0xFF, +0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, +0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x03, 0x0F, 0x3F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC7, 0xC7, 0x8F, +0x8F, 0x9F, 0xBF, 0xFF, 0xFF, 0xC3, 0xC0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xFC, +0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, 0xF8, 0xF0, 0xF0, 0xE0, 0xC0, 0x00, 0x01, 0x03, 0x03, 0x03, +0x03, 0x03, 0x01, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, +0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x03, 0x03, 0x00, 0x00, +0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, +0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x01, 0x00, 0x00, 0x00, 0x03, +0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +]; + +module.exports = adafruitLogo; \ No newline at end of file diff --git a/tests/demoTime.js b/tests/demoTime.js new file mode 100644 index 0000000..da4031d --- /dev/null +++ b/tests/demoTime.js @@ -0,0 +1,139 @@ +var pngtolcd = require('png-to-lcd'), + Oled = require('../oled'), + font = require('oled-font-5x7'), + temporal = require('temporal'); + +var oled = new Oled({ + width: 128, + height: 64, +}); + +test(oled); + +// sequence of test displays +function test(oled) { + + // if it was already scrolling, stop + oled.stopScroll(); + + // clear first just in case + oled.update(); + + // make it prettier + oled.dimDisplay(true); + + temporal.queue([ + { + delay: 100, + task: function() { + // draw some test pixels + oled.drawPixel([ + [127, 0, 1], + [127, 31, 1], + [127, 16, 1], + [64, 16, 1] + ]); + } + }, + { + delay: 10000, + task: function() { + oled.clearDisplay(); + // display a bitmap + pngtolcd(__dirname + '/images/cat-128x64.png', true, function(err, bitmapbuf) { + oled.buffer = bitmapbuf; + oled.update(); + }); + + } + }, + { + delay: 10000, + task: function() { + oled.clearDisplay(); + // display text + oled.setCursor(0, 0); + oled.writeString(font, 1, 'Cats and dogs are really cool animals, you know.', 1, true, 2); + } + }, + { + delay: 10000, + task: function() { + oled.clearDisplay(); + // draw some lines + oled.drawLine(0, 0, 127, 31, 1); + oled.drawLine(64, 16, 127, 16, 1); + oled.drawLine(0, 10, 40, 10, 1); + } + }, + { + delay: 10000, + task: function() { + oled.clearDisplay(); + // draw a rectangle + oled.fillRect(0, 0, 10, 20, 1); + } + }, + { + delay: 10000, + task: function() { + // create concenctric rectangle outlines + oled.clearDisplay(); + + //calc how many squares we can fit on the screen + var padding = 2; + var square_count = ((oled.WIDTH / 2 ) / (padding * 2) ) - 1; + + for(var i = 0; i < square_count; i ++){ + var x = ((i + 1) * padding); + var y = ((i + 1) * padding); + var w = oled.WIDTH - (x * padding); + var h = oled.HEIGHT - (y * padding); + oled.drawRect(x, y, w, h, 1, false); + } + oled.update(); + } + }, + { + delay: 10000, + task: function() { + // create concenctric circle outlines + oled.clearDisplay(); + + var x = oled.WIDTH / 2; + var y = oled.HEIGHT / 2; + var radius = oled.HEIGHT - 1 + + //calc how many circles we can fit on the screen + var circle_count = radius / 3; + + for(var i = 0; i < circle_count; i++){ + var r = radius - (i * 3); + oled.drawCircle(x, y, r, 1, false); + } + oled.update(); + } + }, + { + delay: 10000, + task: function() { + oled.clearDisplay(); + // display text + oled.setCursor(0, 7); + oled.writeString(font, 2, 'SCROLL!', 1, true, 1); + oled.startScroll('left', 0, 6); + } + }, + { + delay: 10000, + task: function() { + oled.stopScroll(); + oled.clearDisplay(); + oled.update(); + oled.setCursor(0, 7); + oled.writeString(font, 2, 'DIAGONAL SCROLL', 1, true, 1); + oled.startScroll('left diagonal', 0, 15); + } + } + ]); +} diff --git a/tests/images/cat-128x64.png b/tests/images/cat-128x64.png new file mode 100644 index 0000000..dfb5239 Binary files /dev/null and b/tests/images/cat-128x64.png differ diff --git a/tests/images/cat-microview.png b/tests/images/cat-microview.png new file mode 100644 index 0000000..79175e7 Binary files /dev/null and b/tests/images/cat-microview.png differ diff --git a/tests/images/cat.png b/tests/images/cat.png new file mode 100644 index 0000000..53fa8b7 Binary files /dev/null and b/tests/images/cat.png differ diff --git a/tests/images/noopkat-mono.png b/tests/images/noopkat-mono.png new file mode 100644 index 0000000..30ef354 Binary files /dev/null and b/tests/images/noopkat-mono.png differ diff --git a/tests/images/noopkat.png b/tests/images/noopkat.png new file mode 100644 index 0000000..b73a1c4 Binary files /dev/null and b/tests/images/noopkat.png differ diff --git a/tests/images/parrot-tiny.png b/tests/images/parrot-tiny.png new file mode 100644 index 0000000..d277400 Binary files /dev/null and b/tests/images/parrot-tiny.png differ