Advanced Night Light

Daniel Koch

Issue 78, January 2024

A versatile night light with auto-fading to a sleep brightness, different control options, wake-up option, and even battery backup! - by Daniel Koch

Finding the right night light for your kids is not always as easy as many would think. While some kids can sleep anywhere, in any conditions, many others need some light at night to feel secure in their familiar environment as they fall asleep and when they wake. It is also really helpful when they want to get up: Older ones can find their own way out of the room, while for younger ones, at least there is some light when you head into their room.

However, not all night lights are equal. Some are too bright for a particular child, while some do not throw enough light. Some have timers built in and turn off after an hour or so (meant to allow a child to get to sleep then turn off), while others have daylight sensors that cannot be adjusted. Some have motion sensors and again, these are rarely adjustable for sensitivity or direction.

Finally, the light source is often an issue, with many of the dull ones still relying on grain of wheat light globes for some unknown reason.

This more advanced light stemmed from a need within my extended family, triggered after a family dinner one night. A young child in the family was staying over at their grandparents' house, and as it was a last minute arrangement, the normal night light was not around.

While searching for a suitable table lamp with a dull enough light source, the conversations between the child's parents and the rest of the family suggested that this particular child likes a light bright enough to very clearly see the room while falling asleep, but then finds that too bright later on, triggering a wake-up. Further discussion about other kids, including when adults in the family were young themselves, led to the following criteria:

  1. The light must be LED.
  2. The LED will have at least two brightness levels.
  3. There will be a delay after turning the light on, after which the light dims from the brighter level to the lower preset level.
  4. The light will dim slowly down to the lower level.
  5. It will have an input for either a remote control or a motion detector, or both.
  6. It will use an off-the-shelf housing to help make it look like a regular household item.

That naturally means a microcontroller-based project. While there are ways to do this with analog circuitry, it is excessively complex for the task and while we like building analog circuits for the sake of it, there is nothing to be gained in this case, and much to be lost: Specifically, end-user ease-of-use. Many people who are not into electronics could easily understand the process for using Arduino IDE to change some well-highlighted, clearly commented variables for the two timers, if they are taught well. Many more, we feel, than would be able to change resistor and capacitor values in a timer to get the desired result. Of course, if you are building this for your own kids, that concern is not relevant.

In some parts of this project, we have taken the engineering principle of 'minimum viable product' to heart and stuck with it firmly. In other parts of the project, we have thrown the principle on the ground and stomped on it. You will be able to see quite clearly which is which.

PIR and remote inputs are going to be factored into this design, and will use the small 433MHz ASK RF modules that we covered recently. This enables non-line-of-sight control for the remote, and PIR placement. The remote can be configured however you like if you can code, but ours will trigger the same function as the hard-wired button. It could be used when a parent is entering the room or just when a child is calling out during the night.

The remote returns the LED to its medium brightness level. The PIR can do the same thing, and will effectively be a PIR module connected in place of the remote control's button, using the same circuit. Either the PIR or the big button remote can be used if a particular child doesn't like a lot of light to sleep with but wants to see well when they wake up in the night.

We have built in a third brightness level, as alluded to already, one which may better suit eyes that have been closed while asleep, in which case the original brighter setting may well be too bright. The code would either allow a second button press within a given time frame to turn the light on to its original brightness, or be set up so that the remote only activates this middle brightness level, and only turning the power off and on will activate the timer for the original higher brightness.

That's the theory, anyway. That may not turn out to be achievable!


The circuit is relatively straightforward, with the microcontroller and RF module handling most of the work. The LED is a 3W RGB WS2812 LED from Adafruit. We normally avoid this over the ones we have from LEDsales because the 12V operation of those is better for most of our projects than the 5V of the Adafruit ones.

However, in this case, we have only one to drive, so the advantages of using 12V to drive more LEDs over distance is gone. We also have a need to run on USB power.

Also worth noting is that we have used a DC-DC converter and battery charger module to charge a lithium battery. This is to ensure the light will stay on during storms or other power failures. The reset button on the microcontroller, which is an Arduino Nano, is broken out to an external switch to be installed at the rear of the lamp housing. Power for charging and running the circuit will be from a USB port, so that any USB charger laying around the house can be used.

External pull-down resistors are used instead of the Arduino's internal pull-up resistors to help minimise current use while on battery, although on reflection, the tiny amount of current flowing into the Arduino's input impedance is likely ignorable.


Even for such a simple circuit, prototyping was felt to be necessary. Accordingly, we set about breadboarding the Nano, RF module, switch, and LED. The remote control was to be dealt with later. To make coding easier, we started with the simpler functions then slowly built others in, but we prototyped everything from the start. We used the RF modules sold as a pair from Phipps electronics, as the receiver works on 5V while the transmitter can handle 3.5V to 12V, meaning we can make the future remote control or PIR transmitters USB-rechargeable too. The LED is connected only with plug-to-socket jumpers, so connectivity is far from perfect but is adequate for testing. The pushbuttons are both test-rig items, not the ones we will use in the long term, and so are just any old buttons with jumper wires soldered on. We have three: One for the hardware reset connection; one for the bedside button; and one for the master button which we may or may not use.


We have been quite open about using ChatGTP recently to help us write code. It can never just do the job on its own, except for the absolute simplest code. However, in partnership with a human, it is a great tool. For the experienced coder, it's a great time saver, rapidly providing the building blocks to which you can apply your knowledge. For the less experienced, it enables projects that may not otherwise be possible or would take hours of research and trial and error.

We have found that the best way to use ChatGTP to write code is to move in stages, and check frequently that all parts of the code work. For example, after adding a feature, check that everything that used to work still does, not just the new feature. Sometimes, ChatGTP changes parts of the code to implement the new request, without calculating that it will have a negative impact elsewhere. Such was the case after we added the pushbutton to our code. We have also found that treating it like a person never goes astray, partly because it's easy to slip into the habit of addressing your co-workers like machines if you engage exclusively with an AI for too long then change back to a team conversation!

Initially, we asked for a code that turned on a WS2812 LED at full brightness, called 'before_bed_brightness', then waited for a thirty minute interval, before dimming the LED across two minutes to a very low 'asleep' brightness. We also asked for a 'wake_up_brightness' to be used later, and for clear commenting so that a non-familiar user would easily be able to find the bits of code to change for brightness and timing. We got exactly what we asked for!

Therefore, we uploaded it to the prototype and adjusted the times so that we were not waiting too long during testing: Ten seconds instead of thirty minutes for the before bed time, and three seconds instead of two minutes for the dimming time. We did this by commenting out the whole equation the AI had used, and just entering our values. The AI's formula was intended to make it easier for a non-familiar person because the first number is just the number of desired minutes. The two multipliers after it turn the number into milliseconds for the code to use.

