Introduction: Bedfellow Robot Bed

About: My name is Randy and I am a Community Manager in these here parts. In a previous life I had founded and run the Instructables Design Studio (RIP) @ Autodesk's Pier 9 Technology Center. I'm also the author of t…

Bedfellow is an autonomous robot bed which seeks out new engagements. In other words, I have robotized my personal bed to socialize and share itself with others.

Perhaps a little bit more of an explanation is in order. A bedfellow can be defined as a “person who shares a bed with another.” While it is typically assumed that bedfellows are in a mutually exclusive relationship, this sometimes is not the case. On occasion a bedfellow may go off and share your bed with a plurality of others aside from yourself. With this anomaly in mind, I have created the Bedfellow robotic bed as a potential solution. My intent in doing this was to functionally replace any wandering bedfellows. With a bed capable of sharing itself with whoever else it may chance upon, there is no need to keep someone else around to perform this function for you.

On a practical note -- Okay -- Perhaps not a practical note -- But on the technical front... This is basically an autonomous self-driving electric vehicle. Whereas companies like Google have spent millions of dollars and tasked teams of people with producing such a contraption, I did the same thing myself for a fraction of the cost. Granted, this bed is perhaps not as streetworthy as a normal automobile, but if one were to think of a car less as something to get from point-A to point-B and more as an expression of individuality -- well then -- this vehicle is much more unique and way better for picking up potential partners. No one can pass up going for a ride in my bed.

At the very least, this is probably the most elaborate IKEA hack ever created.

Step 1: About the Design

In making Bedfellow, I basically converted my personal Queen bed into an autonomous self-driving electric vehicle. Don't let its furniture-ness fool you. There is a bit of umph behind this. The bed is capable of driving with a sustained 8 horsepower of force and is capable of peaking up to 25 horsepower for a limited time. The current top speed is unknown, but it is assuredly faster than any bed should go. There is also a lot of torque behind it. It has carried up to at least 12 people at once and has not shown any noticeable signs of slowing down.


The bed was designed to support up to 3,000 pounds worth of weight, and is built around a wooden torsion box frame. The central drive column is capable of supporting the entire 3,000 pounds in its own right. I did this in case the bed encountered a highly uneven surface and all four outer casters found themselves off the ground.

The outer casters have springs to absorb some of the shock and account for uneven surfaces. However, there is no real suspension to speak of, so it is not exactly a road vehicle. A pothole might be potentially devestating. This bed was largely designed for indoor domestic use.

The two drive wheels are centrally located underneath the bed. With this wheel arrangement, the bed is capable of turning on point like a tank by rotating the wheels opposite from one another. This makes it able to move around fairly competently in tight spaces. The motors are connected to the drive wheels by way of a 20:1 gear reduction. Without this, the whole thing would move very - very - fast. This gear reducer is basically a giant worm drive mechanism that reduces the bed's movement to gallery-friendly speeds.

There are two high-powered DC motors being controlled by two Alltrax motor controllers. These controllers are typically used in golfcarts and other electric vehicles. My specific model is capable of handling up to 400 amps. In the motor control circuit there is also a solenoid for engaging the power, and a reverse contactor for reversing motor direction. Each motor has its own seperate drive circuit and battery bank. Currently the drive system is operating at 24V, but I can be boosted to 48v for increased speed. However, traveling any faster than it is currently capable is likely not a good idea. There are also two chargers for each battery bank onboard.

The whole system is being controlled by an Arduino Mega which is reading 12 ultraonic sensors and interfacing the Alltrax motor controllers. The logic is rather simple. It is basically picking a random direction to move, checking to see if there is anything very close by in that direction, and then if all is clear - it moves. If there is something in the way, it picks another direction randomly and tries again. There are four safety bumpers which are connected to the Arduino using interrupts. If they are hit, the bed immediately stops moving and restarts its routine.

This may seem simple and arbitrary, but people interface with it as though it has intelligence and is purposefully considering them. Since this robot is rather large, people approach it as an equal and it creates a relationship between person and machine that none of my other smaller robots have ever really seemed to capture.

As already mentioned, the entire system was built around my personal Queen-sized bedframe and incorporated my actual mattress. The frame itself was a standard Ikea box frame. The aspects of the bed frame that were maintained are no longer particularly structural, but rather aesthetic. It is a bit like tearing down an entire building, but keeping the facade.

Step 2: Yeah Yeah... I Get It...

Before you flood a thousand discussion boards talking about how pointless these instructions are, I just want to point out that I get it. No one is likely ever going to recreate this and, even if they wanted to, they probably don't have access to all of the tools necessary to easily do so. This project uses a ton of expensive parts, is designed around a discontinued Ikea bed frame, takes forever to make, is largely cost prohibitive, and does not make sense to many highly rational individuals.

So - why even share it? Let alone - why share it in such painstaking detail?

For the last ten years I have strived to make all of my art 'open source.' While open source software is by and large a solved problem, 'open source' hardware is still in its early stages. Beyond that, 'open source' art is basically a little explored frontier on the borders of Imagination Land, making it even more problematic. While I can write extensively on the shortcomings of making 'open source' art, I'd prefer to briefly focus on some of the benefits of the practice.

1) Sharing Means Caring
Sharing process and technique -- even if the project is not directly replicated -- is generally useful. It shows others how I accomplished various aspects of this project. Even if someone does not build a robot bed, they might find the instructions I posted on interfacing an Arduino to a 8HP electric motor useful. Or -- perhaps -- they always wondered where to source 12" diameter non-marking wheel capable of supporting a 3000 pound load. Now after reading my project, they know. I solved that problem, and now someone else does not have to re-invent the wheel so-to-speak. Sharing my accomplishments helps other people move forward more easily with their own.

2) Motivational Speaking
Someone may see the amount of effort some random guy on the internet put into bring their vision into the world and be inspired to take on a project of their own design. That is not to say that a robotic bed is going to get someone off their couch in their basement and have them suddenly work day and night to find a cure for cancer. However, it might get them off the couch to do something. And the more people who get inspired to proactively take steps to re-shape the world as they see fit -- no matter how silly -- the better off I feel that we will be.

3) Entertainment Value
By now I have created hundreds of online step-by-step tutorials. Some are easily accessible to the average person and some require a degree of advanced skill and/or knowledge. I would say that across the board very few actually get directly replicated. Considering that these projects collectively have millions upon millions of page views, I would venture to guess that the majority of people who look at them are simply curious about the thing itself or the process I used to ge there. It is the same reason people watch How It's Made on TV. It is not that they are researching to open a factory producing consumer goods, but rather simply have an innate desire to better understand the world. People are generally curious.


Of course, I could list out probably a half a dozen more reasons for why I share my work in this manner. However, I think I primarily hit on the key points. Hopefully that helps to clear things up.

Step 3: Go Get Stuff

You will need:

