Self Automated Christmas Tree Advent Calendar

by sglau in Circuits > Microcontrollers

184 Views, 0 Favorites, 0 Comments

Self Automated Christmas Tree Advent Calendar

IMG-1645.jpg

Have you ever wanted a Christmas advent calendar that could be reusable? Have you ever forgotten to open a window on a specific day? Have you ever thought your advent calendar was not personable? Well, with my self automated Christmas calendar, your problems will be solved!

Supplies

Screenshot 2023-01-30 4.20.18 PM.png

For this project you will need:


1) A Particle Argon

2) Breadboard

3) PIR Senor

4) Neo Pixel Light Strip (3 lights)

5) Servo

6) A Few Pieces of Cardboard

7) Acrylic Paint

8) Scissors

9) OLED Display

10) Tape

The Code

Screenshot 2023-01-30 12.40.15 PM.png

When you begin your code, you will need to import a few libraries:

After you import the OLED and NeoPixel libraries, you will want to:

  • Define the number of lights on your light strip
  • Define the pin number for your lights
  • Define the pixel type for the lights
  • Define the width and height of the OLED display
  • Define the OLED reset
  • Initialize the PIR sensor and the sensor value

In the void setup() :

  • Set the brightness of the LED lights
  • Set the original position of the servo along with the pin it is connected to on your Argon

Here are a few documents that may help with programming Servos, the NeoPixel Lights, the OLED Display, and the PIR Sensor:

Full Code:

#include <Adafruit_SSD1306.h>

// This #include statement was automatically added by the Particle IDE.
#include <neopixel.h>

#define PIXEL_COUNT 3 // 24 Pixels on our ring
#define PIXEL_PIN D6 // Ring uses D6 as default pin
#define PIXEL_TYPE WS2812B // Ring uses WS2812 Pixels
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2


#define LOGO16_GLCD_HEIGHT 16 
#define LOGO16_GLCD_WIDTH 16 


#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif


Adafruit_NeoPixel light(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);


Servo myServo; // create Servo object to control a servo
int sensor = 5; 
 
int sensorVal =0;

int ledPin = 4;
int ledCount = 3;

//time a = 0;

void setup()
{
  // Has to be a PWM capable pin; In this case, D2.
  Serial.begin(9600);
  light.begin();
  light.setBrightness(5);
  myServo.attach(3);
  myServo.write(10);
  pinMode(sensor, INPUT);
   
  pinMode(7, OUTPUT);

   
  delay(2000);
  
  
  

 // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3D (for the 128x64)
 // init done
  
  display.display(); // show splashscreen
  delay(2000);
  display.clearDisplay(); 
 // Display static text
 
   

  // 0 and 180 are not numbers you usually try to use on these micro servos
   
}

unsigned long prevTime = 0;
void loop()
{
 //light.setPixelColor(2,(255,100,255));
  // colorWipe(light.Color(0, 255, 255), 50);
  //light.show();
  
   
  sensorVal = digitalRead(sensor);
  // Does nothing
  if(sensorVal==HIGH )
  {
    colorWipe(light.Color(255, 0, 255), 50);
    myServo.write(170);
    digitalWrite(7, HIGH);
     
    display.setTextSize(10);
    display.setTextColor(WHITE);
    display.setCursor(0,0);
    Time.zone(-6);
    display.println(Time.day());
    display.display();
     
     
  
  } 
  unsigned long currTime = millis();
  if(currTime - prevTime >= 8000 && sensorVal == HIGH)
   
  {
    prevTime = millis(); 
    delay(1000);
    display.clearDisplay();
    display.println(" ");
    display.display();
    myServo.write(10);
    delay(1000);
      
    
     
 
     
    

  }
   
  if(sensorVal==LOW)
  {
    //myServo.write(100);
     
    colorWipe(light.Color(0, 0, 0), 50);
    digitalWrite(7, LOW);
     
    return;
  }
   
 
   
}

void colorWipe(uint32_t c, uint8_t wait)
{
  for(uint16_t i=0; i<PIXEL_COUNT; i++)
  {
    light.setPixelColor(i,c);
    light.show();
    delay(wait);
  }
}

Utilizing the Time Class and Looping

Screenshot 2023-01-30 8.36.07 PM.png
Screenshot 2023-01-30 8.36.49 PM.png

In order to get the door of the advent calendar to open and close, I needed to find a way to delay the servo just enough for the person in front of the calendar to read the day it is. I utilized the time class in order to achieve this.

  • In the void loop(), I constantly checked if my PIR sensor detected motion or didn't
  • Once my PIR sensor did detect motion, my lights would trigger and my servo would turn to 170 degrees
  • Along with my servo moving and the lights turning on, my OLED display would utilize the time class to access the current day it is
  • However, the door of my advent calendar will not close immediately. I created another if statement that checked if eight seconds have passed since motion was last detected. If motion was detected for a second time, the OLED display will clear and the door will close

The Sensors

IMG_1649.jpg

How to wire the OLED Sensor:

  • For the OLED Sensor, you have four different wires: the VCC, the GND, the SCL, and the SDA.
  • I connected the VCC wire to my 3V pin on my Argon.
  • I connected the SCL and SDA wires respectfully to the SCL and SDA pins on my Argon.

How to wire the PIR Sensor:

  • For the PIR Sensor, you will also have three different wires: the VCC, the pin, and the GND.
  • In respect to my code, I connected the pin on my PIR Sensor to D5 on my Argon.
  • I connected the VCC wire to the positive rail on my breadboard which was connected to my USB pin on my Argon.

How to wire the Servo:

  • For the Servo, you will have three different wires: the VCC, the DIN, and the GND.
  • In respect to my code, I connected the DIN pin to D3 on my Argon.
  • I connected the VCC wire to the positive rail on my breadboard and connected that to my USB pin on my Argon.

How to wire the NeoPixel LED Lights:

  • For the NeoPixel LED Lights, I soldered three long solid core wires to GND, DIN, and VCC.
  • Like the rest, I connected the GND to the negative rail on my breadboard.
  • I connected the DIN pin to D6 on my Argon.
  • I connected my VCC to the USB on my Argon.

Assembly

IMG-1643.jpg
IMG-1642.jpg

For this step, you will need your:

  • Cardboard
  • Tape/ Hot Glue
  • Acrylic Paint
  • Your Sensors

Now that you have finished the wiring of your advent calendar, you can be creative when it comes to building how you want your advent calendar to look!

Tips

IMG-1644.jpg
IMG-1600.jpg

I have found in order to open the advent calendar door the easiest, I would need to elevate my servo ( mainly because of the shape I decided to go with for the calendar. )

  • I first punctured three holes on the left-hand side of the tree and made sure that the door could open easily with very minimum pressure.
  • Once I elevated my servo to be roughly the height of my calendar, I connected my twine from the fin of the servo diagonally to the lower right-hand corner of the calendar door. ( The angle the twine created was about 45 degrees )


Congrats! You made your own advent calendar! How exciting!