However, we immediately discovered a fault during the first test run of this initial code. After dimming to the 'asleep_brightness', the LED promptly returned to full brightness. So, we asked the AI to make changes:

We duly loaded the code onto the Arduino Nano and sure enough, the LED stayed at the 'asleep_brightness' level until the reset button was pressed or power was cycled. So, we moved on to adding features. We told the AI that we had added a button to pin 7 and that it was active-high, held low with an external resistor and that it would go high when pressed. When this button is pressed, the LED needs to increase slowly in brightness to the 'wake_up_brightness' value.

Again, the AI scrolled out a code for us, and we uploaded it to the Nano. However, there was an issue:

However, as can be seen from the chat, the AI is pretty good at following feedback. The next attempt did not work either, however, so we tried a new tactic. We restated the entire criteria in new words:

This time, the code worked exactly as we wanted it to. Next up we asked the AI to add a separate variable for the duration of the light being at 'awake_brightness', so that we can change how long the light stays brighter during the night. Yet again, there was a problem:

The new code the AI scrolled out this time was exactly as we intended. There would be tweaks later, such as adding the RF feature, but it would trigger existing parts of the code so we were happy to proceed with the build.

The issues we encountered here were just like the ones we find when we code from scratch: We forget about the impact of a change on another, distant part of the code, or we simply don’t think things through, or any of a myriad of causes. The difference for us is the sheer speed: Rather than fault-finding line by line ourselves, or spending time researching and developing, the ChatGTP process is quite smooth and fast.

This does do what it is asked to do, so the quality of the instructions is key. Even then, sometimes language is interpreted differently or the AI just makes mistakes. One example is that the AI used the code INPUT_PULLDOWN to use internal pulldown resistors even though there is no such thing. We just shortened it to 'INPUT" to work with our external resistors.

However, having a human to guide the AI results in a perfectly usable product at the end. Although not shown in the screenshots, the AI provides a summary of what changes it has made and why and how they work, which is great for those using ChatGTP because their own coding skills are not up to a given task. It also helps a more experienced human using AI to save time, determine if the AI has the right idea.

Sometimes there is a lot of backward and forward needed, while other times the first couple of versions the AI outputs are good enough. Whether or not it is useful to you is really an individual decision.


As it stands in this stage of the build, the light functions as follows:

  • At power on, the LED lights to full brightness, and stays at full brightness for thirty minutes.
  • After this time, the LED begins to dim, down to a low brightness level. It takes five minutes to make this transition.
  • After the fade period, the LED remains at the low brightness level until one of the buttons (the remote or the bedside button) is pressed, or the microcontroller is reset.
  • When the button or remote are pressed, the LED fades up from the low brightness state to a mid-brightness state, taking thirty seconds to do so.
  • The mid-brightness state is held for five minutes, after which the LED fades gradually down to the low brightness state, taking two minutes to do so.

All of the times and brightnesses can easily be changed in the code. We expect many people who are not coders by nature can be shown how to change the relevant values in the clearly commented and formatted code, so that parents can adjust the timings to respond to experimentation, if someone else has built the light for them.

The code uses a mathematical equation to turn all times into milliseconds for the timers to work. The format is 'nn * 60 * 1000', where 'nn' is the time in minutes that you want that specific timer to run for. To change any timer, the user just has to change the number that is in the 'nn' position in the equation. While a lot of non-electronics people freak out at the idea of coding, anyone with reasonable word document skills has the ability to understand where to find and how to change the relevant bits. The timers are:

#define before_bed_time  (30 * 60 * 1000)

This line is the time that the LED is at high brightness at the start, and is the time the child has to go to sleep before any fading, currently set to 30 minutes.

#define sleep_fade_time (5 * 60 * 1000)

This is the time across which the LED fades from high to the lower brightness level, currently set to 5 minutes.

#define awake_time (5 * 60 * 1000)

This is the time which the LED spends at the mid-brightness level when the button or remote are pressed, currently set to 5 minutes.

#define wake_up_time (30 * 1000)

This is the fade time from low up to mid-brightness when the button is pressed. This one is an odd one out because it is less than one minute, so the 'nn' position is missing and instead, the '30' is what needs to change as the current time is 30 seconds.

#define awake_fade_time (2 * 60 * 1000)

This timer is the fade down timer from mid-brightness, back to low brightness for sleep. This one is the most likely to need adjusting, as 2 minutes, the current setting, may not be enough for many children.

The brightnesses are as follows. They can be set to any brightness between 255, which is maximum brightness, and 0, which is fully off. This will likely need experimentation to suit each child.

#define high_brightness 255

This is the brightness at the start, when power is first applied and the child is getting ready to sleep or has just got into bed.

#define mid_brightness 50

This is the brightness the LED fades up to if triggered during the night. It should be bright enough to see by but lower than the high brightness because the eyes are so much more sensitive after being closed for some time.

#define low_brightness 10

This is the lowest brightness, for during sleep. It should be just enough for the child to recognise their surroundings or feel secure by not being in complete darkness, but not be bright enough to interfere with sleep or spill out into other rooms.

We did want further functionality, but the issues the new functions were causing with other parts of the code, and the general integration process, was taking more time than it was felt to be worth. Those with more coding skill than us will likely succeed.

We wanted to have a function whereby if a front panel button was pressed while the LED was in the high- or mid-brightness states, or in any of the fade periods, it would immediately start fading to low brightness, with a new fade time of 'transition', set to around 30 seconds.

The same would apply if the bedside button was pressed during the same conditions. In both cases, the button would have the effect of terminating any current timer, and fading the LED down from its existing state to the lowest state via a comparatively rapid time. Unfortunately, it became not worth the effort to us, so we left these features out. However, others who have the skills and the need may choose to add them.


We have supplied the code with and without the RF functionality. This will be overkill for some people who would rather just build the lamp with a button, or not even a button in some cases.

Therefore, the versions without the RF function do not have the RadioHead library, and are consequently much smaller. While we have used Arduino Unos and Nanos to build our versions, the code without the RF libraries would easily fit on smaller, cheaper microcontrollers like the ATtiny85. Each version is labelled and there is a 'Lamp_Basic', 'Lamp_RF', and then of course 'Remote_Control' and 'Motion_Sensor' codes too, but these cannot function without RF.


The front panel button for the build is currently redundant. We added it to the prototype because we want to have the function described above one day. We can attach a cable to the Nano while it is in place in the lamp, so we can code without a rebuild. Fitting the buttons once it is built is not possible. For that reason, we fitted the button now. However, it currently does nothing and so is not defined in the code.

