Automatic Curtain With Arduino





Introduction: Automatic Curtain With Arduino

Project time ! : Automatic curtain opener/closer.

I did see some other projects for closing and opening (automatically) the curtains, I certainly wanted to build one myself now.

Most other designs I saw were built using a fishing line. I did not want to use a fishing line, because fishing lines always will break at some point ?

For this automatic curtain I used a teethed timing belt (with metallic enforcement, so very strong) and a timing pully wheel (20 teeth), which are also used for some 3d printers.

Aim was that the curtains will open and close automatically, when it gets light or dark, and a manual override of course. I considered a timer too with a RTC, but so far this works fine now, without a RTC.

Also, see the short manual and this video of the end result :


Step 1: Materials and Tools You Need

Step 1 :

Gathering all the stuff you need. This could vary in other situations.

The materials I used :

The components

“Mechanical” :

Timing belt for 3d printers : 3
or 6 meters, depending on the size of your window/curtain.

(example : if your curtain has to cover 1.5 meters, you need a belt of 3 meters)

(ordered this at AliExpress : GT2 belt width 6 mm RepRap 3D printer 10 mtr.)

20 teeth pulley wheel

(ordered this at AliExpress : GT2 Timing Pulley 20 teeth Alumium Bore 5mm fit for GT2 belt Width 6mm RepRap 3D Printer Prusa i3)

Smooth (no teeth) axis wheel (or a second free rolling pulley wheel)

Wood 20x10x1.8 cm

Wood 2x2x6 cm

Aluminium strips with slide hole (sometimes these are used for aligning picture frames on a wall, I had them lying around somewere)

Some 5mm nuts and bolts

Some 3 mm nuts and bolts

Some screws and plugs for attaching to the wall

Aluminium plate 0.2x2x30cm, cut 4 strips from 2x1.5 cm

Electrical stuff :

Arduino Uno R3

Power suplly 12V 2A (depending on what motor you use)

Motor with gear (60 to 120 rpm)

Motor driver L298n

Small circuit board 3x2.5 cm

3 Leds

3 resistors 220 or 330 ohm (current limiting resistors for LEDs)


1 resistor 330 Ohm (analog divider with LDR)

4 resistors 10K (pull up resistors for switches )

Some headers for small circuit board

Wires (Dupont/Arduino wires), male-male – male-female

Case (115x90x55)

Switch with three positions on/off/on

2x (small) Reed Relays with magnets

Heat Shrink tube/wire

Tools used :

Solder Iron / Solder




Hot Glue


Wire Stripper



Step 2: Steps Creating the Modules

Step 2 :

First, I planned to make things as modular as possible : Motor rig, second axis rig, Arduino, motor controller, connector interface, case.

I started with creating the motor rig and connector (for connecting the motor, reed switches and LDR to the controller via a RJ45 connector) on a crafted piece of wood.

The whole depends a bit on what kind of motor you have/use, but key is that the belt driven by the pulley wheel is very near the rails of the curtain (about 1 to 1.5 cm. next to it).

I had a couple of motors with gears lying around, which I saved long time ago from a professional coffee brewer. They were 24 volts with a gear which reduces the RPM of the motor to about 120 RPM when on 24 volt. I use the motor on 12 Volt here, so geared RPM is about 60. I used 12 V because the Arduino is powered also with the power supply I had for this project, and to reduce the max. wattage for the connector (see more on that below).

Attach the teethed pully wheel to the axis of the motor/gear. The axis of the gear was 6 mm, the pully wheel 5 mm. so I needed to drill the hole of the pully wheel larger to 6 mm.

Then created a mount for this given motor, cutting out the wood so the motor and gear would fit in nicely and to be able to mount the Reed switches next to it, and attach it to the wall with two plugs and screws.

Next I used a RJ45 connector (female), to connect all the wires from the motor and two reed switches and a LDR. The eight wires (4 pairs) in a network cable are just enough to do the job.

The motor only draws between 0.1 and 0.3 amps (with 12 Volts, 1.2 to 4 watts) (depending on the load it gets from the curtain). A single wire in a Network cable (at least in the ones I have) can easily maintain 10 watts. As a matter of fact, PoE standard is 15 watts per pair, but you need a good certified PoE cable too then.

And the used length of the cable is only about 2 meters. This was my main concern though : Will the wiring for the motor be able to carry the wattage the motor needs. So far, no problems, no heating up of connections or wires, and I built in a software safety : The motor can and will only run for a maximum amount of given/defined time (30 to 50 seconds, also again depending on how long it will take to close or open the curtain). You need to tweak this for you own situation.