(x1) Queen box bedframe (preferably Ikea)
(x2) Motenergy ME0909 4HP continuous motor
(x12) Ultrasonic rangefinding sensors
(x1) 20:1 right-angle 4.74 HP reducer (left)
(x1) 20:1 right-angle 4.74 HP reducer (right)
(x10) 1 x 1 x 6' hardwood beam
(x2) 1 x 2 x 8' hardwood beam
(x3) 4' x 8' x 1/4" plywood
(x1) 4' x 8' x 3/4" plywood
(x4) Poly/iron non-marking swivel casters
(x1) 32" x 32" x 1/2" aluminum
(x2) 400a motor controller
(x2) 200A Solenoid
(x1) 20' of 2AWG cable (red)
(x1) 20' of 2AWG cable (black)
(x30) 2AWG wire lug connectors
(x2) 10W 220 ohm resistors
(x2) 250A Fuse
(x2) 3.11" H-series timing pulley
(x2) 3.44" H-Series timing pulley
(x2) 27" H-Series timing belts
(x4) SH-Style 7/8" bore quick-disconnect bushings
(x2) High speed cast iron mounted steel 1.375" bearings
(x1) Fully keyed 1.375" x 9" drive shaft
(x4) 1.375" shaft collars
(x1) 15A cord
(x1) 5/16" x 5/16" x 12" spring steel key stock
(x1) 1" x 1" x 8' aluminum square stock
(x1) 24" x 2.5" aluminum rod
(x1) 1" diameter, 1/2" inner diameter x 25' aluminum tube
(x1) 2" x 6" x 1-1/2" aluminum rectangular stock
(x1) 1/2" x 4' x 4' aluminum sheet
(x1) 1/4" x 8' x 4' aluminum sheet
(x1) 1/2" OD x 1/4" ID x 12" aluminum tube
(x2) 7" x 3" x 4-1/2" aluminum boxes
(x2) 1" rubber gaskets
(x1) 12" poly/iron wheels with 1.375" keyed bore
(x4) UB121000 100AH 12V gel cell batteries
(x2) 24V 20A charger
(x1) DPST master battery disconnect switch
(x2) SPST relay - 24V
(x2) SPDT relay - 24V
(x1) Arduino Mega
(x1) Arduino Mega Proto Shield
(x12) 1N4004 diodes
(x2) 6A diode
(x4) TIP120 transistor
(x4) 1K resistors
(x4) 10K resistors
(x4) 10uF capacitors
(x2) 5A fuses
(x2) 5A fuse holders
(x1) DC power plug
(x6) 4-Position screw terminals
(x12) 4-pin female headers
(x3) 2.875" x 1.875" PCB
(x2) 2.0625" x 6" PCB
(x1) 15' USB A to B cable
(x20) M3 standoffs
(x40) M3 x 10mm bolts
(x1) 12" x 12" x 1/4" clear acrylic
(x2) 81" TS-47 black sensing edge switch
(x2) 62" TS-47 black sensing edge switch
(x2) DC182 24V reverse contactor
(x1) 15-30v to 12v / 10 amp converter
(x1) 1" x 24" shrink tube
(x1) 2' 14AWG wire
(x3) Crimp terminals
(x1) 3-prong souble socket
(x1) 3 prong screw mount power inlet
(x1) Insulation foam
(x1) Queen-sized mattress
(x1) Queen-sized fitted sheets
(x1) Queen-sized top sheet
(x2) Pillows
(x2) Pillow cases
(x1) Comforter
(x30) 6-32 x 1" bolts
(x30) 6-32 nylon insert lock nuts
(x2) 1/4-20 set screws
(x2) 1/2-20 x 1" bolts
(x4) 1/2-20 x 4" bolts
(x20) 1/4-20 washers
(x20) 1/4-20 nylon lock nuts
(x8) 5/16-18 x 2"
(x16) 3/8-16 x 1-1/2" flathead bolts
(x8) 3/8-16 x 1-1/2 bolts
(x8) 3/8-16 split ring washers
(x8) 3/8-16 washers
(x25) 3/8-16 split ring washers
(x200) 1/2-13 nylon insert lock nuts
(x200) 1/2" fender washers
(x200) 1/2" split ring lock washers
(x2) 1/2-13 x 12" bolts
(x8) 1/2-13 x 9" bolts
(x4) 1/2-13 x 3" bolts
(x28) 1/2-13 x 10" bolts
(x32) 1/2-13 x 1" flat head bolts
(x16) 1/2-13 x 2" bolts
(x20) 1/2-13 x 2-1/2" bolts
(x8) 7/16-14 x 2" bolts
(x8) 7/16-14 x 3/4" bolts
(x10) 6-32 tee nut inserts
(x10) 6-32 x 1.5" bolts
(x10) 6-32 washers
(x10) Ratchet straps
(x1) Assorted black zip ties
(x1) Drop cloth
(x1) Random odds and ends

(Note that some of the links on this page are affiliate links. This does not change the cost of the item for you. I reinvest whatever proceeds I receive into making new projects. If you would like any suggestions for alternative suppliers, please let me know.)

Step 4: Cut the Drive Assembly Plates

Use the attached bracket templates to cut out motor mount brackets out of 1/2" aluminum.

To do this I used a water jet. However, the shapes are not remarkably complicated and you could feasibly accomplish the same using a manual mill such as a bridgeport. With enough patience, you may also even be able to use a drill press and band saw.

Also note, throughout this project I use the water jet and a 400W laser cutter. Yes, I know that you likely don't have one. However, most of these parts are simple and can be produced using a host of techniques and tools. That said - this will be the last time I am going to address this here.

Step 5: Countersink the Motor Plate

Countersink the eight holes around the perimeter of the small square of the motor mount plate that mates with the gear box.

Remember that the heads of the bolts need to be flush with the gear boxes, and there is both a right and left hand side. In other words, the motor mount plates should not be identical but mirror each other.

Step 6: Remove the Bolts

Remove the bolts fastening down the metal retaining plates for the input shaft of the gear reduction boxes.

Step 7: Attach the Motor Plate

Place the motor drive plate on top of the existing plate encasing the gearbox's output shaft.

Firmly fasten both plates in place using the four mounting bolts. These bolts need to be fairly tight to keep the gearbox from leaking oil.

Repeat for other motor assembly.

Step 8: Attach the Bearing

Attach the bearing to the other motor assembly plate.

Repeat for the other motor assembly.

Step 9: Wheel Standoffs

Cut the 1" tube into eight 7" sections.

Step 10: Wheel Cage

Pass 9" x 1/2-13 bolts through the bearing motor plate, 1" tube, and finally the gearbox motor plate. Firmly secure them in place using nylon lock nuts to complete the wheel cage.

Repeat for the second assembly.

Step 11: Slotted Lock Rings

Cut two slotted lock rings using the attached file. These are meant to keep the key from sliding out of place when the gearbox shaft rotates at high speeds.

To elaborate - The quick-release bushing has enough bite to grab the input shaft, but the lock nut misses the key. So, there is nothing holding the key in place and when it begins to rotate, the key will likely slide out. While the bushing might have enough bite to just keep the pulley in place without slipping, I am not about to chance it. I made these to keep the key in place and prevent the pulley from coming loose.