The other button, the one which activates mid-brightness in the basic version, is the external one. Our current plan, different from when we started the project and the button was going to be wireless, was at this point to use speaker wire and a small enclosure to mount a regular pushbutton near the child's bedside.

Ideally this should be a larger arcade-style button for ease of use by small, sleepy hands. Accordingly, we used a stereo 3.5mm socket so we could add 5V to power the arcade button's LED. These are generally wired for 12V but we don't want them bright anyway, so we needed a 15kΩ resistor even with 5V! We'll cover that in the button build steps.

The final input is the RF receiver. This will handle any future wireless options, but for now that will just be the remote. We could have a wireless bedside button, and a wireless PIR module too. The PIR idea is that if the child stirs enough, the light would be triggered to fade into mid-brightness before the child is awake.

The sensitivity control on the PIR modules themselves would be used to ensure the child has to stir a lot or even sit up to trigger the light. We have not built this in this instalment, but many makers are familiar enough with the PIR modules for Arduino.

We envisaged one of these PIR modules and an ATtiny85 development board to run the VirtualWire library, or a Nano running the better but bigger RadioHead library, as discussed in our recent 433MHz ASK module article. It depends on the justifiable expense between the two controllers. See 'Mega Hertz' from Issue 74 for more details on the libraries, how to use the RF modules, and which microcontrollers are suitable.

The PIR could be placed on a shelf or some other location where the bed is in full view from a distance. On that note, the idea of either a wired or wireless bedside button is that the lamp itself is placed elsewhere in the room, to light the room without being too intense right at the bedside. The wire would have to be run behind furniture to stay safe and not be a tripping or choking hazard.


We tried several light sources during our development of this project, and different ones will suit different people. For initial code testing, we used a plain single WS2812 RGB LED, cut from an LED strip. It did the job just fine but we can see few situations where that would be bright enough for anyone (though doubtless somewhere there is a child for whom that is a perfect amount of light).

It was not long, however, before we wanted to gauge how a usable lightsource would look. We turned to a 3W (3 x 1W dies) WS2812 RGB LED.

This is a functional option for many people and throws a reasonable amount of light. The main thing we did not like about this was that there is still not enough light to, say, read by unless it is close, and the 'white' is far from white. While the 'white' can be adjusted by playing with ratios of red to green to blue, we felt it better to order a 4W version, which has a 1W white die added to the mix.

They can be bought in cool, neutral, and warm white. We went for warm white. However, the lead time was seven to ten days plus freight time, and we decided to order them but proceed with other options. In the end, because it was close to Christmas, they did not turn up in time.

Mounting this 3W LED in our chosen lamp involved glueing, because not only is the lamp base made of glass and therefore unsuitable to drill into, the mounting holes were in a very awkward location. Because of the combination of the LED's aluminium substrate and glass lamp body, plus the heat generated by the LED, we thought carefully about adhesive choice. In the end, we went with cyanoacrylate, or Superglue when known by its brand name. We used a thicker preparation from Zap, which is a common brand among model makers. The product next to it, Zip Kicker, is an essential tool when working with cyanoacrylates. It triggers the chemical reaction in the glue without needing pressure or the exclusion of air the way cyanoacrylate normally does. This means you can put on too much, position the job carefully, and then set the glue.

The next option we tried was something we had on hand: Individual 5050-sized WS2812 RGBW LEDs from LEDsales. These have solder pads underneath for power and data connections, and the components mounted on top. We wanted to try an arbitrary guess of ten of them, but the geometry of twelve worked better so we went with that. We made a 3D-printed holder for them, and set to work. The LEDs were all placed into the holes, which were a firm fit if we did not overtrim the PCBs. They were carefully placed so as to align the pads in such a way that they followed the curve. For the ones that were not tight, this was a challenge. After they were in, we soldered small lengths of wire between the data pads, making sure Data Out faced Data In on the next LED. The first Data In pad was soldered to a longer wire, while the final Data Out was left unconnected.

Next, we used tinned copper wire to connect all the 5V pads and all the GND pads. We left the first 5V connection longer, and the last GND connection, and soldered on hookup wire for power connection. This process was fiddly and we found that soldering one pad, then bending the wire around the curve and soldering three or four LEDs down the line was very helpful. Then, the ones in between were soldered too.

Finally, to make sure everything stayed secure, we double-checked our connections, making sure we had not missed any of the power or data pads, before covering everything liberally with liquid electrical tape. Just joking! We did not check first, and had to peel off the liquid electrical tape to figure out that we had missed the 5V connections on one of the LEDs. This is a painful process and the lesson was not forgotten quickly!

With the mount secure, we attached it to the base of the lamp glass with Blu Tack, having learned our lesson about going permanent immediately, and passed the wires through the base and out the cable entry hole. We connected the wires to the breadboard prototype for testing, to see if this light source was bright enough. It was mediocre, at a similar brightness to the 3W LED but with a much better colour because we only used the white chips.

While the light output of this ring was a bit disappointing, the premise was sound and we liked the white colour. Accordingly, we set about making one with more LEDs: twenty-four of them. We re-engineered the mount while we were at it. It has a central locating ring now, fitting the centre hole of the glass, and a counterpart support piece so that the underside is supported to exactly the LED height when turned upside down. This means the LEDs can be worked on without being pushed back through the holes when the frame is on the workbench.

The LEDs were soldered in the same way as for the 12-LED version above, and, after checking, were coated with liquid electrical tape. Then, the mount was pushed into the centre of the glass, being held in location by the centre of the mount print. This worked much better than Blu Tack. The wires were connected to the prototype as before, and tested. This time, the light was much brighter, satisfactorily bright. Still, there will be people who want more!

To make an even brighter lamp, we decided to go with a LED strip. We took this approach in the past, with the giant LED project. Instead of a helix, however, and all the fun calculations of slope and angle and such, we elected to make a 3D-printed cylinder with five stacks of horizontal LED strip. Then, data wires were run in an 'S' pattern so that Data Out went to Data In on the strip above.

Power connections were run up opposite sides with bare tinned copper wire, so two coats of liquid electrical tape were applied to the Data and GND pads for the 5V side and Data and 5V pads for the GND side. On a 50mm internal diameter (inside the recesses) cylinder, this configuration netted 110 LEDs with 144 LED/m strip (it should be 145 but the strip is 1m long), and 45 LEDs for 60 LED/m strip. We made one of each.

The catch here is that 144 LED/m strip is thirsty. It draws 43W/m, and at 5V, that's close to 9A! It requires larger wire than we wanted to use and it was also blindingly bright, so the 60 LED/m strip is more realistic. The 60 LED/m version draws 1.54A (measured) for the whole cylinder, and is definitely bright enough for the task, unless you really want full general-use room light or are lighting a big space. If you do, the 144 LED/m version with 110 LEDs used, draws 3.98A This absolutely exceeds the current capacity of the LiPo Rider module and requires a redesigned power supply.

