Augmented reality sandbox control box updated

This slideshow requires JavaScript.

I constructed a couple of these control boxes for my ARsandbox project using Arduino Micro and Adafruit Feather 32u4. The main goal is to make the interaction between a user and the software more intuitive. The two flashing buttons add and remove water from the simulation, which is pretty nice. I wanted to add another feature, to move the elevation up and down. Say you have a lot of sand in the box but you want to display some “water”. You have to remove a lot of sand (time consuming) from the box or edit a config file (near impossible for an average user). On the other hand, if I can change the base plane location in the calculation, I can achieve the above goal without removing sand or editing files. With help of the original developer Dr. Oliver Kreylos, I started messing with the source code. It took me a day to understand what I could do to change the base plane and how to do it. I ended up creating a tool to manipulate the plane. Now that the plane can be moved, I added a rotary encoder to the control box to emulate the keyboard keys assigned to move the plane. Voila!

The photo gallery above shows 5 shots of different elevation values. You can clearly see the “sea” on bottom right is shrinking after each turn of the knob.

Here is a short video. I was slowly raising the elevation so more and more land became above water. Then I quickly returned the land back into water:

Here is a photo of the inside of the box:

I added a breakout board for rotary encoder and buttons. It’s very tightly sandwiched between the two buttons. There is no space between the board and the buttons, not even a fraction of millimeter. I don’t know how these pieces just managed to fit. Here is the breakout board:

I made this a while ago as an interface for my phi-panels LCD backpacks. This breakout board is pretty simple. There are two encoder channels and one shaft button, plus six push buttons, which I am not using. I just connected to the encoder channels, shaft button, and the common. I had to cut off a strip on the right side of the board to fit into the box. I was using my phi_interfaces library to read the encoder and emulate a button push if the encoder is rotated one way, another button if the encoder is rotated the other way. I didn’t assign any function for the shaft button. I am thinking that I should use it to switch between elevation adjustment and water speed adjustment. If you want one, I have a few available, with rotary encoders (I don’t have knobs). Leave me a message. I’ll break off a strip of the board so it will fit in the same box I’m using. Otherwise, you can get it printed yourself if you know how to do that. Here is the design file in EAGLE CAD:

Keypad circuit

If you know how to design boards, you can easily I haven’t updated the Adafruit Feature 32u4 version but will probably design a new printed circuit board so assembling will be easier, and not involving cutting off part of a board. Some code in case anyone wants to replicate it.

[code language=”cpp” collapse=”true”]

* Credit: Dr. John Liu
* Purpose: This sketch emulates keyboard keys "1" and "2" with two push buttons with LEDs. It also flashes the LEDs
* If a rotary encoder is present, it will emulate ‘5’ and ‘6’ if you rotate the encoder’s shaft. This combined with my modification on ARsandbox source code will shift color mapping up and down.
* This version uses p-channel mosfets and open drain with 10Kohm pull-up to 5V to control LEDs with the 3.3V Adafruit Feather32u4.
* Notes: On Adafruit Feather 32u4, pin 9 is connected to battery sensing voltage divider.
* 2018-01-28
* Visit for more information
#include "Keyboard.h"
const int button_1=2; // 11 for Adafruit feather 32u4, 2 for Arduino Micro;
const int button_2=3; // 10 for Adafruit feather 32u4, 3 for Arduino Micro
const int EncoderChnA=7;
const int ChnCommon=8;
const int EncoderChnB=9;
const int ShaftBtn=10;
const int EncoderDetent=18;

const int button_1=11; // 11 for Adafruit feather 32u4, 2 for Arduino Micro;
const int button_2=10; // 10 for Adafruit feather 32u4, 3 for Arduino Micro

const int led_1=6;
const int led_2=5;
const unsigned long led_on_ms=300;
const unsigned long led_off_ms=1700;
const unsigned int button_1_key=’1′; //KEY_LEFT_ARROW;
const unsigned int button_2_key=’2′; //KEY_RIGHT_ARROW;
const unsigned int UpKeyOut=’5′;
const unsigned int DownKeyOut=’6′;

int prev_1=HIGH;
int prev_2=HIGH;
int led_stat=LOW;

unsigned long prev_1_ms=0;
unsigned long prev_2_ms=0;
unsigned long blink_timer_0_ms=0;
unsigned long blink_timer_1_ms=0;

int debounce_ms=25;

char mapping[]={‘U’,’D’}; // This is a rotary encoder so it returns U for up and D for down on the dial.
phi_rotary_encoders MyEncoder(mapping, EncoderChnA, EncoderChnB, EncoderDetent);
//multiple_button_input* dial1=&my_encoder1;

void setup()
// make pin 2 an input and turn on the
// pullup resistor so it goes high unless
// connected to ground:
pinMode(button_1, INPUT_PULLUP);
pinMode(button_2, INPUT_PULLUP);
digitalWrite(ChnCommon,LOW); // Using this pin as ground since some prototypes don’t have enough gnd pins.

void loop()
unsigned char ch=MyEncoder.getKey(); // Rotary encoder emulates two buttons.
if (ch==mapping[0])
else if (ch==mapping[1])

switch (led_stat)
case LOW:
if (millis()-blink_timer_0_ms>led_on_ms)
pinMode(led_1,INPUT); // Open drain to let pull-up resistor pull drain to 5V.
pinMode(led_2,INPUT); // Open drain to let pull-up resistor pull drain to 5V.

case HIGH:
if (millis()-blink_timer_0_ms>led_off_ms)
pinMode(led_1,OUTPUT); // Pull drain to GND.
pinMode(led_2,OUTPUT); // Pull drain to GND

if ((digitalRead(button_1) == HIGH)&&(prev_1==LOW))
if (millis()-prev_1_ms>debounce_ms)
//Serial.println("1 released");