If this runtime is exceeded, the motor will stop and not be driven again by the motorcontroller. The reason for the exceeded runtime then needs to be investigated and solved before you reset the Arduino/controller (just unplug/plug the power cable to reset).

A straight one to one network cable would be ideal, but most ethernet cables (if not all) will have a twist in the connector, so the coloured wires you use on one end, will not be the same on the other end, if you know what I mean. You have to keep track accurately of how you wire things up.

Two pairs I could use as they were, the orange and brown pairs were the same on both ends, but the blue and green pair on one end, became a mix of the two on the other end. No Problem, as long as you know what combination of colours is hooked up to what on the other end.

Step 3: Creating the Second Axis

This is a simple step : see the pictures. Create a small second axis rig for the belt to run on, I used an aluminium strip with slide hole which makes it easily possible to put the correct tension on the belt easily. Attach it near the rail on the other end of the curtain/window. See photo.

Thus, with a small wooden block, aluminium strip with slide strip, 5mm bolt and 2 nutts put together that thingy in the photo, and drill holes to attach to the wall with some plugs and screws near the rail on the right end of the curtain.

Step 4: The Belt

The belt :

This really needs to be done precisely. Because I used adjustable axises and reed switches, I created some margins, but the length of the belt needs to be quite exact, and the location of the magnets and clips even more.

I bought this belt from AliExpress, 10 mtr reinforced teethed timing belt (for 20 teeth pulley wheel (also from/via AliExpress)), costed only 7.60 Euros.

In the end, I used up all 10 meters, one for a 3 mtr wide curtain (so I needed approx. 6 meter of this belt), and another one for a smaller window, a 1.7 mtr wide curtain, so another 3.4 mtr used

To get the exact length of the belt, you need to mount the motor rig and second axis rig to the desired places on the wall. Wrap the belt with enough tension around the wheels and cut the belt.

In the 4 aluminium strips of 0.2x1.5x2 cm drill 3 mm holes. Clamp two strips on top of each other, and drill three holes (so the holes are nicely alligned, to put the bolts through later on). Two holes on the edges/ends and one somewhere in the middle, but make sure the belt can move between two holes. This is to attach one set of strips to the belt for one end of the curtain, and the other two aluminium strips are used to attach/clamp the two ends of the belt together with the help of a small piece of belt 1.5 cm long (see photos).

This connection thus serves two purposes, connect the belt ends to make a loop, and act as the one of the two curtain attachments. Tighten the nuts on this clip firmly, so the belt is strong enough to pull and push the curtain. The force is not that much, 2 to 3 kg at most (unless there is something going wrong ?!) .

The other clip should not be tightened yet, as the position of this clips needs to be adjusted for the other curtain later.

Once the belt is finished, wrap it around the pully wheel and axis wheel and tension the belt firmly with the adjustable axis/aluminium strip on one end.

Don’t attach the curtains yet to the clips, you need to test and adjust everything correct before you can attach the curtains.

The clip which is not the "loop" connection should thus still be “slidable”.

Step 5: The Arduino, Motor Controller and Interface Board

The Arduino, motor controller and interface board.

For modularity, I used a small interface board (PCB) to create the necessary headers and resistors for pull up and for the LDR divider, and then connect with female headers all the wires of the RJ45 connector and manual override switch.

In the end, the interface board is maybe a weak point in the whole, and was maybe unneccesary, and direct connections where perhaps better and easier.

The pins allocation on the Arduino is as follows ;

// pins allocation :

// A0 - LDR

// 0 + 1 - Serial printing

// 2 - led green

// 3 - led red

// 4,5 - motor driver L298n

// 6,7 - FREE

// 8 - Top reed switch - close(d)

// 9 - bottom reed switch - open(ed)

// 10 - Manual switch open

// 11 - Manual switch close

// 12 - FREE

// 13 - blink alive led (external Yellow)

Connect all the wires to the interface board via the Arduino wires (male-female) according to the pin alocations above.

Solder the 3 leds with the anode (long leg) + resistor to the pins 2,3 and 13 of the Arduino, and the cathodes to ground.

I used :

Pin 2 to Green, for indicating curtain opening. (left curtain to the left seen from front)

Pin 3 to Red, for indicating curtain closing. (left curtain to the right seen from front)