It is worth pointing out that you can vary these easily by reducing the number of LED strips fitted: For example, you could fit three strips rather than five of the 60 LED/m version, for a good compromise between the 24-LED ring brightness and the full tower brightness. Just alter the code accordingly.

The disadvantage for us with these cylinders is that the RGB strip is a bit hard to come by in RGBW and when it is around, it is usually expensive. The rings we made earlier can be bought pre-made, too, particularly Adafruit ones. However, again, they are usually RGB and lacking white dies, and that is why we made our own.

NOTE: Power supply must be reworked if these large LED strips are to be used. The LiPo Rider Plus that we used has a 5V output of 2.5A max, and most USB cords cannot supply more than this as an input. This will mainly apply during the high brightness condition.

Low and mid-brightness conditions will be under this value even in the 144 LED/m version, which in testing for us at a brightness of 70 for low brightness, drew 0.24A.

Setting an even lower value would reduce that again. Measure your LED strip's current draw using a larger power supply before committing to a design.


Some people would wonder why we did not just use a white LED or LED strip with PWM Control. WS2812 LEDs have an inbuilt controller so all that is needed between the LED or strip, and the microcontroller, are data and power connections. This is true for one LED or one thousand LEDs. With plain LEDs and the use of PWM, a driver has to be built and it is usually a MOSFET driver.

Heat is an issue if the MOSFET is not switched fast enough and while many MOSFET drivers found online are simple, a properly implemented one is more complex, especially if heat is to be kept to a minimum. On top of that, the versatility of having colour if the child wants it is preserved when using WS2812. For example, those with the skills could code for a rainbow or colour-cycling effect instead of plain white light.

On top of that, there is a body of research on colour and the mind, with greens and blues often calming and peaceful. Red is often used as a night vision-preserving light. The human eye generally takes around 45 minutes to adjust from white light to starlight conditions, but only 7 minutes from red light. In addition, red is a less noticeable colour when not in direct view; in other words, in peripheral vision. So, if light spilling from the room is an annoying issue, red light may be the solution as it will be less noticeable.

The catch is that humans have little depth perception in red light, so bumping into or tripping over things because the distance is hard to judge will be more likely under red light.

If you do want to use a white LED but keep the WS2812 practicality, you can buy WS2811 ICs (WS2812 is the LED with driver, WS2811 is the driver IC alone) in packs of 10 SMD components, and make your own white light sources. However, this would doubtless be fiddly as you would need one IC per three LEDs.

You can attach one white LED to each of the WS2811 IC's outputs, normally used for red, green, and blue. You would need to match the current handling of the IC to the LEDs to avoid destroying the IC.


The housing for our nightlight comes from Kmart, but you can use anything you like. The idea is to reuse some sort of beside, table, or shelf lamp which has a hollow base with space for circuitry. We did have to 3D print a larger base for ours, but with effort, we could probably pack the circuitry into the existing ase. We just couldn't do it in a way that allowed connection of USB leads to either the Nano for updated programming, or the LiPo Rider DC-DC/charger combination module. To pack into the base as supplied, these would be inaccessible.

Accordingly, we designed a 3D-printed base specific for our lamps, to give some extra depth. This is not the only option, however, if you want to use a different lamp. Any enclosure would do the job, like mounting a different, tripod-style lamp on a craft box from a hardware store, or anything else of that nature. You could also go with a different option entirely, like some sort of ornament that is not normally illuminated, or having circuitry separate to the lamp itself, with only the light source wires running to an enclosure elsewhere, like an inline power supply would look.

We started by stripping the mains electrics out of our housing. The lamp was originally a mains-powered touch control with a small edison screw fitting for a globe. We unscrewed, levered off, and cut all of that away, leaving the silver metal base and the white frosted glass lamp body. Then, we were ready to move on to the next step.


We made several 3D-printed parts for this build, some of which are specific for the way we did things or the lamp we bought, but there is merit to sharing them anyway. The base for the lamp suits only the lamp we bought, but as a readily-available item from Kmart, we think there is a chance other people wanting to build this project will use the same one.

The inline case for the lamp build where the electronics are not in the lamp is generic and suits any build. The LED array housings and the LED strip mounts do have the base to suit the lamps we made them for but are easily modifiable by anyone with basic modelling skills. In fact, they could be modified with a saw!

We used a Flashforge Guider IIS, and printed in basic eSun PLA+ filament at 210°C and a bed temperature of 60°C. All print times are for that printer, but filament quantity should be fairly consistent across all printers. It will change depending on whether you add a raft or brim, or change infill settings. When support was necessary, we used linear support.

We generally do not print with a raft or a brim unless we have support touching the plate (and even then, we go for a brim over a raft) but this will depend on your printer. The Flashforge Guider IIS is a very consistent printer that is easy to calibrate just right. Some printers need a raft or brim for any successful print, particularly entry-level printers. In any case, unless noted, filament amounts quoted include support and brim shen we noted that we used them.

Unless noted otherwise, we print with two shells (or walls, depending on your slicer), three top and three bottom layers, and 15% infill with no raft or brim. Here are the parts we made:


The 12-LED holder is a plain ring. The one in the photos was constructed as an initial test, but the one for download has the centering components added. The holes are for 9.5mm diameter PCB-mounted WS2812 LEDs, which are the ones we bought from LEDsales in RGBWW, but regular single Adafruit Neopixels should fit too. It should be printed (and is shown in the image) upside down. There is an outer rim underneath to keep the wiring up off the base of the lamp and contain liquid electrical tape. No support needed.

  • Max Build Volume Required: 85 x 85 x 8mm
  • Filament: 10.7g/3.59m
  • Print Time: 48 minutes


This is the bigger version of the one above, when we realised we needed more light. It was also printed upside down,

and it is worth mentioning the cable channels that are built in to guide the connecting wires down the centre of the lamp. Again, no support needed.

  • Max Build Volume Required: 93 x 93 x 8mm
  • Filament: 11.3g/3.79m
  • Print Time: 54 minutes


This flat disc is used to install the LEDs into the holders above. It is a flat disc the same height as the components on the LED PCB, while the holder is the same thickness as the PCB. The result is that the LEDs can sit flat on the workbench even if they are a loose fit in the holder, while soldering of the pads takes place.

  • Max Build Volume Required: 65 x 65 x 1.7mm
  • Filament: 7.2g/2.42m
  • Print Time: 31 minutes