if ((digitalRead(button_1) == LOW)&&(prev_1==HIGH))
if (millis()-prev_1_ms>debounce_ms)
//Serial.println("1 pressed");

if ((digitalRead(button_2) == HIGH)&&(prev_2==LOW))
if (millis()-prev_2_ms>debounce_ms)
//Serial.println("2 released");

if ((digitalRead(button_2) == LOW)&&(prev_2==HIGH))
if (millis()-prev_2_ms>debounce_ms)
//Serial.println("2 pressed");

Here is the instruction of the software update:

Here is the link to the two files you need for the update:


Without my button box, you can still use keyboards such as 5 and 6 to invoke the feature.

19 Responses to Augmented reality sandbox control box updated

  1. Hi, great project! Excuse me, could you kindly point me to the code in the SARndbox code that changes the base level? I tried changing the distance in the BoxLayout.txt file but I didn’t see any change. I’d appreciate your help, thanks!

    • liudr says:

      I have not posted my code update yet. It’s been a while but I think I have all my steps written down somewhere. You need to know how to compile code in order to make this change. I’m not sure I can support all requests of how to compile code. Anyway, do you have a button box made out of arduino like the one I posted the details and code? Using computer keyboard is only good for tests. Once kids get a hold of the keyboard, you’ll be sorry you had the keyboard out. Sand will clog keys if they aren’t banging on them already. Pressing the escape will quit sandbox also.

      • mascorella says:

        Hey! I’ve been looking for the same thing.. I’m comfortable compiling the code and be happy to work through any issues. This would be fantastic! I have the various buttons built and some basic interactivity happening, but the ability to change the height would be awesome.


      • liudr says:

        I need some time to gather my notes together. Will get back to you soon.

      • mascorella says:

        Than you – that’s brilliant!

      • mascorella says:

        Hi! Just wondering if you had time to get this together? I am keen to get this worked out soon. Thanks again!

      • liudr says:

        It’s been long enough. If I don’t post anything, I’ll forget all the details. Took me quite a lot of time to dig into the source code and find where and how to add this feature. Got some pointers from Dr. Kreylos. I’ve updated the post. Hope my instructions are clear enough. You need some basic nix skills to make this update.

      • mascorella says:

        Thank you! I’ll take a look. I am comfortable with ‘nix so should be fine. Greatly appreciated!

  2. Kevin Irr says:

    Hey I have made the 2 button portion using your method of using Arduino Feather. However is there a schematic for the breakout board. There are two encoder channels and one shaft button and where it connects to on the board Feather.
    Thank you.

    • liudr says:


      Please read the code lines 16 to 20. The channels A and B as well as shaft push button (not currently used for anything) are all described there. The common of the two channels is connected to a GPIO since I ran out of GND pins on my arduino. The pictures on the post are Arduino Micro, which is same as Arduino Feather 32U4 in functionality. If you want the design files of the rotary encoder board, I can post as well. Let me know.

      • Kevin says:

        Yes, please I would be interested in the design files of the rotary encoder board. I have done a marvelous job.

      • liudr says:

        The file was designed in EAGLE CAD. You can use it for free (personal use) from autocad, which now owns EACLE CAD. You need to know how and where to order printed circuit boards to get it printed. I have a few left if you need one, let me know. I’ll break off a portion that won’t fit in the box (if you’re using the same box from polycase). I’ll add it to the post in just a second.

  3. HI Liudr. Really great addition to the AR sandbox and just what I have been looking for! Do you still have any boards left? If yes, I would be very happy to have one.

    • liudr says:

      I have 3 sets of boards I can make into kits for $20:
      1 rotary encoder board
      1 rotary encoder
      1 buttons board
      2 transistors
      2 10Kohm resistors
      2 330 ohm resistors
      Male headers for connections
      Jumper wires for buttons
      Cable gland for USB cable

      The above parts will save you time and shipping fees and learning how to print circuit boards. I’ll post a photo later.

      What you still need:
      2 buttons (1 yellow 1 blue)
      1 Adafruit feather 32u4
      Encoder knob
      MicroUSB cable

      I don’t expect a lot of people will be buying these parts. But in case I’m wrong, leave me a message. I can design a new board to make assembly a lot easier. No more wires. Unless there’s enough interest, I won’t be able to justify the time and effort to make these.

      • Hi Liudr. I would love to save the PCB hazzle as you’ve already done it 🙂 No problem to find the other components. How can I pay you and would you mind shipping internationally?

      • liudr says:

        For the usb cable gland, it would probably need some minimal order quantity such as 10 or 20. I’ll have say two options, $10 for just the two boards with first class shipping, or $20 for more parts so you don’t have to spend shipping cost to gather these other parts.

  4. Hi Liudr. Please tell me how to proceed. We can switch to mail if that’s more convenient?

  5. geekonabike says:

    While waiting for the hardware for a two button no rotary dial box, the UCDavis blog was taken off line :/
    Does anyone know of a method to get the instruction for the raspberry pi based usb controller board okreylos recommended for the button only 1 & 2 key emulator?
    I think I may only need the driver for the board, then remap the button to the keyboard button, but no luck locating said driver.

    • liudr says:

      I’ve not worked on the sandbox project for the past couple of years so I don’t know the status of the “official” blog or forum I used to visit. I know this project means a lot to many people so if that blog did go offline for good, it’s not good at all. The code I have posted here should work fine without having the rotary encoder. The code literally turns the box into a keyboard with the two buttons acting as 1 and 2 on a keyboard. No driver on PC/Linux required. There is no need for a raspberry pi. I’ve not seen such implementation, although it’s quite possible. But, trying to emulate a keyboard with a raspberry pi sounds like over-engineering.

Leave a Reply