Introduction: Pull the Light - Light Module Using Neopixel & Pull Up Switch

Features of the Light module

  • Arduino Uno
  • Hardware & enclosure purchased from internet
  • Neopixel & Power supply borrowed from School of Informatics & Product Design
  • Light module controlled by power supply
  • All functions controlled via users interaction
  • Animation types of Neopixel strip: Rain type, Shower type, Spark lightning type, Pop type, Irregular type
  • The pull up switch is connected to the Neopixel strip and the animation changes when pulled Neopixel strip

Step 1: Before We Begin

Hello Instructables and Makers.

We started and interactive design project in terms of what would happen if we could feel the emotion of rain through animation of light. I thought that the user's sensibility would be maximized through an interface that pulls light directly.

Lest's get to work

Step 2: Parts Needed

Based on one Light Module

***Neopixels and Power supply were used with the support of our department.***

Electronics:

    1. Arduino Uno
    2. 3 color wire (Black, Red, any Color)
    3. 3pin connector ( Link to buy )
    4. Pull up switch 1 ( Link to buy )
    5. shrinking tube
    6. WS2812b addresable LED strip with 74 LED (Neopixel strip)*2
    7. Power supply (5V 350A) 1

    ***50 sets are needed for the Arduino, the Pull Switch and the NeoPixels.***

    Hardware:

      1. Acrylic bar 2t (10mm*1000mm) 1
      2. Acrylic board 5t(60mm*60mm) 1
      3. Foemax 10t (1200mm*1800mm) 1
      4. Black spray
      5. Cable tie
      6. String
      7. Hardboard
      8. Grid board

      Step 3: Connectivity and Building the Hardware

      First,we need the Acrylic Cutting to make one lighting module.

      • As a means to experience the animation of light, draft a lighting module that is fixed by attaching 74 LEDs in the form of a neopixel strip onto a 2mm thick acrylic bar with a 1M area. We have produced two types of lighting modules: typical linear and spiral.
      • For linear types, the existing neopixel strips can be held and secured, but spiral types require manual operation. Each of the 74 LED is split into pieces, attached to a spiral acrylic, and bonded together with lead.

      Attach the Neopixel strip to the acrylic and secure each strip to prevent it from being spread by heat, or tie with a thin fishing line. In the case of linear type, the sphere needed to be pulled onto the end of the module was installed to design the aesthetic look and we finished the ping pong ball with a black spray. Then they drilled a small hole in the ping pong ball and connected it with a rope. The next most important part, the switch and the neopixel, is connected as shown. The switch is then secured to the ceiling shelf.

      In the case of spiral type, there is a risk that direct pulling of the spiral module could break the acrylic under pressure, so the pull section(Input) and the module(Output) were separated. To maximize the light falling, modules were installed vertically on the ceiling, linear modules were fixed to the air, spirals were fixed directly to the ceiling. And we connected the ping pong ball and the switch to the fishing line so it could be operated.

      The acrylic cutting as shown in the drawing above is required to secure the switch to the shelf. A 6cm square shaped switch is approximately 5mm thick, with the switch centered and a cable tie inserted through holes on both sides to secure the switch firmly. A circular hole at the bottom of the center exposes the pull of the switch, below which a three wire cable is pulled out and connected to the cable terminal of the module. And similarly, through a hole in the four corners, the shelf and acrylic are secured with cable ties. As described above, the linear module is connected directly to the pull, but the spiral module connects the pin and the switch separately.

      Step 4: Create Using 50 Light Modules

      We've designed a user experience for richer light by deploying a total of 50 modules.

      We had a shelf that was 1,800mm wide and 1,200mm long, and we connected each switch and module so that you could experience the rain and rain environment that we initially planned, and we had each module stand alone to enable multi-tasking.

      Depending on the design drawing, a round hole was drilled into the foemax to hide the installation and to make sure that the connected area of the LED module is not visible. Since the distance from the acrylic board to the LED module connection where the switch is attached is about 1cm, a 1cm thick foemax was used.

      The metal square frame was used to hold the installation together with screws and cable ties while maintaining overall weight and balance. If the length of the exposed connections is more than that when the maker tries, the thicker board is inefficient and other structures are recommended.

      To facilitate the user's experience at eye level, the completed installation is placed on a support of approximately 2m high, but the caution is that it is very cumbersome to install the embedded LED module with the switch, so all connections should be removed. We climbed up the ladder and connected the module with the installation fixed onto the support.

      The most important part of this whole process is to ensure that the work is done securely and fully secured to ensure that the experience is made possible in a safe environment.

      A total of 10 arduino and 50 LED modules were used and five LED modules were connected per arduino for more efficient and seamless multi-tasking. See attached blueprint for details. Neopixel multi-tasking coding using the full switch according to the design diagram will be discussed in detail in the next step.

      Step 5: Arduino Coding & Wiring

      Wiring

      • 50 modules were connected according to the layout of step 4.
      • Each module was divided into 10 sets of 50 modules to enable multi-tasking and to provide a clear connection.
      • As shown in the set 1 image above, five modules were connected to a single arduino, and the 5v pins of neopixel were tied together at once to connect the power supply.
      • The GND of the neopixels and the switches were also tied together and, for ease of perception, the switches were plugged into pins 2, 3, 4, 5, 6 and the neopixels were plugged into pins 9,10,11,12,13.
      • The switches and neopixels were connected in 2-9, 3-10, 4-11, 5-12, 6-13 ways, respectively.
      • It should be noted that since the connections of the lines are complex and there is a risk of fire due to short circuits, the shrinking tube was heated to ensure that the weak parts did not break.

      Neopixel multi-tasking coding with pull up switch

      • 5 light animation (Rain type, Shower type, Spark lightning type, Pop type, Irregular type)
      <p>#include <adafruit_neopixel.h><br></adafruit_neopixel.h></p><p>/*사용하고자하는 패턴을 추가함*/ 
      enum  pattern { NONE, RAINBOW_CYCLE, THEATER_CHASE, COLOR_WIPE, SCANNER, FADE, TWINKLE, STAR, RAINBOWSPARKLE, METEOR, LIGHT, BLOSSOM };
      /*네오 픽셀을 방향을 설정함*/ 
      enum  direction { FORWARD, REVERSE };</p><p>/*패턴의 클래스를 입력함*/ 
      class NeoPatterns : public Adafruit_NeoPixel
      {
      /* 패턴을 추가하고 업데이트하기위한 함수*/ 
        public:
          pattern  ActivePattern;  
      /*클레스 함수에 패턴의 방향을 입력*/ 
          direction Direction;  </p><p>       
      /*변수 Interval을 추가*/    
          unsigned long Interval;   
      /*변수 lastUpdate를 추가*/ 
          unsigned long lastUpdate; 
      /*변수 Color1, Color2를 추가*/     
          uint32_t Color1, Color2;  
      /*변수 TotalSteps를 추가*/ 
          uint16_t TotalSteps;
      /*변수 Index를 추가*/       
          uint16_t Index;  </p><p>    
      /*패턴을 완료했을시 다시 불러오는 함수*/     
          void (*OnComplete)();  
      /*네오패턴에서 네오픽샐의 갯수, 핀번호, 타입, 콜백을 불러오는 함수*/ 
          NeoPatterns(uint16_t pixels, uint8_t pin, uint8_t type, void (*callback)())
            : Adafruit_NeoPixel(pixels, pin, type){
            OnComplete = callback;
          }</p><p>/*패턴을 업데이트 하기위한 케이스 구문*/  
          void Update(){
      /*패턴의 시간 설정. 멀티태스킹을 구현하는 구문*/      
            if ((millis() - lastUpdate) > Interval){
              lastUpdate = millis();
      /*ActivePattern의 스위치구문*/           
              switch (ActivePattern)
              {
      /*case RAINBOW_CYCLE에서는 RainbowCycleUpdate를 실행하라*/ 
                case RAINBOW_CYCLE:
                  RainbowCycleUpdate();
      /*case RAINBOW_CYCLE에서 나와라*/  
                  break;</p><p>/*case THEATER_CHASE에서는 TheaterChaseUpdate를 실행하라*/ 
                case THEATER_CHASE:
                  TheaterChaseUpdate();
      /*case THEATER_CHASE에서 나와라*/ 
                  break;</p><p>/*case COLOR_WIPE에서는 ColorWipeUpdate를 실행하라*/             
                case COLOR_WIPE:
                  ColorWipeUpdate();
      /*case COLOR_WIPE에서 나와라*/ 
                  break;
                  
      /*case SCANNER에서는 ScannerUpdate를 실행하라*/ 
                case SCANNER:
                  ScannerUpdate();
      /*case SCANNER에서 나와라*/ 
                  break;</p><p>/*case FADE에서는 FadeUpdate를 실행하라*/          
                case FADE:
                  FadeUpdate();
      /*case FADE에서 나와라*/ 
                  break;</p><p>/*case TWINKLE에서는 TwinkleUpdate를 실행하라*/          
                case TWINKLE:
                  TwinkleUpdate();
      /*case TWINKLE에서 나와라*/ 
                  break;</p><p>/*case STAR에서는 StarUpdate를 실행하라*/    
                case STAR:
                  StarUpdate();  
      /*case STAR에서 나와라*/ 
                  break;</p><p>/*case RAINBOWSPARKLE에서는 RainbowsparkleUpdate를 실행하라*/ 
                case RAINBOWSPARKLE:
                  RainbowsparkleUpdate();
      /*case RAINBOWSPARKLE에서 나와라*/ 
                  break;
                
      /*case METEOR에서는 MeteorUpdate를 실행하라*/ 
                case METEOR:
                  MeteorUpdate(); 
      /*case METEOR에서 나와라*/ 
                  break;</p><p>/*case LIGHT에서는 LightUpdate를 실행하라*/ 
                 case LIGHT:
                  LightUpdate();
      /*case LIGHT에서 나와라*/ 
                  break; </p><p>/*case BLOSSOM에서는 BlossomUpdate를 실행하라*/ 
                 case BLOSSOM:
                  BlossomUpdate();   
      /*case  BLOSSOM에서 나와라*/    
                  break;      
              }
            }
          }</p><p>/*패턴의 방향을 설정하는 구문*/   </p><p>/*Index를 증가시키고 초기화하는 함수*/
          void Increment(){
      /*만약 정방향이면 인덱스를 증가시켜라*/      
            if (Direction == FORWARD){
              Index++;
      /*만약 인덱스가 전체 네오픽셀 구동 갯수와 같거나 많다면 0으로 초기화시켜라*/        
              if (Index >= TotalSteps){
                Index = 0;
      /*패턴을 완료시키는 함수*/    
                if (OnComplete != NULL){
                  OnComplete(); 
                }
              }
            }</p><p>      
      /*만약 정방향이 아니면 인덱스를 감소시켜라*/       
            else{
              --Index;
      /*만약 인덱스가 전체 네오픽셀 구동 갯수와 같거나 적다면 전체 구동 갯수에서 1을빼라*/ 
              if (Index <= 0){
                Index = TotalSteps - 1;
      /*패턴을 완료시키는 함수*/         
                if (OnComplete != NULL){
                  OnComplete(); 
                }
              }
            }
          }</p><p>/*반대방향으로 움직이게하는 함수*/    
          void Reverse(){
      /*애니메이션 함수에 Reverse를 썼을시, 만약 방향이 정방향이면*/        
            if (Direction == FORWARD){
      /*방향은 그와 반대이며 전체 구동 갯수에서 1일빼라*/            
              Direction = REVERSE;
              Index = TotalSteps - 1;
            }
      /*그 외의 방향이 정방향이면 인덱스를 0으로 설정해라*/      
            else{
              Direction = FORWARD;
              Index = 0;
            }
          }</p><p>/*애니메이션을 설정하는 함수들*</p><p>*RainbowCycle의 시간과 방향을 입력*/   
          void RainbowCycle(uint8_t interval, direction dir = FORWARD){
      /*실행되는 패턴은 RainbowCycle임*/
            ActivePattern = RAINBOW_CYCLE;
      /*시간은 void RainbowCycle()안에 입력되는 interval과 같음*/      
            Interval = interval;
      /*총 구동갯수는 255임*/ 
            TotalSteps = 255;
      /*인덱스는 0으로 설정함*/ 
            Index = 0;
      /*방향은 void RainbowCycle()안에 입력되는 dir = FORWARD과 같음*/        
            Direction = dir;
          }</p><p>/*RainbowCycle를 업데이트했을 경우*/ 
          void RainbowCycleUpdate(){
      /*변수 i가 네오픽셀 개수보다 작으면 i를 증가시켜라*/ 
            for (int i = 0; i < numPixels(); i++){
      /*변수 i가 증가함과 동시에 RGB의 무지개 컬러로 변화하면서 작동해라 */       
              setPixelColor(i, Wheel(((i * 256 / numPixels()) + Index) & 255));
            }
      /*애니메이션을 보여주는 함수 */          
            show();
            Increment();
          }</p><p>/*TheaterChase의 컬러와 시간 방향을 입력*/   
          void TheaterChase(uint32_t color1, uint32_t color2, uint8_t interval, direction dir = FORWARD){
      /*실행되는 패턴은 RTHEATER_CHASE*/
            ActivePattern = THEATER_CHASE;
      /*시간은 void TheaterChase()안에 입력되는 interval과 같음*/  
            Interval = interval;
      /*총 구동갯수는 numPixels갯수임*/ 
            TotalSteps = numPixels();
      /*컬러 1,2를 설정*/ 
            Color1 = color1;
            Color2 = color2;
      /*인덱스는 0으로 설정함*/ 
            Index = 0;
      /*방향은 void TheaterChase()안에 입력되는 dir = FORWARD과 같음*/
            Direction = dir;
          }</p><p>/*TheaterChase를 업데이트했을 경우*/    
          void TheaterChaseUpdate(){
      /*변수 i가 네오픽셀 개수보다 작으면 i를 증가시켜라*/ 
            for (int i = 0; i < numPixels(); i++){
      /*만약 변수 i에 인덱스를 더해서 3으로 나눈 것이 0과 같다면 i를 Color로 변환시켜라*/   
              if ((i + Index) % 3 == 0){
                setPixelColor(i, Color1);
              }
      /*그렇지 않다면 i를 Color로 변환시켜라*/    
              else{
                setPixelColor(i, Color2);
              }
            }
      /*애니메이션을 보여주는 함수 */   
            show();
            Increment();
          }</p><p>/*ColorWipe의 컬러와 시간 방향을 입력*/
          void ColorWipe(uint32_t color, uint8_t interval, direction dir = FORWARD){
      /*실행되는 패턴은 COLOR_WIPE*/
            ActivePattern = COLOR_WIPE;
      /*시간은 void ColorWipe()안에 입력되는 interval과 같음*/  
            Interval = interval;
      /*총 구동갯수는 numPixels갯수임*/    
            TotalSteps = numPixels();
      /*컬러 1을 설정*/
            Color1 = color;
      /*인덱스는 0으로 설정함*/  
            Index = 0;
      /*방향은 void ColorWipe()안에 입력되는 dir = FORWARD과 같음*/
            Direction = dir;
          }</p><p>/*ColorWipeUpdate를 업데이트했을 경우*/ 
          void ColorWipeUpdate(){
      /*index를 컬러1로 변환시켜라*/ 
            setPixelColor(Index, Color1);
      /*애니메이션을 보여주는 함수 */   
            show();
            Increment();
          }</p><p>/*Scanner의 컬러와 시간을 입력*/   
          void Scanner(uint32_t color1, uint8_t interval){
      /*실행되는 패턴은 SCANNER*/
            ActivePattern = SCANNER;
      /*시간은 void Scanner()안에 입력되는 interval과 같음*/   
            Interval = interval;
      /*구동갯수는 총갯수에서 1을빼고 2를 곱해라*/      
            TotalSteps = (numPixels() - 1) * 2;
      /*컬러 1을 설정*/ 
            Color1 = color1;
      /*인덱스는 0으로 설정함*/  
            Index = 0;
          }</p><p>/*ScannerUpdate를 업데이트했을 경우*/    
          void ScannerUpdate(){
      /*변수 i는 영이고 총갯수보다 작을경우 i를 증가시켜라*/  
            for (int i = 0; i < numPixels(); i++){
      /*만약 변수 i가 인덱스와 같다면 i를 color1로 변환시켜라*/ 
              if (i == Index){
                setPixelColor(i, Color1);
              }
      /*그렇지 않다면 변수 i를 전체구동갯수에서 인덱스를 뺀값과 같다 */  
              else if (i == TotalSteps - Index){
                setPixelColor(i, Color1);
              }
      /*그 밖에는 i를 디밍시켜라 i의 값만큼 */  
              else {
                setPixelColor(i, DimColor(getPixelColor(i)));
              }
            }
      /*애니메이션을 보여주는 함수 */  
            show();
            Increment();
          }</p><p>/*Scanner의 컬러1,2와 스텝, 시간, 방향을 입력*/   
          void Fade(uint32_t color1, uint32_t color2, uint16_t steps, uint8_t interval, direction dir = FORWARD){
      /*실행되는 패턴은 FADE*/
            ActivePattern = FADE;
      /*시간은 void Fade()안에 입력되는 interval과 같음*/  
            Interval = interval;
      /*구동갯수는 스텝값임*/  
            TotalSteps = steps;
      /*컬러 1, 2를 설정*/
            Color1 = color1;
            Color2 = color2;
      /*인덱스는 0으로 설정함*/      
            Index = 0;
      /*방향은 void Fade()안에 입력되는 dir = FORWARD과 같음*/
            Direction = dir;
          }
          
      /*FadeUpdate를 업데이트했을 경우*/    
          void FadeUpdate(){
      /*변수 red값은 다음과 같음*/  
            uint8_t red = ((Red(Color1) * (TotalSteps - Index)) + (Red(Color2) * Index)) / TotalSteps;
      /*변수 green값은 다음과 같음*/  
            uint8_t green = ((Green(Color1) * (TotalSteps - Index)) + (Green(Color2) * Index)) / TotalSteps;
      /*변수 blue값은 다음과 같음*/     
            uint8_t blue = ((Blue(Color1) * (TotalSteps - Index)) + (Blue(Color2) * Index)) / TotalSteps;
      /*위의 red, green, blue 값으로 컬러를 셋팅함*/  
            ColorSet(Color(red, green, blue));
      /*애니메이션을 보여주는 함수 */ 
            show();
            Increment();
          }</p><p>/*모든 네오픽셀을 끄는 구문*/    
             void alloff() {
      /*총 네오픽셀 갯수는 74개이며*/            
            int NPIXEL = 74;
      /*변수 i가 증가하며 모든 네오픽셀의 컬러 값을 0으로 변환함*/       
            for (int i = 0; i < NPIXEL; i++) {
              setPixelColor(i, 0, 0, 0);
            }
          }</p><p>/*Twinkle의 컬러1와 시간을 입력*/   
           void Twinkle(uint32_t color1, uint8_t interval){
      /*실행되는 패턴은 TWINKLE*/
            ActivePattern = TWINKLE;
      /*시간은 void Twinkle()안에 입력되는 interval과 같음*/     
            Interval = interval;
      /*컬러 1를 설정*/
            Color1 = color1;
      /*총 구동갯수는 numPixels갯수임*/
            TotalSteps = numPixels();
            Index = 0;
          }</p><p>/*TwinkleUpdate를 업데이트했을 경우*/    
          void TwinkleUpdate(){
      /*모든 네오픽셀의 컬러를 0으로 셋팅*/ 
            setAll(0, 0, 0);
      /*변수 Pixel은 random 74*/ 
            int Pixel = random(74);
      /*random 74개에서 2로나눈 수를 랜덤하게 켜라*/  
            setPixelColor(Pixel/2, 50, 100, 255);
            setPixelColor(Pixel, 250, 255, 250);
            setPixelColor(Pixel/2, 200, 250, 255);
            setPixelColor(Pixel, 255, 255, 255);
            setPixelColor(Pixel, 250, 230, 250);
            setPixelColor(Pixel/2, 150, 200, 255);
      /*애니메이션을 보여주는 함수 */  
            show(); 
      /*랜덤하게 끄는 함수 */ 
            setPixelColor(Pixel, 0, 0, 0);
      /*애니메이션을 보여주는 함수 */
            show(); 
            Increment();
          }</p><p>/*Star의 컬러1 값을 입력*/   
          void Star(uint32_t color1){
      /*실행되는 패턴은 STAR*/
            ActivePattern = STAR;
      /*시간은 void Star()안에 입력되는 interval과 같음*/     
            Interval = Interval;
      /*총 구동갯수는 numPixels갯수임*/   
            TotalSteps = numPixels();
      /*컬러 1을 설정*/
            Color1 = color1;
            Index = 0;
          }</p><p>/*StarUpdate를 업데이트했을 경우*/ 
          void StarUpdate(){
      /*인덱스와 컬러를 셋팅*/   
            setPixelColor(Index, Color1);
            show();
      /*변수 i가 0이고 구동 갯수보다 작으면 i를 감소시킴 = 한칸씩 이동하는 애니메이션*/ 
            for (int i = 0; i < numPixels(); i--) {
              setPixelColor(i, Color(0, 0, 0));
            }
      /*애니메이션을 보여주는 함수 */
            Increment();
          }</p><p>/*Rainbowsparkle의 시간과 방향을 입력*/  
         void Rainbowsparkle(uint8_t interval, direction dir = FORWARD){
      /*실행되는 패턴은 RAINBOWSPARKLE*/
            ActivePattern = RAINBOWSPARKLE;
      /*시간은 void Rainbowsparkle()안에 입력되는 interval과 같음*/ 
            Interval = interval;
      /*총 구동갯수는 numPixels갯수임*/ 
            TotalSteps = numPixels();
            Index = 0;
      /*방향은 void Rainbowsparkle()안에 입력되는 direction과 같음*/       
            Direction = dir;
          }</p><p>/*RainbowsparkleUpdate를 업데이트했을 경우*/ 
          void RainbowsparkleUpdate(){
      /*변수 i가 0이고 구동 갯수보다 작으면 i값을 증가하는데*/    
            for (int i = 0; i < numPixels(); i++){
      /*변수 i가 0이고 구동 갯수보다 작으면 i값을 증가하는데*/  
              if ((i + Index) % 2 == 0){
              uint32_t c = random(255);
              setPixelColor(i, c);
              }
              else{
                setPixelColor(i, random(255));
              }
            }
      /*애니메이션을 보여주는 함수 */
            show();
            Increment();
          }
         
      /*Meteor의 시간과 방향을 입력*/  
          void Meteor(uint32_t color1){
      /*실행되는 패턴은 METEOR*/
            ActivePattern = METEOR;
      /*시간 설정*/ 
            Interval = Interval;
      /*총 구동갯수는 numPixels갯수에서 1일뺀 후, *2를 한것과 같음*/   
            TotalSteps = (numPixels()-1) * 2;
      /*컬러 1을 설정*/
            Color1 = color1;
            Index = 0;
          }</p><p>/*MeteorUpdate를 업데이트했을 경우*/ 
          void MeteorUpdate(){
            for (int i = 0; i < numPixels(); i++){
              if (i == Index){
                setPixelColor(i, 100, random(255), 255);
              }
              else {
                setPixelColor(i, DimColor(getPixelColor(i)));
              }
            }
      /*애니메이션을 보여주는 함수 */  
            show();
            Increment();
          }</p><p>/*Light의 시간과 방향을 입력*/  
          void Light(uint32_t color1){
      /*실행되는 패턴은 LIGHT*/ 
            ActivePattern = LIGHT;
      /*시간 설정*/  
            Interval = Interval;
      /*총 구동갯수는 numPixels갯수에서 1일뺀 후, *2를 한것과 같음*/  
            TotalSteps = (numPixels()-1) * 2;
      /*컬러 1을 설정*/
            Color1 = color1;
            Index = 0;
          }</p><p> /*LightUpdate를 업데이트했을 경우*/   
          void LightUpdate(){
            for (int i = 0; i < numPixels(); i++){
              if (i == TotalSteps - Index){
                setPixelColor(i, 150, random(200), 40);
              }
              else {
                setPixelColor(i, DimColor(getPixelColor(i)));
              }
            }
      /*애니메이션을 보여주는 함수 */
            show();
            Increment();
          }</p><p>/*Blossom의 시간과 방향을 입력*/  
          void Blossom(uint32_t color1){
      /*실행되는 패턴은 BLOSSOM*/      
            ActivePattern = BLOSSOM;
      /*시간 설정*/
            Interval = Interval;
      /*총 구동갯수는 numPixels갯수에서 1일뺀 후, *2를 한것과 같음*/
            TotalSteps = (numPixels()-1) * 2;
      /*컬러 1을 설정*/
            Color1 = color1;
            Index = 0;
          }</p><p> /*BlossomUpdate를 업데이트했을 경우*/     
          void BlossomUpdate(){
            for (int i = 0; i < numPixels(); i++){
              if (i == TotalSteps - Index){
                setPixelColor(i, 255, random(255), 100);
              }
              else {
                setPixelColor(i, DimColor(getPixelColor(i)));
              }
            }
      /*애니메이션을 보여주는 함수 */
            show();
            Increment();
          }</p><p>////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      /*네오픽셀의 켜지는 위치와 색을 지정해주는 함수 */
          void setAll(byte red, byte green, byte blue) {
            for(int i = 0; i < numPixels(); i++ ) {
              setPixelColor(i, red, green, blue); 
            }
            show();
          }</p><p>/*네오픽셀의 디밍, 즉 밝기를 조절하는 함수*/
          uint32_t DimColor(uint32_t color){
            // Shift R, G and B components one bit to the right
            uint32_t dimColor = Color(Red(color) >> 1, Green(color) >> 1, Blue(color) >> 1);
            return dimColor;
          }</p><p>/*모든 네오픽셀의 칼라를 조절*/
          void ColorSet(uint32_t color){
            for (int i = 0; i < numPixels(); i++){
              setPixelColor(i, color);
            }
            show();
          }</p><p>/*레드값을 불러옴*/
          uint8_t Red(uint32_t color){
            return (color >> 16) & 0xFF;
          }
      /*그린값을 불러옴*/
          uint8_t Green(uint32_t color){
            return (color >> 8) & 0xFF;
          }
      /*블루값을 불러옴*/
          uint8_t Blue(uint32_t color){
            return color & 0xFF;
          }</p><p>/*Rainbow 컬러를 불러옴*/
          uint32_t Wheel(byte WheelPos){
            WheelPos = 255 - WheelPos;
            if (WheelPos < 85){
              return Color(255 - WheelPos * 3, 0, WheelPos * 3);
            }
            else if (WheelPos < 170){
              WheelPos -= 85;
              return Color(0, WheelPos * 3, 255 - WheelPos * 3);
            }
            else{
              WheelPos -= 170;
              return Color(WheelPos * 3, 255 - WheelPos * 3, 0);
            }
          }
      };</p><p>/*strip을 불러오기위한 함수 / *사용하는 스트립별로 모두 지정해주어야함*/
      void strip1Complete();
      void strip2Complete();
      void strip3Complete();
      void strip4Complete();
      void strip5Complete();</p><p>/*네오픽셀의 갯수 설정*/
      #define NUMPIXELS 74
      /*사용하는 버튼의 갯수 설정*/
      #define B_NUM  5
      /*Import strip1~5까지, 갯수는 74개 스트립 연결핀은 strip1은 8 ~ strip5까지12*/
      NeoPatterns strip1(74, 8, NEO_GRB + NEO_KHZ800, &strip1Complete);
      NeoPatterns strip2(74, 9, NEO_GRB + NEO_KHZ800, &strip2Complete);
      NeoPatterns strip3(74, 10, NEO_GRB + NEO_KHZ800, &strip3Complete);
      NeoPatterns strip4(74, 11, NEO_GRB + NEO_KHZ800, &strip4Complete);
      NeoPatterns strip5(74, 12, NEO_GRB + NEO_KHZ800, &strip5Complete);
      /*배열을 사용한 연결 버튼핀 설정*/
      const int buttonPin[B_NUM] = {2, 3, 4, 5, 6}; 
      /*배열을 사용하여 버튼 상태를 지정해줌*/
      int buttonState[B_NUM];
      /*2번핀부터 6번핀까지 상태는 순서대로 LOW임*/            
      int lastButtonState[B_NUM] = {LOW, LOW, LOW, LOW, LOW}; 
      /*2번핀부터 6번핀까지 버튼 카운터를 초기화시킴*/     
      int buttonCounter[B_NUM] = {0, 0, 0, 0, 0};
      /*2번핀부터 6번핀까지 최대 버튼 카운터는 5임*/     
      int buttonCounterMax = 5;
      /*모든 버튼핀을 읽일수있도록 변수 추가*/  
      int reading[B_NUM];
      unsigned long lastDebounceTime[B_NUM] = {0, 0, 0, 0, 0}; 
      /*모든 버튼핀을 읽는 시간간격은 delay50과 같음*/ 
      unsigned long debounceDelay = 50;</p><p>void setup(){
      /*복잡하게 저항 연결이 필요없도록 인풋 풀업방식의 버튼설정 : GND - 5V(Connect to Pin number)*/  
            for (int i = 0; i < B_NUM ; i++) {
          pinMode(buttonPin[i], INPUT_PULLUP);
        }
          Serial.begin(9600);
      /*스트립 1~5를 셋팅*/    
        strip1.begin();
        strip2.begin();
        strip3.begin();
        strip4.begin();
        strip5.begin();</p><p>  //strip1.TheaterChase(strip1.Color(255, 0, 255), strip1.Color(255, 50, 0), 20, FORWARD);</p><p>}</p><p>/*버튼 카운터 변수값은 5임*/ 
      int counter = 5;
      void loop(){
      /*버튼 수보다 i가 작으면 i를 증가시키고*/ 
        for (int i = 0; i < B_NUM; i++) {
      /*i값은 각각의 버튼을 읽는 것과 같다.*/ 
          reading[i] = digitalRead(buttonPin[i]);
          if (reading[i] != lastButtonState[i]) {
      /*iDelay값을 없애기위한 함수.*/
            lastDebounceTime[i] = millis();
          }
          if ((millis() - lastDebounceTime[i]) > debounceDelay) {
            if (reading[i] != buttonState[i]) {
              buttonState[i] = reading[i];
              buttonCounter[i]++;
      /*버튼 카운팅이 위에서 설정한 Max값 5를 넘으면 0으로 초기화 시켜라.*/
              if (buttonCounter[i] > buttonCounterMax)
                buttonCounter[i] = 0;
            }
          }    
          lastButtonState[i] = reading[i];
        }
      /*모든 스트립을 업데이트함.*/
        strip1.Update();
        strip2.Update();
        strip3.Update();
        strip4.Update();
        strip5.Update();</p><p>  /////SWITCH_2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      /*버튼 배열의 0번째 즉. 2번핀에 연결된 버튼을 활용하여 애니메이션이 구동되도록 하는 스위치 케이스 구문*/
        switch (buttonCounter[0]) {</p><p>/*첫번째 버튼을 활동시키면 구동되는 애니메이션*/    
          case 0 :
            strip1.ActivePattern = BLOSSOM;
      /*해당 애니메이션의 시간을 설정*/   
            strip1.Interval = 20;
      /*구동되는 네오픽셀의 갯수를 설정*/  
            strip1.TotalSteps = strip1.numPixels();
            break;
      /*두번째 버튼을 활동시키면 구동되는 애니메이션*/      
          case 1 :
             strip1.ActivePattern = RAINBOWSPARKLE;
            strip1.Interval = 50;
            strip1.TotalSteps = strip1.numPixels();
            break;
      /*세번째 버튼을 활동시키면 구동되는 애니메이션*/   
          case 2 :
            strip1.ActivePattern = SCANNER;
            strip1.Interval = 10;
            strip1.TotalSteps = (strip1.numPixels() - 1) * 2;
            break;
       
       /*네번째 버튼을 활동시키면 구동되는 애니메이션*/      
           case 3 :
            strip1.ActivePattern = TWINKLE;
            strip1.Interval = 1;
            strip1.TotalSteps = strip1.numPixels();
            break;
       /*다섯번째 버튼을 활동시키면 구동되는 애니메이션*/     
           case 4 :
            strip1.ActivePattern = METEOR;
            strip1.Interval = 10;
            strip1.TotalSteps = strip1.numPixels();
            break;
        }
        Serial.print(buttonCounter[0]);
        Serial.print(",  ");
        Serial.println(buttonCounter[1]);</p><p> /////SWITCH_3///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        
        switch (buttonCounter[1]) {
        
          case 0 :
            strip2.ActivePattern = STAR;
            strip2.Interval = 50;
            strip2.TotalSteps = strip2.numPixels();
            break;
            
          case 1 :
            strip2.ActivePattern = RAINBOWSPARKLE;
            strip2.Interval = 100;
            strip2.TotalSteps = strip2.numPixels();
            break;
        
          case 2 :
            strip2.ActivePattern = SCANNER;
            strip2.Interval = 20;
            strip2.TotalSteps = (strip2.numPixels() - 1) * 2;
            break;
       
          
           case 3 :
            strip2.ActivePattern = TWINKLE;
            strip2.Interval = 5;
            strip2.TotalSteps = strip2.numPixels();
            break;
           
           case 4 :
            strip2.ActivePattern = METEOR;
            strip2.Interval = 40;
            strip2.TotalSteps = strip2.numPixels();
            break;
        }
        Serial.print(buttonCounter[0]);
        Serial.print(",  ");
        Serial.println(buttonCounter[1]);</p><p> /////SWITCH_4///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        
        switch (buttonCounter[2]) {
          case 0 :
            strip3.ActivePattern = STAR;
            strip3.Interval = 50;
            strip3.TotalSteps = strip3.numPixels();
            break;
          case 1 :
            strip3.ActivePattern = RAINBOWSPARKLE;
            strip3.Interval = 100;
            strip3.TotalSteps = strip3.numPixels();
            break;
        
          case 2 :
            strip3.ActivePattern = SCANNER;
            strip3.Interval = 20;
            strip3.TotalSteps = (strip3.numPixels() - 1) * 2;
            break;
       
          
           case 3 :
            strip3.ActivePattern = TWINKLE;
            strip3.Interval = 5;
            strip3.TotalSteps = strip3.numPixels();
            break;
           
           case 4 :
            strip3.ActivePattern = METEOR;
            strip3.Interval = 25;
            strip3.TotalSteps = strip3.numPixels();
            break;
        }
        Serial.print(buttonCounter[0]);
        Serial.print(",  ");
        Serial.println(buttonCounter[1]);</p><p> /////SWITCH_5///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        
        switch (buttonCounter[3]) {
         
          case 0 :
            strip4.ActivePattern = STAR;
            strip4.Interval = 50;
            strip4.TotalSteps = strip4.numPixels();
            break;
         
          case 1 :
            strip4.ActivePattern = RAINBOWSPARKLE;
            strip4.Interval = 100;
            strip4.TotalSteps = strip4.numPixels();
            break;
        
          case 2 :
            strip4.ActivePattern = SCANNER;
            strip4.Interval = 20;
            strip4.TotalSteps = (strip4.numPixels() - 1) * 2;
            break;
       
          
           case 3 :
            strip4.ActivePattern = TWINKLE;
            strip4.Interval = 5;
            strip4.TotalSteps = strip4.numPixels();
            break;
           
           case 4 :
            strip4.ActivePattern = METEOR;
            strip4.Interval = 25;
            strip4.TotalSteps = strip4.numPixels();
            break;
        }
        Serial.print(buttonCounter[0]);
        Serial.print(",  ");
        Serial.println(buttonCounter[1]);</p><p> /////SWITCH_6///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        
        switch (buttonCounter[4]) {
          case 0 :
            strip5.ActivePattern = STAR;
            strip5.Interval = 50;
            strip5.TotalSteps = strip5.numPixels();
            break;
            
          case 1 :
            strip5.ActivePattern = RAINBOWSPARKLE;
            strip5.Interval = 100;
            strip5.TotalSteps = strip5.numPixels();
            break;
        
          case 2 :
            strip5.ActivePattern = SCANNER;
            strip5.Interval = 20;
            strip5.TotalSteps = (strip5.numPixels() - 1) * 2;
            break;
       
          
           case 3 :
            strip5.ActivePattern = TWINKLE;
            strip5.Interval = 5;
            strip5.TotalSteps = strip5.numPixels();
            break;
           
           case 4 :
            strip5.ActivePattern = METEOR;
            strip5.Interval = 25;
            strip5.TotalSteps = strip5.numPixels();
            break;
        }
        Serial.print(buttonCounter[0]);
        Serial.print(",  ");
        Serial.println(buttonCounter[1]);
      }</p><p>// strip1 Completion Callback
      void strip1Complete(){
        strip1.Color1 = strip1.Wheel(random(255));
        strip1.Color2 = strip1.Wheel(random(255));
        strip1.Index = 0;
      }</p><p>// strip2 Completion Callback
      void strip2Complete(){
        strip2.Color1 = strip2.Wheel(random(255));
        strip2.Color2 = strip2.Wheel(random(255));
        strip2.Index = 0;
      }</p><p>// strip3 Completion Callback
      void strip3Complete(){
        strip3.Color1 = strip3.Wheel(random(255));
        strip3.Color2 = strip3.Wheel(random(255));
        strip3.Index = 0;
      }</p><p>// strip4 Completion Callback
      void strip4Complete(){
        strip4.Color1 = strip4.Wheel(random(255));
        strip4.Color2 = strip4.Wheel(random(255));
        strip4.Index = 0;
      }</p><p>// strip5 Completion Callback
      void strip5Complete(){
        strip5.Color1 = strip5.Wheel(random(255));
        strip5.Color2 = strip5.Wheel(random(255));
        strip5.Index = 0;
      }</p>
      

      Step 6: Result and Making Film

      Thank you for your interest in our project although it's not enough.

      Make it Glow Contest 2018

      Participated in the
      Make it Glow Contest 2018