This was used for the 10mm wide 60 LED/m strip, but a taller one was needed for the 12mm 144 LED/m strip. It needs to be printed with supports, and in the configuration shown in the screenshot so that support is minimised. As no supports touch the build plate when printed this way, no raft or brim is necessary regarding the supports. Your printer characteristics or your own preference may dictate that you use one.

  • Max Build Volume Required: 53 x 53 x 88mm
  • Filament: 58g/19.35m
  • Print Time: 4 hours, 19 minutes


This is the version for the 12mm 144 LED/m strip. It needs to be printed with supports, and in the configuration shown in the screenshot so that support is minimised. As no supports touch the build plate when printed this way, no raft or brim is necessary regarding the supports. Your printer characteristics or your own preference may dictate that you use one.

  • Max Build Volume Required: 53 x 53 x 98mm
  • Filament: 65g/21.8m
  • Print Time: 4 hours, 51 minutes


The lamp base is designed to fit the metal part of the Kmart lamps we bought. It contains a larger-diameter base to add height, a smaller diameter section to go inside the metal part, and an extension on the back to increase room and make button-mounting easier. We printed this one with three shells, and had to use support for the inside of the extension and the vertical openings in the walls. No brim or raft is needed for the supports as they do not touch the plate.

  • Max Build Volume Required: 123 x 120 x 51mm
  • Filament: 75g/25.17m
  • Print Time: 4 hours, 28 minutes


The PIR case is in three sections which stack together and are held with bolts. We printed all three together and so the time and filament data is for the single print. It will fit, with care, on a 150 x 150mm bed but not a 140mm version, as some stated 150mm beds are. In that case, you will need to print individually. There is support for some openings and the recesses for the cap head bolts, and it does touch the plate but only for the bolt recess support. A brim or raft is usually for the support to succeed but some printers and support types will let you get away without brim or raft in this print

  • Max Build Volume Required: 150 x 150 20mm
  • Filament: 54g/18.13m
  • Print Time: 4 hours, 7 minutes


This is the bedside button housing. Support is needed when printed as shown, which minimises the visible area that support has to be removed from. The underside of the lid needs support, as does the recessed panelling on the box and the sides of the lid, and the holes in the vertical surfaces. A raft or brim will almost certainly be necessary with this print.

  • Max Build Volume Required: 100 x 180 x 42 (both parts together)
  • Filament: 120g/40.3m
  • Print Time: 7 hours, 53 minutes

The Build: Lamp

Parts Required:JaycarAltronicsCore Electronics
1 x Solder BreadboardHP9570H0701-
1 x Packet Wire LinksPB8850P1014A-
1 x 330Ω Resistor *RR0560R7546-
2 x 10kΩ Resistors *RR0596R7582-
1 x 1000µF Electrolytic CapacitorRE6220R5182-
1 x Arduino NanoXC4414Z6372-
1 x 433MHz ASK RF Receiver ^ZW3102Z6905APhipps Electronics: PHI1002291
1 x LiPo Rider Plus Lithium Battery and DC-DC Converter module %--Element14: 393212402
1 x 3.5mm Stereo Socket, InlinePS0134P0084-
1 x Pushbutton Momentary SwitchSP0710S1084A-
1 x 6mm Tactile Momentary SwitchSP0603S1122-
1 x Pushbutton Latching SwitchSP0718S1082A-
1 x 26650 Tag Lithium BatterySB2319S4761-
1 x 3-Pin Header PlugHM3413P5493-
1 x 3-Pin Header SocketHM3403P5473-
20 x PCB PinsHP1250H0804A-
20 x PCB Pin SocketsHP1260--
1 x Antenna for RF Receiver, 173mm of hookup wire---
Various hookup wire and heatshrink---
1 x USB CableWC7900P1990B-
24 x PCB-Mounted WS2812 RGBWW LEDs, or as per text.--LEDSales: RGBWW_2812_10MM
1 x Enclosure if needed, to expand lamp base space.--3D-Printed part matching lamp base, or separate enclosure. See Text.

Parts Required:

* May only be available in pack quantities, quantity shown is that needed in the project. ^ We used a Transmitter and Receiver pack pair from Phipps Electronics % Several other options exist, see article text.

Because there is a minimum of circuitry, we were tempted to air wire the few components involved but quickly decided against that. We went with a solder breadboard so that we could copy the layout of our prototype. In the end, we made changes from the prototype anyway, and fit the lot on a small breadboard rather than the larger one we prototyped on.

The resistors for the switches stood on end to save space, because the rail-to-row distance is slightly shorter on these boards than the solderless equivalent. The only other circuitry involved is a 1000µF electrolytic capacitor to help smooth power supply sudden demands, and the RF module, which we mounted close to the end of the Nano and soldered a 172mm antenna onto. The antenna connection on this model is a pad on the board, not a pin.

Note also that the hardware reset switch will be mounted in the 3D printed base, but the bedside switch will be in its own housing and therefore, the case features a 3.5mm socket for this switch connection, the wires going to PCB pins on the breadboard. We wired in the other button but moved it to the side of the enclosure. We still had not, at this point, written code to use this button (the one wired to pin 8) but we may in the future and disassembling the lamp to fit a switch later would be painful.

Since the prototype, we had decided to add a latching type pushbutton as a power switch. The power from the LiPo Rider module's 5V output goes to the switch, which then connects to the 5V rail on the board. This means the 3.3V section is constantly on, but as the battery is mainly for filling in power failures, not as a primary operating mode, we don't see this as a big issue.

The reset switch is now a small tactile unit which was glued into a hole in the 3D-printed base section. The front-panel button, power switch, reset button, and the connections to the 3.5mm socket all go to PCB pins on the board. We were careful to only solder the pins we needed to use on the Nano, because if we want to recycle this later, the less desoldering there is to do, the more successful the result.

All of the switches and the 3.5mm socket had flying leads soldered on, with PCB pin sockets on the other ends. The connections and the sockets were covered with heat shrink to prevent shorting. We used small silicone wire for its flexibility. We also added wires to the PCB pins for the LED connection, and used a 3-pin header socket so that we could put a matching plug on the LED or LED array that we eventually choose to use.

The switches were fitted next. The redundant button was fitted into the side, and glued in place because its plastic nut no longer fits the depth of the case. The latching pushbutton for the power switch was fitted into its hole at the back of the enclosure. The reset tactile switch was glued into place securely, and the 3.5mm stereo socket was pushed home. It interference-fitted very well on ours but was secured to the back with glue anyway. All that remained now was to glue the PCB, LiPo Rider Plus module, and battery into place before connecting the PCB pins and sockets. Finally, a USB cable was fed through the hole in the case and terminated into the USB pins on the LiPo Rider.

