Table of contents

Thursday, 21 August 2014

TheLAMPA – remote controlled, adjustable workbench lamp – part 1

The following post is the first part of a series about my most recent project I’m working on, TheLAMPA. I hope you will like it.

As this is a live project I will be writing new posts along with the progress I make.

I will share my considerations, failures, difficulties, etc. If you have any suggestions, advices (good or bad ) or simply want to help - please leave a comment.  Thank you!

Ok, here we go ☺ 

I have bought a lamp in IKEA recently:  

The lamp is sort of a billiard-lamp shape type. The central part (aluminium H-shaped profile, 80x6x2cm) holds a fluorescent bulb. Then, it has 10cm wide aluminium ‘strap’ running around as a shade.

Ok, it may be quicker to draw it in a MS Paint ☺

This is a top view (the fluorescent tube sits in the middle rectangular part):

This is what I would like to do:
  • leave the H-shaped profile untouched and hide there all the electronics, drivers, motors, pulleys, etc.
  • put 16 LED MR16 “bulbs” between the H profile and the shade
  • print mounting brackets for the MR16 sockets and bolt them to the H profile 
  • use only 1 switching-mode power supply, 230V to 12V for the LEDs. For the electronics a simple 5V stabiliser may be enough 
  • use ATmega328P microcontroller to drive the whole thing. The code will be written probably in Arduino IDE as there are plenty of libraries supporting all the hardware I may need for this project.