Pin 13 to Yellow for alive blinking (Yet, I did not use this anymore, as a blinking led in the dark can get annoying, but it is there to use ?, I programmed the led not to be really used, on the other hand, using the DARK or LIGHT indication for blinking only during the day, is easily possible too).

As a matter of fact, programming this all went along building this controller. The idea of the red and green led came later, and the use of the/a yellow became less/not important.

Step 6: Putting It All Together

Built the case. The case which is CASE115x90x55MM on the outside, on the inside it was a bit smaller (107x85x52,

Drill 5 mm holes for the Leds, a 6 mm hole for the switch, a 6 mm hole for the connector wire/network cable, and holes for the Arduino power connector and USB connector (which is easy for programming/updating the Arduino)

Also, solder two wires from the Arduino power connector to the motor controller. The arduino is powered via this external power connector, and so is the motor controller.

Put the Arduino, motor controller and PCB in the case and connect all wires (LED'S with 220 ohm resistors, switch with pull up resistors, and also lead the ethernet cable though the hole to the PCB and connect to the headers.

Attach the motor rig to the wall on the left side of the window, the second axis wheel to the right side of the window, put the belt around the pulley wheels, connect the ethernet cable to the RJ45 connector on the motor rig, power up the Arduino with only the USB at first.

Upload the program/firmware "curtain-2.ino", and test the LED values and reed switches, and manual swith via the Arduino IDE Serial monitor output. Special care for first tests, depending on how you wired the motor to the motor controller, the motor should turn anti-clockwise for closing the curtain, and clockwise for opening. If that is not correct, you can either cross the wires on the motor controller or PCB, or re-program the "motor_open()" and "motor_close()" function to do the opposite.(signal controller to turn clockwise or anti-clockwise).

The magnets for the reed switches should be placed at the correct strategic places. When the clip for the curtain on the right is at the correct place (thus, also far on the right, when the curtain is open), then the clip for the left curtain is far on the left (curtain open), and the magnet for the bottom reed switch should be very near on the left of the clip for the left curtain (see also video and photos).

The magnet for the top reed switch should then be on the top of the belt in the middle of the window (again, when curtain is open). The photos and video will make it clear.

The top magnet will move to the left (towards the motor rig), when closing the curtain, and should activate the reed switch, when the curtains meet each other in the middle (closed position) If the reed switch is activated too late, you have a (big) problem. The motor will try to pull the curtains together, but they already are, thus the belt will stall or slip, or the motor stalls, pulling high current. So tuning this is very important, and this also goes for the closing position of course. But anyway, tuning this did not really take that much time and effort, really.. Sticking/glueing the magnets on top and bottom of the belt needs to be precise, with the slide option of the reed switches on the motor rig, you have the margins to tune it just right : see this movie for a final test

Testing the belt and reed switches

You can use the manual swith override to test this.

Covering/uncovering the LDR you can simulate dark and light.

When the clips on the belt stop on the correct places, you can attach the curtains to the clips and enjoy the automatic closing and opening of your curtains :-)



    • Woodworking Contest

      Woodworking Contest
    • Clocks Contest

      Clocks Contest
    • Oil Contest

      Oil Contest

    We have a be nice policy.
    Please be positive and constructive.


    4 Questions

    Where you set extra 2 or 3 min delay in ver 2.21. For trail i want to check direct without waiting from dark to light or vice versa. And you share new code but im not understanding what is going on. Sorry im not good in coding and all.



    No probbem asking !

    This waiting time is done via the variable minuteslightchange

    This is defined on line 53 and set to 3 minutes. set it to 0 and there will no waiting in between light and dark change...

    this is the code for the define :

    const unsigned long minuteslightchange=3; // light change interval in minutes, to prevent "hogging" curtain due to light/dark change

    and on lines 174 and 200 the waiting is done in the if statement there :

    if (millis() - prevlmeasure > minuteslightchange * 60L * 1000L)

    millis() returns the runtime of the arduino in milliseconds. So multiplying here the minuteslightchange * 60 ( becomes seconds) and again by 1000 (becomes milliseconds) the elapsed time is compared with this outcome..

    Hope this helps further...

    Thanks man now its working. And sorry its my arduino problem i change atmega 328p ic now its working properly. what you say about delay about summer please share code with us. thank you man for your help and awesome project.


    Ha, glad to hear it's working now !!

    I attached the new code. Mind though, that calculatiing the length of the night is also based a bit on your location too. I live in the south of the Netherlands, and based on that location the length of night during the year, the extra waiting time is calculated, so curtain will open at round about 7:45 - 8:00 o'clock.(or later because in autumn/winter, it will get light outside later)

    Alongside the exra wait time calculation in the morning, I made this visible too via the Led's. While waiting, every 2 minutes the green and yellow led will show the time before the curtain will be openend. The two led's will first flash both together, to indicate countdown will be shown. Then the green led wil flash once for every 10 minutes waiting, then the yellow led will flash for every remaining minutes, example : 2 green led flash, 5 yellow led flash (will flash a bit faster than the green led) means 25 minutes waiting left (+ an extra wait (2 or 3 minutes) which was already applied to prevent the curtain from hogging because of light changing due to clouds or whatever after just opening). The flashing could be annoying, just modify the code to not call the function indicate_number(n) then.

    b.t.w., during init fase, the version number is also shown via this indicate_number(n) routine. so init will take a bit longer and you see the leds flash a bit more, but don't worry, that is the intention here :-)

    Have fun with it !

    And thanks for your comments.

    Yes im using l298n motor driver and gear motor. Motor is not moving but some jerck. In serial monitor its showing about to close certain and all but motor is no moving. Please help me iwant to make this project.



    Attached an image for full schematics (breadboard view from fritzing).

    Extra note : I used an external Power supply of 12 V, 2A with a barrel jack, which I

    connect to the Arduino. I then soldered the + and GND of the barrel jack connector from the Arduino to the L298 power connector, to power the L298N with this same power supply (you can also tap via extra wires from the barrel jack to the L298N, so the L298 gets powered via the same external power supply and you do not have to solder)

    Because your motor is not reacting, it could mean one of the following

    1. the connections 4 and 5 from the Arduino to the L298 controller are not correct.

    2. GND from L298N is not connected to GND of Arduino

    3. The L298N can use 3 connections per motor to steer a motor. En(able)A, IN1 and IN2.

    (En(able)B, IN3 and IN4 are for the second motor, not used here).

    The EnA is either bridged via a Jumper (default, and means you cannot/have to use a PWM signal, which is indeed NOT used in this project, so there should be a jumper on EnableA on the L298N. Only IN1 and IN2 are used to pin 4 and 5. If pin 4 is set HIGH and pin 5 LOW, motor should turn one way, if pin 4 is set LOW, and pin 5 HIGH, motor should then run in opposite direction. Pin 4 and 5 LOW means motor stops.

    4. The L298N (or motor?) is broken

    You can check also following links (which I also did use to get the idea) to use a L298N with Arduino :

    In both links, the PWM signal is used to steer (the speed) a motor, but you can ignore that, as long as there is this jumper on ENA

    Let me know how your are getting along.

    (Maybe for some more encouragements :-) - I built two of these curtain controllers, and both are now operable for almost 6 months, and work flawlessly. The only thing what happened twice now, was that the hook of one curtain became unhooked somehow (one time the tension of the belt was not really good anymore and had also to retension the belt a bit). Hooking the curtain back in, and curtain nicely opens and closes again.

    Furthermore :

    Because I started the build in october 2017, winter was coming and nights were long and getting longer and curtain opening and closing time was acceptable. But now, almost summer, the curtains in our bedroom begins opening early, which is not convenient (it wakes us up too early !!).

    So I modified the code a bit, to wait a bit longer before opening, and this depending on the lenght of the night (there is no clock (RTC) attached to the Arduino, which might have been a bit easier or more controllable, but this works too) )

    2 more answers

    Yes i know only motor 1 is used in code. I try all things but motor is not working at all.


    Ok, We will get that motor running :-)

    While I am working on the schematics, can you check if you connected the GND from the Arduino, to the GND of the L298N motor driver ? (when the motor/curtain rig is powered separately from the power of the arduino, this is absolutely necessary).

    Furthermore, with the L298N you can steer two motors. Only 1 is used for this project (Motor 1 terminal on :the L298N), make sure the motor is connected to this terminal.

    Hope this already helps,

    kind regards,


    my motor are not working please help me and please share wiring diagram.


    I do not have ful schematics right now, but for a good project, there shuold be one, so good qiestion!
    I will cteate this and shate it. Just give me a few days. In the mean tome, what kind of motor did you you use ? Did you use the L298N motorcontroller too ?

    Anyway, I will come back to you very soon


    Great instructable!

    Want to do it.

    My curtains are quite high and difficult to reach so I'll make a wireless version. Nice instructable though, a good basis for me to start on.

    I'd love to have something like this in my room :)