Step 12: Attach the Gearbox Pulley

This part is a little tricky.

Insert 3/8-16 x 1-1/2" flat head bolts into the countersunk holes in the motor assembly mount plate.

Place the motor plate around the input shaft plate.

Insert four 5/16-18 x 2" bolts throught the cover plate and slide split ring washers onto them. Slide the cover plate over the ends of the flat head bolts such that there is a 1/2" gap between the cover plate and the input shaft plate.

Insert the mounting bolts in the quick disconnect bushing and slide it onto the input shaft.

Mount the keyed lock ring right in front of the quick disconnect bushing such that it is flush with the end of the drive shaft.

Slide the pulley onto the quick disconnect bushing and slip a wrench between the crack in the plates to tighten the bolts. This will require cycling through all three bolts to tighten each a little at a time until the pulley is locked firmly in place.

Repeat for the other assembly.

Step 13: Attach the Motor Pulley

Pass the motor shaft through the center hole of the motor mounting plate

Slide the quick disconnect bushing onto the motor shaft. Slide the pulley on and lock both in place by tightening the mounting screws with a wrench.

Place the belt loosely around both pulleys.

Use 3/8-16 bolts, washers, split ring washers, and nylon lock nuts to loosely attach the motor plate to the larger 1/2" aluminum motor assembly plate.

Slide the plate away from the gearbox until the pulley is made taught.

Finally, tighten all of the bolts down to lock the motor firmly in place.

Repeat for the other assembly.

Step 14: Wheel Cage Mounts

Starting one inch from either edge of one of the foot long 1" square stock, drill a 1/2" hole on center every two inches inches.

Rotate the square tube and then drill 1/2" holes on center every two inches that are 2" in from either edge.

Repeat for the other piece.

Step 15: Motor Plate Mount

Starting 3/4" from either edge of one of the 9" long 1" square stock sections, drill a 1/2" hole on center every two and a half inches.

Rotate the square tube and then drill 1/2" holes on center every two and half inches that are 2" in from either edge.

Repeat for the other piece.

Step 16: Attach the Mounts

Using 1/2-13 x 2-1/2" bolts and nylon lock nuts, attach the wheel cage and motor plate mounts to the wheel cage and motor mounts respectively.

Step 17: Caster Standoffs

Cut four 3-3/8" sections from the 24" x 2.5" aluminum rod.

Step 18: Alignment Plate

Use the attached template to center punch drill holes on one side of one of the 3-3/8 aluminum rods.

Step 19: Drill Mounting Holes

Using the marked centers, drill four 27/64" by 1" deep holes.

Step 20: Tap the Mounting Holes

Thread the four holes using a 1/2-13 tap.

Step 21: Countersink the Plates

Countersink all of the plate hole using an 82 degree countersink bit.

Step 22: Repeat

Bolt the first plate loosely in place.

Turn the assembly on its side and sse the alignment guide and the second plate to center punch the opposite side of the cylinder.

Drill and tap this side of the cylinder the same as the opposite end.

Repeat this process for all four posts.

Step 23: Attach the Plates

Use 1/2-13 x 1" flat head bolts to attach the plates to both sides of all of the cylinders.

There should now be 4 overly engineered spacing posts.

Step 24: Start the Torsion Box

I built a torsion box that was 60" x 80". This was precisely the inside measurement of my bedframe.

The inside frame of the torsion box consists of two maple 1 x 2's running the outer length, and maple 1 x 1's connecting these every 10" from center leaving out the beam at the 40" mark.

To connect them I laid everything out, drilled pilot holes, applied glue and then screwed it all together. I then waited for the glue to set.

Step 25: Plywood Panels

Once the inner frame was dry, I laid out 1/4" plywood panels over top of the frame. Since standard sectional lumber is typically only 4' wide and they apparently have stopped manufacturing 5' wide over-sized 1/4" plywood, I had to use two sheets - a 12" x 80" sheet and a 48" x 80" sheet.

To affix the plywood, I applied a generous amount of glue and then tacked the sheets to the frame using a nail gun.

Step 26: Caster Plywood Insert Mounts

Cut out four caster plywood insert mounts using the attach file.

These will sit inside the frame between the two sheets of plywood and be used to mount the caster spacing posts.

Step 27: Glue

Flip the torsion box over if you have not done so already.

Glue the caster plywood insert mounts into each corner of the torsion box.

Step 28: Battery Box Spacers

Cut the 1" aluminum pipe into 28 equal 7-1/2" sections.

Step 29: Mount the Casters

Affix the casters to the spacing posts using 1/2-13 x 2" bolts and nylon washer lock nuts.

Step 30: Plywood Motor Mount Inserts

Cut out two plywood moter mount inserts using the attached files. Glue those to the plywood in the center of the torsion box.

Apply weight to ensure they lay flat once the glue is dry. The batteries work really well for this purpose.

Step 31: Cut the Plywood Battery Inserts

Cut the plywood battery inserts and alignment plate using the attached file.

Step 32: Glue the Battery Inserts

Position the wooden battery inserts inside the torsion box.

Use the wooden alignment panel and some spare 1/2-13 bolts to make sure the plates are aligned.

Once the alignment is good, lift the panels, apply a generous amount of glue underneath, lower them back down, and then realign them.

Place a fair amount of weight on top of these panels - I used the batteries - and wait for them to dry.

Step 33: Drill Holes

Once all of the plywood inserts are in place, I drilled out all of the mounting holes through the top plywood panel.

Step 34: Insulation Foam

Insert pink insulation foam into the gaps in the frame. This will help prevent creaking and echoing noises when it is later put to use.

Step 35: Second Side

Finally, I glued on the second layer of plywood to complete the box. I alternated the side on which I placed the thin strip so that there was not a seam running down one side of the box.

Once dry this side was dry, I routed out the two rectangular wheel channels. I also drilled the rest of the mounting holes all the way through the box. However, I did both of these in a bit of a rush and forgot to get pictures.

Step 36: Clean the Edges

Use a router to trim away any over-hanging plywood edges and ensure the the frame is square.

Remove any lingering screws used in the initial construction of the frame.

Step 37: Cut the Wheel Shaft

Cut the wheel shaft into two 4.5" sections.

Step 38: Wheel

When building the bed, I had a number of constraints on the wheels. Foremost, the gallery I was placing the bed in required non-marking wheels. Thus, I had to specifically find non-marking polyurethan wheels.

I also had to find wheels which were low-profile and 12" or less.

It also had to fit on the 1.375" output shaft of the gearbox.

Finally, and perhaps most importantly, the wheels needed to be able to support the weight of the entire assembly plus the weight of up to a dozen riders. The reason for this was that if there was an uneven floor, there could be a case in which all of the weight was bearing down upon the drive assembly.

My wheel options were obviously very limited and the likelihood of finding an off-the-shelf solution was rather unlikely. Thus, I had to have the wheel custom made. I eventually found a place that were able to make 12" polyurethan wheels with a 1.375" keyed bore, and a cast iron core capable of supporting around 3,000 pounds a piece. As you can imagine - like most everything else in this project - they did not come cheaply or quickly.