The program however, will be responsible for:
  • Controlling each LED independently.
    I plan to use PWM (Pulse Width Modulation) – this will allow me to change the brightness of each LED (and of course turn it on and off).
    PWM works in a way that a high frequency square waveform is used (usually between 10kHz and 100kHz) so the eye will not see the flicker. The only variable is the pulse width/duration (how long in a single period the logical ‘1’ is on). If a factor is 50% it means, the HIGH state is for 50% of the time, same as the LOW state (all this happens thousands times a second). If the factor is 100% - it means the LED will be powered constantly. Same with factors like: 10%, 17%, 80%, etc... the LED will be in the ON state just for a proportional time, and then off for the rest. It will be blinking but the eye will not see it - it will be just an average light which will appear dim.
    Seems that TLC5940 is a perfect fit for this purpose. Also, by using different LED types I will get different colour temperatures which could be used for different purposes.
  • Receiving commands from a TV remote controller.
    A popular IR sensor TSOP31238 and a piece of code to understand what the remote controller is saying. Then just implementing actions based on commands received. Instead of using bunch of inputs in the microcontroller for a keyboard I will use only one – to read the data from the IR sensor. I will need to read all the codes first to know which code is assigned to which button. And then I can use the codes in a program. I’m thinking of using Volume Up/Down buttons to change the brightness and the Channel Up/Down buttons to change the height. Also, I’m thinking about making it more advanced, for example pressing a TXT button followed by “90” will make the light 90% or another button followed by “30” will lift the lamp by 30cm. POWER could turn the lamp off and pull it to the highest, park position. And so on, and so on
  • Controlling 2 motors to lift/lower the lamp.
    This will be a bit challenging as I would need to rethink few cases. At the minute I’m thinking about using 2 servos – these are incredibly strong (they have built-in gears already) and very small. The issue is that they only have 270 degrees freedom. I need to take the servo apart and remove the lock. Then it will rotate freely 360 degrees. But... the other issue is that it will not hold the position. A small servo can be turned by hand so the gravity may/will pull the lamp down once the power is disconnected :/  The solution may be to use a worm gear. The construction allows only one direction of driving it – the small, “threaded” gear turns the large one but not the other way around – this is exactly what I need. I’m going to print a cylinder with grooves to allow the lifting string to wind nicely (and not on top of each other, tangling) but this introduces another issue I need to solve: let’s say I want to have a working distance of 1m and the cylinder has 1cm in diameter (remember, we are working in a tight space within the lamp). It means that circumference will be just over 3cm (2*PI*r) so I would need 32 turns to get it done. If I’m going to lie the string every 1mm it will give me a barrel of 35mm in length... not good...
    OR... I could print a big, narrow gear with a string-thick groove in the middle – then the string will be rolled on top of the previous layer. This will eliminate the previous issue but will cause inconsistent lifting speed (as the diameter will change with every layer) and it will be a bit harder for the motor as well (higher = more string = greater diameter = more string to be pulled during one revolution). But if the worm gear will be used – this should not be a problem at all. In this case I may need a faster motor than a servo as one rotation of the worm gear will rotate the big one just by 1 tooth. I will need to test if first as it may be just right ☺  Also, I don’t want to wait 10 minutes for the lamp to arrive where I need it.
  • Reading data from acceleration sensor to make sure the lamp is level (it will be impossible to make identical movement with 2 separate motors). I would like to read the slope degree during lifting/lowering and if the lamp is off more than... 5 degrees? then I will stop/slow down one of the motors and speed up the other one to make the lamp level again. I have two candidates of accelerometers. Basically the same price but one is digital, the other on is analogue. In this project I don’t need super high precision or fast data rate.
    In digital accelerometer I would need to write a protocol to communicate with it, play with configuration registers, read a full set of data, understand it, and then extract only the part I need…
    The analogue one is much easier to implement as it returns a voltage depending on a position of the accelerometer. It returns 3 separate voltages (for X-Y-Z axis) but I’m interested only in one axis so I can use just one pin of the microcontroller to feed it to the built in Analogue-Digital Converter. The choice is: the analogue one, MMA7361.
    The datasheet says 1.65V is zero-g for an axis, so it is „level”. The program needs to consider if the voltage is lower, it need to lift one end, if higher – the other one, until the voltage gets back to 1.65V (with some hysteresis of course).
  • Showing current status on a display.
    A 7 segment, 4 digit display should be enough for the use. By pressing a button it may show the status, height, brightness, selected LED, etc. For example, pressing a MUTE button may show „LED” string, then pressing 5, may show „LED5” - changing settings for 5th LED. Changing height will show the distance, etc.
    I’m also thinking about using a standard, 2x16 LCD screen but from a distance of 1-2m (when the lamp is under a ceiling) it may be hard to read. I could use a library with custom characters, to write big characters using both lines of the LCD but then, I would get the same 3-4 characters display with much worse clarity and viewing angles than the bright and sharp LED display.
  • Recognising lamp’s position/height - another „problematic” point.
    • To measure the position of the lamp I could use ultrasonic distance sensor or an infrared one. If I mounted it on the lamp, pointed upwards I would know how far the ceiling is. But the problem is... dust. After a period of time I will be getting wrong measurements. I could mount it under the ceiling but this will introduce another set of visible wires going to the main board inside the lamp
    • The other option is to use a set of infrared emitter-receiver line and mount it somewhere beside the cylinder with the wire reel. The beam should be broken only when the reel is full/empty (meaning 2 sets of transmitters per motor). The downside of the solution is that this will be very hard to calibrate, align, get repetitive results.
    • 3rd option – multiturn potentiometer. I would need to pick the correct one – depends how many turns the motor/barrel will do for the full range of movement. Let’s say it is 80 revolutions – I could use 100-turn potentiometer. This will give me a safe margin for use the pot without breaking it, giving 80% of its range. Good enough for this project. ATmega328P microcontroller has a 10 bit ADC, it can recognise 1024 levels. In this case it will be „only” 800 positions (if I use a full range of the potentiometer) which gives me resolution of 1.25mm (for the distance of 1m). This is just to know the position of the lamp. The accelerometer will be used to make the lamp level. Also, it will be possible to know where the lamp is after booting up by simply reading the value of the potentiometer.
  • Saving/recalling ‘favourite’ height/brightness.
    The microcontroller has 1kB of EEPROM, so it can store 1024 8-bit values. It will not be erased when the power is off. To store 1 favourite height position and brightness I will need: 1 memory cell to store the height (0-100% or 0-100cm, both figures fit in 8-bit datatype), and then brightness: the PWM can be driven using 8-bit variable, it has 256 levels – same story, just 1 byte per value. Even having 16 LEDs + height position I will need only 17 cells of memory per one favourite setting - it means I could store 1024/17 = 60 settings. I will probably stick to 10 only (easily accessible using buttons 0-9 on a remote controller + a dedicated button to store or recall the settings). 

I have decided to go with LEDs as they use much less power and are more efficient comparing to halogen bulbs – I don’t want to have a 300W heater just beside my head. Also, they are not getting that hot so the printed plastic holders will not melt and also, I will not get my forehead skin peeled off when I touch the bulb accidentally ☺ (for high density boards I may need a lot of light so the lamp will be hanging very low).

I’m hoping to write the next part soon, once I get my head around the above and prepare some materials.

If you like my project and/or you would like to support it, please use the Donate button ☺ 

Follow me on Twitter, Google+, Thingiverse, YouTube or by email to receive the latest updates.


  1. Seems like a very interesting project. Thumbs up!

  2. Any progress? wheres the code to the chip?

  3. hi I would like to buy this lamp from you.Let me know if you want to sell it

  4. Hi. The lamp itself was purchased in IKEA, it was about €100.
    The project is not finished yet but I will publishing any updates to this blog.
    This is an open source project so anyone will be able to make their own lamp.