The Tenergy Lumi Bloom is a great, inexpensive, modular table lamp, here’s how to convert it to a ceiling fixture.
To accomplish this modification I designed a number of 3D printable parts which you can find on Thingiverse. One could alternately craft these parts out of wood or some other material using the 3D designs as a guide.
The table lamps themselves are great, the branches and bulbs use the same socket base so you can create your own tree-like lamp structure and change it up at any time.
This mod has the lamp running 120 volt bulbs into the house electrical rather than 12 volt bulbs via the included adapter. If you are not comfortable making this change or working with lighting electrical please refrain from undertaking this modification.
While this modification allows you to purchase multiple lamps in order Replica watch best to add more bulbs to one ceiling fixture please take into account the combined wattage of the bulbs that you are using to limit the number of branches and bulbs you include.
This lamp uses 12 volt bulbs, the base of which are longer than 120 volt bulbs. That being the case, 120 volt candelabra-size bulbs will not screw deep enough into the sockets to make the required connection.
To solve this problem I designed a threaded spacer with a hole in the center into which I glued about 3mm of the base of a nail (all but 2mm or so of the pin cut off).
The flat of the nail sits on the center connection of the socket when the shim is screwed in and the pin of the nail is what the bulb’s center lead will sit on when the bulb is screwed in. The nail bridges the electrical connection while the spacer screws tight into the socket and prevents any shorts. I used nails labelled 1″ 2d and Krazy Glue. The nails friction fit quite well, but to be extra caution I glue them anyway. Both the cap and tip of the nail may need to be scraped or sanded after gluing to ensure a good connection.
While one of these shims will be required for each 120 volt candelabra bulb you use with this lamp, when you’re connecting a branch to a socket rather than a bulb you will have to remove the shim. Consequently when you are re-configuring the lamp you’ll end up shuffling the shims from socket to socket.
When inserting these shims, screw them in reverse a couple turns to get them level, then they should screw in properly. Don’t tighten to hard or you’ll risk cracking the shim, snug is good to make the connection.
These shims have a slot so that a flat-head screwdriver can be used to insert and remove them. **Ensure the power to the light is off before remove or inserting any bulbs, shims, or branches.*
Fixture_Spacer_Shim.stl
To use this lamp as a ceiling fixture you must remove the base plate and power adapter socket. Then you can print this shim which will brace the lamp against your ceiling and has holes 89mm apart for connecting to the electrical fixture box in your ceiling. This shim acts as a brace that allows you to tighten the fixture without fear of bowing the plastic base.
Once you’ve printed this shim and checked against your electrical box you can use the holes as guides to drill through the base of the lamp. Drill slowly, and I wouldn’t recommend a punch of any sort since it might crack the plastic.
Bolt_Cap_Base.stl Bolt_Cap_Cover.stl
This cap and cover allow you to hide the bolts which must go through the base and the shim to connect the lamp to your ceiling electrical fixture box. Insert the bolt into the base, mount the lamp, then place the cover on the base. It should friction fit and give a nice finished look to the fixture.
Power_Adapter_Cover.stl
This small piece is to fill the opening left after you remove the 12 volt adapter socket from the base. It simply slides into place.
Printing
I print rafts with most things, these included, other than that these models are quite simple and you shouldn’t run into any issues.
Light up your little one’s balance bike with this simple do-it-yourself headlight.
There’s not a lot to say here, glue something ferromagnetic (something magnets stick too) to the front of the balance bike and purchase a puck shaped utility light with a magnet on the back to stick to it. I used a washer and crazy glue, super simple, loads of fun. The light may slide off the washer in the event of a collision — but putting it back on is half the fun!
For my son’s second birthday I decided to introduce him to die-cast cars and what better way than building a drag strip race track with an electronic start gate, timing and race results?
While Hot Wheels does offer a 6-Lane Raceway and a number of other drag strip style tracks, they didn’t have the timing and electronic start gate that I knew an Arduino and some other bits could provide, so I set to work. The basic idea is was have a servo motor open the start gate by pulling down a hinged plate with dowel stoppers to release the cars and a photocell (photoresistor/LDR) pointed at an infrared LED on each track to detect each car crossing the finish line.
Some quick searching revealed a number of projects from which I could draw insight and inspiration, most useful were apachexmd’s Hot Wheels Track Timer and Robby C’s Ultimate Guide to Building a Hot Wheels Race Track. This demystified a number of points, I hadn’t really had any fun with die-cast cars since I was kid myself, turns out there are some oddities.
Tracks
One of the oddities is that Hot Wheels doesn’t offer any long track for sale, all of their tracks are sold in segments a foot or two long that must be connected — the only exception being a vintage 50-foot Track Pak Raceway sold at some point in the 70′s or 80′s which can be found for upwards of $100 currently. Another track option is BluTrack which is sold in many lengths but only in a two-lane configuration for some reason. I decided to buy the readily available Hot Wheels segments in the form of 4 Hot Wheels Track Builder Straight Track kits.
I had some 1/2″ x 8″ pine left over from framing a door I thought I would use to mount the track on. There are a number of methods folks have employed to mount the Hot Wheels track on wood, I decided to use a method mentioned on Robby C’s page which involves using screws to secure a stack of two different sized washers to the wood at intervals.
A small washer below a larger one provides the elevation that the track needs to slide onto the larger washer. The exact washers and screws I used can be seen in the gallery below, be sure to drill pilot holes for the screws and try to keep them straight, the straighter the screws are, the better they will fit in the washer and, in turn, the smaller the bump in the track will be. This method (at least with the sizes I used) does leave ever so slight bumps in the track once it’s fitted, but I felt it was slight enough that it wouldn’t adversely affect the races. I used one of these washer guides for each section of track positioned to sit in the center of the track, except for the finish line track where I placed one at either end.
The track has 4 main pieces (though one I cut into two to make it more modular). These four pieces are a small section of track for the finish line which has the results display attached, the main straightaway, the start incline and a support for the start incline. Following some of the ideas on Robby C’s page again I decided to use hinges to connect the start incline track to its support piece as well as to the straightaway allowing for an adjustable incline. If you use hinges with removable pins it allows for easier disassembly.
I ended up cutting the straightaway into two sections, and I’ll probably do the same with the incline so that I can make the entire track shorter and thus more palatable in the living room.
For the joint between the incline and the straightaway I made sure that no track joints would run across the curve allowing for the longest pieces of track at this joint and thus a smooth transition for cars from the incline to the straightaway.
The flat joints I cut where the tracks connect, this makes disassembly a bit easier, but I’m not sure it was the right choice as some of the wood warped and having a track joint and a wood joint at the same spot may not result in the smoothest run. Experiment with the hinges and see which orientation works best for your setup.
Start Gate
The start gate on this track uses a high torque servo to actuate a hinged plate that has 4 wood dowels inserted into it. The dowels feed up through routed slots in the wood and tracks to hold the cars at the start gate.
The Hot Wheels tracks can be cut easily with a sharp exacto, though it’s difficult to get the corners of cuts perfectly smooth. The track can also be drilled, one method is to drill an appropriate diameter hole at either end of the route you wish to cut and then connect the two holes with a single exacto cut on either edge.
To start the race the servo pulls a stiff wire which is connected to the hinge plate with a small L-bracket, this pulls the dowels back down through the routed slots and releases the cars. The slots I routed in the wood were 1/2″, the track slots were a little smaller than that, somewhere between 1/4″ and 1/2″ as the dowels themselves were 1/4″ diameter and needed some clearance to move smoothly. The dowels are simply friction fit into drilled holes.
It may not be obvious from the video and photos, but I drilled a small hole in the L bracket which fit the wire much better than the large screw holes. This prevented any extra travel of the wire at the hinge plate connection when the servo actuates.
The wire I used to connect the servo to the hinge plate is a malleable steel of some sort, when my son decides to push or pull on the start gate hinge or dowels it will bend this wire rather than stress the servo, after which I inform him that is not how it’s suppose to function and bend the wire straight again. For my setup a run-of-the-mill servo wasn’t strong enough to push and pull the 1/4″ wooden hinged plate so I picked up a high torque servo. If you made a lighter, thinner hinge plate you may be alright with a weaker servo.
Robby C mentions something about this type of drop-out start gate being not as fair as a gate that lifts rather than drops, but I’m not sure why that would be — in any case, my goal was not to create a track fit for the world cup of die-cast racing. A lift gate would have required more fabrication, so I opted for the simpler drop-out.
Finish Line
The finish line employs 4 photocells, also know as photoresistors or LDR’s (Light Dependent Resistors) which sit in an enclosure above the track in holes drilled into a piece 1/2″ piece of wood. These photocells point down through the drilled holes, through larger drilled holes in the enclosure at 4 infrared LED’s embedded in the wood under the track and aligned with holes in the track above. Placing the photocells in holes in the 1/2″ piece of wood keeps them focused on their respective infrared LED underneath without picking up a lot of ambient light.
While the infrared LED’s don’t produce any light visible to the naked eye, they are detected by the photocells and when a car passes over the infrared LED, the reading on the respective photocell drops dramatically and thus the Arudino brain can determine when each car passes the finish line by waiting for the photocell reading to drop.
Embedding the photocells into a piece of wood also allowed me to align that wood with holes I drilled in the track wood for the infrared LED’s before placing the wood, along with the photocells in the enclosure. Once I’d aligned the wood, I drilled holes in it for the photocells, wired up the photocells and placed that entire piece of wood into the enclosure. The holes I drilled in the enclosure were much larger and thus I had room to align the wood with the photocells to the infrared LED’s without having to worry about aligning exactly with the holes in the enclosure.
I wrote a specific Arduino sketch in order to align the photocells which wrote the photocell values to the computer via a serial connection. Since then I have added a debug mode to the race track, pressing both the start race and track reset buttons simultaneously will engage the debug mode where the Arduino will write the photocell values out to the 7-segment race result displays so that I can check the photocell alignments.
One of the issues I ran into was that it seemed the power needed to actuate the start gate servo would draw too much from the rest of the circuit causing the infrared LED’s to dim and trigger the photocells. To get around this I added a 150ms delay to allow the circuit to recover after opening the start gate.
Circuit
None of the electronics used in the project are very complex. I collected various components mostly from RobotShop, SparkFun, Creatron and locally.
These components and their circuits are all connected to the Arduino which runs the sketch at the bottom of this post. If I get a chance to draw one up, I’ll post a circuit diagram.
Car Storage
After purchasing a good starting set of cars to go along with the drag track I needed some way to store the hoard. It seemed likely that a generic storage container would do the trick as long as the compartment sizing matched. I wasn’t all that pleased with the purpose-build die-cast storage containers. A little bit of searching revealed this Creative Options Thread Organizer which fits 48 cars almost perfectly. It’s only half-full in the photo below, with the same number of compartments on the reverse side still to be populated.
Next Steps
While it turned into a race to finish this project in time for my son’s birthday, I had initially intended to integrate a Raspberry Pi to record race statistics and another fun function, but I’ll leave that to everyone’s imagination until I get around to implementing it. The whole setup could also use some Hot Wheels stickers.
Update
I’ve since removed a section from the start incline and the straightaway to reduce the overall size of the track in order to move it to a more permanent location (rather than across our living room). Below is a short video of my son operating the shortened track, he doesn’t seem to mind the change and still enjoys the track quite a bit.
Arduino Sketch
/* Hot Wheels Drag Strip v1.2 */
#include <Servo.h>
#include <SPI.h> // Include the Arduino SPI library
// SPI SS pins
const int displayPinLane1 = 7;
const int displayPinLane2 = 4;
const int displayPinLane3 = 6;
const int displayPinLane4 = 5;
// Photocell pins
const int photocellPinLane1 = 2;
const int photocellPinLane2 = 3;
const int photocellPinLane3 = 4;
const int photocellPinLane4 = 5;
int photocellReadingLane1;
int photocellReadingLane2;
int photocellReadingLane3;
int photocellReadingLane4;
const int photocellThreshold = 4;
// Button pins
const int startButtonPin = 2;
const int resetButtonPin = 3;
const int gateServoPin = 14;
Servo gateServo;
// Servo positions
const int openGateServoPosition = 10;
const int closeGateServoPosition = 30;
int startButtonState = 0;
int resetButtonState = 0;
int raceStatus = 0;
int lane1Status = 0;
int lane2Status = 0;
int lane3Status = 0;
int lane4Status = 0;
int currentPlace = 0;
unsigned int counterLane1 = 0; // These variables will count up to 65k
unsigned int counterLane2 = 0;
unsigned int counterLane3 = 0;
unsigned int counterLane4 = 0;
String displayString;
char tempString[10]; // Will be used with sprintf to create strings
int animationTimer = 0;
bool showPlace = true;
void setup()
{
gateServo.attach(gateServoPin);
gateServo.write(closeGateServoPosition);
pinMode(startButtonPin, INPUT);
pinMode(resetButtonPin, INPUT);
// -------- SPI initialization
pinMode(displayPinLane1, OUTPUT);
digitalWrite(displayPinLane1, HIGH);
pinMode(displayPinLane2, OUTPUT);
digitalWrite(displayPinLane2, HIGH);
pinMode(displayPinLane3, OUTPUT);
digitalWrite(displayPinLane3, HIGH);
pinMode(displayPinLane4, OUTPUT);
digitalWrite(displayPinLane4, HIGH);
// Begin SPI hardware
SPI.begin();
// Slow down SPI clock
SPI.setClockDivider(SPI_CLOCK_DIV64);
clearDisplays();
s7sSendStringSPI(displayPinLane1, "Ln 1");
s7sSendStringSPI(displayPinLane2, "Ln 2");
s7sSendStringSPI(displayPinLane3, "Ln 3");
s7sSendStringSPI(displayPinLane4, "Ln 4");
// High brightness
setBrightnessSPI(displayPinLane1, 255);
setBrightnessSPI(displayPinLane2, 255);
setBrightnessSPI(displayPinLane3, 255);
setBrightnessSPI(displayPinLane4, 255);
}
void loop()
{
animationTimer++;
if(animationTimer > 200) {
if(showPlace == true) {
showPlace = false;
} else {
showPlace = true;
}
animationTimer = 0;
}
photocellReadingLane1 = analogRead(photocellPinLane1);
photocellReadingLane2 = analogRead(photocellPinLane2);
photocellReadingLane3 = analogRead(photocellPinLane3);
photocellReadingLane4 = analogRead(photocellPinLane4);
resetButtonState = digitalRead(resetButtonPin);
startButtonState = digitalRead(startButtonPin);
if(resetButtonState == HIGH && startButtonState == HIGH) {
// Debug mode
clearDisplays();
s7sSendStringSPI(displayPinLane1, String(photocellReadingLane1)+" ");
s7sSendStringSPI(displayPinLane2, String(photocellReadingLane2)+" ");
s7sSendStringSPI(displayPinLane3, String(photocellReadingLane3)+" ");
s7sSendStringSPI(displayPinLane4, String(photocellReadingLane4)+" ");
delay(1000);
} else if(resetButtonState == HIGH && raceStatus > 0) {
raceStatus = 0;
clearDisplays();
s7sSendStringSPI(displayPinLane1, "Ln 1");
s7sSendStringSPI(displayPinLane2, "Ln 2");
s7sSendStringSPI(displayPinLane3, "Ln 3");
s7sSendStringSPI(displayPinLane4, "Ln 4");
lane1Status = 0;
lane2Status = 0;
lane3Status = 0;
lane4Status = 0;
counterLane1 = 0;
counterLane2 = 0;
counterLane3 = 0;
counterLane4 = 0;
currentPlace = 0;
gateServo.write(closeGateServoPosition);
} else {
if (raceStatus == 0 && startButtonState == HIGH) {
// start the race
gateServo.write(openGateServoPosition);
// wait for servo to drop
delay(150);
raceStatus = 1;
} else if (raceStatus == 1) {
// race is running
int carsAcross = 0;
if (photocellReadingLane1 < photocellThreshold && lane1Status == 0) {
showPlace = true;
currentPlace++;
carsAcross++;
lane1Status = currentPlace;
gateServo.write(closeGateServoPosition);
}
if (photocellReadingLane2 < photocellThreshold && lane2Status == 0) {
showPlace = true;
if(carsAcross == 0) {
currentPlace++;
}
carsAcross++;
lane2Status = currentPlace;
gateServo.write(closeGateServoPosition);
}
if (photocellReadingLane3 < photocellThreshold && lane3Status == 0) {
showPlace = true;
if(carsAcross == 0) {
currentPlace++;
}
carsAcross++;
lane3Status = currentPlace;
gateServo.write(closeGateServoPosition);
}
if (photocellReadingLane4 < photocellThreshold && lane4Status == 0) {
showPlace = true;
if(carsAcross == 0) {
currentPlace++;
}
carsAcross++;
lane4Status = currentPlace;
gateServo.write(closeGateServoPosition);
}
updateDisplay(displayPinLane1, lane1Status, counterLane1);
updateDisplay(displayPinLane2, lane2Status, counterLane2);
updateDisplay(displayPinLane3, lane3Status, counterLane3);
updateDisplay(displayPinLane4, lane4Status, counterLane4);
if (lane1Status == 0) {
counterLane1++;
}
if (lane2Status == 0) {
counterLane2++;
}
if (lane3Status == 0) {
counterLane3++;
}
if (lane4Status == 0) {
counterLane4++;
}
}
}
delay(10); // This will make the display update at 100Hz.*/
}
void clearDisplays()
{
clearDisplaySPI(displayPinLane1);
clearDisplaySPI(displayPinLane2);
clearDisplaySPI(displayPinLane3);
clearDisplaySPI(displayPinLane4);
}
void updateDisplay(int displayPin, int laneStatus, unsigned int laneCounter) {
// Magical sprintf creates a string for us to send to the s7s.
// The %4d option creates a 4-digit integer.
sprintf(tempString, "%4d", laneCounter);
// This will output the tempString to the S7S
if(laneStatus == 0 || showPlace == false) {
s7sSendStringSPI(displayPin, tempString);
// Print the decimal at the proper spot
if (laneCounter < 10000) {
setDecimalsSPI(displayPin, 0b00000010); // Sets digit 3 decimal on
} else {
setDecimalsSPI(displayPin, 0b00000100);
}
} else {
setDecimalsSPI(displayPin, 0b000000000);
if(laneStatus == 1) {
s7sSendStringSPI(displayPin, "1st ");
} else if(laneStatus == 2) {
s7sSendStringSPI(displayPin, "2nd ");
} else if(laneStatus == 3) {
s7sSendStringSPI(displayPin, "3rd ");
} else {
s7sSendStringSPI(displayPin, "4th ");
}
}
}
// This custom function works somewhat like a serial.print.
// You can send it an array of chars (string) and it'll print
// the first 4 characters in the array.
void s7sSendStringSPI(int ssPin, String toSend)
{
digitalWrite(ssPin, LOW);
for (int i=0; i < 4; i++)
{
SPI.transfer(toSend[i]);
}
digitalWrite(ssPin, HIGH);
}
// Send the clear display command (0x76)
// This will clear the display and reset the cursor
void clearDisplaySPI(int ssPin)
{
digitalWrite(ssPin, LOW);
SPI.transfer(0x76); // Clear display command
digitalWrite(ssPin, HIGH);
}
// Set the displays brightness. Should receive byte with the value
// to set the brightness to
// dimmest------------->brightest
// 0--------127--------255
void setBrightnessSPI(int ssPin, byte value)
{
digitalWrite(ssPin, LOW);
SPI.transfer(0x7A); // Set brightness command byte
SPI.transfer(value); // brightness data byte
digitalWrite(ssPin, HIGH);
}
// Turn on any, none, or all of the decimals.
// The six lowest bits in the decimals parameter sets a decimal
// (or colon, or apostrophe) on or off. A 1 indicates on, 0 off.
// [MSB] (X)(X)(Apos)(Colon)(Digit 4)(Digit 3)(Digit2)(Digit1)
void setDecimalsSPI(int ssPin, byte decimals)
{
digitalWrite(ssPin, LOW);
SPI.transfer(0x77);
SPI.transfer(decimals);
digitalWrite(ssPin, HIGH);
}
The best thing about IKEA’s ANTILOP Highchair is that it’s cheap, and I mean dirt cheap. With a price tag of $19.99 you don’t have to worry about destroying it, or even not liking it. Coming in as a close second best thing is the fact that you can purchase extra trays which you can modify into activity centers you can swap in and out, such as this pro-gamer training rig.
For the Highscore Chair I added some Joysticks and Buttons I had lying around, loosely intended for expanding my arcade cabinet. These parts have the added advantage of actually being functional, down the road I can hook them up to a Raspberry Pi, an Arduino, MIDI out (Update: I’ve since added MIDI out), or just to some lights and buzzers — if you’ve got any ideas I’d love to hear them. The sky’s the limit as to what you can add to these trays, just keep safety in mind, for example, I placed the joysticks out of the arc of the baby’s head if he were to fall forward.
The trickiest part of this whole process is swapping out the trays. There are four rather stiff tabs that snap in place when attaching the tray. I may make a tool of some sort to make removal easier but in the mean time four butter knives do the trick. It’s probably best to swap the trays without the baby in the highchair, just slip a butter knife under each tab and once all four are in you can remove the tray easily (the butter knives will fall), really, any flat object would work, popsicle sticks perhaps? Now having thought about it, I’ll probably cut off the inner two tabs, the tabs are surprisingly strong I don’t see any risk of the baby removing the tray even if I remove two of them, however removing two would probably allow removal of the tray by an adult pressing one tab with each hand and pushing up on the tray with a knee or the like.
The plastic is very easy to drill, a stepped bit works wonders. Cutting would be a little more difficult but nothing a dremel wouldn’t be able to handle.
Update: I did end up snipping off the inner two tabs on both trays (with some sheet metal shears) and it worked like a charm. The trays can now be removed without the need for tools. Just push on the two remaining tabs with your thumbs keeping your fingers behind the lip for leverage, then use your chest, shoulder or chin (whatever works) to push up on the tray, once the tabs clear the lip you can let go and just lift the tray off. Be sure not to leave any sharp edges and swapping is still best done while the chair is unoccupied due to the number of places little fingers could get pinched while putting the tray on.
Update: I’ve since added MIDI out, which amounts to 10 MIDI triggers, 8 for each joystick and one for each button. The Highscore Chair now triggers samples loaded onto an Akai MPC1000, but with MIDI out it could be used as any sort of control surface now. The MIDI out is accomplished through an Arduino UNO, by following a couple of simple tutorials, found here and here, you can get buttons triggering MIDI notes in no time. I’ll shoot a new video when the little fellow is up for it. While the underside of the tray is already quite isolated from the baby due to the structure of the chair for added safety I’ll be putting the Arduino, battery and MIDI Jack in an enclosure and covering the entire tray undercarriage.
Here’s the Arduino sketch, very bare-bones. I cranked it out after a long day so I didn’t want to risk using the wrong array syntax so it’s just long hand, maybe that helps readability for beginners? Anyhow it would be much shorter if it used arrays. Basically there’re variables for each button pin and variables for the state of each button, it will only send one MIDI note per button push and wait until the button’s been released and pressed again before re-sending that note. This sketch is hard-coded to send MIDI notes 36 through 45 on channel 1 at 69 velocity.