When they did finally arrive, they were beautiful and quite happy-making.

Step 39: Mount the Wheels

Loosen the wheel cage bolts and remove the bearing plate.

Slide a shaft collar onto the gearbox output shaft, and lock it in place about 1/2" from the aluminum plate.

Mount the 4.5" keyed shaft in the bearing assembly. Slide a shaft collar onto the shaft, but don't tighten it down yet.

Slide the wheel onto the gearbox shaft and insert a 5/16" steel key that is the legnth of the wheel bore.

Insert the key shaft in the bearing into the wheel and reassemble the wheel cage.

Finally, tighten the set screws on the wheel and the remaining shaft collar. The wheel should not be positioned snuggly between the shaft collars and locked firmly in place.

Step 40: Mount the Casters

Using 1/2-13 x 2-1/2" bolts, fender washers, and lock nuts, affix the casters to the torsion box.

Step 41: Bolt on the Drive Assemblies

Roll the tosion box platform to some place out of the way.

Position the drive assemblies under the torsion fram such that the mounting holes from the 1" square stock brackets align with the appropriate holes in the torsion box.

The assemblies will be lopsided to begin with and lifting the torsion box off the ground. This is okay.

Insert 1/2-13 x 3" bolts with fender washers down through the frame and into the square stock holes as best you can. This is largely for alignment.

Once everything is roughly in place, use ratchet straps wrapped around the frame to lift the assemblies off the ground and make them flush with the torsion box. It is always wise to put a metal block under the lifted corner to prevent it from crushing you in case the strap breaks.

Push all the bolts all the way through now, and fasten them very tightly with nylon insert lock nuts. If you need to knock a few bolts through with a hammer, that is okay. Hammering is an important aspect of robotics.

Once they are bolted to the frame, use fender washers and 7/16-14 x 1-3/4" bolts to fasten the gear box to the top of the torsion box.

The drive assemblies should now be firmly locked in place and the bed is now not going anywhere (for a little while at least). The whole thing should now weigh about 300-400 poounds and since the gearbox uses a worm gear assembly, the wheels won't spin unless the motor is engaged. Thus, this thing is not really getting pushed around or lifted.

Step 42: Drill the Bumper Rails

Drill 1/8" holes through the aluminum mounting channels every 10" on center from either edge.

Step 43: Drill the Bed Frame

Use the aluminum channels to mark drilling holes along the bottom edge of the bed frame panels.

Drill through these holes with an 1/8" drill bit.

Step 44: Mount the Bumpers

Bolt the aluminum channels to the outer base of the bed frame.

Once they are firmly attached, insert the rubber bumpers into the channel.

Step 45: Drill Sensor Holes

On one panel of the bed frame, use a hole saw or spade bit to drill two 1" holes 3-1/2" from each outer edge and one on center.

Repeat for the other three panels. You should be drilling 12 holes in total.

Step 46: Fuse Cables

Create two 12" red cables with wire lugs connectors, and two more 36" red cables with wire lug connectors.

Use nuts and bolts to attach a fuse between the 12" cable and the 36" cable for both sets.

Step 47: Insulate

Place shrink tube around both of the fuse's exposed wire terminals while leaving exposed the viewing window on the fuse.

Use a heat gun to shrink it into place.

Step 48: Kill Switch Box

Cut a hole for the power kill switch in one of the aluminum boxes using the attached template.

Also, cut a 1" hole in the center of each 4.5" x 3" side.

Step 49: Insert the Hardware

Bolt the kill switch to the box using 3/8" nuts and bolts.

Also, insert 1" rubber gaskets into each of the holes on the side.

Step 50: Wire It Up

Connect the red fuse cable to one of the terminals on the switch. Connect a red solenoid cable to the terminal that is horizontally opposite to the red cable.

Below the red battery cable, connect the other red fuse cable. And finally, connect the remaining red solenoid cable to the only open available terminal.

There should now be a fused power cable and a red solenoid cable connected to each pair of terminals on the kill switch.

Step 51: Mount the Kill Switch

Bolt the kill switch to the side of torsion box frame using 1/2-13 x 3" bolts, fender washers and lock nuts.

Re-attach the back cover plate to the kill switch box.

Step 52: Attach the Frame

Attach the box from to the torsion box using a combination of the frame's existing hardware and 6-32 bolts, washers and tee nuts.

This frame is not remarkably necessary for structural reasons, but still should be firmly attached for reasons of standard wear and tear.

Step 53: Insert the Sensors

Insert the sensors into their mounting holes on the frame and hot glue them in place.

Step 54: Mount the Bumpers

On center in one corner of each bumper channel, use a hand drill and make a 1/4" hole through the channel and bed frame.

Pass the rubber bumper switch's wires through this hole and then press the bumpers in place.

Each bumper has two wires which are basically the same. This is nice because if one wire were to fail (which happens!), the other can take its place. Redundancy is important for safety switches.

Step 55: The Charger Box

Cut a plug hole in the remaining aluminum box using the attached template.

In the lid of the same box, cut holes for the power sockets using the other attached template.

Step 56: Wire the Charger Junction Box

Bolt the standard power sockets to the inside of the charge box lid using M5 nuts and bolts.

Connect a 14AWG wire to each of the three connection terminals on the jack.

Trim those wires to be 6" - 8" long and attach a crimp terminal to the end of each.

Affix the power jack to the inside of the charger box using its mounting hardware.

Press the crimp terminals to the corresponding tabs on the power jack. That said, the only which is really important to match correctly is the ground wire.

Step 57: Mount the Solenoids

Cut two 2" x 3" x 1.5" aluminum tubes.

Drill two 1/2" mounting holes that are centered and 4" spaced in the bottom of each rectangle.

Mark and drill appropriate mounting holes for the solenoids and reverse contactor on the side face of each rectangle.

Step 58: Wire the Drive Circuit

Wire up the drive circuit as outlined in the wiring diagram.

Be sure to used the 2AWG cable for the high current 24V connections.

To see a generic DC motor wiring diagram from Alltrax, check out this link.

Step 59: Attach the Bottom Plate

Attach the bottom drive circuit plate by placing it on a sheet of cardboard and sliding it under the bed.

Once roughly in position, lift it up onto blocks and bolt the front to the underside of the gear box using 7/16-14 x 3/4" bolts.

Secure the back side of the plate in place by insert 1/2-13 x 12" bolts down through, fender washers, the torsion box, aluminum tubes, and finally the plate itself. Finally, lock the bolts in place with nylon insert nuts.

Step 60: Wire the Motors

Wire the red wire from the reverse contactor to the leftmost terminal on the left motor.

Wire the black ground wire from the motor controller to the right terminal on the left motor.

Repeat this process for the right motor.

Step 61: Drive Circuit Interface

Build the drive circuit interface boards as outlined in the attached schematic. It is advised to use screw terminals for all of the connection points.

