Touch LED Table - Retrogaming and Ambiant Light




About: LED table made for education retrogaming and pleasure. ideal for #fablab projects. Now with touch!

Arbalet is an ARduino-BAsed LED Table, a flat surface filled with several hundreds of coloured square lights designed for Education, Geeks, and Pleasure. With its limited number of pixels and a DIY touch interface, Arbalet brings our old 80's arcad games back into fashion through a modern, classy, and hackable device.

Arbalet is intended to be easily reproducible, highly customizable, and programmable to create new games, light animations and applications. It's not only a LED table but also an open development platform programmed in Python or even via a visual programming language to teach programming to beginners.

This tutorial describes how to build an Arbalet Lava (LAser-cut VAriant)of 150 pixels with a 6-key touch interface using laser cutting. Its LEDs are connected to an Arduino controller driven from USB by a Linux computer running Python games and light effects. The latter can be a Raspberry Pi to make the table autonomous.

Step 1: Cut the Wooden Boards

SVG files are online for 3, and 5 or 6mm MDF boards. You need only one thickness among 5 and 6, depending of the material you find more easily in your local retail store.

Download the SVG files and use a laser cutting machine to get you wooden spare parts.

You might consider painting one side of the 5mm/6mm parts using a spray-paint can or a brush, that will be the outer side. The other side (inner) can be painted in white for a better light reflection.

Step 2: Leg Preparation and Assembly

According to the diameter of your bolts, pre-pierce the battens by choosing the drill bit right smaller than the bolt diameter ; e.g. 7mm for a bot of 8mm. Then screw the 4 bolts into the 4 legs. You can use the nuts to force. Finally, assemble the 4 legs to the main part of the host box using washer and nuts.

Step 3: LED Strip Cutting, Gluing and Soldering

Use only strips with density of 30 LED/meter, you might want to use other densities but would need to cut the strip at every LED to respect the spacing of 33.3mm ending in a waste of time and effort.

Using scissors cut the strip every 500mm = 15 LEDs. Make sure you cut in the middle of a coppered connection.

You must end up with 10 strips of 15 LEDs, whose one has a male connector.

Using a pencil, trace the lines where you will glue the pieces of strips. They are 10 lines horizontally centred.

The first column must be traced 83.3mm from the edge, then each line is 33.3mm from the previous one. The distance between the first and the last (10th) line is 333.3mm.

Then pre-place the 10 pieces of strips according to next diagram. It is primordial that you alternate each piece of strip. For this you can rely on their arrows whose direction must change each column: → ← → ← and so on…

Glue the pieces of strips on your pencil lines once you are sure the Data line forms a coil.

Cut and strip 9x3 = 27 pieces of wires to reconnect the data and power lines between each piece of strip. Connect 5V (red) together, GND (black) together, and DATA (often green or yellow) together, as shown on the electrical diagram next step.

Also connect the power supply of both extremities (GND to GND and 5V to 5V) via 2 direct wires. It allows to better dispatch the power to avoid a difference of colour at extremities.

Step 4: Solder the Circuit Board

Arbalet's electronics, illustrated on the diagram, is composed by:

  • An Arduino board, connected to a computer through USB
  • A custom PCB, connected to a 5V power supply
  • An optional touch sensor MPR121 connected to 6 active surfaces

The custom board will be mounted right above the Arduino board, with its male PIN headers directly plugged in Arduino's female headers, ensuring its fastening as well as its data connection.

Solder the components and connections on the custom board as shown on the diagram. White wires on the diagram are not actual wires but direct male-female connections of PIN headers.

Step 5: Install Firmware (Arduino) and Software (Python)

In this step we:

  • Test that we are able to drive the LED strip, implying that our electronic board and LED strip soldering both work
  • Upload the Arbalet firmware onto Arduino
  • Install the Python software on the workstation

Use preferrably a Linux distribution for the workstation, other operating systems might need different procedures and software dependencies. In the tuto we assume you are running a Debian-based distribution (Ubuntu, Linux Mint, ...). A Raspberry Pi running Raspbian is also an excellent pick.

Install a bunch of dependencies by typing in a terminal:

sudo apt-get install arduino git python2.7 python-setuptools ipython-notebook python-pygame python-numpy python-xlib python-bottle python-opencv python-pyaudio

If you are not familiar with Arduino you might want to follow some Arduino tutorials first. At least, plug your ARduino to a USB port and check in Tools > Board that the right model of board is selected and that the list Tools > Serial port is not empty, meaning that a plugged Arduino is detected.

