Motorized WiFi IKEA Roller Blind





Introduction: Motorized WiFi IKEA Roller Blind

About: IT-professional by day, DIY hobbyist (among other things) on my free time. I always have one or more projects going on. Usually something to do with home improvement or a tech project or a combination of the...

I confess. I have been sucked in to a home automation addiction. The next thing on my radar was to automate roller blinds. There are commercial products available but the ones I found are surprisingly expensive (about 80 - 90 USD). Since I need a bunch, it was hard to motivate the purchase (and less fun). I decided to design my own.

If you like this Instructable, please vote for it in the Microcontroller contest (press Vote above)!

These were my requirements:

  • WiFi capable
  • MQTT control (0% - 100%)
  • Manual push button operation
  • Use low cost standard electronic components and 3D-printable parts
  • Persist state on power off

This instructable is a followup to

Step 1: Bill of Materials

The motor parts add up to about 15-20 USD per unit. The shade itself is 19 USD.

Step 2: Wiring

  • Wire the motor to the shield as seen in the pictures. Take note of the colors.
  • Solder cables to the micro switch as seen in the picture. If you can, use red, black and white as in the picture.
  • Attach the button wires to (GPIO) 5 as seen in the picture

Step 3: Set Up a MQTT Broker

MQTT is a lightweight publish/subscribe protocol suitable for small IoT devices. The devices interact with a message broker which manages the distribution of messages. You can either use a local mqtt broker, e. g. Mosquitto inside your own network or connect to a cloud MQTT broker. Which option is best? It depends on your needs. If you want to be able to connect to the broker from anywhere you may prefer the cloud option. If you prefer to keep your IoT within you network you should use a local broker.

Setting up a cloud broker:

  1. Register at CludMQTT:
  2. Creat a new broker instance
  3. Click the instance info and keep the info handy
  4. For testing purposes, download MQTT.fx:
  5. Add a profile to MQTT.fx with the credentials from your newly created cloud broker.
  6. Connect. If it works you have successfully tested the connection to your fresh cloud broker.

Step 4: The Software

The ESP8266 on which the NodeMCU development board is a single chip computer with I/O capabilities and WiFi. The chip can be programmed in various ways. The two most popular options are the Arduino IDE and the Lua interpreter. For this project I chose Lua out of convenience. Some of the features in the software are easier in Lua because of the built in file system.

Flash the Lua Firmware

Even if your NodeMCU is pre-flashed with a Lua firmware I recommend that you re-flash it with a new firmware. That way you get a fresh version and can slim the binary to only contain the needed modules.

  1. Cook a LUA firmware here: Select the following modules: file, GPIO, MQTT, net, node, PWM, timer, WiFi and optionally enable SSL
  2. Wait for the email with the firmware download link, then download. It should only take a few minutes. You may want to check your spam filter for it. That's where mine was.
  3. Download Flash tool:
  4. Flash the firmware using the flash tool
    1. Run the tool
    2. Connect the NodeMCU holding the flash button
    3. Select the serial port
    4. Select the firmware file
    5. Press Flash