To explain what is going on, the SPST relay is being used to turn on and off the motor controller and the SPDT relay is being used to engage the reverse contactor and change directions. When the direction is about to be changed, the SPST relay cuts the power and then the SPDT relay changes direction. This is important to do to keep the circuit from breaking.

The 6A diode and fuse are largely just there to prevent voltage and/or current spikes.

The other set of diodes is being used to connect the reverse relay to the ignition terminal without crossing wires between forward and backwards.

Step 62: The Remaining Circuit

Build the rest of the circuit as specified in the schematic above.

Step 63: Code

Okay - so - when working with code it is ideal to use something like Github to keep track of revisions. I don't do this. Thus, I accidentally wrote over the most current working version of the code. I do have the last saved version, but I am not certain how complete it is. It is likely a little buggy.

Novertheless, since none of you will likely build this thing any which way, and the bed is currently in pieces and not operational, I am just going to post what I have.

I am also sharing test code for manually controlling the motors. If you are looking at this project for interfacing an Arduino to very large motors through an Alltrax motor controller, this code will be more useful to you anyhow.

Last saved version of Robot Bed test code:

/*
This example code is in the public domain.
 
 */

//establish throttle pins
int leftThrottle = 3;    // LED connected to digital pin 9
int rightThrottle = 5;    // LED connected to digital pin 9

//establish solenoid pins
int leftOn = 7;    // LED connected to digital pin 9
int rightOn = 8;    // LED connected to digital pin 9

//establish contactor pins
int leftReverse = 9; 
int rightReverse = 10;    

//The drive speed sent to the throttle
int gospeed = 86;

volatile int foserious = 0;


 //FRONT
 int FrontLeftSnd = 30;
 int FrontLeftRcv = 31;

 int FrontCenterSnd = 32;
 int FrontCenterRcv = 33;

 int FrontRightSnd = 34;
 int FrontRightRcv = 35;

 //RIGHT SIDE
 int Side1LeftSnd = 36;
 int Side1LeftRcv = 37;

 int Side1CenterSnd = 38;
 int Side1CenterRcv = 39;

 int Side1RightSnd = 40;
 int Side1RightRcv = 41;

 //BACK
 int BackLeftSnd = 42;
 int BackLeftRcv = 43;

 int BackCenterSnd = 44;
 int BackCenterRcv = 45;

 int BackRightSnd = 46;
 int BackRightRcv = 47;

 //LEFT SIDE
 int Side2LeftSnd = 49;
 int Side2LeftRcv = 48;

 int Side2CenterSnd = 51;
 int Side2CenterRcv = 50;

 int Side2RightSnd = 53;
 int Side2RightRcv = 52;

 //array of all of the input and output pin names. Used later to read all of the sensors in a for loop.
 int SensorOutputs[] = {FrontLeftSnd, FrontCenterSnd, FrontRightSnd, Side1LeftSnd, Side1CenterSnd, Side1RightSnd, BackLeftSnd, BackCenterSnd, BackRightSnd, Side2LeftSnd, Side2CenterSnd, Side2RightSnd};
 int SensorInputs[] = {FrontLeftRcv, FrontCenterRcv, FrontRightRcv, Side1LeftRcv, Side1CenterRcv, Side1RightRcv, BackLeftRcv, BackCenterRcv, BackRightRcv, Side2LeftRcv, Side2CenterRcv, Side2RightRcv};

 int dontgo = 0;

 //number of total sensors
 int SensorCount = 12;

 int nothingHappening = 0;

 int realCloseLike = 0;

 int goingforward = 0;
 int goingbackward = 0;
 int goingright = 0;
 int goingleft = 0;

 int backhit = 0;
 int fronthit = 0;
 int righthit = 0;
 int lefthit = 0;

 int amountToMove = 1000;

 int picked;

void setup()  { 
   
  cli();//stop interrupts

  TCCR1A = 0;// set entire TCCR1A register to 0
  TCCR1B = 0;// same for TCCR1B
  TCNT1  = 0;//initialize counter value to 0
  // set compare match register for 1hz increments
  OCR1A = 512;// = (16*10^6) / (1*1024) - 1 (must be <65536)
  // turn on CTC mode
  TCCR1B |= (1 << WGM12);
  // Set CS10 and CS12 bits for 1024 prescaler
  TCCR1B |= (1 << CS12) | (1 << CS10);  
  // enable timer compare interrupt
  TIMSK1 |= (1 << OCIE1A);

  sei();//allow interrupts
    
  Serial.begin(9600);

  
  pinMode(leftOn, OUTPUT);
  pinMode(rightOn, OUTPUT);
   
  pinMode(leftReverse, OUTPUT);
  pinMode(rightReverse, OUTPUT);


  //Make sure the power is off
  digitalWrite(leftOn, LOW);
  digitalWrite(rightOn, LOW);
  digitalWrite(leftReverse, LOW);
  digitalWrite(rightReverse, LOW);
   
  //bumper sensor pins 
  pinMode(18, INPUT);
  pinMode(19, INPUT);
  
  
  //Set distance sensor output pins
  pinMode(FrontLeftSnd, OUTPUT); //pin 30
  pinMode(FrontCenterSnd, OUTPUT); //pin 32
  pinMode(FrontRightSnd, OUTPUT); // pin 34
  pinMode(Side1LeftSnd, OUTPUT); //pin 36
  pinMode(Side1CenterSnd, OUTPUT); //pin 38
  pinMode(Side1RightSnd, OUTPUT); // pin 40 
  pinMode(BackLeftSnd, OUTPUT); //pin 42
  pinMode(BackCenterSnd, OUTPUT); //pin 44
  pinMode(BackRightSnd, OUTPUT); // pin 46
  pinMode(Side2LeftSnd, OUTPUT); //pin 49
  pinMode(Side2CenterSnd, OUTPUT); //pin 51
  pinMode(Side2RightSnd, OUTPUT); // pin 53
  
  //Set distance sensor input pins
  pinMode(FrontLeftRcv, INPUT); //pin 31
  pinMode(FrontCenterRcv, INPUT); //pin 33
  pinMode(FrontRightRcv, INPUT); //pin 35
  pinMode(Side1LeftRcv, INPUT); //pin 37
  pinMode(Side1CenterRcv, INPUT); //pin 39
  pinMode(Side1RightRcv, INPUT); //pin 41
  pinMode(BackLeftRcv, INPUT); //pin 43
  pinMode(BackCenterRcv, INPUT); //pin 45
  pinMode(BackRightRcv, INPUT); //pin 47
  pinMode(Side2LeftRcv, INPUT); //pin 48
  pinMode(Side2CenterRcv, INPUT); //pin 50
  pinMode(Side2RightRcv, INPUT); //pin 52
  
   
   //And wait a moment
   delay(3000);

} 

void loop()  { 
  
  lookAllAround();
  
  moveRobot();
  delay(amountToMove);
  slowstop();
  delay(1500);


}


