Project tutorial
Zen Garden CNC End Table

Zen Garden CNC End Table © CC BY-NC

It is an enclosed zen garden built into an end table.

  • 54 respects

Components and supplies

Apps and online services

About this project

I am a Makr. I sit at night in front of the TV with my family with a moleskin, or another one of my project notepads and sketch ideas. Many of my conversations are of the "wouldn't it be cool if _______" variety. Many of my ideas never leave my project pages. This one did. I think it is awesome. It is an enclosed zen garden built into an end table. The movement was inspired from a CNC or a 3D printer and actually started to use ramps 1.4 (a 3D printer Arduino shield) until I thought of a much easier way to build it.

I wanted the end product to represent peacefulness. I wanted to bring some zen to my living room. I think that I did.

Many of the things I build are not pretty, just the way it is. In the process of building this I never explained what exactly I was building to my wife. Just that it would be furniture that would be good-looking enough to want it in our house. To put this into context you should know that I share everything with my wife. She is my best friend. But on this project I simply promised her that the end result would be something that she would be proud to have in her living room. She knew it was an end table, but that was it. So I worked extra hard to make this end table look really nice for her.

I have built 3D printers. I have also built some simple furniture (bookshelf, bench, etc.), but I have never built anything that combines technology into furniture. So I really thought this would be a fun project.

I had the initial idea for this table about six months ago. The Tables and Desks contest (and all those beautiful black and yellow tools as prizes) inspired me to start this project.

Step 1: Design and Idea

I wanted to build an end table, something that would sit by itself or next to a couch, maybe have a lamp on it. I wanted it to be more "art" than anything, an infusion of technology into wood. I always see the rock gardens with the wooden rake, I always thought they were very peaceful. That is really what i was going for in this build, peaceful tech-infused art.

In order to accomplish this I thought about using a gantry similar to a 3D printer without the z-axis. In this way I could drive a ball bearing using magnets through some sort of medium, probably sand. I also thought about programming it to "print" pictures, or designs by itself.

I think I'm going to use Arduino with 2 stepper motor drivers and some rather simple code. Rather than programming a set space into the code, I simply installed an end-stop on the min and max for both axis, so 0,0 triggers motor stop, as well as XXX,XXX max triggers motor stop. This will make programming much easier.

Step 2: Part and Materials Required

Okay, so this is a list of the parts that I used. This does not mean that you have to use the same parts, I just want to give you a general idea of the the parts that I used to make this.

  • Wood. I basically went to my wood bin and found some 4x4 that I had salvaged from a treehouse, and some select pine that my wife had bought for window trim (promised her I would buy her more). I scrounged up all the big wood pieces I could find and brought them to my shop. I also used 1/4 in birch plywood that I bought from menards several years ago for a different project.
  • 1/8 MDF I used this in between the top and the base just to give the top something to glue to. In retrospect, I probably could have skipped it and if I were to do it again I would.
  • 2020 aluminum extrusion. I used this in building the frame of the gantry.
  • 3d printer parts I have built many 3d printers in the past and have a lot of these parts on hand. I ended up using belting, smooth rods, smooth rod bearings, and other misc 3d printer type parts.
  • Kreg pocket hole jig This is not absolutely needed but makes building any kind of furniture so much easier. In this project I used it on the Top and attaching the top to the base.
  • 1/4in Plate Glass --- Local Glass and Paint Store -- Note that this is not safety glass and can create dangerously sharp shards if broken, but for this project i wanted strength and thickness.
  • 220mf 16v capacitor x 2
  • Prototyping breadboard
  • Permaboard Solder breadboard

Step 3: Assembling the Gantry

I started with some rough drawings and built the gantry. This is possibly not the most efficient way to build this. This is just the way I did it, keeping in mind that I was trying to use parts leftover from other builds and such. I had some 20/20 aluminum extrusion left over from another build so I used that for the frame for my gantry. I designed and 3D-printed the corner brackets and have included the files for those here.

