├── .github ├── ISSUE_TEMPLATE.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── githubci.yml ├── Adafruit_WS2801.cpp ├── Adafruit_WS2801.h ├── README.md ├── examples ├── gridtest │ └── gridtest.pde └── strandtest │ └── strandtest.pde └── library.properties /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Thank you for opening an issue on an Adafruit Arduino library repository. To 2 | improve the speed of resolution please review the following guidelines and 3 | common troubleshooting steps below before creating the issue: 4 | 5 | - **Do not use GitHub issues for troubleshooting projects and issues.** Instead use 6 | the forums at http://forums.adafruit.com to ask questions and troubleshoot why 7 | something isn't working as expected. In many cases the problem is a common issue 8 | that you will more quickly receive help from the forum community. GitHub issues 9 | are meant for known defects in the code. If you don't know if there is a defect 10 | in the code then start with troubleshooting on the forum first. 11 | 12 | - **If following a tutorial or guide be sure you didn't miss a step.** Carefully 13 | check all of the steps and commands to run have been followed. Consult the 14 | forum if you're unsure or have questions about steps in a guide/tutorial. 15 | 16 | - **For Arduino projects check these very common issues to ensure they don't apply**: 17 | 18 | - For uploading sketches or communicating with the board make sure you're using 19 | a **USB data cable** and **not** a **USB charge-only cable**. It is sometimes 20 | very hard to tell the difference between a data and charge cable! Try using the 21 | cable with other devices or swapping to another cable to confirm it is not 22 | the problem. 23 | 24 | - **Be sure you are supplying adequate power to the board.** Check the specs of 25 | your board and plug in an external power supply. In many cases just 26 | plugging a board into your computer is not enough to power it and other 27 | peripherals. 28 | 29 | - **Double check all soldering joints and connections.** Flakey connections 30 | cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints. 31 | 32 | - **Ensure you are using an official Arduino or Adafruit board.** We can't 33 | guarantee a clone board will have the same functionality and work as expected 34 | with this code and don't support them. 35 | 36 | If you're sure this issue is a defect in the code and checked the steps above 37 | please fill in the following fields to provide enough troubleshooting information. 38 | You may delete the guideline and text above to just leave the following details: 39 | 40 | - Arduino board: **INSERT ARDUINO BOARD NAME/TYPE HERE** 41 | 42 | - Arduino IDE version (found in Arduino -> About Arduino menu): **INSERT ARDUINO 43 | VERSION HERE** 44 | 45 | - List the steps to reproduce the problem below (if possible attach a sketch or 46 | copy the sketch code in too): **LIST REPRO STEPS BELOW** 47 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Thank you for creating a pull request to contribute to Adafruit's GitHub code! 2 | Before you open the request please review the following guidelines and tips to 3 | help it be more easily integrated: 4 | 5 | - **Describe the scope of your change--i.e. what the change does and what parts 6 | of the code were modified.** This will help us understand any risks of integrating 7 | the code. 8 | 9 | - **Describe any known limitations with your change.** For example if the change 10 | doesn't apply to a supported platform of the library please mention it. 11 | 12 | - **Please run any tests or examples that can exercise your modified code.** We 13 | strive to not break users of the code and running tests/examples helps with this 14 | process. 15 | 16 | Thank you again for contributing! We will try to test and integrate the change 17 | as soon as we can, but be aware we have many GitHub repositories to manage and 18 | can't immediately respond to every request. There is no need to bump or check in 19 | on a pull request (it will clutter the discussion of the request). 20 | 21 | Also don't be worried if the request is closed or not integrated--sometimes the 22 | priorities of Adafruit's GitHub code (education, ease of use) might not match the 23 | priorities of the pull request. Don't fret, the open source community thrives on 24 | forks and GitHub makes it easy to keep your changes in a forked repo. 25 | 26 | After reviewing the guidelines above you can delete this text from the pull request. 27 | -------------------------------------------------------------------------------- /.github/workflows/githubci.yml: -------------------------------------------------------------------------------- 1 | name: Arduino Library CI 2 | 3 | on: [pull_request, push, repository_dispatch] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/setup-python@v4 11 | with: 12 | python-version: '3.x' 13 | - uses: actions/checkout@v3 14 | - uses: actions/checkout@v3 15 | with: 16 | repository: adafruit/ci-arduino 17 | path: ci 18 | 19 | - name: pre-install 20 | run: bash ci/actions_install.sh 21 | 22 | - name: test platforms 23 | run: python3 ci/build_platform.py main_platforms 24 | 25 | - name: clang 26 | run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r . 27 | 28 | - name: doxygen 29 | env: 30 | GH_REPO_TOKEN: ${{ secrets.GH_REPO_TOKEN }} 31 | PRETTYNAME : "Adafruit WS2801 Library" 32 | run: bash ci/doxy_gen_and_deploy.sh 33 | -------------------------------------------------------------------------------- /Adafruit_WS2801.cpp: -------------------------------------------------------------------------------- 1 | /*! 2 | * @file Adafruit_WS2801.cpp 3 | * 4 | * @mainpage Adafruit WS2801 Library 5 | * 6 | * @section intro_sec Introduction 7 | * 8 | * Example to control WS2801-based RGB LED Modules in a strand or strip 9 | * 10 | * @section author Author 11 | * 12 | * Written by Adafruit 13 | * @section license License 14 | * MIT license 15 | */ 16 | #include "Adafruit_WS2801.h" 17 | 18 | #ifdef __AVR_ATtiny85__ 19 | 20 | // Teensy/Gemma-specific stuff for hardware-assisted SPI @ 1 MHz 21 | 22 | #if (F_CPU > 8000000L) 23 | #define SPI_DELAY asm volatile("rjmp .+0\nrjmp .+0"); // Burn 4 cycles 24 | #elif (F_CPU > 4000000L) 25 | #define SPI_DELAY asm volatile("rjmp .+0"); // Burn 2 cycles 26 | #else 27 | #define SPI_DELAY // Run max speed 28 | #endif 29 | 30 | #define SPIBIT \ 31 | USICR = ((1 << USIWM0) | (1 << USITC)); \ 32 | SPI_DELAY \ 33 | USICR = ((1 << USIWM0) | (1 << USITC) | (1 << USICLK)); \ 34 | SPI_DELAY 35 | 36 | static void spi_out(uint8_t n) { 37 | USIDR = n; 38 | SPIBIT 39 | SPIBIT 40 | SPIBIT 41 | SPIBIT 42 | SPIBIT 43 | SPIBIT 44 | SPIBIT 45 | SPIBIT 46 | } 47 | 48 | #else 49 | 50 | // All other boards support Full and Proper Hardware SPI 51 | 52 | #include 53 | #define spi_out(n) (void)SPI.transfer(n) //!< Sets up SPI 54 | 55 | #endif 56 | 57 | // Constructor for use with hardware SPI (specific clock/data pins): 58 | Adafruit_WS2801::Adafruit_WS2801(uint16_t n, uint8_t order) { 59 | rgb_order = order; 60 | alloc(n); 61 | updatePins(); 62 | } 63 | 64 | // Constructor for use with arbitrary clock/data pins: 65 | Adafruit_WS2801::Adafruit_WS2801(uint16_t n, uint8_t dpin, uint8_t cpin, 66 | uint8_t order) { 67 | rgb_order = order; 68 | alloc(n); 69 | updatePins(dpin, cpin); 70 | } 71 | 72 | // Constructor for use with a matrix configuration, specify w, h for size 73 | // of matrix. Assumes configuration where string starts at coordinate 0,0 74 | // and continues to w-1,0, w-1,1 and on to 0,1, 0,2 and on to w-1,2 and 75 | // so on. Snaking back and forth till the end. Other function calls 76 | // provide access to pixels via an x,y coordinate system 77 | Adafruit_WS2801::Adafruit_WS2801(uint16_t w, uint16_t h, uint8_t dpin, 78 | uint8_t cpin, uint8_t order) { 79 | rgb_order = order; 80 | alloc(w * h); 81 | width = w; 82 | height = h; 83 | updatePins(dpin, cpin); 84 | } 85 | 86 | // Allocate 3 bytes per pixel, init to RGB 'off' state: 87 | void Adafruit_WS2801::alloc(uint16_t n) { 88 | begun = false; 89 | numLEDs = ((pixels = (uint8_t *)calloc(n, 3)) != NULL) ? n : 0; 90 | } 91 | 92 | // via Michael Vogt/neophob: empty constructor is used when strand length 93 | // isn't known at compile-time; situations where program config might be 94 | // read from internal flash memory or an SD card, or arrive via serial 95 | // command. If using this constructor, MUST follow up with updateLength() 96 | // and updatePins() to establish the strand length and output pins! 97 | // Also, updateOrder() to change RGB vs GRB order (RGB is default). 98 | Adafruit_WS2801::Adafruit_WS2801(void) { 99 | begun = false; 100 | numLEDs = 0; 101 | pixels = NULL; 102 | rgb_order = WS2801_RGB; 103 | updatePins(); // Must assume hardware SPI until pins are set 104 | } 105 | 106 | // Release memory (as needed): 107 | Adafruit_WS2801::~Adafruit_WS2801(void) { 108 | if (pixels) 109 | free(pixels); 110 | } 111 | 112 | // Activate hard/soft SPI as appropriate: 113 | void Adafruit_WS2801::begin(void) { 114 | if (hardwareSPI == true) { 115 | startSPI(); 116 | } else { 117 | pinMode(datapin, OUTPUT); 118 | pinMode(clkpin, OUTPUT); 119 | } 120 | begun = true; 121 | } 122 | 123 | // Change pin assignments post-constructor, switching to hardware SPI: 124 | void Adafruit_WS2801::updatePins(void) { 125 | pinMode(datapin, INPUT); // Restore data and clock pins to inputs 126 | pinMode(clkpin, INPUT); 127 | datapin = clkpin = 0; 128 | hardwareSPI = true; 129 | // If begin() was previously invoked, init the SPI hardware now: 130 | if (begun == true) 131 | startSPI(); 132 | // Otherwise, SPI is NOT initted until begin() is explicitly called. 133 | } 134 | 135 | // Change pin assignments post-constructor, using arbitrary pins: 136 | void Adafruit_WS2801::updatePins(uint8_t dpin, uint8_t cpin) { 137 | if (begun == true) { // If begin() was previously invoked... 138 | // If previously using hardware SPI, turn that off: 139 | if (hardwareSPI) { 140 | #ifdef __AVR_ATtiny85__ 141 | DDRB &= ~(_BV(PORTB1) | _BV(PORTB2)); 142 | #else 143 | SPI.end(); 144 | #endif 145 | } else { 146 | pinMode(datapin, INPUT); // Restore prior data and clock pins to inputs 147 | pinMode(clkpin, INPUT); 148 | } 149 | pinMode(dpin, OUTPUT); // Enable output on 'soft' SPI pins: 150 | pinMode(cpin, OUTPUT); 151 | } 152 | 153 | datapin = dpin; 154 | clkpin = cpin; 155 | #ifdef __AVR__ 156 | clkport = portOutputRegister(digitalPinToPort(cpin)); 157 | clkpinmask = digitalPinToBitMask(cpin); 158 | dataport = portOutputRegister(digitalPinToPort(dpin)); 159 | datapinmask = digitalPinToBitMask(dpin); 160 | #endif 161 | hardwareSPI = false; 162 | } 163 | 164 | // Enable SPI hardware and set up protocol details: 165 | void Adafruit_WS2801::startSPI(void) { 166 | #ifdef __AVR_ATtiny85__ 167 | PORTB &= ~(_BV(PORTB1) | _BV(PORTB2)); // Outputs 168 | DDRB |= _BV(PORTB1) | _BV(PORTB2); // DO (NOT MOSI) + SCK 169 | #else 170 | SPI.begin(); 171 | SPI.setBitOrder(MSBFIRST); 172 | SPI.setDataMode(SPI_MODE0); 173 | #if defined(__AVR__) || defined(CORE_TEENSY) 174 | SPI.setClockDivider(SPI_CLOCK_DIV16); // 1MHz max, else flicker 175 | #else 176 | SPI.setClockDivider((F_CPU + 500000L) / 1000000L); 177 | #endif 178 | #endif 179 | } 180 | 181 | uint16_t Adafruit_WS2801::numPixels(void) { return numLEDs; } 182 | 183 | // Change strand length (see notes with empty constructor, above): 184 | void Adafruit_WS2801::updateLength(uint16_t n) { 185 | if (pixels != NULL) 186 | free(pixels); // Free existing data (if any) 187 | // Allocate new data -- note: ALL PIXELS ARE CLEARED 188 | numLEDs = ((pixels = (uint8_t *)calloc(n, 3)) != NULL) ? n : 0; 189 | // 'begun' state does not change -- pins retain prior modes 190 | } 191 | 192 | // Change RGB data order (see notes with empty constructor, above): 193 | void Adafruit_WS2801::updateOrder(uint8_t order) { 194 | rgb_order = order; 195 | // Existing LED data, if any, is NOT reformatted to new data order. 196 | // Calling function should clear or fill pixel data anew. 197 | } 198 | 199 | void Adafruit_WS2801::show(void) { 200 | uint16_t i, nl3 = numLEDs * 3; // 3 bytes per LED 201 | uint8_t bit; 202 | 203 | // Write 24 bits per pixel: 204 | if (hardwareSPI) { 205 | for (i = 0; i < nl3; i++) 206 | spi_out(pixels[i]); 207 | } else { 208 | for (i = 0; i < nl3; i++) { 209 | for (bit = 0x80; bit; bit >>= 1) { 210 | #ifdef __AVR__ 211 | if (pixels[i] & bit) 212 | *dataport |= datapinmask; 213 | else 214 | *dataport &= ~datapinmask; 215 | *clkport |= clkpinmask; 216 | *clkport &= ~clkpinmask; 217 | #else 218 | if (pixels[i] & bit) 219 | digitalWrite(datapin, HIGH); 220 | else 221 | digitalWrite(datapin, LOW); 222 | digitalWrite(clkpin, HIGH); 223 | digitalWrite(clkpin, LOW); 224 | #endif 225 | } 226 | } 227 | } 228 | 229 | delay(1); // Data is latched by holding clock pin low for 1 millisecond 230 | } 231 | 232 | // Set pixel color from separate 8-bit R, G, B components: 233 | void Adafruit_WS2801::setPixelColor(uint16_t n, uint8_t r, uint8_t g, 234 | uint8_t b) { 235 | if (n < numLEDs) { // Arrays are 0-indexed, thus NOT '<=' 236 | uint8_t *p = &pixels[n * 3]; 237 | // See notes later regarding color order 238 | if (rgb_order == WS2801_RGB) { 239 | *p++ = r; 240 | *p++ = g; 241 | } else { 242 | *p++ = g; 243 | *p++ = r; 244 | } 245 | *p++ = b; 246 | } 247 | } 248 | 249 | // Set pixel color from separate 8-bit R, G, B components using x,y coordinate 250 | // system: 251 | void Adafruit_WS2801::setPixelColor(uint16_t x, uint16_t y, uint8_t r, 252 | uint8_t g, uint8_t b) { 253 | boolean evenRow = ((y % 2) == 0); 254 | // calculate x offset first 255 | uint16_t offset = x % width; 256 | if (!evenRow) { 257 | offset = (width - 1) - offset; 258 | } 259 | // add y offset 260 | offset += y * width; 261 | setPixelColor(offset, r, g, b); 262 | } 263 | 264 | // Set pixel color from 'packed' 32-bit RGB value: 265 | void Adafruit_WS2801::setPixelColor(uint16_t n, uint32_t c) { 266 | if (n < numLEDs) { // Arrays are 0-indexed, thus NOT '<=' 267 | uint8_t *p = &pixels[n * 3]; 268 | // To keep the show() loop as simple & fast as possible, the 269 | // internal color representation is native to different pixel 270 | // types. For compatibility with existing code, 'packed' RGB 271 | // values passed in or out are always 0xRRGGBB order. 272 | if (rgb_order == WS2801_RGB) { 273 | *p++ = c >> 16; // Red 274 | *p++ = c >> 8; // Green 275 | } else { 276 | *p++ = c >> 8; // Green 277 | *p++ = c >> 16; // Red 278 | } 279 | *p++ = c; // Blue 280 | } 281 | } 282 | 283 | // Set pixel color from 'packed' 32-bit RGB value using x,y coordinate system: 284 | void Adafruit_WS2801::setPixelColor(uint16_t x, uint16_t y, uint32_t c) { 285 | boolean evenRow = ((y % 2) == 0); 286 | // calculate x offset first 287 | uint16_t offset = x % width; 288 | if (!evenRow) { 289 | offset = (width - 1) - offset; 290 | } 291 | // add y offset 292 | offset += y * width; 293 | setPixelColor(offset, c); 294 | } 295 | 296 | // Clear all pixels 297 | void Adafruit_WS2801::clear() { 298 | if (pixels != NULL) { 299 | memset(pixels, 0, numLEDs * 3); 300 | } 301 | } 302 | 303 | // Query color from previously-set pixel (returns packed 32-bit RGB value) 304 | uint32_t Adafruit_WS2801::getPixelColor(uint16_t n) { 305 | if (n < numLEDs) { 306 | uint16_t ofs = n * 3; 307 | // To keep the show() loop as simple & fast as possible, the 308 | // internal color representation is native to different pixel 309 | // types. For compatibility with existing code, 'packed' RGB 310 | // values passed in or out are always 0xRRGGBB order. 311 | return (rgb_order == WS2801_RGB) 312 | ? ((uint32_t)pixels[ofs] << 16) | 313 | ((uint16_t)pixels[ofs + 1] << 8) | pixels[ofs + 2] 314 | : (pixels[ofs] << 8) | ((uint32_t)pixels[ofs + 1] << 16) | 315 | pixels[ofs + 2]; 316 | } 317 | 318 | return 0; // Pixel # is out of bounds 319 | } 320 | -------------------------------------------------------------------------------- /Adafruit_WS2801.h: -------------------------------------------------------------------------------- 1 | /*! 2 | * @file Adafruit_WS2801.h 3 | */ 4 | 5 | #ifndef __ADAFRUIT_WS2801__ 6 | #define __ADAFRUIT_WS2801__ 7 | 8 | #if (ARDUINO >= 100) 9 | #include 10 | #else 11 | #include 12 | #include 13 | #endif 14 | 15 | // Not all LED pixels are RGB order; 36mm type expects GRB data. 16 | // Optional flag to constructors indicates data order (default if 17 | // unspecified is RGB). As long as setPixelColor/getPixelColor are 18 | // used, other code can always treat 'packed' colors as RGB; the 19 | // library will handle any required translation internally. 20 | #define WS2801_RGB 0 //!< Sets mode to RGB 21 | #define WS2801_GRB 1 //!< Sets mode to GRB 22 | 23 | /*! 24 | * @brief Class that stores state and functions for interacting with WS2801 LEDs 25 | */ 26 | class Adafruit_WS2801 { 27 | 28 | public: 29 | /*! 30 | * @brief Constructor for use with arbitrary clock/data pins 31 | * @param n How many LEDs there are 32 | * @param dpin Data pin 33 | * @param cpin Clock pin 34 | * @param order RGB or GRB 35 | */ 36 | Adafruit_WS2801(uint16_t n, uint8_t dpin, uint8_t cpin, 37 | uint8_t order = WS2801_RGB); 38 | /*! 39 | * @brief Constructor for use with a matrix configuration, specify w, h for 40 | * size of matrix. 41 | * @param x Width of the matrix 42 | * @param y Height of the matrix 43 | * @param dpin Data pin 44 | * @param cpin Clock pin 45 | * @param order RGB or GRB 46 | */ 47 | Adafruit_WS2801(uint16_t x, uint16_t y, uint8_t dpin, uint8_t cpin, 48 | uint8_t order = WS2801_RGB); 49 | /*! 50 | * @brief Constructor for use with hardware SPI (specific clock/data pins) 51 | * @param n 52 | * @param order 53 | */ 54 | Adafruit_WS2801(uint16_t n, uint8_t order = WS2801_RGB); 55 | /*! 56 | * @brief Empty constructor; init pins/strand length/data order later: 57 | */ 58 | Adafruit_WS2801(); 59 | /*! 60 | * @brief Release memory (as needed): 61 | */ 62 | ~Adafruit_WS2801(); 63 | 64 | void 65 | /*! 66 | * @brief Activate SPI 67 | */ 68 | begin(void), 69 | /*! 70 | * @brief Shows the pixels 71 | */ 72 | show(void), 73 | /*! 74 | * @brief Set pixel color from separate 8-bit R, G, B components 75 | * @param n Pixel to set 76 | * @param r Red value 77 | * @param g Green value 78 | * @param b Blue value 79 | */ 80 | setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b), 81 | /*! 82 | * @brief Set pixel color from 'packed' 32-bit RGB value 83 | * @param n Pixel to set 84 | * @param c packed 32-bit RGB value to set the pixel 85 | */ 86 | setPixelColor(uint16_t n, uint32_t c), 87 | /*! 88 | * @brief Set pixel color from separate 8-bit R, G, B components using x,y coordinate system 89 | * @param x Pixel x 90 | * @param y Pixel y 91 | * @param r Red value 92 | * @param g Green value 93 | * @param b Blue value 94 | */ 95 | setPixelColor(uint16_t x, uint16_t y, uint8_t r, uint8_t g, uint8_t b), 96 | /*! 97 | * @brief Set pixel color from 'packed' 32-bit RGB value using x,y coordinate system: 98 | * @param x Pixel x 99 | * @param y Pixel y 100 | * @param c packed 32-bit RGB value to set the pixel 101 | */ 102 | setPixelColor(uint16_t x, uint16_t y, uint32_t c), 103 | /*! 104 | * @brief Clear the entire string 105 | */ 106 | clear(), 107 | /*! 108 | * @brief Change pin assignment post-constructor, using arbitrary pins 109 | * @param dpin Data pin 110 | * @param cpin Clock pin 111 | */ 112 | updatePins(uint8_t dpin, uint8_t cpin), 113 | /*! 114 | * @brief Change pin assignment post-constructor, switching to hardware SPI 115 | */ 116 | updatePins(void), 117 | /*! 118 | * @brief Change strand length 119 | * @param n Length to change to 120 | */ 121 | updateLength(uint16_t n), 122 | /*! 123 | * @brief Change RGB data order 124 | * @param order Order to switch to 125 | */ 126 | updateOrder(uint8_t order); 127 | uint16_t 128 | /*! 129 | * @brief Returns the number of pixels currently connected 130 | * @return Returns the number of connected pixels 131 | */ 132 | numPixels(void); 133 | uint32_t 134 | /*! 135 | * @brief Query color from previously-set pixel 136 | * @param n Pixel to query 137 | * @return Returns packed 32-bit RGB value 138 | */ 139 | getPixelColor(uint16_t n); 140 | 141 | private: 142 | uint16_t numLEDs, 143 | width, // used with matrix mode 144 | height; // used with matrix mode 145 | uint8_t *pixels, // Holds color values for each LED (3 bytes each) 146 | rgb_order, // Color order; RGB vs GRB (or others, if needed in future) 147 | clkpin, datapin; // Clock & data pin numbers 148 | #ifdef __AVR__ 149 | uint8_t clkpinmask, datapinmask; // Clock & data PORT bitmasks 150 | volatile uint8_t *clkport, *dataport; // Clock & data PORT registers 151 | #endif 152 | void alloc(uint16_t n), startSPI(void); 153 | boolean hardwareSPI, // If 'true', using hardware SPI 154 | begun; // If 'true', begin() method was previously invoked 155 | }; 156 | 157 | #endif // __ADAFRUIT_WS2801__ 158 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Adafruit WS2801 Library [![Build Status](https://github.com/adafruit/Adafruit-WS2801-Library/workflows/Arduino%20Library%20CI/badge.svg)](https://github.com/adafruit/Adafruit-WS2801-Library/actions)[![Documentation](https://github.com/adafruit/ci-arduino/blob/master/assets/doxygen_badge.svg)](http://adafruit.github.io/Adafruit-WS2801-Library/html/index.html) 2 | 3 | Example library for driving Adafruit WS2801 pixels! 4 | 5 | 6 | Designed specifically to work with the Adafruit RGB Pixels! 7 | 12mm Bullet shape ----> https://www.adafruit.com/products/322 8 | 12mm Flat shape ----> https://www.adafruit.com/products/738 9 | 36mm Square shape ----> https://www.adafruit.com/products/683 10 | 11 | These pixels use SPI to transmit the color data, and have built in 12 | high speed PWM drivers for 24 bit color per pixel 13 | 2 pins are required to interface 14 | 15 | Adafruit invests time and resources providing this open source code, 16 | please support Adafruit and open-source hardware by purchasing 17 | products from Adafruit! 18 | 19 | Written by Limor Fried/Ladyada for Adafruit Industries. 20 | BSD license, all text above must be included in any redistribution 21 | 22 | ------------------------------------- 23 | 24 | To download. click the DOWNLOADS button in the top right corner, rename the uncompressed folder Adafruit_WS2801. Check that the WS2801 folder contains Adafruit_WS2801.cpp and Adafruit_WS2801.h 25 | 26 | Place the Adafruit_WS2801 library folder your /libraries/ folder. You may need to create the libraries subfolder if its your first library. Restart the IDE. 27 | -------------------------------------------------------------------------------- /examples/gridtest/gridtest.pde: -------------------------------------------------------------------------------- 1 | #include "SPI.h" 2 | #include "Adafruit_WS2801.h" 3 | 4 | /***************************************************************************** 5 | Example sketch for driving Adafruit WS2801 pixels! 6 | 7 | 8 | Designed specifically to work with the Adafruit RGB Pixels! 9 | 12mm Bullet shape ----> https://www.adafruit.com/products/322 10 | 12mm Flat shape ----> https://www.adafruit.com/products/738 11 | 36mm Square shape ----> https://www.adafruit.com/products/683 12 | 13 | These pixels use SPI to transmit the color data, and have built in 14 | high speed PWM drivers for 24 bit color per pixel 15 | 2 pins are required to interface 16 | 17 | Adafruit invests time and resources providing this open source code, 18 | please support Adafruit and open-source hardware by purchasing 19 | products from Adafruit! 20 | 21 | Written by David Kavanagh (dkavanagh@gmail.com). 22 | BSD license, all text above must be included in any redistribution 23 | 24 | *****************************************************************************/ 25 | 26 | // Choose which 2 pins you will use for output. 27 | // Can be any valid output pins. 28 | // The colors of the wires may be totally different so 29 | // BE SURE TO CHECK YOUR PIXELS TO SEE WHICH WIRES TO USE! 30 | uint8_t dataPin = 2; // Yellow wire on Adafruit Pixels 31 | uint8_t clockPin = 3; // Green wire on Adafruit Pixels 32 | 33 | // Don't forget to connect the ground wire to Arduino ground, 34 | // and the +5V wire to a +5V supply 35 | 36 | // Set the first variable to the NUMBER of pixels in a row and 37 | // the second value to number of pixels in a column. 38 | Adafruit_WS2801 strip = Adafruit_WS2801((uint16_t)7, (uint16_t)7, dataPin, clockPin); 39 | 40 | void setup() { 41 | 42 | strip.begin(); 43 | 44 | // Update LED contents, to start they are all 'off' 45 | strip.show(); 46 | } 47 | 48 | 49 | void loop() { 50 | // Some example procedures showing how to display to the pixels 51 | drawX(7, 7, 100); 52 | bounce(7, 6, 50); 53 | } 54 | 55 | void drawX(uint8_t w, uint8_t h, uint8_t wait) { 56 | uint16_t x, y; 57 | for (x=0; x 5 | #endif 6 | 7 | /***************************************************************************** 8 | Example sketch for driving Adafruit WS2801 pixels! 9 | 10 | 11 | Designed specifically to work with the Adafruit RGB Pixels! 12 | 12mm Bullet shape ----> https://www.adafruit.com/products/322 13 | 12mm Flat shape ----> https://www.adafruit.com/products/738 14 | 36mm Square shape ----> https://www.adafruit.com/products/683 15 | 16 | These pixels use SPI to transmit the color data, and have built in 17 | high speed PWM drivers for 24 bit color per pixel 18 | 2 pins are required to interface 19 | 20 | Adafruit invests time and resources providing this open source code, 21 | please support Adafruit and open-source hardware by purchasing 22 | products from Adafruit! 23 | 24 | Written by Limor Fried/Ladyada for Adafruit Industries. 25 | BSD license, all text above must be included in any redistribution 26 | 27 | *****************************************************************************/ 28 | 29 | // Choose which 2 pins you will use for output. 30 | // Can be any valid output pins. 31 | // The colors of the wires may be totally different so 32 | // BE SURE TO CHECK YOUR PIXELS TO SEE WHICH WIRES TO USE! 33 | uint8_t dataPin = 2; // Yellow wire on Adafruit Pixels 34 | uint8_t clockPin = 3; // Green wire on Adafruit Pixels 35 | 36 | // Don't forget to connect the ground wire to Arduino ground, 37 | // and the +5V wire to a +5V supply 38 | 39 | // Set the first variable to the NUMBER of pixels. 25 = 25 pixels in a row 40 | Adafruit_WS2801 strip = Adafruit_WS2801(25, dataPin, clockPin); 41 | 42 | // Optional: leave off pin numbers to use hardware SPI 43 | // (pinout is then specific to each board and can't be changed) 44 | //Adafruit_WS2801 strip = Adafruit_WS2801(25); 45 | 46 | // For 36mm LED pixels: these pixels internally represent color in a 47 | // different format. Either of the above constructors can accept an 48 | // optional extra parameter: WS2801_RGB is 'conventional' RGB order 49 | // WS2801_GRB is the GRB order required by the 36mm pixels. Other 50 | // than this parameter, your code does not need to do anything different; 51 | // the library will handle the format change. Examples: 52 | //Adafruit_WS2801 strip = Adafruit_WS2801(25, dataPin, clockPin, WS2801_GRB); 53 | //Adafruit_WS2801 strip = Adafruit_WS2801(25, WS2801_GRB); 54 | 55 | void setup() { 56 | #if defined(__AVR_ATtiny85__) && (F_CPU == 16000000L) 57 | clock_prescale_set(clock_div_1); // Enable 16 MHz on Trinket 58 | #endif 59 | 60 | strip.begin(); 61 | 62 | // Update LED contents, to start they are all 'off' 63 | strip.show(); 64 | } 65 | 66 | 67 | void loop() { 68 | // Some example procedures showing how to display to the pixels 69 | 70 | colorWipe(Color(255, 0, 0), 50); 71 | colorWipe(Color(0, 255, 0), 50); 72 | colorWipe(Color(0, 0, 255), 50); 73 | rainbow(20); 74 | rainbowCycle(20); 75 | } 76 | 77 | void rainbow(uint8_t wait) { 78 | int i, j; 79 | 80 | for (j=0; j < 256; j++) { // 3 cycles of all 256 colors in the wheel 81 | for (i=0; i < strip.numPixels(); i++) { 82 | strip.setPixelColor(i, Wheel( (i + j) % 255)); 83 | } 84 | strip.show(); // write all the pixels out 85 | delay(wait); 86 | } 87 | } 88 | 89 | // Slightly different, this one makes the rainbow wheel equally distributed 90 | // along the chain 91 | void rainbowCycle(uint8_t wait) { 92 | int i, j; 93 | 94 | for (j=0; j < 256 * 5; j++) { // 5 cycles of all 25 colors in the wheel 95 | for (i=0; i < strip.numPixels(); i++) { 96 | // tricky math! we use each pixel as a fraction of the full 96-color wheel 97 | // (thats the i / strip.numPixels() part) 98 | // Then add in j which makes the colors go around per pixel 99 | // the % 96 is to make the wheel cycle around 100 | strip.setPixelColor(i, Wheel( ((i * 256 / strip.numPixels()) + j) % 256) ); 101 | } 102 | strip.show(); // write all the pixels out 103 | delay(wait); 104 | } 105 | } 106 | 107 | // fill the dots one after the other with said color 108 | // good for testing purposes 109 | void colorWipe(uint32_t c, uint8_t wait) { 110 | int i; 111 | 112 | for (i=0; i < strip.numPixels(); i++) { 113 | strip.setPixelColor(i, c); 114 | strip.show(); 115 | delay(wait); 116 | } 117 | } 118 | 119 | /* Helper functions */ 120 | 121 | // Create a 24 bit color value from R,G,B 122 | uint32_t Color(byte r, byte g, byte b) 123 | { 124 | uint32_t c; 125 | c = r; 126 | c <<= 8; 127 | c |= g; 128 | c <<= 8; 129 | c |= b; 130 | return c; 131 | } 132 | 133 | //Input a value 0 to 255 to get a color value. 134 | //The colours are a transition r - g -b - back to r 135 | uint32_t Wheel(byte WheelPos) 136 | { 137 | if (WheelPos < 85) { 138 | return Color(WheelPos * 3, 255 - WheelPos * 3, 0); 139 | } else if (WheelPos < 170) { 140 | WheelPos -= 85; 141 | return Color(255 - WheelPos * 3, 0, WheelPos * 3); 142 | } else { 143 | WheelPos -= 170; 144 | return Color(0, WheelPos * 3, 255 - WheelPos * 3); 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=Adafruit WS2801 Library 2 | version=1.1.3 3 | author=Adafruit 4 | maintainer=Adafruit 5 | sentence=Arduino library for controlling strips/pixels using WS2801 driver chips 6 | paragraph=Arduino library for controlling strips/pixels using WS2801 driver chips 7 | category=Display 8 | url=https://github.com/adafruit/Adafruit-WS2801-Library 9 | architectures=* 10 | --------------------------------------------------------------------------------