Introduction: Illuminating Dog Ramp

About: Just a guy looking to make cool things

My family and I have three dogs two of which need something to get up onto the bed. We got a hold of a 4-step stair and all was good until recently. One of our dogs is loosing his sight. He is not completely blind but he is half way there. It became clear, no pun intended, that the stairs were too much for him to manage especially in the dark. Going up he felt scared because the slope was too steep and he had to jump each step. Going down, again the slope was too steep and it was difficult for him to know where the actual bottom was. The obvious solution was a ramp, something that had less slope which he did not need to put too much mental and physical effort going up and down.

The primary downside of switching from stairs to a ramp is the orientation. Stairs are perpendicular to the bed (at least that is how we used them). A ramp is parallel to the bed. We did not want our half-blind dog walking onto the ramp and straight off of it like walking off a cliff. So we put rails on the ramp. Most importantly, I added illumination. With this, in the middle of the night he can simply walk up and down the ramp with the illumination showing him the way. It also solves the problem with him waking us up in the middle of the night to help him get up and down.

There are two distinct phases to this project: 1) the ramp build, 2) and the illumination build. If you wanted just the ramp, you can follow these instructions and you will have a ramp at the end. If you decide to add illumination, you can do that at a later time.


The Ramp

The ramp is basically similar to all other ramps currently on the market or shared by other makers. Mine was an ad hoc build using all spare and scrap wood that I had laying around. I do not have a detailed parts list but in general this is what I used. I should mention that my build instructions are specific to the height of our bed, which is very high.


  • Supports: 2 1/2" x 3 1/2" kiln dried wood, 12 linear ft or 2 x 10' boards ($ scrap)
  • Ramp: 72" x 12" x 3/4" plywood, plus a little for waste ($ scrap)
  • Rails: 2 3/4" (height) x 3/4" (thickness), 13 linear ft plus a little for waste ($ scrap)
  • Carpet: 72" x 12", plus a little for waste ($11 @ home depot)
  • EMT conduit: 3/4", about 12" length
  • Flat bar steel: 3/4" x 1/8", about 12" in length
  • Nails, screws
  • Staples
  • Wood glue
  • Sand paper
  • Wood stain
  • Wood clear coat


Typical woodworking tools such as a saw, hammer, drill, tape measure, staple gun, etc. Nothing advanced is needed.

The Illumination

The ramp is illuminated with a NeoPixel strip controlled by a microcontroller which uses sensors to know when the dog is at the head or foot of the ramp.



  • Soldering iron
  • Solder sucker
  • Wire cutters
  • Dremel with bits

Step 1: Step 1: the Ramp

The ramp is made up of 2 parts: the pedestal and the ramp. The ramp attaches to the pedestal using a simple strip of metal which slides into a hole. This makes it easy to disassemble and move. It also makes it easy to build.

Caveat: I am describing how to build the ramp after having built one. When I was actually building it, I did not follow the order I am prescribing. I added rails after the fact because after seeing the completed ramp we were afraid that the dogs could too easily slip off. I also added feet under the bottom-end of the ramp to raise it a bit. So when viewing the pictures, you may see the ramp in a state that does not match the build order.

The Pedestal

The pedestal is simply a rectangular cuboid with a square base. It's not really important how it is assembled (eg, advanced joinery) just so long as it sits fairly flat on the ground and it is not flimsy. For my smaller dogs, the 12" x 12" base along with the weight of the wood is sufficient stability.

Bottom pedestal support:

  • Upright support: Cut 4 lengths of the 2 1/2" x 3 1/2" lumber to 31". Yeah, this is tall. It is the height of the foot board railing.
  • Base support: Cut 4 additional lengths at 6".

Fasten one side together in this fashion: 2 1/2" upright support + base support with the 3 1/2" side on the face + 3 1/2" support. See the drawing for clarity.

Build a total of 4 sides. Fasten the sides to each other forming a square base.