I also included the laser-cut parts for the x- and y-axis. Study the pictures carefully to see exactly how I assembled the carriage and the separate axes. The way that I have assembled the carriage is maybe not the best way, as there are many different ways to build a gantry, but I have used this method with several other builds and it seems to work fine with good reliability.

Step 4: Assemble the Circuit

The first thing I did was to assemble the circuit on a prototyping breadboard, and when I was sure that everything worked the way I wanted it, then I transferred it to the solder board. I have included the fritzing diagram above to help with assembly.

Step 5: The Code

The code we made for this is really simple. I put end-stops on both the min and max for both the x- and y-axis, so there is nothing in the code that determines the size of the gantry. Because the size is not set up in the code it does not matter if your design is smaller or bigger than mine. Nothing will have to be adjusted in the code. The code is here in .TXT format and .INO so you can download it.

Step 6: Testing Movement

After installing the code, I tested it thoroughly. I wanted the diagonal movement to go horizontal and then vertical and then horizontal, similar to an etch-a-sketch. It seems to work well. So now I am going to solder all the connections to the Arduino to make it permanent and see about getting it installed into the table.

Step 7: The Actual Table Part

So I set about trying to decide how I was going to build what I had in my head. What I was thinking was a sort of two level box with the mechanics hidden from view in the bottom part of it. It would be controlled by a joystick hidden under a ledge. Beyond that, I really had no idea how I was going to do it.

After searching the wood pile, I found a 4x4 that I had salvaged from another project, and I found some select pine that was altogether rather nice. So after promising the boss that I would replace what I was about to take, I took the lumber to the shop and started building.

Step 8: Building a Bi-level Box

After measuring and cutting the 1/4in plywood I wanted to try a new way of holding it together while glue sat. I hot-glued cardboard to the corners. This method seemed to work well as it held the box together long enough to get other measures into place to hold it together. After building the division for the top and bottom and assuring that it was level, I fastened a piano hinge so that the bottom of the table that will hold the gantry can drop out to be maintained.

Step 9: Making Table Legs

For the table legs, I wanted to reuse a pine 4x4 I pulled out of a playhouse that used to be in my kids toy room. To start I made sure that the 4x4 was free of screws and nails / staples. I measured and cut the 4x4 into 4 25in sections. Then I proceeded to run the 4 legs through the plainer many times to remove the paint and clean it up.

After a few trips through the plainer, I used a straightedge and clamps to make a makeshift jig so I could use a skill saw like a table saw. It worked well and left me with 4 cleaned and smooth L-shaped legs that worked nicely for my purposes.

Step 10: Installing the Sides

After the legs were attached I set about with the sides. Plenty of careful measuring ensued. You want to be as close as you can so that there are as little gaps as possible. I glued the pieces into place and ran a few screws into them from the bottom side of the bi-level box.

Step 11: Sand Sand and Sand Some More

When building anything of form I recommend gratuitous sanding, starting with a meatier (like 80-120 grit) sandpaper and working toward a finer (< 200 grit) sandpaper. The time you spend sanding out any imperfection will be rewarded when the project is completed.

Step 12: Installing LED Lights

Once I knew where the top would sit, I fashioned a piece of 1/8in MDF to sit in-between the top and the base. I marked where the piece would sit and then flipped it upside down and fastened the LED light strip to the underside with zip ties and hot glue. From my experience, it is foolhardy to wholly rely on hot glue on its own when fastening anything that could create heat on its own (i.e., a light strip). I drilled a hole and ran the power wire for the lights to the underside of the bi-level box. I was going to run the lights from the same 12V as the stepper motors, but I was having issues where the lights were making the motors hum, so I gave the lights its own 12V power supply.

Step 13: Installing the Top

I do not have a lot of experience cutting miters; I am not a born carpenter. But after much trial and error I was able to fashion a good looking top. I used the kreg jig mentioned in the parts step to fasten the four sides of the top together and this worked remarkably well.

