Introduction: Automatic Blind Hooked Up to Existing Projector Screen

Hello my name is Chipsy,
I'm French, reading instructables since at least 2 years, it is the first entry i make on this website.

Why i made this project :

I have a small homecinema system in my living room, with a projector and a commercial motorized projector screen.

I have a big mirror on the left wall, it makes the room brigther, but when watching a movie you want a dark room, and we could see reflections of the movie in it (very annoying) so i installed a grey/black blind i found in a DIY shop, it was a great fix.

Now i had to get it down then up every time by hand, so i tough "why not motorize it?"

Why i didn't just remove the mirror ?
The mirror is embedded in the wall, and it is nice when not watching a movie, it expands the living room. So i wanted to keep it, but still be able to watch a movie without seeing the reflections in the mirror.

Step 1: "Reverse" Engineering the Projector Screen Motor Controller

The existing controller for the projector screen is an integrated circuit that drives the screen motor.
It is controlled via an RF remote.

I grabbed my multimeter, and was able to find 12V on the relay coils.
So i soldered one wire to each relay coil (the terminal that gets down to 0V when the relay is "OFF"), plus one wire for GND.

Step 2: High Level Shifting ( 12V Detection Circuit With Arduino )

The idea with this circuit is being able to "sense" with the Arduino weither the projector screen is going UP or going DOWN.

This circuit works like this :
- When current is provided on the base of the transistor, the current flows from Arduino 5V to GND, the Arduino INPUT is then HIGH.
- When NO current is provided on the base of the transistor, the Arduino INPUT is connected to GND, and then the INPUT is LOW.

I used two transistors (TIP122), one for each relay of the projector screen.

Now i am able to know when the projector screen is going down, or is going up.

Step 3: Motor Controller ( H-bridge Using Relays )

To control the motor, i will be using an H-bridge with a DPDT relay like you can see on this schematic below.

If you want more details, look on this page :
http://oomlout.com/a/products/ardx/circ-11/

This circuit allows the motor to run in forward and reverse weither we set the Arduino pin HIGH or LOW.
The problem with this circuit is that it doesn't allow us to stop the motor *gasp*

In order to stop the motor when we want it, we will need to unplug one of the motor wires, and plug it into another bit of circuit with a kind of Switch hooked up to another Arduino pin.

I did that by inserting another relay in my circuit ( an SPST or SPDT relay will do fine ), controlled by another transistor ( hooked up to another Arduino pin set on OUTPUT )

I tested the circuit with two LEDs : 

Step 4: Determine the LIMITS for the Blind

Okay, so now we can tell the blind motor to go DOWN when the projector screen is going DOWN,
We can tell him to go UP when the projector screen is going UP.

But how do we know when to STOP?

When the instruction to go down is launched, I use a "delay(18000)" 18 seconds delay so that the blind is covering roughly the bottom of the mirror. Everytime it will go down, i tested it, it will arrive at the same position, but NOT exact, 1 or 2 cm different each time.

Because the position it arrives is different each time, we cannot do this when going UP, because after 2 or 3 times everything will be completely out of phase !

So we will use what is called a magnetic switch, to go UP while we didn't detect the switch closing.

It looks like this : http://www.radioshack.com/product/index.jsp?productId=2419297
It is also called a REED switch

I installed the wired part near the top of the blind on the wall, and inserted a neodyme magnet in the bottom of the blind,
so that the switch is activated when the UP position is reached.

Step 5: Test Everything on a Breadboard

I tested everything on a breadboard to develop the arduino code and debug.
It took me 1 complete day, because it is easy to make mistakes with so many wires...

Step 6: Transfer the Circuit on a Perfboard / Stripboard

I won't detail this step, just transferring the parts, being careful not to overheat anything, and triple check before soldering.

Step 7: Enjoy a Juice

Drink some Juice before the final test.

Step 8: Final Test

Step 9: Arduino Code

// Pins
int dir = 2;
int power = 3;
int captor = 4;

// Reed switch
int captorVal = 0;

// Analog pin to read screen DOWN
int screenDown = 0;
int screenDownVal = 0;

// Analog pin to read screen UP
int screenUp = 1;
int screenUpVal = 0;

String screenState; // Projector screen state
String blindState; // Blind state
boolean busy = false;

void setup() {

  // initialize pins
  pinMode(power, OUTPUT);  
  pinMode(dir, OUTPUT);
  pinMode(captor, INPUT);

  // Read reed switch value at setup
  delay(100);
  captorVal = digitalRead(captor);
  delay(100);

  // Set the blindState on setup
  if ( captorVal == LOW ) {
    blindState = "up";
  } else {
    blindState = "down";
  }

  // Logger
  Serial.begin(9600);
}

void loop() {

  // Read projector screen values
  screenDownVal = analogRead(screenDown);
  screenUpVal = analogRead(screenUp);

  if ( screenUpVal > 1000 && screenDownVal > 1000 ) {
      Serial.println("Screen module is OFF !");
      screenState = "off";
  } else if ( screenUpVal < 200 && screenDownVal < 200 ) {
      screenState = "stop";
  } else if ( screenUpVal > 1000 && screenDownVal < 200 ) {
      screenState = "up";
  } else if ( screenDownVal > 1000 && screenUpVal < 200 ) {
      screenState = "down";
  }

  refreshBlindMotor(screenState);
  delay(100);

}

void refreshBlindMotor() {

  Serial.println(blindState);

  // Screen is going UP and blind is DOWN ( and blind is not busy )
  if ( screenState == "up" && blindState == "down" && busy == false) {

    // UP the blind !
    busy = true;
    blindUp();

  // Screen is going DOWN and blind is UP ( and blind is not busy )
  } else if ( screenState == "down" && blindState == "up" && busy == false ) {

    // DOWN the blind !
    busy = true;
    blindDown();

  } else if ( screenState == "stop" ) {
    // TODO : stop the blind ?
  }

}


void blindUp() {

  // Motor ON + UP
  digitalWrite(power, HIGH);
  digitalWrite(dir, HIGH);

  // While reed switch not engaged
  captorVal = digitalRead(captor);
  while (captorVal == HIGH) {
    captorVal = digitalRead(captor);
    Serial.println("Waiting for the blind to reach the far UP position...");
    delay(100);
  }

  // We got out of the while loop,
  // We can stop the blind
  halt();
  blindState = "up";
  busy = false;

  Serial.println("Blind is UP !");

}

void blindDown() {

  // Motor ON + DOWN
  digitalWrite(power, HIGH);
  digitalWrite(dir, LOW);

  // Time is takes for the blind to go DOWN
  delay(18000);

  // Stop the blind
  halt();
  blindState = "down";
  busy = false;

  Serial.println("Blind is DOWN !");

}

void halt() {

  // Cut power to blind motor
  digitalWrite(power, LOW);

  Serial.println("Blind is STOPPED !");

}

Step 10: Conclusion

It was a fun project to make, i did some frustrating mistakes but in the end it just WORKS.

Next steps for improvement :
- Replace Arduino by a simple microcontroller circuit, because i will use the Arduino for other projects.
- Cleaner wiring and 5V power ( wires everywere !! )
- Automatic curtains !!

Anyone willing to do the same in her/his house ? :)