Top of pedestal:

  • Cut 12" x 12" plywood square

Fasten the square to the top of the pedestal supports.

Pedestal Rails:

In essence, this is just a 3-sided box. The cut lengths depend on how one wants to present the corners. I decided to make miter corners.

  • Side rails: Cut 2 lengths of 2 3/4" x 3/4" lumber to 12 3/4"
  • Center rail: Cut 1 additional length at 13 1/2"

Cut a 45 degree miter in each of the side rails, only one end of each rail. Cut a 45 degree miter on both ends of the center rail. Fasten with glue and nails the center rail along the outside side of the pedestal base. Similarly fasten the side rails. The result should be a 3-sided box with interior dimensions 12" x 12".

The Ramp

The ramp is very simple. It is basically a long piece of wood with sides. Nothing more. In my actual build, I did not have complete lengths for the rails since I was using scraps. I had to cobble together multiple pieces and butt join them together. Since that's not important for the build, I will ignore that part.

  • Ramp: Cut 1 length of 12" x 3/4" plywood to 60"
  • Side rails: Cut 2 lengths of 2 3/4" x 3/4" lumber to 60"

Fasten the side rails to the outside side of the ramp using glue and nails.

Ramp Pedestal Attachment

To make the ramp easily movable I wanted to be able to simply hook the ramp onto the pedestal without any need for screws or a screwdriver. I noticed that 3/4" flat bar could almost fit inside EMT conduit which has an outside diameter of 3/4". When the EMT conduit is squeezed together, the inside diameter grows to perfectly fit the flat bar.

  • Cut 2 lengths of 3/4" x 1/8" flat bar to 6"
  • Cut 2 lengths of 3/4" EMT conduit to 6"

For the top half of the conduit, put up to 3" of the EMT conduit in a vise and squeeze it until the flat bar firmly fits inside. Do not over press it. For the bottom 3", press it until they both sides are flat together. You may need to additionally hammer it so that it is completely flat.

Drill 2 holes one above the other into the flattened bottom part of the conduit. Make the holes big enough for your fastener. For the flat bar, drill 2 holes in a similar fashion into the bottom half.

Screw the EMT into two adjacent pedestal supports at the open side of the pedestal. Place it near the top such that when the ramp is attached, the ramp and the pedestal come together at the same height. Make sure the align both EMTs so that they are horizontally level.

Now comes the hard part. Eyeball the angle between the ramp and the pedestal. From the middle of the flat bar, bend it be that angle. Put it in the EMT and lay the ramp on top the flat bar. Adjust the angle of the flat bar so that the ramp sits flush atop the flat bar. There's probably a mobile app that will take a picture and tell you the angle, but it is just faster to just bend and adjust.

Once the angle is set, fasten the flat bar to the ramp.

Fit and Finish

At this point the wood needs to be cleaned up. Fill any imperfections or nail holes with wood putty. Sand everything everywhere. Stain everywhere that will be visible following the manufacturers recommendation. Finish with a clear coat following the instructions.


The final part is the carpet. I first used outdoor carpet thinking that its durability and funky texture would make it last long and more easily grip-able with dog paws. I was so wrong. All of the dogs just slid down the ramp with terror in their eyes. So I turned to traditional house carpet. I picked something that was cheap with a weight of 25oz. In hindsight I should have went with something 40oz or above.

  • Cut 1 length of 12" x 12"
  • Cut 1 length of 12" x 68"

Staple the 12" x 12" carpet piece to the top of the pedestal. Lay the other piece on top of the ramp. Hang 4" off the top and bottom. Fold over the top and staple under the ramp, along the ramp's front side edge, and just at the top of the ramp. Work your way down stapling every so foot or so. Fold over the bottom and staple just at the bottom of the ramp, along the ramp's bottom side edge, and under the ramp.

The ramp is now done.

Adding Feet