Install the rollerblind code

  1. Download the roller blind code here:
  2. Download ESPlorer IDE:
  3. Open Esplorer
    1. Select the serial port
    2. Connect
    3. Open all the lua files
    4. Edit settings.lua and enter WiFi and MQTT settings
    5. Upload all lua files (Save to ESP)
    6. Reset device

    Step 5: Dry Run

    Now would be a good time to check the software and wiring.

    • Open up esplorer and connect
    • Run the following command line (see picture). The motor should rotate 1000 steps (about a quarter of a turn.

    Step 6: 3D Printed Parts

    I designed the parts in Fusion 360.

    Download the parts from and start printing!

    Step 7: Assembly

    This is what you need to do for assembly (watch video):

    1. Heat the soldering iron to about 200 degrees C (400 F).
    2. Embed the nut inserts into the plastics by placing the insert over the tip (so it heats up) and gently push it into the plastic sockets (see picture).
    3. Remove the lever from the micro switch
    4. Loosen the plastic hinge on the lid button (gently push it out and back in)
    5. Push the micro switch in place
    6. Push the motor shield into place
    7. Insert the motor
    8. Screw the plastic parts

    Important note on power: I have found that if you have a narrow window or short travel distance you are fine with just USB power (5v) but for wider and longer blinds you need external power (max 9v DC). You attach external power to the motor shield. Make sure you disconnect USB before you do or you are likely to fry something.

    Step 8: Mount Rollerblind

    Replace the springloaded end mount and insert of the Ikea rollerblind with the printed motor mount and printed insert.

    Step 9: Calibration

    Windows are of different heights; hence the gadget has to be calibrated. This is how:

    1. Long press the button (> 2s)
    2. The shade starts going down
    3. When the shade reaches desired bottom position, short press
    4. When the shade reaches derired top position, short press again
    5. Done!

    Step 10: MQTT Control

    • Download MQTT.fx from here:
    • Start MQTT.fx
    • Create a profile to match the broker you already set up
    • Connect
    • Subscribe to the topic from config.lua e. g. "/house/masterbedroom/#" wihtout the quotes. If you don't have anything else on your broker bus you can subscribe to everything (e. g. "#")
    • You should see heartbeat messages sent out from the device every two minutes
    • To control the device, publish to the topic matching config.lua "/house/masterbedroom/rollerblind/0/set"

    Of course, this setup is obviously not terribly useful for daily operation but it will help you weed out any potential problems. If you just want to control mqtt devices you can download a MQTT cotrol dashboard on you phone. If you want to use other general home automation software I think you should find that most support MQTT integration.

    Step 11: Integration With Openhab (optional)

    I will give you an example of integration with the home automation solution I am using. If you have a pre-installed openhab home automation solution or would like to set one up (there are guides on their home page), this is what you should do to integrate the roller blind.

    1. Install and configure the openhab according to their instructions
    2. Install MQTT binding
    3. Configure MQTT binding for your previously configured broker (local or cloud)
    4. Add the roller blind to your items and sitemap file. See example below.


    Dimmer masterbedr_blind1 "Rullgardin 1" <rollershutter> { mqtt=">[ohab:/house/masterbedroom/rollerblind/0/set:command:*:${command}],<[ohab:/house/masterbedroom/rollerblind/0/status:state:default]" } 


    Slider item=masterbedr_blind1
    Microcontroller Contest 2017

    Runner Up in the
    Microcontroller Contest 2017

    6 People Made This Project!


    • Make it Move Contest

      Make it Move Contest
    • Oil Contest

      Oil Contest
    • Woodworking Contest

      Woodworking Contest

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

    2 Tips

    The board layout seems to have changed since this intractable was originally published.

    It's all in the comments somewhere, so here's a little heads up (thank you @ssvenn for helping me with this) I was confused because there is some explanation to the pictures, but no explanation as to why those steps are necessary.

    - You must (there's no way around this unfortunately) solder the wires to the motor shield and connect them to GPIO 2,3,6 and 7. Jumper wires help cut the soldering in half, but the chip is pretty tough, it's doable though

    - Remove the highlighted resistors and the transistor. According to ssvenn, if you want to power it with 9v, leave one of them in place (I don't know which one though). If you remove the highlighted ones, you're "stuck" with 9v

    - get a cheap buck converter and preferably some connectors to fit your power brick (like these and integrate them into your box (basic 3d modelling skills required)

    - Attach one wire from the 9v output directly to VM, the other one to the buck converter and from there to VIN. Same for GND. Purpose of this being that you only need one power source, it is technically possible to still power it over USB and have the 9v. That's what I'm doing for testing purposes right now

    I have experimented problems with the wifi_setup.lua. Diving in internet I found a problem description like mine and also the solution.

    The solution was change the line 25 of the archive:


    with this one:

    wifi.sta.config{ssid=key, pwd=config.SSID[key]}

    Now it's working. I can'ttake any credit for that, I'm completely newbie to this kind of code, the link I found is this one. If there is any problem with the solution, I'm sorry:

    8 Questions


    hey is it possible to calibrate with out the button ie mqtt or within esplorer. thanks


    New to Lua...immediately upon Saving the init.lua file to ESP8266 (using ESPlorer on Win 7) I get an error and red light. lua: init.lua:13: attempt to call field 'exists' (a nil value). I looked at line 13 in the code and it refers to a file called; "cfg_tot_steps.lua". I cannot find that file anywhere in the Git. What am I missing?

    Any one else get the panic/watchdog reset all the time?

    ================== ==================

    ESP8266 mode is: 1

    MAC address is: 62:01:94:45:db:84

    IP is


    Warning, deprecated API! autoreconnect == 1 is deprecated. It will be removed in the next version. See documentation for details.

    PANIC: unprotected error in call to Lua API (button.lua:23: attempt to perform arithmetic on upvalue '?' (a nil value))

    ets Jan 8 2013,rst cause:4, boot mode:(3,6)

    wdt reset

    load 0x40100000, len 26524, room 16

    tail 12

    chksum 0x7e

    ho 0 tail 12 room 4

    load 0x3ffe8000, len 2184, room 12

    tail 12

    chksum 0x6b

    ho 0 tail 12 room 4

    load 0x3ffe8888, len 136, room 12

    tail 12

    chksum 0x97

    csum 0x97



    Same here, i cannot figure out the solution for this. Can anybody help?


    Trying the "Dry-run" to see if the motor can spin but it seems that there is some issues when I change the GPIO pins for the motor. I have a custom made card where the pins are fixed to:

    * A: = GPIO 16

    * B: = GPIO 14

    * C: = GPIO 12

    * D: = GPIO 13

    stepper_pins = {16,14,12,13}

    Any tip on the error-message below?


    stepper.lua:36: bad argument #1 to 'mode' (Invalid pin)

    stack traceback:

    [C]: in function 'mode'

    stepper.lua:36: in function 'pins_enable'

    stepper.lua:64: in function 'step_take'

    stepper.lua:91: in function 'step_move'

    stdin:1: in main chunk

    Never mind, my mistake in reading how the GPIO are named :-)

    stepper_pins = {0,5,6,7}


    Hey. I finally received my parts today and couldn't wait to try everything but now I'm stuck.

    First off, I ordered the parts exactly as described, only difference being the manual switch which I picked up locally. I flashed it - check. Did the WiFi fix - check. WiFi connection established - check (according to my router) Ran it in ESPlorer - worked.

    However… the motor does nothing. When I enter the code in ESPlorer, the blue light lights up and goes off after a couple of seconds, giving me a confirmation that the new status is now X+/-25. But it doesn't rotate.

    I tried wiring it as depicted, then I changed it like it's described in the stepper.lua (A+ Pink, A- Blue, B- Yellow, B+ Orange, VH(?) Red) but it still doesn't move.

    I ordered two motors/boards since I have two blinds, neither of which works. Any ideas what I'm doing wrong?


    Yes, check out the tip I posted above as well as the pictures by ssvenn. You have to modify the motor shield - there's no way around it

    5 more answers

    i have the same problem any ideas?


    hi, some people seem to have this problem. I think there may be two variants of the driver board. I remember this (or a simial) problem with a solution months ago in the comments. There was a solution too. Unfortunately I couldn't find it right now but maybe you can!


    I bought mine from Amazon last week. Did you do the same? I think next steps are to verify they can move at all using an arduino and the provided motor shield


    @Bitsy21: Mine doesn't even vibrate. I found some documentation on the stepper used and the sequence in the code matches the one provided by the manufacturer (check out this instructable: not a solution, but it gives some insight on how a stepper motor works)

    It's really frustrating since everything else works and if fails due to this seemingly minor issue that nobody else seems to have :/


    I'm having the same problem. I've created two separate blinds and they both have the same problem - the stepper vibrates but doesn't rotate. I've triple checked the wires. This makes me believe its a software issue

    a have problem

    i think i write to wrong place wifi name and wifi pasword

    my error

    PANIC: unprotected error in call to Lua API (wifi_setup.lua:25: bad argument #1 to 'config' (config table not found!))

    my config with my wifi

    local module = {}

    module.SSID = {}
    module.SSID["SatFilma00a"] = "fc9114ada00a46434"

    Hi! first of all thanks for share this great work, has been very usefull to me :)

    I have test your code and I'm wondering how could I change the rotation speed of the stepper. I have changed the value on stepper.lua, line 27, to several other values (from 5 to 20) but I haven't noticed any change, just that the stepper doesn't move at all when i move to very high or very low values ( I think thats this is because of at high speeds the torque is so low that can't even move the axis).

    Is there any way to increase the rotation speed? is the problem is the stepper, do you know if with a bigger one (NEMA17, for example) could I get a faster rotation speed?

    Thanks in advance!

    Hi, thanks for your reply! Finally I have made it work with the nema 17, I'm waiting for the shield and a voltaje regulator to assemble it :)

    1 more answer


    I don't think you can get this tiny stepper to go any faster. I have tried but if you crank it up it will start to stutter. The reason it is at all able to operate the blinds is that is is geared. As for other motors, yes, a nema 17 motor would be capable of operating your blinds at very high speeds. It is a bit bulky though!

    How Can I increase the speed of the motor?


    Hi, the motor is geared and won't go faster. That's the tradeoff with such a small motor.


    I have an issue, when the blind goes down, the lights on my stepper driver stay lit. I do not think the power to the coils is being turned off.

    When the blind goes up, the lights turn off at the end and the power to the coils stop.

    Why would the power to the coils stay on when the blind goes down? I have looked at the code and cannot see any reason why.

    In the morning when the motor should open the blind it fails due to being really hot.

    1 reply

    In the original code I left one pin active when the blind is down. The reason was that I was having problems with gravity pulling the blind down further than I wanted if there was no power. In retrospect, keeping it powered was not the best solution. I belive I changed the code in the repo a while back so that it turns all pins off but I'm not sure. There are (at least) two much better ways to fix the gravity problem. 1) cut the blind (at the top) so that when it is down it is all the way out. 2) modify and use the original spring to counteract gravity. This was suggested by another reader. Remove the spring lock and put the spring on the opposite side from the motor.

    I did have a lot of modifications but the biggest problem is the connection to shield. Do you know that there is a sot-26 I.C. next to the L293DD at least on my motor shield which I believe is the same than yours. The inverter I.C. changes the behavior of the L293. So D1 is connected to ENABLE1, D2 is connected to ENABLE2, D3 is connected to IN1 and inverted to IN2 and finally D4 is connected to D3 and inverted to IN4. I did figure it out When I connect my scope on the signal. Now I change your stepper.lua and I did have to swap two coils wire. Now I do have more torque and it is working way better. All the documentation I found point to the same thing

    9 replies

    Ok I clone your code and made the modification to fix for my esp-12-e motor shield. I also fix some bugs like the missing module.step_ms in config.lua . the state==2 or 0 which force the system not to operate if your not fully close or open. Lua has a big problem with the speed of the stepper. I don't want my blind to take 15 mins to go down so I made a 'C' version. N.B. The wiring is different and check the .ino file to find the correct stepper wire color. B.T.W. the original source code has no licenses so I put M.I.T. on mine

    Ok so this seems to be the latest iteration of versions... should have read all the comments before ordering the parts I guess...

    Using your code @DanielP do I still need to remove the resistors and solder the wires as I saw somewhere else here?`Wish someone would write a updated guide (wink wink... :D )

    No! I modified the code for the motor shield using PWM and DIRECTION.

    The shield is used directly but you need to change the wiring since A+/A- is one coil pair and the B+/B- is the other pair.

    The color is in the code.

    Also I included an ESP8266 and an UNO version with C. This version could be modified to include a percent holding if your blind moves when power is off.

    Sweet, I'll see if I get the time to flash it tonight and try it out!

    Did you get your setup to work properly? I have just bought all the stuff I got to the point where i'm about to test the motor but nothing happens. I have measured on the ESP32 pins and when I press the button both enable pins go high and I can also see pulses on D3 and D4.

    Yes it's working fine! Which Version Lua or the Arduino 'C' version ?Check the jumper on the shield board.! The jumper select if you are using the USB power or the V+ power. Did you connect the center wire to V+.

    Right now I'm using the Arduino code. I have tried both with and without external power on V+. The center wire is going to positive voltage. But the strange thing is that i cannot see any changes in voltage on the L293D outputs which makes me think the chip is damaged. I will order 2 more today and test with those and see if I get the same problem.

    You could use lua and set individual pin level and check manually each pin of the L293. Check the input , the power and the output using a voltmeter.

    Weeee!! I solved it. Turns out that on the shield that I bought D1 and D2 goes to enable pin 1/2 via resistors. These resistors is 800ohms when I measured them. I have a shitty multi-meter so might be 1K resistors, but when I removed these and made a short with solder instead everything works. I'm guessing those resistors should probably be 100ohm to protect the inputs of the L293D but they mounted the wrong value on my board. It will be interesting to see if the new boards I bought have the same value resistors.

    Did anyone have any luck flashing the board on a mac? I've tried various ways, but nothing seems to do the trick. Kinda stranded here

    7 replies

    I tried and failed, then used a PC. If you have no PC available I bet you could make it work with Parallels or VirtualBox on a mac by USB device sharing with a VM, download the windows 10 ISO from microsoft and install a temporary virtual machine with the software you need (no license required, there is a grace period after the install)

    Thanks for the help. I got the initial flashing to work (I think) on a PC. But now it kinda wont connect via ESPlorer. It just has a red dot at the "Open" part in ESPlorer. I've selected the right baudrate and also COM port. But nothing happens. Any idea?

    For mac-users; (at least for NodeMCU)

    1. Start NodeMCU-PyFlasher. Select file.

    2. Hold down the Flash-button and connect usb. Release button.

    3. Select baud rate 115200, Dual I/O (DIO) and Yes wipe all data.

    Now the flasher should transfer and verify.

    4. Close Flasher and open Esplorer. Select the right device. (SLAB_USBtoUART probably)

    5. Open all the Lua-scripts and edit credentials.

    6. Set baud rate to 115200 and click Open (the right side console, up top)

    7. IMPORTANT! Reset the device (NodeMCU) with the physical button and Esplorer should return version and so forth.

    8. Save to ESP on each open file.

    I have. I just flash the firm downloaded from (any of the two you are gona get) with nodemcu flash, here is the link for the osx version, the one in the tutorial is incomplete:

    Then, when you have flashed the firm, you need the ESPlorer (it runs on java) and you can open, edit and flash every file of the code in the board.

    I hope it helps

    Have you find a solution to flash the board on a mac?

    Did you guys see this post? Maybe useful. I haven't tried it myself though.

    Thanks! I’ll definitely try this once I receive my ESP8266. Cheers!