Clone the repositories hosting Arbalet's code, by opening a terminal and typing:

~ $ mkdir Arbalet && cd Arbalet
~/Arbalet $ git clone --recursive
~/Arbalet $ git clone
~/Arbalet $ git clone

The libraries are located in the arbasdk repository we have just cloned, under the path arbasdk/hardware/arduino. Move independently every subdirectory from that directory i.e. arbasdk/hardware/arduino to your Arduino libraries folder i.e. ~/sketchbook/libraries/. Do not nest directories, this is unsupported by the IDE. You must end up with the following folders:


Make sure all Arduino IDE windows are closed and reopen it, you should now see these libraries in File > Examples. If you don't see them make sure they are not nested into subfolders and that the libraries hereabove in folder sketchbook exist and are not empty.

Let's try the samples before going further. In the IDE open the sample Adafruit_Neopixel/simple and identify the macros PIN and NUMPIXELS, replace them by:

#define PIN            12
#define NUMPIXELS      150

Press Ctrl + U to compile and upload. If the bottom window colors in red then compiling or uploading failed, identify the errors using the stacktrace. The IDE should say "Upload successful". Plug the AC adapter to your homemade electronic board. You should see the sample program being executed. If yes, you can drop this sample and upload actual firware. Open the Arduino IDE again and click on File > Examples > Arbalet > Arbalink. Arbalink is the Arbalet SDK. Press Ctrl + U to compile it and upload it. If you have already executed successfully the sample, this step should be a matter of formality. Now "Upload successful" means you're done and ready to run Arbalet programs and games :)

But let's finish building the table first...

Step 6: Assemble the Inner Grid

The 3mm medium board has been cut into 11 vertical and 14 horizontal strips. The horizontal ones have side rods creating two side cavities that will host electronics and support the upper tray.

Notice that 9 vertical strips have wire passings. They are made for the data line you have soldered at step 6. Make sure you alternate them.

Assemble the whole grid made of vertical and horizontal strips by sliding strips into each other as shown on the drawing.

Then eventually rotate the final construction upside down so that side roads are at the top. Finally move the grids on the table tray so that each pixel the structures has created matches a LED.

Step 7: Close the Table

Position and glue the 4 laser-cut sides of the tray. Cut pieces of cooking paper covering the pixels area that will help diffuse the light, as well as two side covers to hide the side cavities hosting electronics.

Finally, cut a piece of glass or plexiglass of 498x498mm, keeping a degree of freedom of 2mm on each side to ensure an easy placing and removing of the glass. The online plans are more suited for 4mm-thick glasses but other thickness will be fine as well.

Step 8: Add the Touch Keys (optional)

This step is not required but is an extension if you would like your table to be touch-sensitive. Although they are different and may return different types of output, touch feature can be provided by many kinds of sensors, including infra-red, barycentre of weight, vibration sensing, ... The method proposed here involves capacitive sensor connected to pieces of ITO plastic.

This plastic is covered with a thin conductive layer that makes it discrete underneath your glass as well as sensitive to capacitive changes. Only 1 side if generally conductive, identify which one thanks to an ohmmeter. Cut 6 pieces of ITO plastic slightly smaller than the size of two pixels i.e. 30x63mm and place them with the conductive side down as shown.

Top of the table:

Connect each conductive side of plastic to an input of the MPR121 located underneath the table tray. This connection uses no soldering, plastic pieces rest on the stripped wires ensuring an electric contact. Fold the stripped wires against the vertical strips to make them stable.

Bottom of the table:

This other extremity of the touch wires are connected to the MPR121. Solder its capacitive inputs 0 to 5 to wires going through Arbalet's pixels from the bottom of the table.

Step 9: Run Games and Applications or Code Yours

Arbalet comes with a set of existing games (Tetris, Snake, Piano Tiles -on the picture-, ... and more to come) and ambiant lights, you can use them or create your own in Python or even using the visual programming language Snap. All applications are located within the Arbalet/arbapps repository.

Now you have already uploaded the firmware you can directly execute Python applications by connecting your Arduino the your laptop, and also plugging a joystick (any simple USB joystick like Logitech Dual Action will do the job).

You can try some of them by typing these commands below and pressing Ctrl + C to close an app before executing another one:

cd ~/Arbalet/arbapps/ColorDemonstrator && ./ -w
cd ~/Arbalet/arbapps/Tetris && ./ -w
cd ~/Arbalet/arbapps/Snake && ./ -w
cd ~/Arbalet/TimeClock/ -w
cd ~/Arbalet/arbapps/SpectrumAnalyser && ./ -w -i files/Nytrogen_-_Nytrogen_-_Trust_no_one.wav
cd ~/Arbalet/arbapps/LightsHero && ./ -w --level difficult

For each application a simulator will pop up and the table will also light with the started application.

Note: the software comes with a bunch of options too long to be detailed here, try adding --help to get a description

To create your own application open the tutorials thanks to ipython notebook:

cd ~/Arbalet/arbadoc/notebooks/en && ipython notebook

The list of tutorials will pop up in your web browser. Click on the first tutorial, and follow the guide...

ipython notebook is interactive python code running in a web browser, you can execute each cell step by step directly from your web browser by selecting the cell to execute (preferably by following the order but you can come back to a previous cell) and pressing Shift + Enter.

Complete the 3 tutorials before starting your own app.

Tip: you can start coding in the tutorials themselves to adapt the program to the behaviour you want and then transform it in a new subfolder of arbapps just like all other applications when it starts becoming big.

Looking for an idea of game or app to program? Have a look to the list of ideas.

Step 10: Software Activation of Touch (optional, for Advanced Makers)

The touch interface is disabled by default. If you have built a touch-enabled table by plugging a MPR121 sensor you can activate it by adding the parameter ­-c config150touch.json when executing an app. For instance:

cd ~/Arbalet/arbapps/Tetris && ./ -w -c config150touch.json

This parameter loads a config file enabling 6 touch keys. In most touch-compatible apps, available touch keys will backlight in light white when they can be touched, switching to strong white when they actually are. You can now play Tetris using the left, right, up (=rotate) and down keys.

In case of issue:

  • If the table used to light without the touch feature but does not with, make sure the MPR121 sensor is properly connected to the Arduino, the loss of communication probably prevents Arduino from doing its workIf the table lights but touch is not detected from above the glass, try touching the stripped wires with your fingers directly, if it works then you can decrease a little bit the value "threshold": 15 in the file config150touch.json, don't forget to reinstall the SDK after every change with:
cd ~/Arbalet/arbasdk/ && sudo python install
  • If touch works but pressing a key activates another one, you have plugged the touch wires differently, you can change the mapping via the "keys" field of config150touch.json (read the description below)
  • If touch works make the change persistent by changing the default configuration into the file default.cfg and reinstalling the SDK, then you no longer need the -c config150touch.json option.

Description of software mapping of touch keys:

Touch keys have a touch key ID between 0 and 5, associated pixels (2 pixels per key), and a role (e.g. "down" or "left"). The configuration can be changed in config150touch.json:

  • Field "keys" specifies the associated pixels associated. The Nth element of the list correspond to key ID N. e.g. the default file specifies that [14, 8] and [14, 9] are touch key ID 0 while [14, 6] and [14, 7] are touch key ID 1.
  • Field "mapping" attributes a role to each touch key ID for a specific touch mode (e.g. "quadridirectional").

For example, using the default file, in quadridirectional mode, the event "down" will be triggered when touch key ID 2 is pressed (because "down" is the 2nd element of the list) which corresponds to both pixels [14, 5] and [14, 4].



  • Classroom Science Contest

    Classroom Science Contest
  • Colors of the Rainbow Contest

    Colors of the Rainbow Contest
  • Fandom Contest

    Fandom Contest

17 Discussions


2 years ago

Cool project but the Instructable is a little skimpy especially Steps 7 & 8. It needs a description of how the electronics is connected and where the code runs. You mention python but we know python does not run on the Arduino. Something is missing

I'm guessing the software comes in two parts. The Arduino code is a loop that reads command from the serial port. These commands tell it to write LEDs and read switches. The host software (Raspberry pi is hopefully supported) decides which LEDs should be which colors and sends serial commands to the Arduino to make it so. This Arduino code is probably available from your web pages. The host is where python must run. There is probably a python library that talks to the Arduino. It is also found on your web pages. The main code is python that uses this library. So this is my guess mostly because it is the only way it could work. Is this guess correct?

I'm also guessing the proper procedure of this Instructable should be:

"Step 1: Go to our web pages to see the real project description and documentation. This Instructable is intended to be a pointer to our already existing project which lives on our web pages, not"

I'm glad people do Instructables like this, this is a cool project I'm glad to learn about, but I wish they would be more up front about what it is.

6 replies

Reply 2 years ago