We did a test run of the initial build - ramp without feet and with outdoor carpet. This is when we discovered that we needed indoor carpet. We also noticed that the slope still might have been too steep. We were not sure, though, if the carpet was throwing off our observations. We just decided to reduce the slope a bit by raising the bottom of the ramp. We have no idea if it was beneficial or not. These instructions will assume that the pedestal ramp attachment is not in place yet.

Decide on the height in which to raise the bottom of the ramp. I raised mine 4". Somehow temporarily attach the top of the ramp into position (I had a helper hold it in place). Lift the bottom of the ramp to the desired height. Vertically position a piece of 2 1/2" x 3 1/5" block along the side at the front of the ramp. Mark the ramp angle onto the face of the block.

Cut 2 pieces of the block at the ramp angle. Fasten them to the bottom of the ramp.

Now the ramp has feet.

Additional Ramp Support

One additional observation I had with the initial test run, the ramp was flexing a bit when our bigger dog got on it. He doesn't weigh that much, so I think it was the quality of the plywood I was using.

To make it more rigid, glue and nail a length of 2" x 2" x 48" along the underside of the ramp. This nicely removes all flex in the ramp.

Step 2: Step 2: the Illumination

The illumination is basically a NeoPixel strip controlled by a Circuit Playground Express (CPX) which uses ultrasonic sensors to know when to turn it on. Also used are the on-board buttons to configure certain parameters as well as the on-board ambient light sensor. All will be explained below.

The Electronics

The Fritzing diagram shows the hookup of the various components. I am using 5v HC-SR04 ultrasonic sensors. Because the CPX has 3v inputs I divide the voltage in order for them to work. If you have the 3v versions of the the HC-SR04 or the US-100, use them instead. I am guessing they are straight connections from the sensor to CPX.

I recommend breadboarding the entire system before soldering. Program the board. Test and verify. Once things are working perfectly, break out the wire cutters and soldering gun.

Soldering the little 10K resistors and the wires in a way such a prototyping board is not needed is very difficult. Fit the 2 resistors in between the front sensor cylinder thingies, solder carefully, use hot glue to seat it properly. Test continuity to make sure it's truly connected and not cross-connected.

The ultrasonic pins are not needed. They just get in the way when positioning the sensors on the ramp. Heat each pin and pull them out. Use a solder sucker to remove any excess solder.

If the NeoPixel strip has lead wires already soldered onto the pads, like mine did, either join your hookup wire to them or replace them with the hookup wire. I replaced them because I did not want a bulky join point in the wire.

If the NeoPixel strip is covered in a silicon sleeve it may be difficult to seal the ends. I tried many different glues and tapes. I read the answer is Amazing Goop, but the closes I had was Shoe Goo by the same manufacturer. It still did not work but it did create a thick skin. Since the strip will be stapled down, having loosely attached thick rubbery skin at the ends seems good enough.

When soldering the hookup wires to CPX, do it on the backside of the board. When CPX sits in its case, there more room in the backside and then front.

Additionally, the CPX case needs to be modified. First, Dremel a tunnel in the valley of each pad that is being hooked up. This will allow the case to snap shut without biting down on the soldered hookup wire. Second, drill 3 holes into the sides of the case, one at the top and two at the bottom. This allows the hookup wire to feed from the sensors and LED strip into the case while still allowing the case to sit flush against the ramp.

Wire Lengths

When it comes time to solder the wires, use the following lengths as a guide:

  • Bottom ultrasonic: 25"
  • Top ultrasonic: 60"
  • NeoPixel strip: 25"

These depend on where each of these will be mounted in relation to the CPX. I mounted the CPX to the non-bedside of the ramp, the NeoPixel strip to the bedside of the ramp, top ultrasonic non-bedside, and bottom ultrasonic in the center at the bottom.

The Code

All of the code can be found in my Github repository illuminating-dog-ramp. The heart of the code lives in Because of the complexity, the code is too large to load and run as a *.py file. It has to be compiled using the mpy-cross compiler. Search the Internet to find a binary for you operating system. Once you find the appropriate compiler, compile the code, copy the compiled code to the lib/ directory, and refer to it from There is an example of and a compile and deploy script in the repository.

