{"id":13521385,"url":"https://github.com/ajfisher/node-pixel","last_synced_at":"2025-05-15T09:03:22.887Z","repository":{"id":12174144,"uuid":"14773126","full_name":"ajfisher/node-pixel","owner":"ajfisher","description":"Library for using addressable LEDs (such as NeoPixels/WS2812) with Firmata and JohnnyFive","archived":false,"fork":false,"pushed_at":"2024-10-21T20:49:33.000Z","size":3135,"stargazers_count":276,"open_issues_count":28,"forks_count":71,"subscribers_count":14,"default_branch":"master","last_synced_at":"2024-10-22T15:39:05.071Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ajfisher.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-11-28T09:43:00.000Z","updated_at":"2024-10-21T20:49:36.000Z","dependencies_parsed_at":"2024-04-22T20:58:47.200Z","dependency_job_id":"caa918a2-fc75-43d3-8880-24cdd6c99f50","html_url":"https://github.com/ajfisher/node-pixel","commit_stats":{"total_commits":389,"total_committers":22,"mean_commits":"17.681818181818183","dds":0.4241645244215938,"last_synced_commit":"c44e77ce381b1611fb1c60812ee17ce23f12f330"},"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ajfisher%2Fnode-pixel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ajfisher%2Fnode-pixel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ajfisher%2Fnode-pixel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ajfisher%2Fnode-pixel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ajfisher","download_url":"https://codeload.github.com/ajfisher/node-pixel/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247584111,"owners_count":20962075,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T06:00:33.727Z","updated_at":"2025-04-07T03:17:53.144Z","avatar_url":"https://github.com/ajfisher.png","language":"C++","funding_links":[],"categories":["C++","Libraries and Plugins"],"sub_categories":[],"readme":"# Node Pixel\n\n![](https://img.shields.io/npm/v/node-pixel.svg)\n[![Join the chat at https://gitter.im/ajfisher/node-pixel](https://img.shields.io/badge/Gitter-Join%20Chat-brightgreen.svg)](https://gitter.im/ajfisher/node-pixel?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n![](https://img.shields.io/david/ajfisher/node-pixel.svg)\n![](https://img.shields.io/github/issues/ajfisher/node-pixel.svg)\n[![Coverage Status](https://coveralls.io/repos/github/ajfisher/node-pixel/badge.svg?branch=master)](https://coveralls.io/github/ajfisher/node-pixel?branch=master)\n[![Travis](https://img.shields.io/travis/ajfisher/node-pixel.svg)]()\n\nThe purpose of this library is to provide a node js interface for addressable\nRGB LEDs. Most commonly these are known as Neo Pixels (if you shop at Adafruit)\nhowever any WS2812b addressable LED should work with this library.\n\nThe current iteration supports two methods of set up:\n\n* a custom version of firmata that provides an interface to talk to the \"pixels\".\n* an I2C \"backpack\" using an arduino pro mini or nano that provides the interface\nand control of the pixels and then the IO controller talks to this backpack over\nI2C messages.\n\nThe pixel library can be used with both Johnny-Five or stock Node Firmata and\ncan be used by any board that provides an IO interface with I2C support such as\na Raspberry PI.\n\nBoth fimwares are provided in this repo in the\n[firmware/build](firmware/build) directory.\n\n## Getting help\n\nIf you need some help getting your pixel strip working with johnny five jump into\nthe [Gitter Chat](https://gitter.im/ajfisher/node-pixel) or reach out to\n[ajfisher on twitter](http://twitter.com/ajfisher) or just raise an\n[issue here.](https://github.com/ajfisher/node-pixel/issues)\n\n## Installation\n\nInstallation of both backpack and custom firmata are covered in detail in the\n[Installation Guide](docs/installation.md).\n\nShort version for node-pixel custom firmata.\n\n```\nnpm install node-pixel\nnpm install -g nodebots-interchange\n```\n\nPlug in your arduino\n\n```\ninterchange install git+https://github.com/ajfisher/node-pixel -a uno --firmata\n```\n\nNote that on windows, you may need to explictly pass a port to flash due to the\nway com ports work. eg:\n\n```\ninterchange install git+https://github.com/ajfisher/node-pixel -a uno -p COM3 --firmata\n```\n\n### A note on multiple strips\n\nMultiple led strips on one arduino or backpack are supported up to a maximum\nof 8 individual strips (8 pins in use at once). Each strip can be different\nlengths but you can only have a maximum of 192 pixels for Firmata and about\n500 pixels for the backpack version.\n\nMultiple strips connected to a single board or backpack are for the purposes\nof node-pixel considered to be a single strip and are joined together in sequence\nin the order that you define them.\n\nOn a backpack, the strips are defined sequentially from pin 0-7 on the backpack.\n\nOn an arduino, each strip can be defined with an individual pin which doesn't\nneed to be sequential (eg you can use pin 3, then pin 9, then pin 7).\n\nOne thing to note is that the timings on these strips are quite tight and you\nwill reach an upper limit of how much data you can push to the board controlling\nthe pixels (all that RGB data going over the wire) and the sheer number of\npixels you can refresh quickly (each pixel is written \"in turn\"). As such,\nyou may run into some blocking conflicts. These are discussed in\n[this issue](https://github.com/ajfisher/node-pixel/issues/15).\n\n# Pixel API\n\nThe Pixel API is provided below.\n\n## Strip\n\nA sequence of LEDs collected together is called a `strip`. A strip has\na controller to tell it to use the custom firmata or I2C backpack. A `strip`\ncan be a single physical strip in which case a single `pin` and `length` can\nbe provided. Otherwise it is made up of multiple physical strips, each of which\nhave their own `pin` and `length` and are composed together into order by using\nthe `strips` array as part of the definition of the object.\n\nFor the purposes of interaction however, once a `strip` is defined, it is all\none logical unit and the firmware will take care of writing data in the right\norder, performing optimisations for strips that have or haven't changed and\nwriting in sequence or parallel as appropriate.\n\n### Parameters\n\n* **options** An object of property parameters\n\n| Property | Type | Value / Description | Default | Required |\n|----------|------|---------------------|---------|----------|\n| pin | Number | Digital Pin. Used to set which pin the signal line to the pixels is being used when using a single strip. | 6 | no (4) |\n| length | Number | Number of pixels to be set on a single strip or all strips if individual lengths are not defined in the `strips` array | 32 | no (5) |\n| color_order | Constant | Determines the order of the RGB values against the pixels. Can be GRB, RGB or BRG  | pixel.COLOR_ORDER.GRB | no (6) |\n| strips | Array | Array of pin and length objects or array of length objects | 6 | no (2)(3) |\n| board | IO Object | IO Board object to use with Johnny Five | undefined | yes(1) |\n| firmata | Firmata board | Firmata board object to use with Firmata directly | undefined | yes(1) |\n| controller | String | I2CBACKPACK, FIRMATA | FIRMATA | no |\n| skip_firmware_check | Boolean | If the controller is FIRMATA, optionally skip the check for the matching node-pixel sketch | false | no |\n| gamma | Number | A number representing the gamma correction for a strip. Can be any decimal number. 2.8 generally works well. | 1.0 (7) | no |\n\n(1) A board or firmata object is required but only one of these needs to be set.\n\n(2) If using a backpack use an array of lengths eg `[8, 8, 8]` which would set\npins 0, 1 \u0026 2 on the backpack to have strips of length 8 each on them.\n\n(3) If using custom firmata then use an array of objects eg\n`[ {pin: 4, length: 8}, {pin: 10, length: 8}, {pin: 11, length: 8} ]`\nwhich would set pins 4, 10 \u0026 11 to have strips of length 8 on each of them.\n\n(4) If not supplied, it is assumed a `strips` array will be provided with a\n`pin` parameter for each object in the array.\n\n(5) If not supplied, it is assumed a `strips` array will be provided with a\n`length` parameter for each object in the array.\n\n(6) If supplied it will apply to all `strips` unless overridden selectively in\nthe `strips` array eg `[ {color_order: pixel.COLOR_ORDER.RGB}, ..]`\n\n(7) Currently set to `1.0` to maintain current behaviour. Will move to `2.8` default\nin version 0.10.\n\n### Properties\n\n* `length` - number of pixels in the `strip`\n* `gamma` - the currently set gamma for the `strip`\n\n### Events\n\n* `onready()` -  emits when the `strip` is configured.\n* `onerror()` - returns the error that occurred.\n\n### Examples\n\n_Johnny-Five instantiation_\n\n```javascript\npixel = require(\"node-pixel\");\nfive = require(\"johnny-five\");\n\nvar board = new five.Board(opts);\nvar strip = null;\n\nboard.on(\"ready\", function() {\n\n    strip = new pixel.Strip({\n        board: this,\n        controller: \"FIRMATA\",\n        strips: [ {pin: 6, length: 4}, ], // this is preferred form for definition\n        gamma: 2.8, // set to a gamma that works nicely for WS2812\n    });\n\n    strip.on(\"ready\", function() {\n        // do stuff with the strip here.\n    });\n});\n```\n\n_Firmata instantiation_\n\n```javascript\npixel = require(\"node-pixel\");\nvar firmata = require('firmata');\n\nvar board = new firmata.Board('path to usb',function(){\n\n    strip = new pixel.Strip({\n        pin: 6, // this is still supported as a shorthand\n        length: 4,\n        firmata: board,\n        controller: \"FIRMATA\",\n\n    });\n\n    strip.on(\"ready\", function() {\n        // do stuff with the strip here.\n    });\n});\n```\n\n_Johnny Five with backpack_\n\n```javascript\npixel = require(\"node-pixel\");\nfive = require(\"johnny-five\");\n\nvar board = new five.Board(opts);\n\nboard.on(\"ready\", function() {\n    strip = new pixel.Strip({\n        board: this,\n        controller: \"I2CBACKPACK\",\n        strips: [4, 6, 8], // 3 physical strips on pins 0, 1 \u0026 2 with lengths 4, 6 \u0026 8.\n    });\n\n    strip.on(\"ready\", function() {\n        // do stuff with the strip here.\n\n    });\n});\n```\n\nNote that Johnny-Five uses the board option and firmata uses the firmata option.\nThis is because the pixel library supports a Board capable of presenting an\nIO interface. The library will work out the right thing to do based on the\nboard being passed and the controller being set.\n\n### Methods\n\n#### show();\n\nThe show method should be called at the point you want to \"set\" the frame on\nthe strip of pixels and show them.\n\nNote that when this method is called it will trigger the process that writes\nthe frame to the strips. If you have a very long strip of LEDs this may take\nsome time (assume 0.5ms per pixel) and is a blocking operation in most cases.\n\nThis gives you an upper limit as to how many frames you can drive per second.\n\nExample\n\n```javascript\n// ... make pixel modifications\n\nstrip.show(); // make the strip latch and update the LEDs\n```\n\nAddressable LEDs work by clocking data along their entire length and so\nyou make the various changes you want to the strip as you need to without\ntriggering the display (like a frame buffer). Once you're ready you can then\ncall `show()` to propagate this data through the LEDs and display the frame.\n\n#### off();\n\nAll LEDs on the strip can be turned off by using the `.off()` method. This effectively clears the current colours set on the strip.\n\n`.clear()` is also aliased to the same method.\n\nExample\n\n```javascript\nstrip.off(); // turn the strip off / clear pixel colours\n```\n\n#### color( *colourstring* );\n\nAll LEDs on the strip can be set to the same colour using the `.color()` method.\n\n`.colour()` is also aliased to the same method.\n\nParameters\n\n* **colourstring** A `String` as a standard HTML hex colour or a CSS colour name,\nor a CSS rgb(r, g, b) value used to specify the colour of the strip. Alternatively\nan `Array` object as an rgb value eg `[r, g, b]`\n\nExamples\n\n_Set strip using a hex value_\n\n```javascript\nstrip.color(\"#ff0000\"); // turns entire strip red using a hex colour\nstrip.show();\n```\n\n_Update strip using a named CSS colour_\n\n```javascript\nstrip.colour(\"teal\"); // sets strip to a blue-green color using a named colour\nstrip.show();\n```\n\n_You can also use CSS RGB values_\n\n```javascript\nstrip.color(\"rgb(0, 255, 0)\"); // sets strip to green using rgb values\nstrip.show();\n```\n\n_Or set using an array of RGB values_\n\n```javascript\nstrip.color([255, 255, 0]); // Sets strip using an array\nstrip.show();\n```\n\n#### shift( *amt*, *direction*, *wrap* );\n\nAll LEDs on the strip can be shifted along the strip forwards or backwards\nby the given amount. This is very useful for long strip animation when you're\nmoving the whole strip by a pixel in one direction each frame and means you\ndon't have to send an update of `framelength` messages\n\nParameters\n\n* **amt** A `Number` representing the number of pixels you want everything to\nshift by.\n* **direction** Either `Pixel.FORWARD` or `Pixel.BACKWARD` value which determines\ndirection of travel. Forward direction is in the flow index values (ie index 1-\u003e2 etc).\n* **wrap** a `Boolean` representing whether to wrap the values that go off the\n\"end\" of the strip back around to the start - useful for circular displays.\n\nExample\n\n```javascript\nstrip.pixel(0).color(\"#000\");\nstrip.pixel(1).color(\"red\");\nstrip.shift(1, pixel.FORWARD, true);\nstrip.pixel(1).color; // will now be nothing\nstrip.pixel(2).color; // will now be red.\n```\n\n#### pixel( *address* );\n\nIndividual pixels can be addressed by the pixel method using their address in\nthe sequence.\n\nNote that if you have two physical strips of 8 and 10 then `pixel(10)` will be\nthe third pixel on the second physical strip.\n\nParameters\n\n* **address** A `Number` indexing the pixel you want. Returns a `Pixel` object.\n\nExample\n\n```javascript\nvar p = strip.pixel(1); // get the second LED. p is now a Pixel object\n```\n\n## Pixel\n\nA pixel is an individual element in the strip. It is fairly basic and it's API\nis detailed below.\n\n### Methods\n\n#### color( *color string* )\n\nColors work exactly the same way on individual pixels as per strips so see the\n`strip.color` reference above.\n\n`.colour()` is aliased to this method as well.\n\nParameters\n\n* **color string** A `String` providing the hex colour, CSS colour name or CSS\nrgb() values to be used to set the individual pixel a certain colour. You can also\npass in an `Array` object that is a set of RGB values as [r, g, b].\n\nExamples\n\n```javascript\nvar p = strip.pixel(1);     // get second LED\np.color(\"#0000FF\");         // set second pixel blue.\n\np = strip.pixel(2);         // get third LED\np.colour(\"orange\");          // set third pixel red/yellow\n\np = strip.pixel(3);         // get fourth LED\np.color(\"rgb(0, 255, 0)\");  // set fourth LED green\n\np = strip.pixel(4);         // get fifth LED\np.color([255, 0, 255]);     // set fifth LED magenta\n```\n\n#### color()\n\nReturns an object representing the color of this pixel with the shape below.\n\n`.colour()` is aliased to this method as well.\n\nParameters\n\n* none\n\nShape\n\n```javascript\n{\n    r: 0,               // red component\n    g: 0,               // green component\n    b: 0,               // blue component\n    hexcode: \"#000000\", // hexcode of color\n    color: \"black\",     // keyword name of color if matching\n    rgb: [0,0,0],       // RGB component array\n}\n```\n\nExample\n\nGet a pixel, set it's colour and then query it's current state.\n\n```javascript\nvar p = strip.pixel(1); // get second LED\n\np.color(\"#0000FF\"); // set second pixel blue.\n\np.color(); // returns {r:0, g:0, b:255, hexcode:\"#0000ff\", color:\"blue\", rgb[0,0,255]}\n```\n\n#### off()\n\nTurns the pixel to it's off state.\n\n`.clear()` is also aliased to this method.\n\nExample\n\nSet a pixel value to off\n\n```javascript\n\nvar p = strip.pixel(1); // get second LED\np.off(); // turn it off\np.color(); // returns {r: 0, g: 0, b: 0, hexcode:\"#000000\", color:\"black\", rgb: [0,0,0]}\nstrip.show(); // pixel will be off\n```\n\n## Detailed examples with circuits\n\n* [Basic single strip using custom firmata](docs/firmata.md)\n* [Basic single strip using Johnny Five Firmata](docs/johnnyfive.md)\n* [Single strip using Johnny Five over I2C Backpack](docs/johnnyfive-i2c.md)\n* [Mutiple strips using Johnny Five over firmata](docs/multipin.md)\n* [Multiple strips using Johnny Five over I2C Backpack](docs/multipin-i2c.md)\n* [Controlling a panel and using `strip.color()`](docs/panel.md)\n* [Static rainbow with a single strip](docs/rainbow-static.md)\n* [Dynamic rainbow over a single strip](docs/rainbow-dynamic.md)\n* [Dynamic rainbow over multiple strips](docs/rainbow-dynamic-multipin.md)\n* [Random pixels flowing down multiple strips](examples/mega-multipin.js)\n\n## TODO and roadmap\n\nThis library is under active development and planned modifications are:\n\n* Provide methods of having different shapes to the strips including 3D\n* Prvide method of pixel selection using polar coordinates for circles and hexes\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fajfisher%2Fnode-pixel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fajfisher%2Fnode-pixel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fajfisher%2Fnode-pixel/lists"}