Chimney Climber

It’s time for Father Christmas to go under intensive training for his big day. Let’s try to get him up the chimney with 21 LEDs.

chimney_hero

You’ll need:

  • 20 red and white LEDs, 1 yellow LED
  • 1 push button
  • 3 shift registers
  • Arduino UNO
  • Breadboard + wires

1) Testing out the circuit
chimney_wiring
Today I’ll make my own version of this Ladder Game Instrucable, using 3 shift registers, 21 LEDs, a pushbutton and a lot of wiring!

For the wiring of shift registers, please refer to the Christmas Carols post from the 19th of December. Adding a third shift register, is exactly the same as adding a second one. And still 3 pins to control them.

Let’s first determine what lights need to be on and cycle through them. We want 2 consecutive lights maximum to be on at the same time, and be able to make the next one blink by turning it on and off.

That’s what the sequence for 1 shift register will look like:

int sequence [9][2] = {{0, 1}, {1,3}, {2,6}, {4,12}, {8,24},  {16,48}, {32, 96}, {64,192}, {128, 0}};

For each we store 1 light being lit up (multiples of 8), and a group of 2 consecutive lights being lit up (multiples of 3).
Then, in the loop, we cycle through this double array.

for (int i = 0; i <22; i++) {
    for (int j = 0; j < 2; j++){
        digitalWrite(latchPin, LOW);
        if(i < 5) {
          shiftOut(sequence[i+3][j]);
          shiftOut(0);
          shiftOut(0); 
        } else if(i == 5) {
         shiftOut(128);
         shiftOut(sequence[i-5][j]);
          shiftOut(0); 
        }else if(i > 5 && i < 13) {
         shiftOut(0);
         shiftOut(sequence[i-5][j]);
          shiftOut(0); 
        } else if(i == 13) {
         shiftOut(0);
         shiftOut(128);
         shiftOut(sequence[i-13][j]);
        }else if(i > 13 ) {
         shiftOut(0);
          shiftOut(0);
         shiftOut(sequence[i-13][j]); 
        } 
        
        digitalWrite(latchPin, HIGH);
        
        delay(100);
    }
    delay(100);
  }


2) Game logic
Now, we want to make an LED blink, and if the button was pressed while the LED was on, we want to move on to the next step, if not we start again from 0.
We need to avoid using a delay , as it will delay the reading of the button as well, instead we can set an interval for the blink using millis(). See the Blink Without Delay Arduino example.

That’s what our loop() function looks like now:

unsigned long currentMillis = millis();
      if(currentMillis - previousMillis > interval) {
        previousMillis = currentMillis;
        if(isOn == 0) {
         isOn =1; 
        } else {
         isOn = 0; 
        }
        
        turnLightOn();
      }
    
      checkButton();

The turning on and off of the lights is now handled outside the loop() function and looks like this:

void turnLightOn() {
       
      digitalWrite(latchPin, LOW);
      if(current_step < 5){
        if(current_step == 0 && isOn == 0){ 
          shiftOut(0);
          shiftOut(0);
          shiftOut(0);          
        } else {
          shiftOut(sequence[current_step+3][isOn]);
          shiftOut(0);
          shiftOut(0);
        
        }
      } else if (current_step == 5){
        shiftOut(transition[0][isOn]);
        shiftOut(sequence[current_step-5][isOn]);
        shiftOut(0);
      }
      else if (current_step>5 && current_step<12) {
        shiftOut(0);
        shiftOut(sequence[current_step-5][isOn]);
        shiftOut(0);       
      } else if (current_step==12){
        shiftOut(0);
        shiftOut(transition[0][isOn]);
        shiftOut(sequence[current_step-12][isOn]);
      
      }else if (current_step >12) {
        shiftOut(0);
        shiftOut(0);
        shiftOut(sequence[current_step-12][isOn]);
         if(current_step >19) {
           current_step = 0;
         }      
      }
      digitalWrite(latchPin, HIGH); 
}

Finally, we check the button’s input; you might want to read the Button State Change example, for more details. And here’s our final function:

void checkButton () {
  buttonState = digitalRead(buttonPin);
  if (buttonState != lastButtonState) {
    if (buttonState == HIGH) {
      if(isOn == 1){
        current_step++;
      } else {
       current_step = 0; 
      }
    } 
  }
  lastButtonState = buttonState;
}

And that’s it! We’ve got our game! To make it more tricky, you can even reduce the interval for each step.

Advertisements

One thought on “Chimney Climber

  1. Pingback: Claus-o-meter | 300 LEDs before Xmas

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s