ISR(TIMER1_COMPA_vect) {
  //Interrupt at freq of 1kHz to measure reed switch//generates pulse wave of frequency 8kHz/2 = 4kHz (takes two cycles for full wave- toggle high then toggle low)

 if(lefthit == 0 && righthit == 0 && fronthit == 0 && backhit == 0){
  if(digitalRead(18) == HIGH){
    hardstop();
    Serial.println(goingbackward);
    Serial.println(goingforward);
    Serial.println(goingleft);
    Serial.println(goingright);
    
    Serial.println("FUCK YEAH!");
    if(goingright == 1){
      righthit = 1;
      goingright = 0;
    }
    if(goingleft == 1){
      lefthit = 1;
      goingleft = 0;
    }
    if(goingbackward == 1){
      backhit = 1;
      goingbackward = 0;
    }
    if(goingforward == 1){
      fronthit = 1;
      goingforward = 0;
    }
  }
  

  }

 if(lefthit == 0 && righthit == 0 && fronthit == 0 && backhit == 0){  
  if(digitalRead(19) == HIGH){
    hardstop();
    Serial.println("FUCK NO!");
    Serial.println(goingbackward);
    Serial.println(goingforward);
    Serial.println(goingleft);
    Serial.println(goingright);
    
    if(goingbackward == 1){
      backhit = 1;
      goingbackward = 0;
    }
    if(goingforward == 1){
      fronthit = 1;
      goingforward = 0;
    }
   if(goingright == 1){
      righthit = 1;
      goingright = 0;
    }
    if(goingleft == 1){
      lefthit = 1;
      goingleft = 0;
    }
  }
 }
  

  
}


void moveRobot(){
  

  
  //first see if hit -- if hit while moving in any of the directions - auto-pick the other direction 
  //-- otherwise pick randomly 
  if(backhit == 1){
    amountToMove = 1000;

    backhit = 0;
    fronthit = 0;
    lefthit = 0;
    righthit = 0;
    picked = 0;
  }
  else if(fronthit == 1){
    amountToMove = 1000;

    backhit = 0;
    fronthit = 0;
    lefthit = 0;
    righthit = 0;    picked = 1;
  }
   else if(lefthit == 1){
    amountToMove = 500;

    backhit = 0;
    fronthit = 0;
    lefthit = 0;
    righthit = 0;
    picked = 2;
  }
   else if(righthit == 1){
    amountToMove = 500;

    backhit = 0;
    fronthit = 0;
    lefthit = 0;
    righthit = 0;
    picked = 3;
  }
  else{
    picked =  random(3);
    Serial.println("WTF!?");
    amountToMove = 1000;
  }


   switch(picked){
     case 0:   
       goingforward = 1;
       goingbackward = 0;
       goingright = 0;
       goingleft = 0;
       forwards();
       Serial.println("go forwards");
       
       break;
     case 1: 
       goingforward = 0;
       goingbackward = 1;
       goingright = 0;
       goingleft = 0;       
       backwards();
       Serial.println("go back");

       break;
     case 2:   
       goingforward = 0;
       goingbackward = 0;
       goingright = 1;
       goingleft = 0;  
       right();
       Serial.println("go right");

       break;
     case 3:    
       goingforward = 0;
       goingbackward = 0;
       goingright = 0;
       goingleft = 1;
       left();
       Serial.println("go left");

       break;
     }
     
     delay(1);        // delay in between reads for stability

}


void forwards(){

  
  //activate the reverse contactor
  digitalWrite(leftReverse, HIGH);
  delay(50);
  digitalWrite(rightReverse, HIGH);
  
  delay(100);
  
  //activate the solenoids
  digitalWrite(leftOn, HIGH);
  digitalWrite(rightOn, HIGH);
  
  //take a breath
  delay(500);

  //engage the throttle
  analogWrite(rightThrottle, gospeed);  
  analogWrite(leftThrottle, gospeed); 
  
}


void backwards(){
    
  
  //activate the solenoids
  digitalWrite(leftOn, HIGH);
  digitalWrite(rightOn, HIGH);
  
  //take a breath
  delay(500);
  
  // engage the throttle
  analogWrite(rightThrottle, gospeed);  
  analogWrite(leftThrottle, gospeed);   
  
}




void right(){
  
  
  if(dontgo == 0){
    //activate the solenoids
    digitalWrite(leftOn, HIGH);
    digitalWrite(rightOn, HIGH);
  
    //activate the reverse contactor
    digitalWrite(rightReverse, HIGH);
  
    //take a breath
    delay(500);

    //engage the throttle
    analogWrite(rightThrottle, gospeed);  
    analogWrite(leftThrottle, gospeed); 
  }
  
  //reset the variable
  dontgo = 0;

}


void left(){
  
  
  if(dontgo == 0){  
    //activate the solenoids
    digitalWrite(leftOn, HIGH);
    digitalWrite(rightOn, HIGH);
  
    //activate the reverse contactor
    digitalWrite(leftReverse, HIGH);
  
    //take a breath
    delay(500);

    //engage the throttle
    analogWrite(rightThrottle, gospeed);  
    analogWrite(leftThrottle, gospeed); 
  }
  
  //reset the variable
  dontgo = 0;
  
}



void slowstop()
{
  
  for(int fadeValue = gospeed ; fadeValue >= 0; fadeValue -=5) { 
    // sets the value (range from 0 to 255):
    analogWrite(rightThrottle, fadeValue);     
    analogWrite(leftThrottle, fadeValue);             
    // wait for 30 milliseconds to see the dimming effect    
    delay(500);                            
  }  
  
  digitalWrite(leftOn, LOW);
  digitalWrite(rightOn, LOW);
  digitalWrite(leftReverse, LOW);
  digitalWrite(rightReverse, LOW);

  int goingforward = 0;
  int goingbackward = 0;
  int goingright = 0;
  int goingleft = 0;

  delay(2000);
  lookAllAround();
  delay(1000);

}

void hardstop()
{
  
  for(int fadeValue = gospeed ; fadeValue >= 0; fadeValue -=5) { 
    // sets the value (range from 0 to 255):
    analogWrite(rightThrottle, fadeValue);     
    analogWrite(leftThrottle, fadeValue);             
    // wait for 30 milliseconds to see the dimming effect    
    altDelay(50);                            
  }  
  
  digitalWrite(leftOn, LOW);
  digitalWrite(rightOn, LOW);
  digitalWrite(leftReverse, LOW);
  digitalWrite(rightReverse, LOW);
}

void altDelay(int x)   {
  for(unsigned int i=0; i<=x; i++)   
  {
    delayMicroseconds(1000);
  }
}