There is one particular lesson we learned by doing all of this: Think ahead! We forgot to paint the enclosure before we fitted all of these parts. That's ok for the switches because we want them painted, but it is not great for the 3.5mm

socket and the PCB and Nano on the inside of the hole for the USB connections!

We know our 3D print suits this lamp only, but there are too many designs of lamp out there to design something that will suit all or even many. We hope if you do choose a different lamp, that these images and steps are enough of a guide to design your own. If not, you may benefit from the inline variation, or you may need to choose your lamp carefully to ensure its base has enough room and some square surfaces for mounting things in.

With the electronics completed, we could assemble the rest of the lamp. Our chosen light source, the 24-LED ring, was glued into the bottom of the glass lamp body, with the wires poking through the hole in the middle. Any of the previously discussed light sources will work here. We just felt the 24 RGBW LEDs gave the right amount of light we needed in warm white mode. On the other end of the wires from the light source, we soldered a 3-pin header to match the one from the PCB. Finally, we glued the glass to the metal base because it was originally held by the 240V lamp holder assembly.

Alternative Build: Inline Version

Parts Required:JaycarAltronicsCore Electronics
1 x Piece of Veroboard-H0714-
1 x Packet Wire LinksPB8850P1014A-
1 x 330Ω Resistor *RR0560R7546-
2 x 10kΩ Resistors *RR0596R7582-
1 x 1000µF Electrolytic CapacitorRR0596R7582-
1 x Arduino Uno---
1 x 433MHz ASK RF Receiver ^ZW3102Z6905APhipps: PHI1002291
1 x LiPo Rider Plus Lithium Battery and DC-DC Converter module %--Element14: 393212402
1 x 3.5mm Stereo Socket, InlinePS0134P0084-
2 x Pushbutton Momentary SwitchSP0710S1084A-
1 x Pushbutton Latching SwitchSP0718S1082A-
1 x 26650 Tag Lithium BatterySB2319S4761-
1 x 3-Pin Header Plug for light sourceHM3413P5493-
1 x 3-Pin Header SocketHM3403P5473-
23 x PCB PinsHP1250H0804A-
23 x PCB Pin SocketsHP1260--
8 x Du-Pont style Header Pins--POLOLU-1901
8 x Du-Pont Style Header bodies--POLOLU-1901
1 x Antenna for RF Receiver, 173mm of hookup wire---
Various hookup wire and heatshrink---
1 x Suitable Enclosure, we used a UB1 sizeHB6011H0201-

Parts Required:

* May only be available in pack quantities, quantity shown is that needed in the project. ^ We used a Transmitter and Receiver pack pair from Phipps Electronics

Not all lamps chosen to fit a given room will have the space for the electronics in this build. Some have none at all, like those with a tripod or open wicker base. For this reason, we made a version of the lamp with all of the electronics in a regular project enclosure, and inputs for the buttons.

The reset button is mounted in the case, which should be mounted in an out-of-sight but still accessible location like behind a bedside table or chair, or anywhere that you can bend down and reach behind without undue effort. The 3.5mm socket for the switch will also be case-mounted.

However, the front panel switch (the one we have not coded for yet), reset button, and the on/off switch may need to be mounted remotely, in a small enclosure of their own for some circumstances. We did not do this, because in our situation, the power point is accessible and the location of the enclosure is also.

Therefore, the bedside button is the only practical control, with the power point's switch being the best on/off system and the cycling of power being a better way to achieve reset. We could not make a practical, decent-looking enclosure for the lamp we were using that would enable mounting of the reset and front-panel button, which isn't even coded to work at the moment anyway. We built the buttons in regardless, but into the case and not into a separate small enclosure.

Accordingly, we drilled holes in a regular project enclosure for the switches and sockets. We also took the chance to use an Arduino Uno because they are slightly cheaper than a Nano, many makers have one or some, and space was not at a premium; and we rearranged the boards so that both the LiPo Rider and Uno had USB plug-in capability though holes in the side of the case. This allows use of a USB-C cable for power rather than cutting and soldering to pins in the case of the former, and updating of the code without disassembly in the case of the latter.

After this, the buttons and components were wired with PCB pin sockets like the previous version, and insulated. Also worth noting is that the PBC has changed: We used a small piece of Veroboard because we no longer need to mount the Nano. Then, the switches and sockets were installed and the wires attached to the relevant PCB pins.

As noted, using the buttons will not be the most practical thing in the space we are putting this, but the buttons are included anyway. If button control is still the best way of operating yet the case will be out of reach in your situation, you may need to use or design a small enclosure to go with your lamp.

Note: Since the first, all-in-one version, we changed our minds about the power switch. For the inline version, we made use of the 3.3V and Enable pins of the LiPo Rider to activate the 5V output. This is shown in the Fritzing.


We did not build a circuit that could fully utilise the 110 LED lamp with its 3.98A full-brightness current draw. The biggest 5V plugpack we could find was 3A and we could not find an inline power supply in 5V either. The 60W versions getting around are all 12V or higher. We tested ours with a benchtop power supply capable of 6.2A. If you want to build this inline version for the 110 LED strip lamp, it will be necessary to upgrade the wire size and header plug and socket to match for the LED wiring. We used a larger header and 7.5A hookup wire to run the 110 LED lamp in an old bedside lamp housing here as a test setup.

The power supply requires a complete redesign, too. The LiPo rider would be gone, replaced by a hefty DC-DC step down converter outputting 5V at 6A that we found online, powered by a 12V 5A inline power supply. The battery would be a 7.2V pack of four 26650s in two sets of two in series, and have its own charger module that uses the internal 5V supply as a power source for charging. This is also a dedicated module we found online with its own step-up converter inbuilt so it can charge 7.2V packs from 5V.

However, some of the parts were not going to arrive in good time and the cost was getting high for what it is. We feel there are too few applications for such a bright version of this lamp, especially one needing the battery backup capability, to justify the expense and effort. However, if you do have such a use, hopefully the above description sets you on the right path.

The Build: Bedside Button

Parts Required:JaycarAltronicsCore Electronics
1 x 15kΩ Resistor *RR0600--
1 x Green 4.8mm Wide-angle LED, or colour and LED of choice--LEDSales: 4.8mm_FYG
1 x White Arcade Button, or colour of choiceSP0669S0914-
1 x 3.5mm Stereo PlugPP0130P0030-
5m 4-Core Shielded Audio Cable ^WB1510W3040-
1 x Button Enclosure of preference. We used treasure Chest 3D print---

Parts Required:

The bedside button is very simple too, but to avoid having it too high, we mounted the arcade button sideways. These arcade buttons are a favourite of ours but come as a kit of parts. It consists of the switch body, containing the return spring and button actuator; the wedge fitting, holding the LED and dropping resistor; the contact section, which holds the microswitch in the right place, as well as housing a socket for the wedge fitting and providing contacts for the LED, and having bayonet fittings on it for the switch body; and finally, the microswitch. We have found it best to place the microswitch onto one of the pins on the housing, at right angles to the location it will end up in, then swing the switch forwards to meet the other pin. The tab holding this pin must be flexed out of the way. After that, the wedge fitting can be inserted and the button housing twisted on.

After switch assembly, the build is so simple that it is no more than soldering a common ground wire to the common 5V wire to the common terminal of the microswitch, and then up to the + terminal of the LED.

Then, the ground wire for the LED can be soldered on, and the signal wire back to the Arduino pin to the Normally Open (NO) switch contact. We used four-core shielded audio cable for its size and convenience, and the fact it fits well into the stereo 3.5mm plug needed at the other end. Two cores were connected for the 5V supply, two for the switch wire, and the grounds were used to return the LED current to circuit ground. We added a cable tie for strain relief on the cable where it exits the box.

Make sure you determine which side of the LED is the positive before assembling anything. You can solder the wires to the terminals first, then if the LED does not light, pull out the wedge fitting and flip it. This is impossible once the whole switch is assembled. All exposed connections were covered carefully (after the photo showing the wiring was taken) with liquid electrical tape. 5V is not dangerous but we cannot disregard the possibility of a child putting something in the box that may cause a short.

One thing we did that is totally optional is to use a white arcade button and modify the LED. We did this so that we could use a yellow-green wide-angle LED with a colour closer to (but not matching, sadly) the colour of the light from the luminous plastic. While you can add an extra resistor outside the switch to reduce the brightness of any of the LEDs these switches come with, we took the opportunity to replace the resistor with our own while we changed the LED. The existing LED and resistor were first carefully unwrapped from the bottom of the wedge fitting, then discarded. We cut the cathode of a 4.8mm yellow-green wide-angle LED down to almost 5mm, then cut the end of a 15kΩ resistor to match. These were soldered together. Then, the LED was inserted into the housing and the legs wrapped around the terminal fitting. Red marker denotes the positive side. We did the same to the terminal once we assembled the switch.

The housing is a treasure chest, to make the button case look a little more at home on the bedside table. It is quite simple and lacks the detail of many that you can download from file sharing sites but the end-use did not really justify more time invested, especially in light of the available modelling skill level! It has a hole in one end for the switch body, a small hole in the back for the cable exit, and a lit that fits onto a raised section of the lower half. We printed this one in glow in the dark filament just for fun.

The Build: Remote Control

Parts Required:JaycarAltronicsCore Electronics
1 x Small Piece of VeroboardHP9540H0714-
1 x 470Ω Resistor *RR0564R7550-
1 x 5mm Red LEDZD0150Z0800-
1 x Arduino NanoXC4414Z6372-
1 x 433MHz ASK RF Transimtter ModuleZW3100Z6900Phipps: PHI1002291
1 x DC-DC Converter moduleXC4512Z6366-
1 x 40-pin Header SocketHM3230P5390-
1 x Momentary PushbuttonSP0656S0961-
1 x Remote EnclosureHB5610H0290-
Hookup wire and heat shrink.---

Parts Required:

* May only be available in pack quantities, quantity shown is that needed in the project.

The remote control is designed so a parent can turn the nightlight on to mid-brightness before entering the child's room. This is particularly useful for those kids who have a habit of getting up and playing with toys or otherwise leaving obstacles on the floor that were not there last time the parent was in the room!

It may also be useful to help you navigate the hallway on the way to the child's room, especially if you have recently moved house and haven't memorised the layout well enough to sleep-walk it yet. Currently, the remote control function triggers the same phase as the bedside button: That is, the mid-brightness level and its associated fader and run timers.

The hardware is quite simple, consisting of an Arduino Nano, a pushbutton, confirmation LED, and RF transmitter module with whip antenna. There is also a power supply consisting of a DC-DC converter, and the unit runs on two AA batteries. It is so simple we only provided a Fritzing and not a schematic. We mounted ours on a piece of Veroboard with tracks cut down the middle, and put it in a commercially available remote control enclosure which includes a battery compartment and contacts.

Assembly was straightforward, being mainly a case of wiring the different modules together.

The button was wired into the case, as was the confirmation LED, with silicone wire to keep the wiring loom flexible. The dropping resistor for the LED was soldered directly to one LED leg. Be very careful with the lid of the case. From the front, it looks like it is symmetrical top to bottom.

We marked it with graphite pencil on the front of the lit because it was the easiest place to measure from, inside the lines made by the recessed section. However, on the back the case is not at all symmetrical! Instead, there are accommodations for the battery terminals and different screw post positions.

With that, the case can be closed and the code can be uploaded and the remote tested.

In terms of design, we wrote the code so that the button powers on the Nano, which then sends the 'on' code and lights the confirmation LED. Therefore, press and hold the button until the LED lights. This was the most battery-effective way we could think of to write the code. It is probably quite clunky and there are doubtless more advanced ways to do this. It is probably also unsuitable or problematic in many other situations. However, for our task, this approach is fit for purpose and on that basis, there is little rationale in expending extra effort or research time to code the 'right way'. If you already know a better way, then there is no reason to follow this method.

The Arduino Nano is quite expensive for the task, but many makers have one or several already. They also function very reliably in the way that many people are already familiar with. The most readily-available cheaper alternative, the ATtiny85 development boards, have more than their fair share of quirks and take some getting used to, as we discovered in our recent 433MHz ASK module project.

They are nowhere near as easy to use as the Nano and more importantly, cannot fit the RadioHead library, instead only able to use the older and less functional VirtualWire library or similar. However, with the aid of the Mega Hertz from Issue 74, you could easily adapt this remote to use the DigiSpark ATtiny85 development boards, or probably a discrete ATtiny85 IC if you wanted to reduce the cost.

The Build: Motion Sensor

Parts Required:JaycarAltronicsCore Electronics
1 x Arduino UnoXC4410Z6240-
1 x LiPo Rider Plus Module--Element14: 393212402
1 x PIR ModuleXC4444Z6382A-
1 x 433MHz ASK RF Transmitter ModuleZW3100Z6900Phipps: PHI1002291
1 x Toggle SwitchST0335S1315-
1 x 1000mAh Lithium Polymer Battery-S4724-
Hookup Wire and Heat Shrink to suit---
1 x Enclosure. We used a 3D printed part but a project box would work.---

Parts Required:

We decided, quite late in the project, to make the PIR-controlled option anyway, despite thinking earlier that we would not. While it does not fit our needs at the moment, we can see situations where others may find it useful. Such a situation is where a child stirs a lot in the night, waking up and wanting light. Instead of reaching for a button, the child only has to sit up or maybe wave their hand. This will suit some children more than the button does. Again we turn to the Arduino Uno because we are using the RadioHead library.

