WingScreen

From Noisebridge
Jump to: navigation, search

A side wing for teh screen

                                               /---------\
                                               |         |
                                  RGB LEDs --  *         |
                                           \   |         |
            .__                             -  *         |
    __  _  _|__| ____    ____                  |         |
    \ \/ \/ /  |/    \  / ___\                 *         |
     \     /|  |   |  \/ /_/  >                |         |
      \/\_/ |__|___|  /\___  /                 *         |
                    \//_____/                  |         |
   ('''' .|'', '||''| .|''|, .|''|, `||''|,    *         |
    `'') ||     ||    ||..|| ||..||  ||  ||    |         |
   `...' `|..' .||.   `|...  `|...  .||  ||.   *         |
                                               |         |
                                               *         |
                                               |         |
                                               *         |
                                               |         |
                                               *         |
                                               |         |
                      /---------\              *         |
                      |  micro  |              |         |
   USB-----|~|--------|  puter  |              *         |
                      \---------/              |         |
                             \                 *         |
                              \----------------|         |
                                               \---------/

StripSerial

Rainbeau test sketch for strip of addressable RGB LEDs.

Requires http://fastled.io/ library.

Updated with optional remote serial control from PC. Six26 (talk) 22:19, 12 September 2014 (UTC)

/*
*  Serial control interface for LED Strip
*
*    Updated: 20140923
*
*      H4X0r'd some shitz uppple
*        -- insert LED of some sort in A0 & Ground (in right direction)
*        -- pseudo lite senzor for mode switching
*        -- pseudo lite mode 8 noise floor graph
*
*    Command Summary:
*      MODE0 == Auto (Rainbeau)
*      MODE1 == Off
*      MODE2 == Remote (PC Control)
*      HH..H == Sequence of Hue values to apply to LEDs
*        Note: Set "MODE2" before sending hues
*      S     == Set saturation
*      MODE3 == Center Peak Rainbeau
*      MODE4 == Center Peak Pastel
*/

#include "FastLED.h"

// How many leds in your strip?
#define NUM_LEDS 72

// Spacing between pixel/color
#define HSV_PAD 4

// Delay between cycles
#define LOOP_DELAY 50

// Strip Data In (DI)
#define DATA_PIN 11

// Define the array of leds
CRGB leds[NUM_LEDS];

float counter = 0;
byte count = 0;

byte mode = 8;
byte hues[NUM_LEDS];
byte sat = 255;      // Saturation 0-255

boolean irEnable = true;
float ir = 0.0;

const int morse[27] = {2,0,1,0,1,0,2,0,0,2,0,2,0,2,0,0,2,0,1,0,1,0,2,0,0,0,0};

String inputString = "";

void setup() { 
  pinMode(13, OUTPUT);
  
  for (int i = 0; i < NUM_LEDS; i++)
  {
    hues[i] = 0;
  }
  
  /*
  *   Confirm GRB color ordering for WS2812b
  *        
  *    \/ \/ \/ \/ BIG FAT NOTE \/ \/ \/ \/
  *
  */
  FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
  
  // Max brightness 0-255 (64 ~< 100ma for 12 LEDs)
  FastLED.setBrightness(64);
  
  Serial.begin(9600);
  Serial.setTimeout(50);
  
  delay(200);
}

void loop() {
  int i;
  int v;
  float p;

  if (irEnable)
  {
    ir = max((analogRead(A0) / 1.0 - ir) * 0.5 - 10 + ir, ir);
    if (ir > 60)
    {
       // Bump mode
       ir = 0;
       if (++mode > 8)
         mode = 0;
    }
  }

  
  if (mode == 0)
  {
    // Rainbeau
    for (i = 0; i < NUM_LEDS; i++)
    {
      leds[i] = CHSV(count + (i * HSV_PAD), sat, 255);
    }
    FastLED.show();
    count++;
    
    delay(LOOP_DELAY);
  }
  else if (mode == 1)
  {
    // Off
    for (i = 0; i < NUM_LEDS; i++)
    {
      leds[i] = CRGB(0, 0, 0);
    }
    FastLED.show();
    
    delay(LOOP_DELAY);
  }
  else if (mode == 2)
  {
    // Remote
  }
  else if (mode == 3)
  {
    // Rainbeau
    for (i = 0; i < NUM_LEDS; i++)
    {
      // variable position dimming
      // Set 'p' to 0.0 - 1.0 so the ends are 0.0 and the center is 1.0
      p = (((NUM_LEDS / 2) - abs(i - (NUM_LEDS / 2.0)))) / (NUM_LEDS / 2.0);
      v = min(255, round(p * 255.0) + 64);

      // sin function added for oscillating color change
      counter += 0.000001337;
      count = sin(counter * 3.14 * 180) * 255 + (i * HSV_PAD);
      leds[i] = CHSV(count, sat, v);
    }
    FastLED.show();
    count++;
    
    delay(LOOP_DELAY);
  }
  else if (mode == 4)
  {
    // Rainbeau
    for (i = 0; i < NUM_LEDS; i++)
    {
      // variable position dimming
      // Set 'p' to 0.0 - 1.0 so the ends are 0.0 and the center is 1.0
      p = (((NUM_LEDS / 2) - abs(i - (NUM_LEDS / 2.0)))) / (NUM_LEDS / 2.0);
      v = min(255, round(p * 255.0) + 64);
      
      // sin function added for oscillating color change
      counter += 0.000001337;
      count = sin(counter * 3.14 * 180) * 255 + (i * HSV_PAD);
      leds[i] = CHSV(count, sat - (v/1.5), v);
    }
    FastLED.show();
    count++;
    
    delay(LOOP_DELAY);
  }
  else if (mode == 5)
  {
    // Monochrome/Peak
    for (i = 0; i < NUM_LEDS; i++)
    {
      p = (((NUM_LEDS / 2) - abs(i - (NUM_LEDS / 2.0)))) / (NUM_LEDS / 2.0);
      v = min(255, round(p * 255.0) + 16);
      leds[i] = CRGB(v, 0, 0); // CHSV(100, sat, v);
    }
    
    // leds[int(random(0, NUM_LEDS))] = CRGB(96,0,0);
    
    FastLED.show();
    count++;
    
    delay(LOOP_DELAY);
  }
  else if (mode == 6)
  {
    // count = 0;
    
    for (i = 0; i < NUM_LEDS; i++)
    {
      leds[i] = CHSV(morse[(i + count) % 27] == 1 ? 120 : 0, sat, morse[(i + count) % 27] == 0 ? 0 : 255);
    }
    FastLED.show();
    
    count++;
    
    delay(LOOP_DELAY);
  }
  else if (mode == 7)
  {
    byte r;
    
    for (i = 0; i < NUM_LEDS; i++)
    {
      // counter = sin(count * 3.14 * 180) * 255 + i;
      
      r = random(127, 255);      
      leds[i] = CRGB(r, random(0, 100) < 20 ? r : 0, 0);
    }
    // count++;
    
    FastLED.show();
    
    delay(LOOP_DELAY / 5);
  }
  else if (mode == 8)
  {
    // ir = max((analogRead(A0) / 1.0 - ir) * 0.5 - 10 + ir, ir);
    
    for (i = 0; i < NUM_LEDS; i++)
    {
      if (i < ir)
      {
        leds[i] = CHSV(0, 255, 255); // ir > 30 ? 127 : 32);
      }
      else
      {
        leds[i] = CHSV(66, 255, 32);
      }
    }
    
    // ir = min(0, ir - 1.337);
    
    FastLED.show();
    
    delay(LOOP_DELAY);
  }
  
  if (irEnable)
    ir = min(0, ir - 1.337);
}

void updateHues() {
  for (int i = 0; i < NUM_LEDS; i++)
  {
    leds[i] = CHSV(hues[i], 255, 255);
  }
  FastLED.show();
  
  // Toggle onboard LED
  digitalWrite(13, !digitalRead(13));
}

void serialEvent() {
  byte byteCount = 0;
  byte data;
  
  inputString = "";
  
  while(Serial.available())
  {
    data = Serial.read();
    inputString += (char)data;
    if (byteCount < NUM_LEDS)
    {
      hues[byteCount++] = data;
    }
    
    // Catch pending bits
    if (!Serial.available())
      delay(20);
  }
  
  if (inputString == "MODE0")
  {
    mode = 0;
  }
  else if (inputString == "MODE1")
  {
    mode = 1;
  }
  else if (inputString == "MODE2")
  {
    mode = 2;
  }
  else if (inputString == "MODE3")
  {
    mode = 3;
  }
  else if (inputString == "MODE4")
  {
    mode = 4;
  }
  else if (inputString == "NINJA")
  {
    mode = 5;
  }
  else if (inputString == "MORSE")
  {
    mode = 6;
  }
  else if (inputString.length() == NUM_LEDS)
  {
    updateHues();
  }
  else if (inputString.length() == 1)
  {
    sat = data;
  }
}

Desktop Emulator

HSV.jpg

See also: FlashDevelop


Main

package 
{
	import flash.display.Screen;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.geom.Rectangle;
	
	/**
	 * ...
	 * @author thex
	 */
	public class Main extends Sprite 
	{
		private var wing:Wing;
		
		public function Main():void 
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			
			initUI();
		}
		
		private function initUI():void
		{			
			var appBounds:Rectangle = stage.nativeWindow.bounds;
			var screen:Screen = Screen.getScreensForRectangle(appBounds)[0];
			var screenSize:Rectangle = screen.bounds;
			
			/* Set in compile config
			  stage.nativeWindow.x = 0;
			  stage.nativeWindow.y = 0;
			*/
			  
			stage.nativeWindow.width = screenSize.width;
			
			wing = new Wing(12, screenSize.width, stage.stageHeight);
			addChild(wing);
		}
		
	}
	
}

Wing

package  
{
	import flash.display.GradientType;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Matrix;
	import flash.utils.getTimer;
	
	/**
	 * ...
	 * @author thex
	 */
	public class Wing extends Sprite 
	{
		private var count:int = 0;
		private var dots:Array = new Array();
		
		public function Wing(dotCount:int, wingWidth:int, wingHeight:int ) 
		{
			trace("Wing: " + wingWidth.toString() + ", " + wingHeight.toString());
			
			var matrix:Matrix = new Matrix();
			matrix.createGradientBox(wingWidth, wingHeight, 1.571, 0, 0);			
			
			this.graphics.beginGradientFill(GradientType.LINEAR, [0x3f3f3f, 0x000000], [1, 1], [0, 220], matrix);
			this.graphics.drawRect(0, 0, wingWidth, wingHeight);
			
			count = dotCount;
			
			initDots();
			
			this.addEventListener(Event.ENTER_FRAME, frameHandler);
		}
		
		private function initDots():void
		{
			var dot:Dot;
			var xOff:Number = (width - (count * Dot.WIDTH)) / count;
			
			for (var i:int = 0; i < count; i++)
			{
				dot = new Dot();
				dot.x = i * (xOff + Dot.WIDTH) + (xOff/2);
				dot.y = height - Dot.HEIGHT;
				
				dot.draw(HSVColor.HSV2RGB(i * 30));
				
				addChild(dot);
				
				dots.push(dot);
			}
		}
		
		private function update():void
		{
			var dot:Dot;
			var hue:Number;
			
			var phase:Number = (getTimer() / 20);
			
			for (var i:int = 0; i < count; i++)
			{
				dot = dots[i];
				
				// Magiq time Rainbeau
				hue = i * 30 + phase;
				hue %= 360;
				
				dot.draw(HSVColor.HSV2RGB(hue));
			}
		}
		
		private function frameHandler(e:Event):void
		{
			update();
		}
		
	}

}

Dot

package  
{
	import flash.display.Sprite;
	import flash.filters.GlowFilter;
	
	/**
	 * ...
	 * @author thex
	 */
	public class Dot extends Sprite 
	{
		public static var WIDTH:int = 64;
		public static var HEIGHT:int = 16;
		
		private static var OFF_COLOR:int = 0xcfcfcf;
		
		private var glowFilter:GlowFilter;
		
		public function Dot() 
		{			
			draw(OFF_COLOR);
		}
		
		public function draw(color:int):void
		{
			this.graphics.beginFill(color);
			this.graphics.drawRect(0, 0, WIDTH, HEIGHT);
			
			glowFilter = new GlowFilter(color, 1, 96, 256, 24, 1);
			filters = [glowFilter];
		}
		
	}

}

HSVColor

package  
{
	/**
	 * ...
	 * @author thex
	 */
	public class HSVColor 
	{
		
		public function HSVColor() 
		{
			
		}
		
		public static function HSV2RGB(h:Number, s:Number = 1.0, v:Number = 1.0):int
		{
			/*
			 * 
			 *  Ported from:
			 *   http://www.cs.rit.edu/~ncs/color/t_convert.html
			 * 
			 *  h = 0-360
			 *  s = 0-1, v = 0-1
			 */
			
			var r:Number;
			var g:Number;
			var b:Number;
			
			var i:int;
			
			var f:Number;
			var p:Number;
			var q:Number;
			var t:Number;

			if( s == 0 ) {
				// achromatic (grey)
				r = g = b = v;
				return 256 * 256 * r + 256 * g + b;
			}

			h /= 60.0;			// sector 0 to 5
			i = Math.floor( h );
			f = h - i;			// factorial part of h
			p = v * ( 1 - s );
			q = v * ( 1 - s * f );
			t = v * ( 1 - s * ( 1 - f ) );

			switch( i ) {
				case 0:
					r = v;
					g = t;
					b = p;
					break;
				case 1:
					r = q;
					g = v;
					b = p;
					break;
				case 2:
					r = p;
					g = v;
					b = t;
					break;
				case 3:
					r = p;
					g = q;
					b = v;
					break;
				case 4:
					r = t;
					g = p;
					b = v;
					break;
				default:		// case 5:
					r = v;
					g = p;
					b = q;
					break;
			}
			
			r = Math.round(r * 255);
			g = Math.round(g * 255);
			b = Math.round(b * 255);
			
			return 256 * 256 * r + 256 * g + b;
		}
		
	}

}