Infineon Team
Published © MIT

Push a Button, Catch a Gift: Build Your Own Advent Calendar!

Experience the Joy of Christmas with a DIY Button-Activated Advent Calendar with the help of Arduino IDE & Infineon's XMC1100 Boot Kit.

IntermediateFull instructions provided8 hours277

Things used in this project

Hardware components

Boot Kit XMC1100 (Arduino shield compatible)
Infineon Boot Kit XMC1100 (Arduino shield compatible)
×1
High-Side-Switch Shield with PROFET +2 12V BTS700x-1EPP
Infineon High-Side-Switch Shield with PROFET +2 12V BTS700x-1EPP
×1
KIT XMC1300 IFX9201 Stepper Shield
Infineon KIT XMC1300 IFX9201 Stepper Shield
×1
Stepper Motor, Mini Step
Stepper Motor, Mini Step
used 40-42 Stepper Motor
×1
12V Lipo Battery
×1
DS3231 RTC Module
×1
Extruder for Stepper motor
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

3D Printer (generic)
3D Printer (generic)
Laser cutter (generic)
Laser cutter (generic)

Story

Read more

Custom parts and enclosures

Filament Holder

The 3D model where the PLA filaments go through

Tube Holder

This is the 3D model where the Teflon tubes are pushed through

Christmas Tree Design with Cuts

Ornaments from: https://de.freepik.com/vektoren-kostenlos/hand-gezeichnete-weihnachtskugeln-eingestellt_5861430.htm#query=christmas%20tree%20ornaments&position=17&from_view=search&track=ais&uuid=96f5f966-a7d0-486d-ac1c-0b3c24c63de8

Deco from: https://de.freepik.com/vektoren-kostenlos/packung-mit-schoenen-dekorativen-weihnachtsbordueren_1443492.htm#&position=0&from_view=search&track=ais&uuid=88ffe556-6cf4-409e-807c-30b433e31ea5

Schematics

Project Schematic

These are main components used in this project and their connections

Code

Motor Calibration

Arduino
This program is used to calibrate how many steps are required for each gift to drop which are written in the neededSteps array with an XMC4700 Relax Kit (because it has push buttons on it)
#include <IFX9201_XMC1300_StepperMotor.h>

#define DIR_PIN IFX9201_STEPPERMOTOR_STD_DIR		// Pin 9 is standard DIR Pin
#define STP_PIN IFX9201_STEPPERMOTOR_STD_STP		// Pin 10 is standard STP Pin
#define DIS_PIN IFX9201_STEPPERMOTOR_STD_DIS    // PIN 11 is standard DIS pin

#define btn 24

const int StepsPerRevolution = 200;
float speed=100;
int stpctr=0;
int steps=50;

Stepper_motor stpr = Stepper_motor(StepsPerRevolution, DIR_PIN, STP_PIN, DIS_PIN);

void setup() {
  Serial.begin(9600);
  
  // put your setup code here, to run once:
  stpr.begin();
  pinMode(btn,INPUT);
	// sets the speed at 10 RPM:
	stpr.setSpeed(speed);  
}

void loop() {
  // put your main code here, to run repeatedly:
  if(!digitalRead(btn))
  {
    stpr.enable();
    stpr.step(steps);// if parameter<0 => motor rotates counterclockwise
    // Serial.println("Motor rolling!");
    delay(50);
    stpctr+=steps;
    Serial.print("STEPS: ");
    Serial.println(stpctr);
  }
  else
  {
    stpr.disable();
  }
}

XMCEEPROM Library

Arduino
To use the EEPROM of and XMC1100 use this library
No preview (download only).

Advent Calendar

Arduino
This is the main code which is flashed on the XMC1100 Bootkit
#include <IFX9201_XMC1300_StepperMotor.h> //for motor control
#include <XMCEEPROMLib.h>                 //to know last date device was turned on
#include <Wire.h>                         //I2C communication for external Clock
#include <DS3231.h>                       //Library for external RTC module
#include <hss-shield-bts700x-ino.hpp>     //Library for High-side-switch shield

#define DIR_PIN IFX9201_STEPPERMOTOR_STD_DIR		// Pin 9 is standard DIR Pin
#define STP_PIN IFX9201_STEPPERMOTOR_STD_STP		// Pin 10 is standard STP Pin
#define DIS_PIN IFX9201_STEPPERMOTOR_STD_DIS		// Pin 11 is standard DIS Pin

using namespace hss                                                                       ;

/** Creation of the hss board object */
Bts700xShieldIno HSS = Bts700xShieldIno(&BTS7002)                                         ;

Error_t err = OK                                                                          ;

//Kill Switch
int switch_no = 4                                                                         ;