void lookAllAround(){

  long duration, inches, cm;
  
  for (int thisPin = 0; thisPin < 1; thisPin++) {
 
    digitalWrite(SensorOutputs[thisPin], LOW);
    delayMicroseconds(2);
    digitalWrite(SensorOutputs[thisPin], HIGH);
    delayMicroseconds(12);
    digitalWrite(SensorOutputs[thisPin], LOW); 
    
    duration = pulseIn(SensorInputs[thisPin], HIGH);
    digitalWrite(SensorOutputs[thisPin], LOW);

    // convert the time into a distance
    inches = microsecondsToInches(duration);

    Serial.print(SensorOutputs[thisPin]); 
    Serial.print(": "); 
    Serial.print(inches); 
    Serial.println("in, ");

//    //check and check again
//    if(inches > 10 && inches < 25){
//        realCloseLike = 0;
//        for(int checkagain = 0; checkagain < 3; checkagain++) {
//           delay(100);
//           digitalWrite(SensorOutputs[thisPin], LOW);
//           delayMicroseconds(2);
//           digitalWrite(SensorOutputs[thisPin], HIGH);
//           delayMicroseconds(12);
//           digitalWrite(SensorOutputs[thisPin], LOW); 
//           
//           duration = pulseIn(SensorInputs[thisPin], HIGH);
//           inches = microsecondsToInches(duration);
//           digitalWrite(SensorOutputs[thisPin], LOW);
//           
//           delay(100);
//           
//           if(inches > 10 && inches < 25){
//             
//                 Serial.print(SensorOutputs[thisPin]); 
//                 Serial.print(": "); 
//                 Serial.print(inches); 
//                 Serial.println("in, ");
//                 
//                 realCloseLike = realCloseLike + 1;
//                 
//                 if(realCloseLike > 2){
//                   dontgo = 1;
//                 }         
//               }
//             }
//           }
     
    
    //Takes about 1/2 second to check all of the sensors @ 50uS
    delay(100);
    
  } 
 }



long microsecondsToInches(long microseconds)
{
  // According to Parallax's datasheet for the PING))), there are
  // 73.746 microseconds per inch (i.e. sound travels at 1130 feet per
  // second).  This gives the distance travelled by the ping, outbound
  // and return, so we divide by 2 to get the distance of the obstacle.
  // See: <a href="http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf"> <a href="http://www.parallax.com/dl/docs/prod/acc/28015-PI...</a"> http://www.parallax.com/dl/docs/prod/acc/28015-PI...</a>>
  return microseconds / 74 / 2;
}



Motor control test code example:

 /*
This example code is in the public domain.
 
 */

//establish throttle pins
int leftThrottle = 3;    // LED connected to digital pin 9
int rightThrottle = 5;    // LED connected to digital pin 9

//establish solenoid pins
int leftOn = 7;    // LED connected to digital pin 9
int rightOn = 8;    // LED connected to digital pin 9

//establish contactor pins
int leftReverse = 9; 
int rightReverse = 10;    

//The drive speed sent to the throttle
int gospeed = 82;

 int nothingHappening = 0;

 int realCloseLike = 0;

 int goingforward = 0;
 int goingbackward = 0;
 int goingright = 0;
 int goingleft = 0;

 int backhit = 0;
 int fronthit = 0;
 int righthit = 0;
 int lefthit = 0;

 int amountToMove = 1000;

 int timeToWait = 30000;

 int picked;

void setup()  { 
   
  cli();//stop interrupts

  TCCR1A = 0;// set entire TCCR1A register to 0
  TCCR1B = 0;// same for TCCR1B
  TCNT1  = 0;//initialize counter value to 0
  // set compare match register for 1hz increments
  OCR1A = 512;// = (16*10^6) / (1*1024) - 1 (must be <65536)
  // turn on CTC mode
  TCCR1B |= (1 << WGM12);
  // Set CS10 and CS12 bits for 1024 prescaler
  TCCR1B |= (1 << CS12) | (1 << CS10);  
  // enable timer compare interrupt
  TIMSK1 |= (1 << OCIE1A);

  sei();//allow interrupts
    
  Serial.begin(9600);

  
  pinMode(leftOn, OUTPUT);
  pinMode(rightOn, OUTPUT);
   
  pinMode(leftReverse, OUTPUT);
  pinMode(rightReverse, OUTPUT);


  //Make sure the power is off
  digitalWrite(leftOn, LOW);
  digitalWrite(rightOn, LOW);
  digitalWrite(leftReverse, LOW);
  digitalWrite(rightReverse, LOW);
   
  //bumper sensor pins 
  pinMode(18, INPUT);
  pinMode(19, INPUT);
  
  
   
   //And wait a moment
   delay(3000);

} 

void loop()  { 

  
  left();
  delay(amountToMove);
  slowstop();
  delay(timeToWait);

  backwards();
  delay(amountToMove);
  slowstop();
  delay(timeToWait);
  
  forwards();
  delay(amountToMove);
  slowstop();
  delay(timeToWait);
  
  right();
  delay(amountToMove);
  slowstop();
  delay(timeToWait);
  
  ///
  
  right();
  delay(amountToMove);
  slowstop();
  delay(timeToWait);
  
  forwards();
  delay(amountToMove);
  slowstop();
  delay(timeToWait);
  
  backwards();
  delay(amountToMove);
  slowstop();
  delay(timeToWait);
  
  left();
  delay(amountToMove);
  slowstop();
  delay(timeToWait);


  ///

  forwards();
  delay(amountToMove);
  slowstop();
  delay(timeToWait);
  
  backwards();
  delay(amountToMove);
  slowstop();
  delay(timeToWait);
  
  forwards();
  delay(amountToMove);
  slowstop();
  delay(timeToWait);
  
  backwards();
  delay(amountToMove);
  slowstop();
  delay(timeToWait);


}


ISR(TIMER1_COMPA_vect) {
  //Interrupt at freq of 1kHz to measure reed switch//generates pulse wave of frequency 8kHz/2 = 4kHz (takes two cycles for full wave- toggle high then toggle low)

 if(lefthit == 0 && righthit == 0 && fronthit == 0 && backhit == 0){
  if(digitalRead(18) == HIGH){
    hardstop();
    
    Serial.println(goingbackward);
    Serial.println(goingforward);
    Serial.println(goingleft);
    Serial.println(goingright);
    Serial.println("FUCK YEAH!");
    
    if(goingright == 1){
      righthit = 1;
      goingright = 0;
    }
    if(goingleft == 1){
      lefthit = 1;
      goingleft = 0;
    }
    if(goingbackward == 1){
      backhit = 1;
      goingbackward = 0;
    }
    if(goingforward == 1){
      fronthit = 1;
      goingforward = 0;
    }
  }
  

  }

 if(lefthit == 0 && righthit == 0 && fronthit == 0 && backhit == 0){  
  if(digitalRead(19) == HIGH){
    hardstop();

    Serial.println(goingbackward);
    Serial.println(goingforward);
    Serial.println(goingleft);
    Serial.println(goingright);
    Serial.println("FUCK NO!");
    
    if(goingbackward == 1){
      backhit = 1;
      goingbackward = 0;
    }
    if(goingforward == 1){
      fronthit = 1;
      goingforward = 0;
    }
   if(goingright == 1){
      righthit = 1;
      goingright = 0;
    }
    if(goingleft == 1){
      lefthit = 1;
      goingleft = 0;
    }
  }
 }
  

  
}