When you are measuring the pieces for the top, make sure you measure right. It is better to be too big and cut again or sand than to have it too small. After you cut the pieces for the top and make sure that they are going to fit together the way you want them too, router the individual pieces so that the glass will fit in there flush. Make sure of the depth of the router so that it matches your glass. In my case, the the glass was 1/4in.

Once the top was glued and screwed together I screwed it to the base using the kreg jig on the backs of the legs where it would not be noticeable.

I called a local car window repair shop and ordered 1/4in plate glass 1/16th in smaller than the opening. I also asked them to sand the edges so that It will not cut hands. I will not be using acrylic to fasten the glass down, simply because I would like to be able to remove the glass so that I can rearrange the rocks.

Step 14: Condition, Stain, Poly, Sand and Poly Again

Because pine is such a porous wood I did not want it to look blotchy, so I used a wood pre-stain conditioner to even out the stain. Then I applied the Minnwax natural cherry poly-stain to it and let it dry. The next day I came back and lightly sanded the table with 320 grit sandpaper and then applied another coat of the poly-stain. If I had to do this again I would stain and poly it separately; it was a nightmare to get the stain and poly coating to not leave drip marks and such. Also if you want it darker, you can not stain it again to get it darker. I ended up sanding it and re-coating it several times until I was happy with the results. I do not think I will be using the poly-stain again.

Step 15: Installing Electronics

I built the trapdoor in the bottom so that the entire gantry can be mounted to the trapdoor and can drop down to be worked on and maintained or upgraded. I mounted the gantry to the trapdoor using plastic conduit 2 hole straps. I installed the straps around the 2020 extrusion. This seems to work well.

I tried several different routes as far as where to mount the Arduino and the breadboard. I ended up cutting a hole in the bottom of the trapdoor about the center, ran all of the cables through that and mounted the electronics under the table.

When I mounted the joystick, I pondered for a long time how I was going to mount it. Honestly I could not think of anything clever, so I just glued it under the lip of the table. I pushed the cable for the joystick as far into the corner as I could and hot glued that as well. It is not the most regal solution, but you cant really see it unless you are crawling next to it, so I am happy with it.

On the underside I mounted the boards with small screws and tried to tidy everything up as well as possible. I also moved the power plugs to the back side of the rear leg and glued it into place.

Step 16: The Toolhead "magnethead"?

I was not sure how to attach the magnet to the bolt that I wanted to use. I thought the bolt would work good because I could easily adjust the z-axis. What I ended up doing is cutting a small length (1 - 1 1/2in) of 3/4in dowel and drilling a hole that the bolt would fit into. Then I screwed the magnet into the top of it. Now I can adjust it up and down by loosening the nut on the bottom.

Step 17: Making the Rock Garden

Once the electronics were installed I set about creating the rock garden. I was not sure how much sand it would take, so I bought a 25 lb box of sand. In hindsight I think I could have gotten away with 5 to 10 pounds. Most of the sand is still in the box. After spreading the sand, I ran the ball around a little. I wanted to check to make sure you could not see the bottom of the box when the ball rolled around. I added sand and kept testing until I found the depth of sand that I was happy with.

Then I added the 2 bags of smooth river rocks around the edges. I tried to spread them evenly. I thought about maybe gluing the river rocks down, but I thought it would be better to be able to rearrange them in the future if I wanted to.

Step 18: Table in Action

Alas, the table, she moves. Once I got the table moving, I just stood there and drove the ball around for way too long - lol. There is something extremely gratifying about watching that metal ball push the sand around. It was a long journey to get to this point and it is so awesome to see this table moving the way I envisioned.

Step 19: All Done