// change this to fit the total number of steps per revolution (SPR) for your motor
const int StepsPerRevolution = 200                                                        ;  

//Array to save how many steps required for a day's gift to drop
//WOULD BE BETTER TO CALIBRATE THAN TO CALCULATE
uint16_t neededSteps[24]={1400,
                      875,400,400,
                    1650,350,350,350,350,350,2200,
                      350,350,350,350,350,1350,
                    350,350,350,350,350,350,350}                                          ;

//save day and previous day
uint8_t day                                                                               ;
uint8_t prev_day                                                                          ;

//setting speed for motor 100 = 10 RPM
float speed=100                                                                           ;

//array iteration to present date 
uint8_t itr=0                                                                             ;

// Stepper motor object
Stepper_motor stepperMotor = Stepper_motor(StepsPerRevolution, DIR_PIN, STP_PIN, DIS_PIN) ;

//RTC Object
RTClib myRTC                                                                              ;

void setup() {
    //init Serial and I²C comms
  Serial.begin(9600)                                                ;
  Wire.begin()                                                      ;

  /** Initialization of the High-Side-Switch-Board */
  err = HSS.init();
  if(OK!=err)
  {
      Serial.println("Initialization failed!")                      ;
  }
  else
      Serial.println("Initialization successful!")                  ;

  //First thing when button is pushed, keep circuit closed -> XMC stays on
  HSS.switchHxOn(switch_no)                                         ; 

  //init the EEPROM  (optional)
  EEPROM.begin(4096);

	// set pins' mode as OUTPUT, set default speed and enable the stepper motor
	stepperMotor.begin()                                              ;

	// sets the speed at 10 RPM:
	stepperMotor.setSpeed(speed)                                      ;	

  //don't need that much delay but better safe than sorry
  delay(5000)                                                       ; 
}

void loop()
{
  //don't need that much delay but better safe than sorry
  delay(6000);
  
  uint16_t steps  = 0                                               ;

  //First thing: read today's date & time
  DateTime now    = myRTC.now()                                     ;
  
  /* 
     get previous day which is saved in an EEPROM Cell, in this case Cell 3
     set EEPROM Cell to 0 with resetEEPROM.ino or with an if condition, 
     initially an empty EEPROM cell has value 255 stored in it
  */
  prev_day        = EEPROM.read(3)                                  ;
  day             = now.day()                                       ; 
  // day=now.minute(); for testing purposes 
  
  //----- DEBUGGING BLOCK--------------------
  delay(1000)                                                       ;
  Serial.println("----------------------")                          ;
  Serial.print("Previous day was: ")                                ;
  Serial.println(prev_day)                                          ;
  Serial.println(EEPROM.read(3))                                    ;
  delay(1000)                                                       ;
  Serial.print("This day is: ")                                     ;
  Serial.println(day)                                               ;
  //-----------------------------------------
  
  delay(1000)                                                       ;

  if(prev_day < day && day <= 24) //if it's not the same day as the day before 
  {
    Serial.println("DATE CHANGED!")                                 ;
    
    //iterate through neededSteps array and accumulate the steps to reach present day
    for(itr=prev_day;itr<=day-1;itr++)
    {
      steps       += neededSteps[itr]                               ;
      Serial.print("steps: ")                                       ; //debugging
      Serial.println(steps)                                         ; //debugging
    }

    dispenseGift(steps)                                             ;
    delay(1000)                                                     ;
    
    //save the present (new) day to EEPROM cell
    EEPROM.write(3,day)                                             ; 
    EEPROM.commit()                                                 ;
    delay(1000)                                                     ;

    Serial.println("XMC...OUT!!!")                                  ; //debugging
    delay(1000)                                                     ;
    
    //switches off Power->XMC shuts down
    HSS.switchHxOff(switch_no)                                      ; 
  }

  else //if it's the same day 
  {
    delay(2000)                                                     ;
    Serial.println("Gift has been already dispensed!!!")            ; //debugging
    HSS.switchHxOff(switch_no)                                      ;
  }

}

/*
    This function is the main function it tells the motor to rotate to draw the filament for a certain amount of steps 
    200 steps = roughly 3.5cm
*/
void dispenseGift(int steps)
{
  Serial.println("Motor rolling!")                                  ; //debugging
  stepperMotor.step(steps)                                          ;
  delay(10)                                                         ;
  stepperMotor.disable()                                            ;
  Serial.println("Motor stopped")                                   ; //debugging
}

Credits

Infineon Team
115 projects • 189 followers
Hands-on projects, tutorials, and code for sensors, MCUs, connectivity, security, power, and IoT. Follow for new builds and ideas.

Comments