Infineon Team
Published © MIT

Turn your boring old Curtains into smart ones

Tune in to this project and turn your boring old traditional curtains into wirelessly controlled smart ones using your Arduino Uno

AdvancedFull instructions provided20 hours602

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1
KIT XMC1300 IFX9201 Stepper Shield
Infineon KIT XMC1300 IFX9201 Stepper Shield
×1
Infrared IR Wireless Remote Control Sensor Module Kits for Arduino
×1
GT2 Belt and pulleys
×1
Stepper Motor, Mini Step
Stepper Motor, Mini Step
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

3D Printer (generic)
3D Printer (generic)

Story

Read more

Custom parts and enclosures

Pulley Lid

Sketchfab still processing.

Belt Connector

Pulley lid

Sketchfab still processing.

Upper Anchor Hook

Sketchfab still processing.

Anchor

Sketchfab still processing.

Lower Anchor Hook

Sketchfab still processing.

Regular Hook

Sketchfab still processing.

Magnet Slider

Sketchfab still processing.

Right sided Edge Pulley

Sketchfab still processing.

Center Pulley

Sketchfab still processing.

Left Sided Edge Stepper Motor Holder

Sketchfab still processing.

Code

Arduino Code

Arduino
This is the code I used for achieving full curtain functionality with my Arduino. I installed the shield directly on top of the Arduino, and connected the signal pin of the IR receiver to pin number 3. This configuration ensures that all components communicate effectively, allowing for smooth operation of the curtains through the remote commands.
#include <IrReceiverSampler.h>
#include <Nec1Decoder.h>
#include <EEPROM.h> 
#include <IFX9201_XMC1300_StepperMotor.h>

static constexpr pin_t RECEIVE_PIN = 3U;
static constexpr size_t BUFFERSIZE = 200U;
static constexpr uint32_t BAUD = 115200UL;
uint8_t receivedSignal = 0;
int8_t revolutionsCounter = 0; 
static IrReceiver *receiver;

#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

const int StepsPerRevolution = 200;  // change this to fit the total number of steps per revolution for your motor
const int MaxRevolutions = 20;       // Maximum number of revolutions from closed to open or open to closed

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

void setup() {
  Serial.begin(BAUD);
  while (!Serial);
  receiver = IrReceiverSampler::newIrReceiverSampler(BUFFERSIZE, RECEIVE_PIN);
  pinMode(53, OUTPUT);
  digitalWrite(53, HIGH);
  
  revolutionsCounter = EEPROM.read(0); // Read stored position from EEPROM
}

void loop() {

  receiver->receive();

  if (receiver->isEmpty())
    Serial.println(F("timeout"));
  else {
    Nec1Decoder decoder(*receiver);
    receivedSignal = decoder.getF();
      Serial.print("Revolutions Counter: ");
  Serial.println(revolutionsCounter);

    switch (receivedSignal) {
      case 90: // Right button - close the curtain one step
        if (revolutionsCounter < MaxRevolutions) {
          Serial.println(F("Closing Curtain 1 step"));
          MyStepperMotor.begin();
          MyStepperMotor.setSpeed(100);
          MyStepperMotor.move_revolution(1);
          revolutionsCounter++;
          EEPROM.write(0, revolutionsCounter); // Update position in EEPROM
          MyStepperMotor.end();
        } else {
          Serial.println(F("Curtain already fully closed"));
        }
        break;

      case 8: // Left Button - open the curtain one step
        if (revolutionsCounter > 0) {
          Serial.println(F("Opening Curtain 1 Step"));
          MyStepperMotor.begin();
          MyStepperMotor.setSpeed(100);
          MyStepperMotor.move_revolution(-1);
          revolutionsCounter--;
          EEPROM.write(0, revolutionsCounter); // Update position in EEPROM
          MyStepperMotor.end();
        } else {
          Serial.println(F("Curtain already fully opened"));
        }
        break;

      case 13: // # Button - close the curtain completely
        if (revolutionsCounter < MaxRevolutions) {
          Serial.println(F("Closing Curtain Completely"));
          int stepsToClose = MaxRevolutions - revolutionsCounter;
          MyStepperMotor.begin();
          MyStepperMotor.setSpeed(100);
          MyStepperMotor.move_revolution(stepsToClose);
          revolutionsCounter = MaxRevolutions;
          EEPROM.write(0, revolutionsCounter); // Update position in EEPROM
          MyStepperMotor.end();
        } else {
          Serial.println(F("Curtain already fully closed"));
        }
        break;

      case 22: // *Button - open the curtain completely
        if (revolutionsCounter > 0) {
          Serial.println(F("Opening Curtain Completely"));
          int stepsToOpen = revolutionsCounter;
          MyStepperMotor.begin();
          MyStepperMotor.setSpeed(100);
          MyStepperMotor.move_revolution(-stepsToOpen);
          revolutionsCounter = 0;
          EEPROM.write(0, revolutionsCounter); // Update position in EEPROM
          MyStepperMotor.end();
        } else {
          Serial.println(F("Curtain already fully opened"));
        }
        break;

      default:
        Serial.println(F("Invalid command"));
        break;
    }
  }
}

Credits

Infineon Team
102 projects • 165 followers
Contact

Comments

Please log in or sign up to comment.