├── index.js ├── Dockerfile ├── example ├── index.js └── fade.js ├── dist ├── example │ ├── index.js │ └── fade.js └── Blinkt.js ├── .eslintrc.json ├── .babelrc ├── .gitattributes ├── LICENSE ├── package.json ├── Makefile ├── .gitignore ├── readme.md └── src └── Blinkt.js /index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./dist/Blinkt.js'); -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM hypriot/rpi-node 2 | COPY . . 3 | RUN npm install 4 | CMD [ "node", "example" ] -------------------------------------------------------------------------------- /example/index.js: -------------------------------------------------------------------------------- 1 | const Blinkt = require('../Blinkt'); 2 | const leds = new Blinkt(); 3 | 4 | leds.setup(); 5 | leds.clearAll(); 6 | leds.setAllPixels(0, 156, 0, 0.1); 7 | leds.sendUpdate(); 8 | -------------------------------------------------------------------------------- /dist/example/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var Blinkt = require('../Blinkt'); 4 | 5 | var leds = new Blinkt(); 6 | leds.setup(); 7 | leds.clearAll(); 8 | leds.setAllPixels(0, 156, 0, 0.1); 9 | leds.sendUpdate(); -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["eslint-config-irrelon"], 3 | "plugins": [ 4 | 5 | ], 6 | "env" : { 7 | "browser" : true, 8 | "node" : true, 9 | "es6" : true, 10 | "mocha": true 11 | } 12 | } -------------------------------------------------------------------------------- /example/fade.js: -------------------------------------------------------------------------------- 1 | const Blinkt = require('../Blinkt'); 2 | const leds = new Blinkt(); 3 | 4 | let r=0, 5 | g=0, 6 | b=0; 7 | 8 | leds.setup(); 9 | 10 | setInterval(function() { 11 | leds.clearAll(); 12 | leds.setAllPixels((++r)%255, (++g)%255, (++b)%255, 0.1); 13 | leds.sendUpdate(); 14 | } , 10); 15 | 16 | -------------------------------------------------------------------------------- /dist/example/fade.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var Blinkt = require('../Blinkt'); 4 | 5 | var leds = new Blinkt(); 6 | var r = 0, 7 | g = 0, 8 | b = 0; 9 | leds.setup(); 10 | setInterval(function () { 11 | leds.clearAll(); 12 | leds.setAllPixels(++r % 255, ++g % 255, ++b % 255, 0.1); 13 | leds.sendUpdate(); 14 | }, 10); -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "modules": "commonjs" 7 | } 8 | ], 9 | "@babel/preset-react" 10 | ], 11 | "plugins": [ 12 | "@babel/plugin-transform-runtime", 13 | "@babel/plugin-proposal-class-properties", 14 | "@babel/plugin-proposal-object-rest-spread" 15 | ], 16 | "ignore": [ 17 | "node_modules" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2019 Irrelon Software Limited 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. 4 | 5 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-blinkt", 3 | "author": "Rob Evans - Irrelon Software Limited", 4 | "description": "A Node.js Library to Interact With the Raspberry Pi Blinkt! LED Hat.", 5 | "version": "1.2.1", 6 | "main": "./dist/Blinkt", 7 | "scripts": { 8 | "test": "node example", 9 | "build": "rimraf dist && babel ./src/*.js --out-dir dist && babel ./example/*.js --out-dir dist/example", 10 | "eslint": "eslint ./src/**.js ./tests/**.js", 11 | "eslint-fix": "eslint --fix ./src/**.js" 12 | }, 13 | "keywords": [ 14 | "node", 15 | "blinkt", 16 | "irrelon" 17 | ], 18 | "private": false, 19 | "dependencies": { 20 | "@babel/runtime": "^7.8.7", 21 | "node-wiring-pi": "0.0.5" 22 | }, 23 | "engines": { 24 | "node": "*" 25 | }, 26 | "repository": { 27 | "type": "git", 28 | "url": "git://github.com/irrelon/node-blinkt.git" 29 | }, 30 | "bugs": { 31 | "url": "http://github.com/irrelon/node-blinkt/issues" 32 | }, 33 | "devDependencies": { 34 | "@babel/cli": "^7.8.4", 35 | "@babel/core": "^7.8.7", 36 | "@babel/plugin-proposal-class-properties": "^7.8.3", 37 | "@babel/plugin-proposal-object-rest-spread": "^7.8.3", 38 | "@babel/plugin-transform-runtime": "^7.8.3", 39 | "@babel/preset-env": "^7.8.7", 40 | "@babel/preset-react": "^7.8.3", 41 | "@babel/register": "^7.8.6", 42 | "babel-eslint": "^10.1.0", 43 | "eslint": "^6.8.0", 44 | "eslint-config-irrelon": "^1.0.10", 45 | "rimraf": "^2.7.1" 46 | }, 47 | "license": "ISC" 48 | } 49 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | #!/bin/make -f 2 | # -*- makefile -*- 3 | 4 | default: help start 5 | @echo "# $@: $^" 6 | 7 | main_src ?= dist/example/fade.js 8 | runtime ?= iotjs 9 | project?=node-blinkt 10 | 11 | iotjs_modules_dir ?= iotjs_modules 12 | iotjs_wiringpi_dir ?= ${iotjs_modules_dir}/iotjs-wiringpi 13 | iotjs_wiringpi_url ?= https://github.com/SamsungInternet/wiringpi-iotjs 14 | iotjs_wiringpi_revision ?= v0.0.1 15 | 16 | deploy_dir ?= ${CURDIR}/tmp/deploy 17 | deploy_modules_dir ?= ${deploy_dir}/iotjs_modules 18 | deploy_module_dir ?= ${deploy_modules_dir}/${project} 19 | deploy_srcs += ${deploy_module_dir}/dist/*.js 20 | deploy_srcs += ${deploy_module_dir}/dist/*/*.js 21 | deploy_srcs += ${deploy_module_dir}/index.js 22 | 23 | help: 24 | @echo "Usage:" 25 | @echo "# make start" 26 | 27 | cleanall: 28 | rm -rf iotjs_modules node_modules 29 | 30 | run/node: ${main_src} node_modules 31 | npm test 32 | 33 | run/iotjs: ${main_src} ${iotjs_modules_dir} 34 | -which iotjs 35 | -iotjs -h 36 | iotjs $< 37 | 38 | run: run/node run/iotjs 39 | 40 | ${iotjs_modules_dir}/wiringpi-node: 41 | mkdir -p $@ 42 | git clone --depth 1 --recursive -b ${iotjs_wiringpi_revision} ${iotjs_wiringpi_url} $@ 43 | 44 | ${iotjs_modules_dir}: ${iotjs_modules_dir}/wiringpi-node 45 | du -ks $@ 46 | 47 | node_modules: package.json 48 | npm install --only=dev 49 | 50 | ${main_src}: package.json node_modules 51 | npm run build 52 | ls $@ 53 | 54 | start: run/${runtime} 55 | 56 | ${deploy_module_dir}/%: % 57 | @echo "# TODO: minify: $<" 58 | install -d ${@D} 59 | install $< $@ 60 | 61 | deploy: ${deploy_srcs} 62 | ls $< 63 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Node template 3 | # Logs 4 | logs 5 | *.log 6 | npm-debug.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | 13 | # Directory for instrumented libs generated by jscoverage/JSCover 14 | lib-cov 15 | 16 | # Coverage directory used by tools like istanbul 17 | coverage 18 | 19 | # nyc test coverage 20 | .nyc_output 21 | 22 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 23 | .grunt 24 | 25 | # node-waf configuration 26 | .lock-wscript 27 | 28 | # Compiled binary addons (http://nodejs.org/api/addons.html) 29 | build/Release 30 | 31 | # Dependency directories 32 | node_modules 33 | jspm_packages 34 | 35 | # Optional npm cache directory 36 | .npm 37 | 38 | # Optional REPL history 39 | .node_repl_history 40 | ### JetBrains template 41 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 42 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 43 | 44 | # User-specific stuff: 45 | .idea/workspace.xml 46 | .idea/tasks.xml 47 | .idea/dictionaries 48 | .idea/vcs.xml 49 | .idea/jsLibraryMappings.xml 50 | 51 | # Sensitive or high-churn files: 52 | .idea/dataSources.ids 53 | .idea/dataSources.xml 54 | .idea/dataSources.local.xml 55 | .idea/sqlDataSources.xml 56 | .idea/dynamic.xml 57 | .idea/uiDesigner.xml 58 | 59 | # Gradle: 60 | .idea/gradle.xml 61 | .idea/libraries 62 | 63 | # Mongo Explorer plugin: 64 | .idea/mongoSettings.xml 65 | 66 | ## File-based project format: 67 | *.iws 68 | 69 | ## Plugin-specific files: 70 | 71 | # IntelliJ 72 | /out/ 73 | 74 | # mpeltonen/sbt-idea plugin 75 | .idea_modules/ 76 | 77 | # JIRA plugin 78 | atlassian-ide-plugin.xml 79 | 80 | # Crashlytics plugin (for Android Studio and IntelliJ) 81 | com_crashlytics_export_strings.xml 82 | crashlytics.properties 83 | crashlytics-build.properties 84 | fabric.properties 85 | 86 | .idea -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # node-blinkt 2 | A Node.js Library to Interact with [Blinkt](https://shop.pimoroni.com/products/blinkt) 3 | 4 | # Install 5 | 6 | ```bash 7 | npm install node-blinkt 8 | ``` 9 | 10 | # Usage 11 | 12 | ```js 13 | var Blinkt = require('node-blinkt'), 14 | leds = new Blinkt(); 15 | 16 | leds.setup(); 17 | leds.clearAll(); 18 | leds.setAllPixels(0, 156, 0, 0.1); 19 | leds.sendUpdate(); 20 | ``` 21 | 22 | # Methods 23 | 24 | ## setup() 25 | Connects to the GPIO and sets the GPIO pin modes. Must be called before any other commands. 26 | 27 | ## setup(dat, clk) 28 | Connects to an alternative set of GPIO pins and sets their modes. Can be called instead of the setup() function if you have wired blinkt up to alternative raspberry pi pins. The default values are 23 and 24 respectively. 29 | 30 | ## clearAll() 31 | Clears the pixel buffer. This is the same as setting all pixels to black. You must also call sendUpdate() if you want to turn Blinkt! off. 32 | 33 | ## setPixel(pixelNum, red, green, blue, brightness) 34 | Sets the specififed pixel to the passed rgb and brightness level. The pixelNum is 35 | an integer between 0 and 7 to indicate the pixel to change. 36 | 37 | ## setBrightness(pixelNum, brightness) 38 | Sets the brightness level between 0.0 (off) and 1.0 (full brightness) for the specified pixelNum. 39 | The pixelNum is an integer between 0 and 7 to indicate the pixel to change. 40 | 41 | ## setAllPixels(red, green, blue, brightness) 42 | Sets all pixels to the passed rgb and brightness level. 43 | 44 | ## sendUpdate() 45 | This method is the most important. You can set pixels colours as much as you want but they 46 | will not update until you call this method. 47 | 48 | # Using alternative IoT.js runtime 49 | 50 | IoT.js is an alternate JavaScript runtime powered by JerryScript engine 51 | targeting more constrained devices. 52 | 53 | 54 | First you need to install iotjs from source or precompiled package: 55 | 56 | * https://iotjs.net 57 | * https://github.com/rzr/webthing-iotjs/wiki/IotJs 58 | * https://libraries.io/npm/wiringpi-iotjs 59 | 60 | Usage: 61 | 62 | ```sh 63 | git clone --depth 1 https://github.com/Irrelon/node-blinkt ; cd node-blinkt 64 | make start 65 | ``` 66 | 67 | [![iotjs-wiringpi](https://pbs.twimg.com/ext_tw_video_thumb/1019945702791766017/pu/img/bbbNf-HJR2FkUb5l.jpg)](https://twitter.com/TizenHelper/status/1019945989388546048# "blinkt-node") 68 | 69 | # Development 70 | Only modify files in the ./src folder. The ./dist folder is generated from the ./src folder via babel to produce an ES5 version. 71 | 72 | You can modify the ./src/Blinkt.js file but please ensure you correctly document the functions you make using JSDoc. Run "npm run eslint" to check your code for errors before committing and fix all issues. You can also run "npm run eslint-fix" to auto-fix most common issues before fixing manual ones. 73 | 74 | Once you are ready to commit an update, run "npm run build" which will generate a new ES5 build. Make sure you update the package.json version as well. 75 | 76 | Thanks! 77 | 78 | # Copyright and License 79 | All works are copyright Irrelon Software Limited. You may use this project under any license that you wish e.g. (MIT, GPL etc). You may use this software, source code, project, part of or in entirety for any reason under any license you wish, or no license at all. The software is given away freely and may be used for non-commercial and commercial, educational, governmental or any other purpose free of charge and free of license. Just go use it! 80 | -------------------------------------------------------------------------------- /dist/Blinkt.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); 4 | 5 | var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); 6 | 7 | var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); 8 | 9 | var wpi = require("node-wiring-pi"), 10 | DAT = 23, 11 | CLK = 24; 12 | 13 | var Blinkt = function Blinkt() { 14 | var _this = this; 15 | 16 | (0, _classCallCheck2["default"])(this, Blinkt); 17 | (0, _defineProperty2["default"])(this, "brightnessMask", 0x1F); 18 | (0, _defineProperty2["default"])(this, "significantBitsMask", 0xE0); 19 | (0, _defineProperty2["default"])(this, "setup", function (dat, clk) { 20 | // Set WPI to GPIO mode 21 | wpi.setup("gpio"); 22 | 23 | if (Boolean(dat) && isNaN(dat)) { 24 | //if dat has value and is not a number 25 | throw new Error("The dat value must be a pin number"); 26 | } 27 | 28 | if (Boolean(clk) && isNaN(clk)) { 29 | //if clk has value and is not a number 30 | throw new Error("The clk value must be a pin number"); 31 | } 32 | 33 | _this._dat = dat || DAT; 34 | _this._clk = clk || CLK; // Set pin mode to output 35 | 36 | wpi.pinMode(_this._dat, wpi.OUTPUT); 37 | wpi.pinMode(_this._clk, wpi.OUTPUT); 38 | _this._numPixels = 8; 39 | _this._pixels = []; // Init pixels 40 | 41 | for (var i = 0; i < _this._numPixels; i++) { 42 | _this.setPixel(i, 255, 255, 255, 1.0); 43 | } 44 | }); 45 | (0, _defineProperty2["default"])(this, "setAllPixels", function (r, g, b, a) { 46 | for (var i = 0; i < _this._numPixels; i++) { 47 | _this.setPixel(i, r, g, b, a); 48 | } 49 | }); 50 | (0, _defineProperty2["default"])(this, "setPixel", function (pixelNum, r, g, b, a) { 51 | if (a === undefined) { 52 | if (_this._pixels[pixelNum]) { 53 | // Set a to current level or 1.0 if none exists 54 | a = _this._pixels[pixelNum][3] !== undefined ? _this._pixels[pixelNum][3] : 1.0; 55 | } 56 | } else { 57 | a = Math.floor(31.0 * a) & _this.brightnessMask; // jshint ignore:line 58 | } 59 | 60 | _this._pixels[pixelNum] = [Math.floor(r) & 255, // jshint ignore:line 61 | Math.floor(g) & 255, // jshint ignore:line 62 | Math.floor(b) & 255, // jshint ignore:line 63 | a]; 64 | }); 65 | (0, _defineProperty2["default"])(this, "setBrightness", function (pixelNum, brightness) { 66 | _this._pixels[pixelNum][3] = Math.floor(31.0 * brightness) & _this.brightnessMask; // jshint ignore:line 67 | }); 68 | (0, _defineProperty2["default"])(this, "clearAll", function () { 69 | for (var i = 0; i < _this._numPixels; i++) { 70 | _this.clear(i); 71 | } 72 | }); 73 | (0, _defineProperty2["default"])(this, "clear", function (led) { 74 | _this.setPixel(led, 0, 0, 0); 75 | }); 76 | (0, _defineProperty2["default"])(this, "sendUpdate", function () { 77 | var i, pixel; 78 | 79 | for (i = 0; i < 4; i++) { 80 | _this._writeByte(0); 81 | } 82 | 83 | for (i = 0; i < _this._numPixels; i++) { 84 | pixel = _this._pixels[i]; // Brightness 85 | 86 | _this._writeByte(_this.significantBitsMask | pixel[3]); // jshint ignore:line 87 | // Blue 88 | 89 | 90 | _this._writeByte(pixel[2]); // Green 91 | 92 | 93 | _this._writeByte(pixel[1]); // Red 94 | 95 | 96 | _this._writeByte(pixel[0]); 97 | } 98 | 99 | _this._writeByte(0xff); 100 | 101 | _this._latch(); 102 | }); 103 | (0, _defineProperty2["default"])(this, "_writeByte", function (_byte) { 104 | var bit; 105 | 106 | for (var i = 0; i < _this._numPixels; i++) { 107 | bit = (_byte & 1 << 7 - i) > 0 ? wpi.HIGH : wpi.LOW; // jshint ignore:line 108 | 109 | wpi.digitalWrite(_this._dat, bit); 110 | wpi.digitalWrite(_this._clk, 1); 111 | wpi.digitalWrite(_this._clk, 0); 112 | } 113 | }); 114 | (0, _defineProperty2["default"])(this, "_latch", function () { 115 | wpi.digitalWrite(_this._dat, 0); 116 | 117 | for (var i = 0; i < 36; i++) { 118 | wpi.digitalWrite(_this._clk, 1); 119 | wpi.digitalWrite(_this._clk, 0); 120 | } 121 | }); 122 | }; 123 | 124 | module.exports = Blinkt; -------------------------------------------------------------------------------- /src/Blinkt.js: -------------------------------------------------------------------------------- 1 | const wpi = require("node-wiring-pi"), 2 | DAT = 23, 3 | CLK = 24; 4 | 5 | class Blinkt { 6 | brightnessMask = 0x1F; // 0b11111 7 | significantBitsMask = 0xE0; //0b11100000 8 | 9 | /** 10 | * Connects to the GPIO and sets the GPIO pin modes. Must be called 11 | * before any other commands. All pixels will start off white at 12 | * full brightness by default. 13 | * @param {Number} dat The data pin number. 14 | * @param {Number} clk The clock pin number. 15 | * @returns {undefined} Nothing. 16 | */ 17 | setup = (dat, clk) => { 18 | // Set WPI to GPIO mode 19 | wpi.setup("gpio"); 20 | 21 | if(Boolean(dat) && isNaN(dat)){ 22 | //if dat has value and is not a number 23 | throw new Error("The dat value must be a pin number"); 24 | } 25 | 26 | if(Boolean(clk) && isNaN(clk)){ 27 | //if clk has value and is not a number 28 | throw new Error("The clk value must be a pin number"); 29 | } 30 | 31 | this._dat = dat || DAT; 32 | this._clk = clk || CLK; 33 | 34 | // Set pin mode to output 35 | wpi.pinMode(this._dat, wpi.OUTPUT); 36 | wpi.pinMode(this._clk, wpi.OUTPUT); 37 | 38 | this._numPixels = 8; 39 | this._pixels = []; 40 | 41 | // Init pixels 42 | for (let i = 0; i < this._numPixels; i++) { 43 | this.setPixel(i, 255, 255, 255, 1.0); 44 | } 45 | }; 46 | 47 | /** 48 | * Sets all pixels to the passed RGB and brightness values. 49 | * @param {Number} r The pixel red value between 0 and 255. 50 | * @param {Number} g The pixel green value between 0 and 255. 51 | * @param {Number} b The pixel blue value between 0 and 255. 52 | * @param {Number} a The pixel brightness value between 0.0 and 1.0. 53 | * @returns {undefined} Nothing. 54 | */ 55 | setAllPixels = (r, g, b, a) => { 56 | for (let i = 0; i < this._numPixels; i++) { 57 | this.setPixel(i, r, g, b, a); 58 | } 59 | }; 60 | 61 | /** 62 | * Sets the specified pixel to the passed rgb and brightness level. 63 | * The pixelNum is an integer between 0 and 7 to indicate the pixel 64 | * to change. 65 | * @param {Number} pixelNum The pixel to set RGB and brightness for. 66 | * An integer value between 0 and 7. Zero is the first pixel, 7 is 67 | * the last one. 68 | * @param {Number} r The pixel red value between 0 and 255. 69 | * @param {Number} g The pixel green value between 0 and 255. 70 | * @param {Number} b The pixel blue value between 0 and 255. 71 | * @param {Number=} a The pixel brightness value between 0.0 and 1.0. 72 | * @returns {undefined} Nothing. 73 | */ 74 | setPixel = (pixelNum, r, g, b, a) => { 75 | if (a === undefined) { 76 | if (this._pixels[pixelNum]) { 77 | // Set a to current level or 1.0 if none exists 78 | a = this._pixels[pixelNum][3] !== undefined ? this._pixels[pixelNum][3] : 1.0; 79 | } 80 | } else { 81 | a = Math.floor(31.0 * a) & this.brightnessMask; // jshint ignore:line 82 | } 83 | 84 | this._pixels[pixelNum] = [ 85 | Math.floor(r) & 255, // jshint ignore:line 86 | Math.floor(g) & 255, // jshint ignore:line 87 | Math.floor(b) & 255, // jshint ignore:line 88 | a 89 | ]; 90 | }; 91 | 92 | /** 93 | * Sets the brightness of the pixel specified by pixelNum. 94 | * @param {Number} pixelNum The pixel to set RGB and brightness for. 95 | * An integer value between 0 and 7. Zero is the first pixel, 7 is 96 | * the last one. 97 | * @param {Number} brightness The pixel brightness value between 0.0 98 | * and 1.0. 99 | * @returns {undefined} Nothing. 100 | */ 101 | setBrightness = (pixelNum, brightness) => { 102 | this._pixels[pixelNum][3] = Math.floor(31.0 * brightness) & this.brightnessMask; // jshint ignore:line 103 | }; 104 | 105 | /** 106 | * Clears the pixel buffer. 107 | * This is the same as setting all pixels to black. 108 | * You must also call sendUpdate() if you want to turn Blinkt! off. 109 | * @returns {undefined} Nothing. 110 | */ 111 | clearAll = () => { 112 | for (let i = 0; i < this._numPixels; i++) { 113 | this.clear(i); 114 | } 115 | }; 116 | 117 | /** 118 | * Clears the pixel . 119 | * This is the same as setting this pixels to black. 120 | * You must also call sendUpdate() if you want to turn Blinkt! off. 121 | * @param {Number} led index to clear. 122 | * @returns {undefined} Nothing. 123 | */ 124 | clear = (led) => { 125 | this.setPixel(led, 0, 0, 0); 126 | }; 127 | 128 | /** 129 | * Sends the current pixel settings to the Blinkt! device. Once you 130 | * have set each pixel RGB and brightness, you MUST call this for the 131 | * pixels to change on the Blinkt! device. 132 | * @returns {undefined} Nothing. 133 | */ 134 | sendUpdate = () => { 135 | let i, 136 | pixel; 137 | 138 | for (i = 0; i < 4; i++) { 139 | this._writeByte(0); 140 | } 141 | 142 | for (i = 0; i < this._numPixels; i++) { 143 | pixel = this._pixels[i]; 144 | 145 | // Brightness 146 | this._writeByte(this.significantBitsMask | pixel[3]); // jshint ignore:line 147 | // Blue 148 | this._writeByte(pixel[2]); 149 | // Green 150 | this._writeByte(pixel[1]); 151 | // Red 152 | this._writeByte(pixel[0]); 153 | } 154 | 155 | this._writeByte(0xff); 156 | this._latch(); 157 | }; 158 | 159 | /** 160 | * Writes byte data to the GPIO pins. 161 | * @param {Number} byte The byte value to write. 162 | * @returns {undefined} Nothing. 163 | * @private 164 | */ 165 | _writeByte = (byte) => { 166 | let bit; 167 | 168 | for (let i = 0 ; i < this._numPixels; i++) { 169 | bit = ((byte & (1 << (7 - i))) > 0) ? wpi.HIGH : wpi.LOW; // jshint ignore:line 170 | 171 | wpi.digitalWrite(this._dat, bit); 172 | wpi.digitalWrite(this._clk, 1); 173 | wpi.digitalWrite(this._clk, 0); 174 | } 175 | }; 176 | 177 | /** 178 | * Emit exactly enough clock pulses to latch the small dark die APA102s which are weird. 179 | * @returns {undefined} Nothing. 180 | * @private 181 | */ 182 | _latch = () => { 183 | wpi.digitalWrite(this._dat, 0); 184 | 185 | for (let i = 0 ; i < 36; i++) { 186 | wpi.digitalWrite(this._clk, 1); 187 | wpi.digitalWrite(this._clk, 0); 188 | } 189 | }; 190 | } 191 | 192 | module.exports = Blinkt; 193 | --------------------------------------------------------------------------------