Thanks for you feedback you're right it was missing details about software. Let me know how it is now.

<quote>This Instructable is intended to be a pointer to our already existing project which lives on our web pages</quote>

Well, "we" don't have web pages, the links only point to github, because it has great software management tools including bug reporting, changes logging, and a wiki. Duplicating information is always a bad idea, and a great effort for the author to make any small update. Pointers make sure the links here point to software with less bugs and more features with also an up-to-date documentation. Instructables is great for step-by-step instructions, github is great for hosting code and reports, hardware does not change so much while software does, especially in this project, ... thus merging both tools seem a neat compromise.


Reply 2 years ago

Major improvement. Thank you very much. That gives me a much better idea what it can do and how I might use it. Even a simulator. This is obviously well thought out. I've been thinking along similar lines for an interactive controller based on bluetooth midi. You solve 90% of my problem in one stroke. I am trying to figure out how make each LED a button. I suppose I could add a bunch of MPR121s but that could get expensive and who knows how many devices you can practically daisy chain on I2C. Hmm. I wonder if I could somehow MUX multiple keys to each pin. Keyboards are traditionally MUXed and scanned to reduce pin count. It might need a second Arduino though. Anyway great Instructable.


Reply 2 years ago

I am definitely thinking to create a MIDI controller as well :) To create a big launchpad, but we need a fully touch surface indeed. People made similar interactive surfaces with IR reflective sensors (emitters + receivers in the same cell), but this is a lot of wires & electronics to MUX/DEMUX them all. The capacitive solution can be expensive (€20 for 12 keys) and the ITO is slightly visible. I was thinking to IR strips 15 + 10 emitters and 15 + 10 receivers (you detect the beam interruption). These strips exists as commercial electronics products (e.g. search for "g4s touch") but nothing as affordable as WS2812B for DIY usage, and this is too precise for this project. If you find a way...


Reply 2 years ago

Great minds think alike. :-) I haven't found a good cheap solution but I was hoping your research was more extensive than mine and might discover something I missed. I'm basically back to mechanical switches trying to think of a design that could be mostly done with "multi color" 3D printers. The question is whether there is transparent conductive material that can be printed. I imagine for each button three layers, conductive on top and bottom and the middle non-conductive layer has a hole. If the hole is the right size pressing will allow the top and bottom to touch. The thickness of the top layer and the size and depth of hole would determine the force necessary for contact. Of course wiring all the buttons up to an external connector is another issue but it would be sort of like making a multi layer PCB but with silicon instead of copper. The key question is printable materials. And I only have access to a single-material 3D printer. Each layer could be printed separately assuming they are thick enough to be handled. The goal would be to print all the buttons at once as a connected unit but I suppose each button could be assembled by hand and then glued together or something.


Reply 2 years ago

Mechanical switches wouldn't suit here, as the surface is still a table and must keep smooth and usable. But for other specific uses (like launchpad) that is probably the easiest way. I would put standard mechanical switches and the LED strips on the top of these (fig 1). You can then 3D-print individual transparent boxes above the LED. If you don't need multitouch you can use a simple matrix wiring (fig 2).


2 years ago

Very cool, definitely going to add this to my long term project list.

I noticed that your video has a heavy emphasis on education. Do you teach courses on how to program or at least, the fundamentals to be able to do this on your own?

1 reply

Reply 2 years ago

I don't have these abilities but get in contact with teachers, workshop leaders, ...


2 years ago

You should use an old broken LCD TV panel to get the white layers of the backlight. I had some 42, 37" left here from broken tv i keep in case of any other projects. Nice project!


2 years ago

very nice project and thanks for sharing , however I appreciated if you be more specific or direct me to how make the LED table be interactive , I ran the same project with ws2812 LED strip beneath the 7cm translucent plexiglass , but not yet figure out how to make my table interactive. as you said there is couple of sensor to use for but maybe in practical not easy as it look

1 reply

Reply 2 years ago

I've improved the explanation of the touch feature in the last steps of the Instructable.

The sensor can detect touch through your 7mm (not cm?) plexiglass, depending on your material you might need some calibration, since thresholds are currently hardcoded within the arbasdk/config/config150touch.json file. Have a look there.

I know there is still documentation missing about this feature, how to configure it, how to change the location of the touch keys, their size, ... this is WIP.


2 years ago

Knowing what you were doing, how long did it take you to make this and now computer/electronic savvy are you?


3 years ago

This looks nice when it is in action.


3 years ago

This is really cool! Nicely done :)