This was a long hard project. It was a lot of fun though.


 * Simple demo, should work with any driver board
 * Connect STEP, DIR as indicated
 * Copyright (C)2015 Laurentiu Badea
 * This file may be redistributed under the terms of the MIT license.
 * A copy of this license has been included with this distribution in the file LICENSE.
  * Edited as found from the StepperDriver library by Ernest E Garner
  * Date: 20-Nov-2016
  * Code Description:
  *    Used to control a basic x/y gantry for the zen table created by Ernest James Garner for
#include <Arduino.h>
#include "BasicStepperDriver.h"

//#define DEBUG

// Motor steps per revolution. Most steppers are 200 steps or 1.8 degrees/step
#define X_MOTOR_STEPS 200
#define Y_MOTOR_STEPS 200

//Motor direction to home
//    options 1 (forward)
//            -1(reverse)
#define STEP_FORWARD 1
#define STEP_REVERSE -1

// All the wires needed for full functionality
#define X_MAX_PIN 6
#define X_HOME_PIN 7 //home pin.
#define X_DIR_PIN 8
#define X_STEP_PIN 9
#define X_ANALOG_PIN A0

#define Y_MAX_PIN 5
#define Y_HOME_PIN 10
#define Y_DIR_PIN 11
#define Y_STEP_PIN 12
#define Y_ANALOG_PIN A2

// Since microstepping is set externally, make sure this matches the selected mode
// 1=full step, 2=half step etc.
#define MICROSTEPS 1

// 2-wire basic config, microstepping is hardwired on the driver
BasicStepperDriver x_stepper(X_MOTOR_STEPS, X_DIR_PIN, X_STEP_PIN, X_HOME_PIN, X_MAX_PIN);
BasicStepperDriver y_stepper(Y_MOTOR_STEPS, Y_DIR_PIN, Y_STEP_PIN, Y_HOME_PIN, Y_MAX_PIN);

int x_position = 0;
int x_analog;
int y_position = 0;
int y_analog;

void setup() {
  #ifdef DEBUG
     * Set target motor RPM.
     * These motors can do up to about 200rpm.
     * Too high will result in a high pitched whine and the motor does not move.
     * We want these motors to move slowly.
     * Tell the driver the microstep level we selected.
     * If mismatched, the motor will move at a different RPM than chosen.

void loop() {

     * Moving motor one full revolution using the degree notation
     // 1024/2 = 512
     // 512 - 40 = 472
     // 512 + 40 = 552
     x_analog = analogRead(X_ANALOG_PIN);
     // Joystick pulled to reverse and HOME not pressed
     //if ((x_analog < 472) && (digitalRead(X_HOME_PIN)==HIGH)) {
      if ((x_analog < 472)) {
      } else if ((x_analog > 552)) {
     #ifdef DEBUG
       Serial.print("X: "); Serial.print(x_analog);  //Serial.print(x_stepper.getDirection());
     y_analog = analogRead(Y_ANALOG_PIN);
     //if ((y_analog < 472) && (digitalRead(Y_HOME_PIN)==HIGH)) {
     if ((y_analog < 472)) {
      } else if ((y_analog > 552)) {
     #ifdef DEBUG
      Serial.print("  Y: "); Serial.println(y_analog);  //Serial.getDirection(y_stepper.


Custom parts and enclosures

Coral Draw Vector


Schematic 1
Fyjwhj4ivo4a8r7 large omvsql1ikq


Similar projects you might like

CNC drawing machine with joysticks

Project showcase by TechnoFabrique

  • 3 respects

Sienci Mill One - Simple and Affordable Desktop CNC

Project tutorial by Sienci Labs

  • 79 respects


Project tutorial by Amit Nandi (BigWiz)

  • 81 respects

CNC Part Picking Machine

Project tutorial by Arduino “having11” Guy

  • 1 comment
  • 13 respects

Triple CNC Machine

Project tutorial by TheTNR

  • 141 respects

Triple CNC Machine - UPGRADE Version

Project tutorial by TheTNR

  • 1 comment
  • 28 respects
Add projectSign up / Login