The rest of this section is a detailed description of the code in The primary way this code works is by creating objects responsible for some aspect of the behavior and updating its state in an endless loop. Care is taken to have not one object dominate the CPU processing which disallows other objects from getting compute time.

Timer class:

Responsible for invoking a callback function after some time has elapsed. It can be prematurely cancelled, restarted as needed, or have its timeout value changed. It must be periodically updated so that it can know if enough time has lapsed in order to call the callback.

Btn class:

The standard CPX library already establishes button objects for Button A and Button B. The Btn class adds additional functionality to those buttons without requiring them to be re-written from scratch. Primarily, they add the ability to invoke a callback function once the button has been released after it has been pressed, ie the finger has lifted off the button.

Mode class:

Responsible for representing a single configuration mode. It controls which pixel lights up when entering the mode. It controls which pixel lights up when selecting an option while in the mode. And once an option is chosen, it invokes a callback function providing the choice. If after the 5 seconds there is no activity, it exists the mode.

ModeMgr class:

Responsible for managing all of the configuration modes and performing the changes related to mode option choices. It defines 5 modes. And for each mode there are 5 choices.

  1. Distance threshold for the bottom ultrasonic sensor
    1. 10cm
    2. 15cm
    3. 20cm
    4. 40cm
    5. 50cm
  2. Distance threshold for the top ultrasonic sensor
    1. 10cm
    2. 15cm
    3. 20cm
    4. 40cm
    5. 50cm
  3. Brightness of the NeoPixel strip. Range is 0.0 - 1.0
    1. 0.5%
    2. 10%
    3. 15%
    4. 20%
    5. 30%
  4. Duration of how long the NeoPixel strip stays on
    1. 10sec
    2. 15sec
    3. 20sec
    4. 25sec
    5. 30sec
  5. Ambient light level - the higher the value, the more light in the room will enable the strip. Range is 0-1023
    1. 5
    2. 10
    3. 20
    4. 50
    5. 75

As the user chooses a new configuration value, the ModMgr updates internal values for each.

RampPixels class:

Responsible for turning on and off the NeoPixels at the configured brightness for the configured duration only if the sonar detected something at the configured distance and if the ambient light is darker than configured value.

Step 3: Step 3: Mount the Illumination System

I mounted the CPX to the non-bedside of the ramp, the NeoPixel strip to the bedside of the ramp, top ultrasonic non-bedside, and bottom ultrasonic in the center at the bottom. Mounting the NeoPixel strip pointed away from the bed was on purpose, so that it would point away from the humans sleeping in the bed. Unfortunately, we have closet mirror doors which reflect the NeoPixels back into our eyes even more prominently than if I would have put the strip on the other side of the ramp. The good thing is that I enough slack in the wire I can switch sides if desired.

Step 4: Step 4: Test and Tune

The last step in the project is to test all of the configuration settings and tune them in the real world. After a few days of tweaking, this is what I have:

  • The top ultrasonic distance is maxed out to 50cm.
  • The bottom ultrasonic distance is also maxed out.
  • The brightness is at 0.05 (1/2%)
  • The duration is at 10sec
  • The ambient level is 5

Future Adjustments

The system is still not perfect. There are a few things that I should adjust.

  • Move the NeoPixel strip to the non-bedside of the ramp.
  • Position the bottom ultrasonic to the bedside and focus it towards the center.
  • Change all the possible brightness levels to no more than 10%. In the dark of night in our room, 10% is the highest I would ever go.
  • 3D print some form or mount for the ultrasonics so that they are more rigidly attached. Every so often they get knocked in such a way it is always picking something up in its field.
  • Change the ambient levels between 2 and 6. Level 5 seems acceptable but I haven't tried lower levels.
Pets Speed Challenge

Participated in the
Pets Speed Challenge