void moveRobot(){
  

  
  //first see if hit -- if hit while moving in any of the directions - auto-pick the other direction 
  //-- otherwise pick randomly 
  if(backhit == 1){
    amountToMove = 1000;

    backhit = 0;
    fronthit = 0;
    lefthit = 0;
    righthit = 0;
    picked = 0;
  }
  else if(fronthit == 1){
    amountToMove = 1000;

    backhit = 0;
    fronthit = 0;
    lefthit = 0;
    righthit = 0;    picked = 1;
  }
   else if(lefthit == 1){
    amountToMove = 500;

    backhit = 0;
    fronthit = 0;
    lefthit = 0;
    righthit = 0;
    picked = 2;
  }
   else if(righthit == 1){
    amountToMove = 500;

    backhit = 0;
    fronthit = 0;
    lefthit = 0;
    righthit = 0;
    picked = 3;
  }
  else{
    picked =  random(3);
    Serial.println("WTF!?");
    amountToMove = 1000;
  }


   switch(picked){
     case 0:   
       goingforward = 1;
       goingbackward = 0;
       goingright = 0;
       goingleft = 0;
       forwards();
       Serial.println("go forwards");
       
       break;
     case 1: 
       goingforward = 0;
       goingbackward = 1;
       goingright = 0;
       goingleft = 0;       
       backwards();
       Serial.println("go back");

       break;
     case 2:   
       goingforward = 0;
       goingbackward = 0;
       goingright = 1;
       goingleft = 0;  
       right();
       Serial.println("go right");

       break;
     case 3:    
       goingforward = 0;
       goingbackward = 0;
       goingright = 0;
       goingleft = 1;
       left();
       Serial.println("go left");

       break;
     }
     
     delay(1);        // delay in between reads for stability

}


void forwards(){
  

  //activate the reverse contactor
  digitalWrite(leftReverse, HIGH);
  delay(50);
  digitalWrite(rightReverse, HIGH);
  
  delay(100);
  
  //activate the solenoids
  digitalWrite(leftOn, HIGH);
  digitalWrite(rightOn, HIGH);
  
  //take a breath
  delay(500);

  //engage the throttle
  analogWrite(rightThrottle, gospeed);  
  analogWrite(leftThrottle, gospeed); 

}


void backwards(){
    
  
  //activate the solenoids
  digitalWrite(leftOn, HIGH);
  digitalWrite(rightOn, HIGH);
  
  //take a breath
  delay(500);
  
  // engage the throttle
  analogWrite(rightThrottle, gospeed);  
  analogWrite(leftThrottle, gospeed);   
  
}




void right(){
  
  
    //activate the solenoids
    digitalWrite(leftOn, HIGH);
    digitalWrite(rightOn, HIGH);
  
    //activate the reverse contactor
    digitalWrite(rightReverse, HIGH);
  
    //take a breath
    delay(500);

    //engage the throttle
    analogWrite(rightThrottle, gospeed);  
    analogWrite(leftThrottle, gospeed); 


}


void left(){
  
  
    //activate the solenoids
    digitalWrite(leftOn, HIGH);
    digitalWrite(rightOn, HIGH);
  
    //activate the reverse contactor
    digitalWrite(leftReverse, HIGH);
  
    //take a breath
    delay(500);

    //engage the throttle
    analogWrite(rightThrottle, gospeed);  
    analogWrite(leftThrottle, gospeed); 

  
}



void slowstop()
{
  
  for(int fadeValue = gospeed ; fadeValue >= 0; fadeValue -=5) { 
    // sets the value (range from 0 to 255):
    analogWrite(rightThrottle, fadeValue);     
    analogWrite(leftThrottle, fadeValue);             
    // wait for 30 milliseconds to see the dimming effect    
    delay(500);                            
  }  
  
  digitalWrite(leftOn, LOW);
  digitalWrite(rightOn, LOW);
  digitalWrite(leftReverse, LOW);
  digitalWrite(rightReverse, LOW);

  int goingforward = 0;
  int goingbackward = 0;
  int goingright = 0;
  int goingleft = 0;

}

void hardstop()
{
  
  for(int fadeValue = gospeed ; fadeValue >= 0; fadeValue -=5) { 
    // sets the value (range from 0 to 255):
    analogWrite(rightThrottle, fadeValue);     
    analogWrite(leftThrottle, fadeValue);             
    // wait for 30 milliseconds to see the dimming effect    
    altDelay(50);                            
  }  
  
  digitalWrite(leftOn, LOW);
  digitalWrite(rightOn, LOW);
  digitalWrite(leftReverse, LOW);
  digitalWrite(rightReverse, LOW);
}

void altDelay(int x)   {
  for(unsigned int i=0; i<=x; i++)   
  {
    delayMicroseconds(1000);
  }
}

Step 64: Mount the Electronics

Cut an electronics mount out of 1/4" clear acrylic using the attached template.

Mount all of the circuit boards to the acrylic plate using 1/4" standoffs and M3 bolts.

Step 65: Testing!

Plug everything in an test all of the circuitry before mounting it underneath the bed.

I cannot stress how important it is to make sure evrything works before really installing it. This will make life much easier.

Step 66: Install the Circuit Board

Once certain everything works, mount the circuit board to the underside of the bed using 1/4" inner diameter by 2" acrylic tubes and 1/4-20 x 4" nuts, bolts and washers.

Step 67: Plug in the Sensors

Plug all of the sensors into their respective sockets on the circuit (if you have not done so already).

Finally, clean up all of the cables using zip ties to keep things nice and tidy.

Step 68: Strap in the Batteries

Strap the batteries to the battery plate using ratchet straps. Make certain that the ratchet mechanisms are on the sides of the batteries and not the tops (of it won't mount to the underside of the bed).

Neatly coil the remaining strap once done.

Step 69: Bolt the Batteries

Bolting the batteries to the underside of the bed is a pain in the neck since each set weighs about 140 pounds.

That said, it is fairly easy if you have a pallet jack. You can just roll them under and lift them a few inches off the ground until they are high enough to pass bolts through.

Without that, I found that putting the batteries on two 8' 2x4s and slowly propping up each end until you catch the bolt also works.

Insert 1/2-13 x 10" bolts down through a fender washer, the wooden torsion box frame, a 7-1/2" aluminum spacing tube and finally the battery mounting plate. Firmly lock the bolt in place with a nylon insert nut.

Step 70: Charger Box

Plug both of the battery chargers into the charger junction box.

When they start running low, plug the charger junction box into the wall.

Step 71: Put the Mattress On

Lift the mattress back onto the bedframe.

Step 72: Make the Bed

When you make the bed, be sure to tuck the sheets under the mattress. You would not want to leave them dangling and risk having them get sucked into the wheels. That could be bad.

Step 73: Turn It On

Flip the large power switch to its side to engage the bed.

Step 74: Enjoy

Let your bed take you for a ride and make new friends.

Did you find this useful, fun, or entertaining?
Follow @madeineuphoria to see my latest projects.

Epilog Contest VII

Participated in the
Epilog Contest VII