The downside of this project is that, using an Arduino Uno or even the ATtiny85 development board with simple coding, means a high power drain. To use low-power sleep modes and the like takes more coding skill than was available when producing this project (read as: The author is an analog person and struggles to learn coding languages, or any language other than English, to be honest). Many readers who do have that knowledge may choose to implement it, but if you do not then the question needs to be asked: Does the end justify the means? We think, with a USB-rechargeable battery, that the PIR as presented will be functional enough for many people.

Again, we turn to the LiPo Rider Plus from Seed Studio. The only other parts are a battery, 433MHz transmitter module with antenna, Arduino Uno to fit the RadioHead library, and an off-the-shelf PIR module! We decided later to add an off switch, and this uses the 3.3V and Enable pins of the LiPr Rider so that the battery can still charge.

To code this version, we had to make sure the Uno only sent one command through the transmitter per PIR input pulse. These are several seconds at the minimum adjustment (and several minutes at maximum). Because the night light will not respond any further after it begins the fading process up from low to mid-brightness, there is no harm in using this duration as the delay for ignoring further inputs from the PIR. This way, the energy used to transmit is not wasted while the lamp would ignore it anyway.

The Uno, PIR, and transmitter all run off the LiPo Rider's 5V output. The only other component we thought useful to add is a latching switch as a power button. This utilises the LiPo Rider's 'Enable' input. When a battery is connected to the LiPo Rider, the 3.3V output is always on. Supplying 3.3V to the Enable pin activates the 5V output. It might be tempting at first to switch the battery but then it would not charge!

We made a custom 3D printed box for this section of the project but there is little to stop you using a commercial project enclosure, except perhaps the ability to make a hole large enough for the PIR lens. Like 3D printing, it depends on the tools you have and a step drill up to 30mm should be good enough for the task if you have one of those.

Before we started, we placed heat set inserts into the holes in the corner posts for M3 bolts. We installed the Uno into the base of the case with small self-tapping screws, then glued the LiPo and LiPo Rider module into the middle section. Before installing the LiPo Rider, it is a good idea to solder on the relevant wires. We used PCB pins for the contacts. Two are for the battery, two for the 5V output, and two for the switch.

We glued the PIR into the top section, then the RF module with antenna attached. We soldered on the wires and covered them with heat shrink. There is a Data input for the RF module, Data Out from the PIR, and power for both. Power is common, so only one set of power wires need to pass down to the LiPo Rider's 5V output in the middle.

Power wires for the Uno are also soldered to these pins. The antenna is routed around the inside of the top section.

To assemble the sections, we threaded the wires from the PIR and RF module through the hole in the middle section, then placed the top over it. M3x30 mm cap head bolts were passed through the holes, and then the wires were attached to the Uno in the base. The ground for the PIR went to the I/O side ground pin, while the LiPo Rider ground went to the power area of the Uno.

The RF Data Out is pin 8 of the Uno, and pin 5 is the PIR input. Power for both was from the 5V pin, while the VIN pin was used for the incoming power from the LiPo Rider. Then, the wiring is folded into the lower section above the Uno, and the bolts are tightened into the threaded inserts to hold the lot together.

One important point here is adjusting the sensitivity of the PIR, so make sure it mounts opposite where the adjustment hole is. The timer trimpot can be adjusted once then ignored. Set it to minimum just to be safe.


The PIR module used here is one of several similar designs from different suppliers, but not all are the same. Sometimes, even the same part number from the same retailer can end up different to what was previously stocked, as we have found in the past with two different modules in the same packaging on the shelf at once. The main points of difference are which potentiometer controls sensitivity and which controls output time, and whether the adjustment from low to high is clockwise or anticlockwise. Some have a 3.3V/5V supply choice jumper too, and on ours this was unlabelled and set for 3.3V! Our sensitivity and timer trimpots were also unlabelled. Finally, on ours, the labels for the power and output pins were under the plastic lens, and cannot be seen until it is removed. So, before installing your PIR module, do some bench testing first! Once we identified our timer trimpot, we set it for minimum and covered it in glue, so only the sensitivity pot can be changed when the motion sensor is assembled.


The remote and motion sensor codes both utilise the RadioHead library to operate the 433MHz ASK modules that we use for transmitting and receiving the radio data. Because of the complexities of this library and these modules, though overall quite simple, we are not describing them in detail here. Instead, check out Mega Hertz, a project from Issue 74. In that project, we looked in depth at how the modules operate, how to use different Arduino libraries to drive them, and what kind of memory and hardware demands they make.

In a nutshell, however, the library is used to send a command from the transmitter, when a suitable input is triggered. In the remote control, this command is a delay in the code which starts on startup, because the button on the remote is actually a power button. In the motion sensor, the high-going pulse from the PIR module activates the command. In either case, the word 'ON' is sent as a serial data string out into the air.

At the other end, a code block within the receiver/base unit code checks for an incoming message. When 'ON' is received, the code activates the same function as the buttons do: In other words, the mid-brightness function and its associated fades. The code for the PIR has no delay built in, even though this means data will be sent and battery used when the motion sensor detects movement after the light comes on. Even though further commands are ignored until the mid-brightness and its fade periods are over, we left the transmitter active in case for some reason the first command is not received.

Rather than explain this code in detail, we have relied on comments within the code to explain it. This is partly because, at the time this article was finished and sent to the amazing graphics and layout team, the code was still being improved and tested. It is also partly because the Mega Hertz article will give far more detail than we can fit here.


Now, all that remains is to plug the USB cable into a USB power supply, place the lamp in a good spot in the room, and plug in the bedside button. We are using a different bedroom for display here a spare at my house, partly because of lighting and visibility (which still wasn't great) and partly because the child this was built for is not mine and as an ex-teacher, I'm paranoid about child protection and privacy. However, while the furniture is full sized adult furniture and there is more of it because it's the spare room, the principle of running the bedside button cable behind furniture can be seen, as can how it plugs in at the back and how we Blu-Tacked the button housing down to the coffee table in this case, to stop it moving when pressed.


As we mentioned, there is some functionality we still want to give this unit. If you are looking to take it further, you could try coding in some of the extra button functions we mentioned. You could add in colour options or have the code turn off some of the LEDs in the low-brightness mode if you are making one of the versions with a very high LED count. We also realised after building that there is huge potential to add noise functions to the lamp with an Arduino-controlled MP3 player module. This could be white noise, rain, crickets, or any of the sounds many parents use to help kids sleep. Besides that, the rest is really up to your imagination!