Wednesday, October 3, 2018

A 3D Printed Sand Table: The Spice Must Flow!

You've probably seen one of these by now, but if you haven't, you're in for a treat- a table with a hidden mechanism that magnetically pulls a steel ball through a shallow layer of sand, leaving behind pretty patterns.

You can go old-school and do this stuff without a computer:

but adding a computer to drive a robotic mechanism really brings out some new possibilities:

These tables, like other CNC machines, use gcode files to control the motion of the ball that leaves tracks in the sand.  There's a web site that generates gcode for this sort of pattern using an open source program called "Sandify".  There are other ways to generate patterns, too- if you simply slice a 3D model and export the gcode, the sand table ignores the Z axis movement and filament extrusion (since it doesn't have a Z axis or extruder) and prints the outlines.

No overview of sand tables would be complete without Bruce Shapiro's work at Sisyphus Industries:

As cool as those are, Michael Dubno has taken the sand table development further than anyone and now has Amazon's Alexa interfaced to his table so he can verbally order it to draw any item that Alexa can find in a photo on the web.  He also has it set up so that it can create stop motion animations like the one below.  Mike's work was written up in Make Magazine in 2009.

Another image of Mike Dubno's sand table.

I decided to try making such a machine for the 2018 Milwaukee MakerFaire using a corexy mechanism, similar to that used in UMMD, but much cheaper, simpler, and faster to build (I don't need micron precision for this application).  As usual, what started out as a quick project, turned into something more...

The Overall Architecture

On a recent scrap yard run I picked up a piece of clear polycarbonate framed in 45 mm square t-slot aluminum, as well as a bunch more of the same t-slot to use for this and other projects.  The framed plastic is 1.880 m x 1.005 m, so I figured that's a good size to use and manageable in terms of the weight, etc.

After thinking about what I'm going to do if something goes wrong and how I'm going to fix it, I came up with a scheme that divides the table into three main parts.  A base that contains the robotic mechanism, the sandbox, and the top cover.  The dimensions of the cover and the base are the same, and the sandbox is slightly larger so it fits over the base while the cover fits into the sandbox.  If something breaks or requires modification or adjustment, I can simply lift the top cover and sandbox off the base and take care of it, without having to vacuum up the sand.

Since this was going to be for a MakerFaire, I decided to keep the height relatively low to the floor to make it easy for kids to see the patterns, and discourage people from putting their hands under the table and possibly getting injured by the mechanism that moves the ball.  I set the overall height at 28" - tall enough that people won't think they're supposed to walk on it (but they may think they should sit on it!).

The Robotic Mechanism

I used a coreXY mechanism similar to the one used in my 3D printer, Ultra MegaMax Dominator (UMMD).   Inspired by this mechanism, I decided to use cables to drive this machine.

Here's a quick review for those who may not be familiar with coreXY mechanisms.  Essentially, there are two fixed motors that drive the carriage in X and Y.  The entire X axis moves when the carriage is commanded to move in Y.  Only one motor turns when the carriage is moving at exactly 45 or 135 degrees, and both motors turn for all other moves.

The diagram above is a stacked belt type corexy mechanism, like I used in UMMD.  It is also possible to put the belts on one level, but they have to twist and cross at M.  Whether you use one level or stacked belts/cables, the critical thing about this mechanism is that belt/cable segments A-H all have to be parallel to their guide rails which requires careful positioning of the pulleys.  Note that whether you use stacked or single level belts/cables, segments J, K, and M don't have to be parallel to the guide rails, and all the other do.

I ultimately made three different versions of this machine, first using cables, then belts in a single plane, and finally stacked belts.  I've divided this post into sections so you can skip ahead to the sections that interest you.  If you want to see how I managed to fail so many times, just keep reading.  Sometimes the failures are more entertaining, and always more educational than the successes.


This is the cable layout I used for the sand table mechanism.  The cable paths inside the motor mounts are a little more complex than shown- to be explained below.   H and L refer to the Z level of the cable on the drive pulleys.  The pulleys in the corner pulley blocks and in the Y axis bearing blocks are all at the L level.

The key to successful cable drive in this machine is getting sufficient friction between the cable and the drive pulley so that the mechanism moves the way you want without slipping.  That means you need friction, and the way you get friction is to wrap the cable around the drive pulley multiple times.  I ended up with three different motor mount designs, the first one awful, the next two much better.

Regardless of whether the mechanism is belt driven or cable driven, you have to provide some means of adjusting the cable/belt tension.  I designed the system to take maximum advantage of the slots in the t-slot aluminum frame.  Cable tension is adjusted by moving the corner pulley blocks and the motor mounts along the rails in the Y direction.  Doing so keeps all the cables parallel to the axes.

I modeled all the hardware and t-slot in Fusion360 and went to work on the pulley and motor mounts.  To keep things very simple, I decided to use a single level design (unlike UMMD) in which the cables are mostly on one level and cross over each other at the M segments.

Three Generations of Motor Mounts

The first used the motor mount and drive pulley shown below, with the cables wrapped 3 1/2 times around each of the drive pulleys in order to get enough friction between the pulley and cable that the mechanism wouldn't slip.  The problem with it is that as the mechanism moves, the cable walks up and down the drive pulley and sometimes overlaps itself on the pulley.  As the mechanism moves with the cable overlapped, it springs loose at random times and makes plinking sounds that don't sound like a mechanism that's going to last very long.  Also, as the cable walks up and down the pulley, belt segments A and G go slightly out of parallel with the Y axis guide.  In this low precision application it's acceptable, but in a 3D printer it would be bad.

The cables have to be put under tension to make the mechanism work- the drive is entirely dependent on the friction between the drive pulley and the cable that will be wrapped around it and the friction is partially a function of the tension.
My original motor mount and drive pulley designs.  Mounting it on the t-slot allows the cables to be tensioned simply by sliding the motor along the slot in the frame so there's no danger of moving the cable out of parallel.
Here's video of the first generation mechanism running.  Note all the plinking noises.

first test sand table mechanism from Mark Rehorst on Vimeo.

I didn't like the noise, and it was probably going to cause some wear on the cable, and possibly lead to breaks, so I redesigned it using a pulley mechanism that prevents the cable from walking up and down the drive pulley.

The cure for the cable walking up and down the pulley is to add additional pulleys that steer it onto the drive pulley and prevent it from overlapping itself.

This was the inspiration for the new motor mount design.  This came from a blog post here:

The new motor mount used a parallel grooved drive pulley and two small, outboard, "steering" pulleys to stop the cable overlap.  It worked well, and the cable went on and off the drive pulley at fixed Z heights, H and L, without walking up and down the pulley.

This is how the cable routes inside the second generation motor mount.  

CAD model of the components used in the mechanism.  The sketch lines are at the positions of the cables to help keep everything lined up accurately.  Most of this stuff is 3D printed, and can be made on relatively small printers.

From the review of the corexy mechanism, above, we know that belt/cable segments J and K don't have to be parallel to the guide rails.  I took advantage of that and designed all the other pulleys in the system to be at the same Z level as the lower end (L) of the drive pulleys.  The high side cable entry onto the drive pulley goes all the way to the corner pulley blocks.  It's not parallel to the rails but it doesn't need to be.  The L side is parallel to the rails because it has to be for proper operation of the mechanism.

This is the second generation motor mount.  Installing the cable is a little tricky, but not too hard since the back of the mount is open.  The 90 lb test dyneema fishing line cable can be tensioned by sliding the whole mount back (to the right).

The cable enters and exits the motor mount by wrapping onto the printed drive pulley.  The cable in the left goes to the top groove in the drive pulley and the one on the right goes to the bottom groove, and 13.6 mm apart, vertically.

Top view of the motor mount.  The cables entering and exiting completely miss the smaller steering pulleys.

How does it work?  See for yourself:

Test of second generation sand table cable driven corexy mechanism from Mark Rehorst on Vimeo.

No more plinking, though the steel pulleys are a little noisy...

After more testing, it seemed that I had some slip in the mechanism, so I redesigned the motor mounts and put one more steering pulley and wrap around the drive pulley to increase the friction between the cable and the drive pulley.  I was careful to keep the cable path from the motor mount to the Y axis pulleys parallel to the Y axis guide rails so none of the other parts had to change.

This is the third and final cable drive motor mount design:

Motor mount rev 3 for cable driven corexy from Mark Rehorst on Vimeo.

The clicking noises are caused by the cheesy pulleys I used for the cables.  When you pay for crap, you get crap.

Y-Axis Pulley Blocks

After much thought and many sketches on a white board, I decided that in the interest of simplicity, speed of construction, and cost, I should make use of the slots in the t-slot frame to guide the mechanism.

Along the way I printed some test pieces to try sliding in the slots of the aluminum frame and found PLA made for squeaky, sort of high friction sliding.  ABS was a little better, but UHMW polyethylene (aka "poor man's Teflon") and slid very smoothly and quietly, so I decided to use it to make the parts that have to slide (no linear bearings in this build!).  The Y axis pulley blocks at either end of the X axis use printed pulley holders and slots to hold pieces of the UHMW PE that are 10 mm thick to fit in the slots of the t-slot frame.  The motion is smooth and quiet and the X axis can't rotate.

Each Y-axis pulley block uses two ball bearing, grooved pulleys to guide the cables.  There is a 16 mm square aluminum tube that connects the two blocks and serves as the guide for the magnet carriage.  The blocks are guided by the slots in the t-slot frame.  There are UHMW PE inserts that fit both the bearing blocks and the t-slots, for smooth, quiet, low friction sliding.

The cable tension will pull the Y axis bearing blocks toward each other, so the square X axis guide tube is the only thing that holds them apart against the cable tension.  I cut the tube about 5mm short, clamped the blocks to their respective rails, then drilled a hole in one of the blocks and the tube and drove in a screw to hold the block's position' at the ends of the tube.

One of two Y axis pulley blocks.  The black thing is the X axis guide tube made of 16 mm square aluminum tube.  The white block is the UHMW PE bearing that slides in the slot in the frame.  The cable on the right passes through a slot because the cable is high (in Z) at the motor mount and low at the corner pulley.

End view showing the two pulleys and cables going to the motor on the left, the corner pulley block on the right, and the magnet carriage in front.  The pulleys are 6 mm thick, 13 mm in diameter, and have 4 mm bore.  I used M4 screws as the axles screwed into the printed plastic block.

The Magnet Carriage

I used a 1" cube, N52 neodymium magnet to be sure it would have plenty of pull to keep the ball under control.  The magnet sits in a printed ABS slider that fits over the 16 mm square aluminum tube.

I wasn't sure if the plywood was going to sag under the weight of the sand, or by how much, so the magnet floats in a square tube with a spring that keeps it pushed up against the plywood even if it sags.  The spring isn't very strong, but strong enough to lift the magnet.  The design accommodates about 8 mm of sag, which is definitely more than enough.
This is the magnet carriage with the magnet in place.  It sits in an over-sized square hole with a spring underneath that will keep it pushed against the plywood table bottom.

The cables are tied to screws driven into the plastic.  Teflon tubing on the screws prevents the sharp threads from cutting the cable.

The cable attachment at the magnet carriage is just knotted (I first used a surgeon's knot, but later switched to a "Davy knot") loops of cable hooked over screws driven into the printed plastic.  The screw threads are covered with Teflon tubing to prevent the sharp threads from cutting the cables.

Corner Pulley Blocks

Each block has two steel pulleys at the same Z level (L) as all the other pulleys, and the cables cross and touch each other, but the cable is very slick and very tough so I don't expect any problems with it cutting through itself.

One of two mirror image corner pulley blocks.  I generated the mirror image in CAD, but you can use the mirror function in Cura when you slice to do the same thing.

The same steel pulleys and M4 screws are used to hold the pulleys in the blocks.  The cables can be tensioned by sliding the block in the slot in the frame.


This mechanism depends on friction between the drive pulleys and cables to operate.  I generated  some very large test pattern files and ran the machine for several hours, hoping any failures would occur while I still had time to fix them before the MakerFaire.  It failed a couple times when the cables came off the screws on the magnet carriage, and some of the bearings in the pulleys started getting extra noisy.  One of the drive pulleys failed and so I reprinted them with 100% fill.  It takes about an hour to string the cables back onto the machine and square it up after something fails and has to be replaced, and that's with the whole mechanism open and exposed.  If something were to fail at the MakerFaire, I'd have to restring the belts after I fixed whatever failed, all with 30k people looking at me and asking questions.  I don't think so!

I may return to cables in a future iteration of this mechanism.  I'll have to choose a better, higher friction cable, and get better pulleys.  Until then,

Belts It Is!

As interesting as it was to try using cables, I decided that I didn't want to take a chance on any failures, so I redesigned the whole thing to run on belts.  I kept the same basic design as the cable set-up, but redesigned the parts for 6mm wide GT2 belt, again, mostly printable parts:

Here are half of the parts redesigned for 6mm wide GT2 belts.  I used stacked F623 bearings for pulleys.  All the pieces except the magnet carriage are symmetrical, so there was no need to mirror any of them.  Note that none of the parts stand above the surface of the t-slot frame, so the table surface will sit flat on top of the frame.

The magnet carriage uses the same belt clamp design I used in UMMD's Z axis- just a couple slots in the plastic and a couple short pieces of belt as inserts.  I used F623 bearings for the pulleys, and 3mm steel pins for their axles.  The pins fit tightly into holes in the plastic parts and are secured with a drop of superglue, just in case.  Some 3mm nylon washers serve as spacers between the pulleys and the blocks.
This is the magnet carriage for belt drive.  Note that the belts are kept absolutely parallel to the X axis guide tube (black).  Belts are clamped in slots by short pieces of GT2 belt (white) that are inserted into the slots with the drive belts.  A spring sits in the round hole under the square magnet.

I was familiar with the very limited stretch of belts in these mechanisms, so I decided to make all tension adjustments only by pulling the motors back along the Y axis rails.  The corner pulley blocks mount in the corners of the frame and are securely bolted to both the X and Y parallel frame members.  The pulleys and bolts were positioned so that I could get a tool in to tighten the bolts even with the pulleys in place.

"A" motor mount and Y axis end-stop switch.  The belt is tensioned by pulling the motor mount to the left and tightening the bolts.  Simple and effective!

The belt I used for this measured 1.8 mm thick, and when wrapped on the 40 tooth drive pulleys, the  diameter was 27.0 mm, so the pulley positions in the Y axis sliders and corner pulley blocks were set based on that dimension.  That ensured that the belts would run parallel to the Y and X guide rails (the frame and the square aluminum tube).  More details on proper coreXY layout here.

I put both belts on the same Z level -i.e., they are not stacked like the belts in my 3D printer, UMMD, that produced all the printed parts for this machine.  That means they had to cross at the end of the table opposite the motors.  I put 180 degree twists in the belts so that where they cross, the smooth back sides are rubbing against each other.  That created a problem- the belts don't want to stay on the pulleys in the corners.  They kept riding up on the flanges and that was wearing out the back side of the belts.

Here's the belt drive mechanism in action:

sand table mechanism converted to belt drive. from Mark Rehorst on Vimeo.

Finding the home position requires two endstop switches, one each for the X and Y axes.  If I wanted to be able to home the X axis regardless of the Y position, I'd have to mount the X endstop switch on one of the Y axis sliders, and that would require dragging a cable the full length of the table, which would be a little tricky.  I decided it was unnecessary to do that- the only time I need to home the machine is at the start of a sequence, and I'll be homing both X and Y, so I mounted both endstop switches on the frame and in the firmware I set the home command to home Y first, then X.

X axis end-stop switch mounted on the "B" motor mount.  Axes must be homed in order- Y first, then X.

One of two identical Y axis sliders.  The pulleys use 3mm diameter stainless steel pins for axles.  The pulleys were carefully positioned to keep the belts running parallel to the X and Y axes.

After letting the machine run for a while, I found that the belts kept climbing onto the flanges of the bearings, and it was slowly chewing a groove into the back sides of the belts.  I decided that the flanges were a little too small so I ordered some pulleys with larger flanges.  Luckily I was able to simply replace the F623 bearings with the new pulleys and everything worked fine- for a while.

The stacked bearings didn't work out so well- the belts kept climbing and riding on the flanges, so I got some pulleys that had larger flanges.  The diameter of the surface where the belt rides is about 0.4 mm smaller than the F623 bearings, which creates some small error in the positioning relative to the motor pulleys, but the error is so small it doesn't affect performance in this application.

One of the corner pulley blocks with the new pulleys.  The black on the pulley is from the back of the belt where it had been damaged from riding on the F623 bearing flanges.  The flanges on these pulleys are large enough that the belt can't climb onto them.
All seemed well until I let the machine run for about 2 days straight.  Then I noticed a squeaking sound coming from the mechanism and discovered that the flange on the pulley on the right rear corner pulley block was chewing on the edge of the belt.  I also found that where the belts cross and their back side contact each other there was a bit of rubber dust.

Rubber dust at belt cross-over.

Rubber dust at right corner pulley block.  The dust (and squeaking noise) was coming from the pulley flange rubbing against the edge of the belt.  Twisting belts is not a good idea.

After letting the machine run for another couple days, the X axis jammed up.  I noticed that the magnet sliding against the underside of the plywood top of the table was creating very fine wood dust that was getting between the magnet carriage and the X axis guide tube.  It really jammed it up tight.  In attempting to free it I noticed some cracks at the base of the cable clamp on the magnet carriage, and broke completely by the time I had finished freeing up the X axis motion.

The magnet carriage broke when I was attempting to free it up.  The magnet pushes against the underside of the plywood table top and that creates some fine dust that was gumming up the motion of the magnet carriage on the X axis guide tube.  This failed mostly because it was made a little too tight for the belts I was using, which put a lot of stress on the joint.

I fixed the jamming problem by redesigning the magnet carriage with holes to allow the dust to fall out.  It would probably be better still to rotate the X axis guide tube 45 degrees so the dust will tend to fall off the tube instead of accumulating on it.  I think sealing the plywood with a coat of polyurethane would minimize dust generation, or use a board with a layer of melamine, or even sheet metal (would induced currents load the motors too much?).

Stacked Belts It Is!

I spent about an hour modifying the printed parts in Fusion360, reprinted them and rebuilt the mechanism using stacked belts.  The modifications mostly involved shifting the pulleys in the corner blocks and the Y axis sliders vertically- I shifted one up 4 mm and the other down 4mm.  The screw holes in the motor mounts were also shifted 4 mm so that everything would line up.

The final Y axis bearing block, belts on two levels.  Notice that belt segment close to the frame passes through the block without touching it.  

The belts still cross at the back of the mechanism, but there's no twist and they never touch each other so there shouldn't be any more wear at the crossing point or the pulley flanges.

The "A" motor and Y axis endstop.  Notice the motor mount is offset vertically from the center of the slot in the frame.  The offset is calculated so that the same mount can be used on the opposite side for the "B" motor but simply flipping the mount over.  I eventually mounted both endstop switches at the A motor to simplify wiring.
After making 3 or 4 variations of printed magnet carriages, and having all of them fail one way or another, I finally came up with a good design.  It uses UHMW bearings set into an aluminum tube that is slotted to anchor the belts.  The part that holds the magnet is still printed, and held in place with zip ties, but all the stress due to belt tension is applied to the aluminum part which is much better able to withstand the force.

Final magnet carriage design for stacked belts.  It is made from 1" square aluminum tube and has slots cut to anchor the belts on two levels, and UHMW bearings (white) to minimize wear.

The new stacked belt corner pulley blocks look like this.  The block is bolted to both of the frame members with t-nuts.  There are tangs that fit the t-slot to center the block in the frame.

More on the design updates here.

The Rest Of The Table

There were several competing goals in the design of this table.  The patterns in the sand should be visible to kids and adults, which means keeping it low, but not so low that people think it's OK to walk on it.  The sand has to be visible but inaccessible, so a clear top cover is needed.  The mechanism should be protected from dopes, or should I say, dopes should be protected from the mechanism?  I need to be able to access the mechanism if something goes wrong, preferably without having to vacuum up the sand to do it.

The table was built in three parts- the base/mechanism, the sandbox, and the cover.  The table surface consists of a piece of 1/2" plywood with a 1x6" wood frame surrounding it.  Furring strips serve as spacers and a place to anchor the plywood to the frame.  The plywood is about 6 mm larger than the base and cover which are 1.88 x 1.005 m.  That means the table surface can fit over the top of the base/mechanism, and the cover can fit into the sandbox part.

In the final assembly, the bottom of the base/frame has a layer of corrugated cardboard covering it to prevent people from getting into the mechanism.

Exploded view of the table showing the three main components of its construction.  The top cover fits into the sandbox, and the sandbox fits over the base.
This is how the parts of the table fit together.

Assembled base/mechanism.  I'm too lazy to model the belts.

Here's the base/mechanism with the leg braces added.  It's hard to see but there are some triangular braces supporting the legs in the other direction.  It's very stable!  I tapped the legs and put bolts on the bottom to use as leveling adjusters.  They have printed TPU shoes to protect a nicer floor than this one.

Testing sand table from Mark Rehorst on Vimeo.

Wood frame around the plywood is assembled.  Next step- paint and silicone sealer.

Here's the table painted black and ready for LED installation and media tests.

Electronics enclosure mounted on one of the leg braces.  The wires will be dressed before the MakerFaire and probably stuck in place with duct tape, making them less attractive to kids and fools.

I searched numerous sources for suitable "sand" to use.  I wanted a combo of pure white, uniform grain size, and good behavior with the ball.  I found some white beach sand listed on, but several customer reviews said it came loaded with fleas!  I settled on sodium bicarbonate (baking soda) blasting media normally used in sand blasting cabinets for stripping paint off metal and wood.  Harbor Freight Tools sells it in 50 lb bags, and I calculated that I'd need about 50 lbs to fill the table to a depth of about 0.5"(assuming that was the right depth).  I clipped a 25% off coupon from a HFT catalog and went to my local store and got a bag for $30.

I took it to the Makerspace and dumped all 50 lbs on the table and started testing.  It quickly became apparent that 50 lbs was far too much media for a table this size.  I was testing with a 1" diameter ball and it kept getting stuck in the sand, so I kept scooping the sand back into the bag until I ended up with about 20 lbs on the table.  I made a tool to quickly level the sand to the correct depth for setting up the table to run.  The tool is just a piece of wood the width of the table with two screws on the bottom edge to set the correct depth of the sand.  A quick pull smooths the sand to uniform depth across the whole table surface.

First test of sand table with sand from Mark Rehorst on Vimeo.

Testing and refining progressed.  I tried a 15 mm ball, I tried varying speeds and accelerations, and played with sand depth.  Setting the sand depth to 1/3 of the ball diameter seems to prevent it from getting stuck, though that may still be a little too much sand if you want to see detailed patterns.  I found that the machine had no trouble running at 500 mm/sec, though it tends to throw the sand around when it runs that fast, so the patterns it creates lose some detail, and in places where the ball follows the same line over and over, it can develop some instability that throws it back and forth as it moves.


For this project, I wanted the sand to be lit from a low angle to create some shadows that would enhance the visibility of the patterns, but I didn't want to use color changing LEDs because I wanted the patterns in the sand to be the attraction, not the flashing lights.  I also wanted the LED's to be out of sight.  I chose to light it with red LEDs on one side and blue LEDs on the opposite side to get some interesting color effects that would enhance the patterns, not distract from them.

I picked up some chip-on-board LEDs via ebay (when will I ever learn?) and wired them up and installed them.  The red LEDs cooked themselves within about 10 minutes even though I was applying 12V and they were supposed to be used as automotive running lights.  I decided to get some strings of 60 LEDs per meter, "5050" LEDs and use them instead.

The LED strips operate from 12V, and the power supply on the controller is 24V, so I used buck converters to power the LEDs.  I can adjust the output voltages of the converters to balance the light output between the blue and red LEDs.  I got some aluminum L brackets and stuck the LEDs to them.  I tested the LEDs for a few hours and found that the aluminum only got a little warm and none of the LEDs burned up.  The buck converters only warmed up a little, too.

New LEDs, looking good from Mark Rehorst on Vimeo.

The mechanism seems to be finished from Mark Rehorst on Vimeo.

Generating patterns

Mike Dubno very generously sent me his software but it was getting too close to the MakerFaire to get it incorporated into the table.  I'll write another post when I get it working after the MakerFaire.  This table is going to be around for a while.

When I was experimenting, I found that a small ball leaves narrower lines with sharper edges than the larger ball, so I decided to try a ball switching scheme to allow some patterns to run with a 25 mm ball and others to run using a 15 mm ball.  Switching balls is very easy- there's a partition wall at the bottom edge of the table and the balls' home positions are on either side of the partition.  To drop the small ball and pick up the big one, just send the magnet to (0,0) using a G1 X0 Y0 command, then home the axes.  That will move the magnet to the right, with the partition stopping the small ball and the magnet picking up the big ball as it passes by.  Dropping the big ball and picking up the small one is just the opposite- home all axes with a G28 command, then go to (0,0) with a G1 X0 Y0 command.  You have to be a little careful about where the ball is when you start a change sequence, but it isn't difficult.

The area reserved for the balls reduces the printable area of the table by about 35 mm in Y.  The total area addressable by the ball is 748 mm x 1565 mm.  I reserved the bottom 35 mm of the table for ball switching, so all the patterns I generated ran from (0, 35) to (748, 1545).  

I used Sandify to generate patterns for the 2018 Milwaukee MakerFaire. Sandify provides a simple but tedious means of generating patterns for sand tables.  The patterns files are gcode that consists of a series of G1  XXXX YYYYY statements.  After playing with the machine for a while, I noticed that most patterns take 4-5 minutes to complete, so I needed about 20 patterns to run so there would be no repeats for at least a few hours.  Also, even if you reuse patterns, the sequence in which they are used affects the result on the table, so relatively few patterns can be put together in multiple ways with different results.

After playing with it for a while, I came up with a system for creating sequences to run on the table.  I generated about 20 patterns that looked nice, and saved the gcode and an associated image file named for the start and end positions plus a unique identifier.  I also used the optional start and end gcode when saving the files to add a G4 S60 dwell command so each pattern will sit unmolested for one minute after it is complete.

That gave me a series of gcode files like this:

TR_L_P1.gcode (start top left corner, end left side, pattern 1)
L_C_P4.gcode (start left side, end center, pattern 4)
C_BR_P3.gcode (start center, end bottom right, pattern 3)
BR_TL_wipe1.gcode (start bottom right, end top left, wipe pattern 1)

The image files allows me to get some idea of what the patterns will look like when one runs after another.  Sometimes a spiral pattern will start from the outside and work its way inward, and I can leave a big hole in that pattern to preserve the central part of the previous pattern.  By manipulating the table dimensions in Sandify, I can generate patterns that occupy only specified portions of the table.

One other thing I found is that things can get a little too busy if you just keep running one pattern on top of another.  I added some wipe patterns after every few regular patterns to smooth out the sand.

There's an M32 command in gcode that should make stringing the files together into a sequence pretty easy, but it isn't working in smoothieware so I had to default to a more tedious means: just manually selected files using the names to sequence them and checking the images to make sure they'll look OK stacked on each other on the table, then concatenate the files.

The final pattern sequence went like this: wipe, pattern 01, pattern xx, pattern yy, wipe, pattern 02, pattern rs, pattern tu, etc., so there were 20 sequences of 3 patterns, and each pattern was visible immediately after a wipe.

After running for several hours, the sand tends to end up pushed out to the edges of the table.  When that happens, I open the top, manually throw a few handfuls of the sand toward the center of the table, then smooth it with a tool I made for the purpose.  The tool is just a piece of wood that is the width of the table and has a couple screws driven into one edge.  I put the tool down in the sand until the screw heads touch the plywood under the sand, then pull it along the length of the table.

Last Minute Tweaks

We had Michael Dubno's software working pretty well at the Makerspace, so I took the RPi with the code and some other hardware to the MakerFaire to try to get it going there.  I had some problems with the network there and was not able to get it running, but I'll have plenty of time to debug the system after the event, so it should be working for next year's Faire.

The ball changing wasn't working too reliably at the Makerspace so I designed a nest that had a couple small magnets to hold the balls.  Unfortunately, that didn't work reliably either, so I removed it at the MakerFaire.

The Result

The sand table worked well at the MakerFaire, and I got a lot of nice comments about it.  It will appear again, maybe bigger and definitely better...

CAD File

The Fusion360 design file for the table is here.


  1. "You've probably one of these by now," (missing the word "seen" I presume)

    Thanks for this extensive write-up! Lovely detailed work as always, your blog is a treasure...

  2. I am so bookmarking this page... It's on the project list. I'll get to it eventually. Thanks for the great write up!

  3. awesome, but very noisy you don't want to sit in the living room with that noise level...

    1. I agree, but if you're willing to run it much slower it is a lot quieter. I built this table for a MakerFaire, a very noisy environment, and one where people won't want to sit and watch a ball moving slowly through the sand. I have some ideas for ways to make it quieter that I'll be working on in the coming months.

    2. Use better drivers for next table. TMC2209 for example. You will not need endstops and they can run in ultra quiet mode.

    3. I switched to a Duet controller board with 256:1 ustepping drivers, but still found them noisy at high speeds. I eventually used pulleys to step up motor speed and allow them to run slower and quieter. However, the motors were just barely adequate for the kind of speeds and accelerations I was using, so I switched to servomotors. They run smoothly and quietly at my normal speeds and accelerations, but can also run at insane speed and acceleration, albeit with a bit more noise.

      If you are going to run at typical sand table speeds, under 100 mm/sec, steppers with high microstepping drivers will run quietly. I like to run at 500 mm/sec or more and higher than typical acceleration so that the mechanism actually reaches that speed.

      Take a look at my most recent post in which I replaced the steppers with servomotors. Performance is insane!

  4. Hi! Love the design, Mark. Incredible job.
    You've linked the Fusion360 design file on openbuilds, but clicking that link leads to a design only consisting of a singular LED clip ( Any chance you can get the full design up?


    1. Oops! Sorry- I ran into this once before- when you share a Fusion360 file, the only thing that shows up is whatever is visible when you last saved the file. The last thing I did in that file was work on the LED clip... doh!

      I'll fix it right away. Try it again.

  5. Great write-up....this is on my project list.

    I know it's an old thread, but any chance you can share the r-pi software ?

    1. I can't share it, but the author, Michael Dubno, has open-sourced it and you can DL it via Github:

      Be sure and check my more recent posts about the sand table. There have been a lot of changes, and more are in the works.

  6. WOW!
    Thanks so much for the link...planning to build my own and this is awesome !!

  7. Hey Mark,
    Did you post the motor mounts, corner bearing holders, etc. as STL files somewhere ?
    Wondering if I missed them...
    Thanks !

    1. The pieces are all components in the Fusion360 CAD drawing here:
      You can save as STL from the CAD file.

    2. Unless I'm missing something, you can no longer export STLs or STEP from the link you provided, would you happen to have an alternate way of sharing the design?

    3. Here's the Fusion360 archive file:

  8. Is it possible to get BOM for this ? I would like to build one myself if possible.

    I would also maybe use 12V batteries to not have a cable running in my living room all the time.

    1. You might be able to extract a BOM from the CAD file. I mean come on, I've done the hard part for you...

      You might want to look at more recent posts detailing the numerous updates I've made to the design before you start building.

      Battery operation would be possible, but I don't know how long they'd be able to run the table before depleting charge. There's about 20W of LEDs lighting up the table in addition to the power required by the motors (most recently 78W servos) and the controller board. I think you'd need a big, expensive battery to get any useful life out of it.

    2. Perhaps a better choice would be a large UPS in the table base.

  9. i tried to download the cad files but you don't have the permissions set for it

    1. I updated the link- try it again. Autodesk decided to break millions of links all over the web by shutting off file sharing...

  10. Hi Mark, I am debating about taking this on for a dinning room table. I'll probably change the leg structure a bit. Also, I was thinking of putting faux leahter under the sand to minimize noise. Did you ever change the steppers? for noise? I can't see to fiind anythinig updated since 2020. Is the project done? any updates?

    1. The Spice Must Flow has been taken apart and rebuilt in a smaller, coffee table size. Before I took it apart, I switched to servomotors that run much quieter and faster than steppers. See:

      In the new table, which should be appearing in a post here in the next few weeks, there is a layer of EPDM rubber roofing membrane on the bottom of the sandbox to make it even quieter. In hindsight, there are other materials that would have been easier to work with.


Leave comments or a questions here and I'll try to post a response as soon as I can.