Created
          February 5, 2015 17:47 
        
      - 
      
- 
        Save indefinit/22eefe92b5dc098266e7 to your computer and use it in GitHub Desktop. 
    modification of WS282X pixel programmer sketch for Arduino
  
        
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | // WS282x programmer | |
| // Takes some commands from the serial and allows you to program WS282x LED modules | |
| // | |
| // Should work with any 168, 328, or 32U4 based Arduino. | |
| // | |
| // to program a pixel, type into your Serial port: | |
| // p n | |
| // | |
| // where n = pixel address number starting at 1 | |
| // | |
| // Copyright 2014 Matt Mets | |
| #include "DmxSimpleMod.h" | |
| #define DATA_PIN 13 // Pin connected to the data output | |
| #define ADDRESS_PIN 7 // Pin connected to the address programmer output | |
| #define POWER_PIN 10 // Pin connected to power rail | |
| #define COMMAND_IDENTIFY 'i' // Idenify one pixel, flashing R-G-B on it | |
| #define COMMAND_POWER 'v' | |
| #define COMMAND_PROGRAM 'p' // Program a channel | |
| #define COMMAND_DISPLAY_PATTERN 'd' // 1:Identify 2:Rainbow Swirl 3: Flash Mode | |
| #define COMMAND_MAX_PIXELS 'm' // Number of pixels to send data to | |
| #define COMMAND_CONTROLLER_TYPE 't' // 1:WS2821S 2:WS2822S | |
| #define COMMAND_SETCOLOR1 'r' | |
| #define COMMAND_SETCOLOR2 'g' | |
| #define COMMAND_SETCOLOR3 'b' | |
| int maxPixel = 100; // Maximum pixel to display | |
| int currentPattern = 2; // Current pattern we are displaying | |
| int currentPixel = 1; // Current pixel for identification mode | |
| int controllerType = 1; // Controller type (1:WS2822S 2:WS2821) | |
| boolean powerOn = false; | |
| void setup() { | |
| pinMode(DATA_PIN, OUTPUT); | |
| digitalWrite(DATA_PIN, LOW); | |
| pinMode(ADDRESS_PIN, OUTPUT); | |
| digitalWrite(ADDRESS_PIN, HIGH); | |
| digitalWrite(POWER_PIN, HIGH); | |
| DmxSimple.usePin(DATA_PIN); | |
| DmxSimple.maxChannel(maxPixel*3); | |
| DmxSimple.begin(); | |
| Serial.begin(19200); | |
| } | |
| void writePixel(int pixel, int r, int g, int b) { | |
| DmxSimple.write((pixel - 1)*3 + 1, b); | |
| DmxSimple.write((pixel - 1)*3 + 2, g); | |
| DmxSimple.write((pixel - 1)*3 + 3, r); | |
| } | |
| uint8_t flipEndianness(uint8_t input) { | |
| uint8_t output = 0; | |
| for(uint8_t bit = 0; bit < 8; bit++) { | |
| if(input & (1 << bit)) { | |
| output |= (1 << (7 - bit)); | |
| } | |
| } | |
| return output; | |
| } | |
| void programAddress(int address) { | |
| // Build the output pattern to program this address | |
| uint8_t pattern[3]; | |
| if (controllerType == 1) { | |
| // WS2822S (from datasheet) | |
| int channel = (address-1)*3+1; | |
| pattern[0] = flipEndianness(channel%256); | |
| pattern[1] = flipEndianness(240 - (channel/256)*15); | |
| pattern[2] = flipEndianness(0xD2); | |
| } | |
| else { | |
| // WS2821 (determined experimentally) | |
| int channel = (address)*3; | |
| pattern[0] = flipEndianness(channel%256); | |
| pattern[1] = flipEndianness(240 - (channel/256)*15); | |
| pattern[2] = flipEndianness(0xAE); | |
| } | |
| DmxSimple.end(); // Turn off the DMX engine | |
| //digitalWrite(POWER_PIN, HIGH); // Turn on our power rail to avoid pre-shorting | |
| delay(50); // Wait for the engine to actually stop | |
| digitalWrite(ADDRESS_PIN, HIGH); // Set the address output pin high if it wasn't already | |
| digitalWrite(DATA_PIN, LOW); // Force the data pin low | |
| delay(50); // Let this sit for a bit to signal the chip we are starting | |
| DmxSimple.usePin(ADDRESS_PIN); // Use the address output pin to generate the DMX signal | |
| DmxSimple.maxChannel(3); | |
| DmxSimple.write(1, pattern[0]); // Pre-load the output pattern (note this might trash the LED output, meh) | |
| DmxSimple.write(2, pattern[1]); | |
| DmxSimple.write(3, pattern[2]); | |
| digitalWrite(ADDRESS_PIN, LOW); // Set the address pin low to begin transmission | |
| delay(1000); // Delay 1s to signal address transmission begin | |
| DmxSimple.begin(); // Begin transmission. Only the first one actually counts. | |
| delay(20); // Wait a while for the the signal to be sent | |
| DmxSimple.end(); | |
| digitalWrite(ADDRESS_PIN, HIGH); // Set the address output pin high if it wasn't already | |
| // Reset the output, and set the output to our new pixel address. | |
| DmxSimple.usePin(DATA_PIN); | |
| DmxSimple.maxChannel(maxPixel*3); | |
| DmxSimple.begin(); | |
| } | |
| void identify() { | |
| #define FLASH_SPEED 300 | |
| static int brightness; | |
| static int maxBrightness = 100; | |
| for(int pixel = 1; pixel <= maxPixel; pixel++) { | |
| int r = 0; | |
| int g = 0; | |
| int b = 0; | |
| if(brightness < FLASH_SPEED/3) { | |
| r = 1; | |
| } | |
| else if(brightness < FLASH_SPEED*2/3) { | |
| g = 1; | |
| } | |
| else { | |
| b = 1; | |
| } | |
| if(pixel == currentPixel) { | |
| writePixel(pixel, 100, 100, 100); | |
| } | |
| else { | |
| writePixel(pixel, 100, 100, 100); | |
| } | |
| } | |
| brightness=(brightness+1)%FLASH_SPEED; | |
| } | |
| void colorCheck() { | |
| //Serial.print(pixel); | |
| for(int i = 0; i<10; i++){ | |
| for(int i = 0; i<maxPixel; i++){ | |
| writePixel(i, 60, 60, 60); | |
| } | |
| delay(50); | |
| for(int i = 0; i<maxPixel; i++){ | |
| writePixel(i, 0,0,0); | |
| } | |
| delay(50); | |
| } | |
| for(int i = 0; i<maxPixel; i++){ | |
| writePixel(i, 60, 0, 0); | |
| } | |
| delay(500); | |
| for(int i = 0; i<maxPixel; i++){ | |
| writePixel(i, 0, 60, 0); | |
| } | |
| delay(500); | |
| for(int i = 0; i<maxPixel; i++){ | |
| writePixel(i, 0, 0, 60); | |
| } | |
| delay(500); | |
| } | |
| void color_loop() { | |
| static uint8_t i = 0; | |
| static int j = 0; | |
| static int f = 0; | |
| static int k = 0; | |
| static int count; | |
| static int pixelIndex; | |
| for (uint16_t i = 0; i < maxPixel*10; i+=10) { | |
| writePixel(i/10+1, | |
| 128*(1+sin(i/30.0 + j/1.3 )), | |
| 128*(1+sin(i/10.0 + f/2.9)), | |
| 128*(1+sin(i/25.0 + k/5.6)) | |
| // 128*(1+sin(i/10.0 + f/9.0 + 2.1)), | |
| // 128*(1+sin(i/30.0 + k/14.0 + 4.2)) | |
| ); | |
| } | |
| j = j + 1; | |
| f = f + 1; | |
| k = k + 2; | |
| } | |
| void countUp() { | |
| #define MAX_COUNT 400 | |
| static int counts = 0; | |
| static int pixel = 0; | |
| for (uint16_t i = 0; i < maxPixel; i+=1) { | |
| if(pixel == i) { | |
| writePixel(i+1, | |
| 255, | |
| 255, | |
| 255 | |
| ); | |
| } | |
| else { | |
| writePixel(i+1, 0,0,0); | |
| } | |
| } | |
| counts++; | |
| if(counts>MAX_COUNT) { | |
| counts = 0; | |
| pixel = (pixel+1)%maxPixel; | |
| } | |
| } | |
| void pictureFrame() { | |
| #define MAX_COUNT 10 | |
| static int counts = 0; | |
| static int pixel = 0; | |
| static uint8_t i = 0; | |
| static int j = 0; | |
| static int f = 0; | |
| static int k = 0; | |
| static int count; | |
| static int pixelIndex; | |
| for (uint16_t i = 0; i < 10; i+=1) { | |
| if(pixel == i) { | |
| writePixel(i+1, | |
| 0, | |
| 0, | |
| 0 | |
| ); | |
| } | |
| else { | |
| // writePixel(i+1, 90,0,255); | |
| writePixel(i+1, | |
| 128*(1+sin(i/9.0 + j/10.3 )), | |
| 128*(1+sin(i/3.0 + f/20.9)), | |
| 128*(1+sin(i/6.0 + k/50.6)) | |
| ); | |
| } | |
| } | |
| writePixel(11,255,0,0); | |
| counts++; | |
| if(counts>MAX_COUNT) { | |
| counts = 0; | |
| pixel = (pixel+1)%maxPixel; | |
| } | |
| j = j + 1; | |
| f = f + 1; | |
| k = k + 2; | |
| } | |
| void setRed(){ | |
| for(int i=0; i<maxPixel; i++){ | |
| writePixel(i,255,0,0); | |
| } | |
| } | |
| void loop() { | |
| if(powerOn){ | |
| digitalWrite(POWER_PIN, HIGH); | |
| }else { | |
| digitalWrite(POWER_PIN, LOW); | |
| } | |
| if(currentPattern == 1) { | |
| identify(); | |
| } | |
| else if(currentPattern == 2) { | |
| colorCheck(); | |
| //color_loop(); | |
| } | |
| else if(currentPattern == 4) { | |
| pictureFrame(); | |
| } | |
| else if(currentPattern == 5){ | |
| setRed(); | |
| } | |
| else { | |
| countUp(); | |
| } | |
| } | |
| void serialEvent(){ | |
| if(Serial.available() > 0) { | |
| char command = Serial.read(); | |
| int parameter = Serial.parseInt(); | |
| if (command == COMMAND_POWER){ | |
| Serial.println(command); | |
| powerOn = !powerOn; | |
| } | |
| if(command == COMMAND_IDENTIFY) { | |
| if(parameter < 1 || parameter > maxPixel) { | |
| parameter = 1; | |
| Serial.print("Identifying pixel on channel: "); | |
| Serial.println(parameter); | |
| currentPixel = parameter; | |
| currentPattern = 5; | |
| } | |
| } | |
| else if(command == COMMAND_SETCOLOR1) { | |
| for(int i=0; i<maxPixel; i++){ | |
| writePixel(i,255,0,0); | |
| } | |
| } | |
| else if(command == COMMAND_SETCOLOR2) { | |
| for(int i=0; i<maxPixel; i++){ | |
| writePixel(i,0,255,0); | |
| } | |
| } | |
| else if(command == COMMAND_SETCOLOR3) { | |
| for(int i=0; i<maxPixel; i++){ | |
| writePixel(i,0,0,255); | |
| } | |
| } | |
| else if(command == COMMAND_PROGRAM) { | |
| if(parameter < 1 || parameter > maxPixel) { | |
| parameter = 1; | |
| } | |
| Serial.print("Programming pixel to address: "); | |
| Serial.println(parameter); | |
| programAddress(parameter); | |
| currentPixel = parameter; | |
| delay(100); | |
| writePixel(currentPixel,255,0,0); | |
| } | |
| else if(command == COMMAND_DISPLAY_PATTERN) { | |
| Serial.print("Displaying pattern: "); | |
| Serial.println(parameter); | |
| currentPattern = parameter; | |
| } | |
| else if(command == COMMAND_MAX_PIXELS) { | |
| Serial.print("Setting max pixel to: "); | |
| Serial.println(parameter); | |
| maxPixel = parameter; | |
| } | |
| else if(command == COMMAND_CONTROLLER_TYPE) { | |
| Serial.print("Setting controller type to: "); | |
| Serial.println(parameter); | |
| controllerType = parameter; | |
| } | |
| } | |
| } | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment