LED tiles

Decorate your home with colorful, modular and affordable LED tiles. This version is fully 3D printable, no need for a custom PCB and everything is Open Source. The LED animation is more dynamic compared to most LED tiles since each tile has 12 individual controllable LEDs.

Part list for 15 units ($36@Amazon 221015):

  • 15x LED ring with 12 WS2812 LEDs, 50mm outer diameter
  • 15x 3D printed base (preferably printed with white PLA)
  • 15x 3D printed lid
  • 1m Power wire cable (for copper wire strands)
  • 1x nodeMCU ESP32 development board
  • Speaker cables 0.75mm^2
  • 5V PSU 10A (50W)

Equipment:

  • 3D printer (FFF/FDM with white PLA filament)
  • Solder station with a medium tip
  • Basic tools: needle- and cutting pliers, knife, hot-glue
  • Computer to program the WLED firmware (using a Micro USB cable)

Design

My kids wanted to have LED tiles in their rooms, but complained about the price which was around $20 per piece (2022-07). Instead of chipping in, I saw this as an excellent project to work on together, teaching them 3D modeling and basic electronics, while saving them lots of money (design and assembly time not included :)

We started comparing hexagonal and triangle shapes, and settled with something in between, a truncated triangle that allows lots of freedom in how they can be assembled. After experimenting with LED strips and round PCB rings, we settled for the PCB rings since they look really cool and cost less than $2 per piece.

The rough 3D modeling was done in a few minutes, and a test print allowed me to demonstrate how the thickness affected the diffusion of the light. Around 10mm between LEDs and the front resulted in a nice diffusion, while still keeping the ring shape intact. By curving the inside area around the LEDs, the light was distributed more evenly. When it was time to design the snaps for the connections between the modules, my kids lost their interest, and I was on my own… I did a few iterations and added 3D-PCB channels for the wires connecting the modules internally. By avoiding a PCB and special connectors the cost and design was minimized, and by soldering the modules together the connections become more reliable. This makes the design somewhat less flexible, but once mounted on the wall, it would probably not be altered that often anyway ;)

Routing – top view

Build

Building a module is quite easy since you only need four parts: 1x LED ring , 1x 3D printed base, 1x 3D printed lid and 20cm cable with copper strands for wiring.

Print the base and the lid with the following settings: White PLA, 0.4mm nozzle, no support and 0.2mm layer height. Note that the lid requires a smooth and leveled bed since it is only two layers thin. Unless your printer has auto leveling, I recommend that you spend time on tuning the printer before you start mass production.

Fresh out of the oven.

Follow this assembly video showing how the wires are soldered to the LED ring and routed to the base.

Each unit takes around 5 minutes to assemble (once you have done a few). I printed and assembled 3 units per day in a work week, so during the weekend we could combine 15 units and complete the project.

I did a custom base for the first unit, where the snap was replaced by wire channels, allowing me to route the 3 strands of speaker cable connecting the light to the control unit (one cable for 5V, one for GND and one for data).

ESP32 with connected wires. A plastic bag prevents short circuit (until I 3D print a cover)

The units are daisy-chained so that the first unit drives the second etc. Since each unit has one in and two out, the driving scheme can be splitted, creating two branches (with replicated light patterns), like in the video in the beginning of this post.

The units are connected to each other by soldering.

Program

WS2812 LEDs can be controlled in lots of different ways, I chose to use the excellent WLED project where an ESP32 hosts a web interface with tons of effects and settings that can be accessed over Wi-Fi thru a computer or mobile phone. Follow the getting started guidelines on how to program and use the device.

WLED interface on mobile phone

Mount

The complete structure was attached to the wall using small nails in some of the unit’s attachment holes (making minimal damage to the wall). Once in place and tested, we mounted the lids.

mount with a small nail

 Future development

I might build a small interface to the ESP32, so it can be controlled without a mobile/computer.

Download project files

All files required for this project are available at this GitHub repository: https://github.com/vonkonow/LED-tile

License

This project is open source under MIT License so feel free to adapt, improve and share your result!
(Attribution is optional but appreciated /Johan von Konow ;)

3D printed USB-C Eurorack power supply

Build your own USB powered Eurorack PSU

For the versatile LEET modular project, I designed a 3HP power supply that converts 5V USB-C to +12V and -12V. It is convenient to use, but not suited for powering a large number of units.

It should be quite straight forward to build it on a stripboard if you don’t have access to a 3D printer.

The 3D printed 3HP case

Specification

  • Easy to build – only five components
  • No need for a custom PCB
  • Small formfactor (3HP)
  • Power it from your computer or power bank.
  • Suitable for small loads (5-6 LEET modules when powered from USB)
All components but the pin header…

BOM

  • USB-C breakout PCB
  • CN6009 Step up DC/DC module
  • MP1584 Step down DC/DC module
  • Small slide switch (~20x6x13 mm)
  • 2×5 pin header
  • PLA for the 3D printer

Build

Download the 3D models and print them. I used the following parameters:

  • PLA material
  • 0.4mm nozzle
  • Support for the main body

The assembly is quite straight forward, but the limited space makes it a bit challenging. I recommend that you connect everything outside the case, with wires in suitable length and then trim the voltages (+/-12V). When everything works – move it in place and resolder wires when necessary.

a step down module creates -12V from a virtual ground

Test the unit carefully before you connect it to other modules. It works great for me, but build and use it on your own risk – I do not take any responsibility for damage caused by this project.

Download project files

All files required for this project are available at this GitHub repository:

https://github.com/vonkonow/LEET-Modular/tree/main/power

License

This project is open source under MIT License
(Attribution is optional, but appreciated /Johan von Konow ;)

SokoDay – easy to pick up, hard to put down.

Description

SokoDay downloads three new Sokoban puzzles every day from a server. One short, one medium and one long (referring to number of moves to solve the level). You can build your own device with a 3D printer, soldering iron and a handful of components. 

Sokoban is an addictive game where you push boxes to designated areas. It has been praised for being “pure and simple, very playable and mentally challenging”.

a 40 sec video showing how a medium level is loaded and solved
  • Fun and challenging to play
  • Easy to build
  • No PCB needed – 3D print two parts and connect the components using 3DPCB
  • Only a handful of components needed
  • Open source and easy to hack (write new games, change hardware etc.)
  • Use of modules simplifies design and removes the need for soldering tiny components
  • Portable – built in Li-ion battery and USB-C charging circuit
  • Wi-Fi connection to server with over 10 000 levels
  • Emulator avaliable

Idea

One day I realized that a Sokoban game could be played using a low resolution RGB matrix as display. Different colors could represent the player, boxes, walls and goals. It was such a simple idea that I expected to find several projects when I searched for it online. When I couldn’t find any, I was excited to start the development. Little would I know that I would spend several months completing and tuning the project until I was satisfied with the result. It was however a very fun project, covering electronics, embedded programming with Wi-Fi connections, industrial design, web servers and lots of scripts to gather, filter, sort and solve the different Sokoban levels.

Instead of letting the players choose from ten thousand challenges, I thought ‘less is more’ and got the idea to present a new challenge every day instead. This was in line with my ambition to make the game simplistic and clean, while hiding the backend from the user.

Sokoban game manual

  Red pulsating LEDPlayer
  Pink LEDWall
  Green LEDTarget
  Blue LEDBox (on floor)
  Cyan LED (blue + green)Box on target
  Yellow pulsating LED (red+ green)Player on target
  Black (LED off)Empty floor
Display color explanation
  • Use the four switches to move the player
  • A box can only be pushed (not pulled)
  • Push the boxes to their designated areas (targets)
  • When all boxes are on top of the goals the game is won

Note that there is no undo, you must reload the level to start over – “You don´t play Sokoban because it is easy, you play it because it is hard ;)”. This forces you to think several steps ahead instead of trial and error. It can be frustrating, but it becomes more rewarding.

You select one of three daily levels by holding down the navigation keys during power on.

  • Pressing up during power on loads the short level
  • Pressing right during power on loads medium level and
  • Pressing down during power on loads the long level

By pressing left and then one of the other keys (short, medium, long) during power up you can change the default level to be loaded. This setting is stored in nonvolatile memory and will be used during a normal power up (without navigation key). This is useful to match your preferred level or if you e.g. print several games, each with one level length.


Emulator

http://vonkonow.com/sokoplay/

If you are unsure if this game is for you, I built an html-based emulator, allowing anyone to test the game in a web browser. The daily levels are identical with the ones on the handheld device and it also shows map credits and solution. Test the game and decide if it is for you, if you like it, I highly recommend building the handheld version which provides a better experience ;)

BOM

  • 1x D1-mini board (ESP8266 based, Wemos Lolin or compatible) – This module provides both the CPU/ brain of the game and the wireless access
  • 1x WS2812 8×8 RGB LED Matrix (PCB, not FPC)
  • 1x charging module (with USB-C connection)
  • 1x Li-ion battery 503450 1000mAh (50x34x5mm) a smaller battery works, but gives a shorter battery lifetime…
  • 4x 6x6mm through hole tact switches
  • 1x miniature sliding switch (3 pin 2 position SPDT SS12D00 4mm handle)
  • 1x 20cm power or ethernet cable (providing the strands that connects the components)
  • 1x 3D printed base (PLA)
  • 1x 3D printed diffuser (preferably white PLA)

Building instructions

The device is quite easy to assemble – if you have access to a 3D printer and can identify the hot side of a soldering iron.

  • 3D print the base and the display diffuser (I used a Prusa i3 MK3S with 0.4mm nozzle and 0.2mm layer height).
  • Download the Arduino code and update the name and password of the Wi-Fi networks. (By adding home, work and mobile tethering credentials, you can use the device anywhere). It is also recommended to change the OTA password (see details below). Then compile and upload the code to the D1 mini board. (add esp8266 support if it is not present in the board manager, select 8266 lolin(wemos)D1mini board and the appropriate serial port).
  • Place the modules (D1 mini board, charging board) and battery in place (ensure that the holes align with the base) and secure them with a drop of hot glue (to avoid rattling noises).
Schematic drawing showing how the modules are connected (from top side)
  • Solder two wires to the power switch. Thread the wires through the hole in the base unit and secure the switch with a generous amount of hot glue (but ensure there is no glue preventing the sliding action). Route one wire to the D1 (but do NOT solder it in place) and the other to the charging module. Flip it over and solder the wire to the charging module (positive terminal).
  • Place the four 6x6mm tact switches and solder the common ground wire to their terminals, start where the channel ends and then route the wire through the channel and solder it to the switches one by one. Thread the wire through the base and the charging module (but do NOT solder it in place). Repeat the procedure for the other 4 wires connecting the switches to the D1 module (they can be soldered to the D1 module).
  • Connect the charging module to the ground of D1. (It is now ok to solder both wires to the charging module, but do NOT solder the other end to the D1). Solder the battery wires to the charging module (verify the polarity + is red, – is black).
  • Verify all connections carefully, check for cold solder joints and short circuits.
  • Add two wires to D1 power and ground and solder them in place with the existing wires from the switch and charging module. Also solder the third wire for the RGB data to D1 and route all three wires through their channels and through the base unit. Route the wires through the RGB matrix (ensure it is oriented so the top wire goes to data in) and place it on top of the other components. Once in place solder the wires and trim them, but spare a cm until you have verified that everything works.
All components but the display matrix in place.
Topside view with LED module mounted (covering battery, D1 & charging modules)
  • Power on the device and verify its operation (it should display random blue dots when it is searching for Wi-Fi and internet access. Once it works, trim the display wires (when the device is powered off) and add the diffuser.
  • Done, you now have three daily Sokoban levels for the coming eight years :)

Development

Once I knew what I wanted to do, I planned the project and selected suitable components, I needed to verify that both the D1 board and the display module could be operated on ~3.7V from the battery. I did some prototyping and verified that everything worked as planned. I used the built-in weak pull ups in the esp8266 for the switches, removing the need for external resistors. Since the display matrix uses serial communication, the schematics becomes dead simple and assembly too.

No D1 mini board? – Print one ;)

I only had one D1 module at home, so when I wanted to build more devices, I created a 3DPCB adaptor board that converts an ESP12F, a 3.3V LDO and two capacitors to a D1-ish board. It doesn’t have all connections of the original board, but it works for this purpose. Please note that you need to take special care programming the esp8266E module with a serial interface since it doesn’t have the USB interface of the D1-mini…

Software

By using existing Arduino libraries for Wi-Fi connection and WS2812 I could focus on the game.

Game and communication

Since Sokoban is such an easy game to understand (but difficult to master), programming the game rules is a walk in the park. Once that was done (with a hard coded map), I started to implement the server communication. Instead of using bare sockets I relied on a http connection over port 80, where the client downloads a text description of the map from a web server. Unfortunately, the ESP8266 doesn’t support TLS1.3, so it must rely on unencrypted communication, which however is fine since the game data isn’t confidential nor sensitive.

Winner animation

When the game is won the device uploads number of moves for completion and displays a rainbow plasma animation. Since the ESP8266 is so powerful I didn’t even need to create look up tables for the sinus, cos and square root functions and got good performance doing floating point calculation in real time. To be honest, I think I spent more time tweakig the plasma feature than on the actual game ;)

Over the Air programming

The device supports OTA updates, enabling you to reprogram them wirelessly. For this to work, you first need to program them with Wi-Fi credentials to the same network. It is recommended to change the password for OTA to prevent them from being hacked (I don’t want to see the devices being used as a bot-net ;) Once the device is powered on and connected to the same network, the unit can be selected in the port menu in the Arduino environment.

Industrial design

After I had verified that the components worked together, I started to sketch on how I wanted the device to be designed. I stacked the modules in different arrangements and modelled shapes in 3D where I experimented with portrait and landscape orientation, gamepad type and parting lines. I spent quite a lot of time on a tabletop version with a slanted top surface that was designed to be easy and ergonomic to use and I even made wooden block models where I experimented with the size and feel of the product. The wedge shape gave it some attitude, but it also became a bit bulky.  I then experimented with a square model with a switch on each side. I liked that the design had no orientation and since a Sokoban level can be played upside down this was pretty cool. But after printing a block model I realized that the ergonomics weren’t good when you had to hold it and press the spread-out buttons with two hands.

I realized that a thinner and symmetrical design was more pleasant to handle. My first attempt exposed the modules, which looks both cool and unfinished at the same time, when I tried to hide the modules behind the matrix, the box shape became quite boring. I therefore sketched on parting lines and contrast between the base and the diffuser, and once I split the front surface in an output and input area, I knew I was getting close. A few iterations with different radiuses and chamfers and I was happy with the design.

The diffuser is quite smart, by adjusting the thickness of the ribs and material it both diffuses and blocks the light, creating a pleasant rectangle that blends the individual LEDs. Test the game with and without it to see the notable difference.

Server side

A Sokoban game needs good levels to be fun. There are lots of different level collections online, and after analyzing different options I used the levels found on https://www.sourcecode.se/sokoban/levels .

Filter size of playfield

Since most levels are bigger than 8×8 (number of LEDs) I wrote a script that filtered out all levels above a certain size. I thought about having a dynamic view of a larger playfield, but playing Sokoban is difficult enough when you see the whole level, and seeing just a bit would probably be more painful than pleasant. Since the outer edge of a level doesn’t need to be visible, I realized that I could display levels up to 10×10 in size. I also wrote a script that cleaned the levels by removing tiles outside the playing field and removed corner bricks in the outer wall (because it looks nicer). To do this I virtually flooded the level with water, and once flooded I removed everything outside the water and then rebuilt the containing edge.

Providing solutions

I wanted to provide a solution to all the maps in the game, I therefore wrote a script that converted the levels to a format accepted by jsoko. I then ran all the maps with a timeout of 6 seconds. This resulted in a list with lots of solutions. Another script merged the solutions with corresponding level and separated the solved maps from the ones that were not solved before the timeout. I repeated the process with 60s and 600s timeouts. After more than a month of continuous crunching using a quite powerful computer, I had solutions to over 10 000 levels with a size of 10×10.

Level format

I decided to create a simple custom text format for the levels instead of using a database or XML/ JSON. This makes the infrastructure easier to maintain, and since the files are quite small it scales decent. If I one day want to switch to a database, I just need a script to convert the text files. The levels are separated with a semicolon, a comma separates the level from the metadata and colons are used to separate the field names from the data in the metadata area. Here is an example of a level:

     ###
 ####  
# $    
# $###*#
#  .#..#
 ## $  #
  #   @#
   ####
,
Name:erim239-fifth collection
Columns:9
Rows:8
Authour:Erim Sever
Collection:Erim Sever Collection
Description: These levels are copyright Erim Sever  
Moves:54
Pushes:14
Solution:llluulluuRRRRurrdLDDlddlluRdrUdrUlllulluurDldRuurrRurD
Device Retries:2
Solved:1
;

Analysis and groups

I wrote another script that compiled the number of moves for the solution of each level, I imported the data in Excel and plotted a histogram to understand the distribution.

This allowed me to build a custom graph that divided the solution space in three rather equal parts. Another script then filtered out levels within an interval of moves and I then had three groups:

  • Group one can be solved in 10 to 70 moves. This is group short, or S
  • Group two can be solved in 71 to 129 moves. This is group Medium or M
  • Group three can be solved in 130 moves and more. This group is called Large, or L

The server provides 3 new levels every day, one from each group. The server uses three php scripts that isolates todays three levels. It also updates the number of times the level has been downloaded and completed, which provides rough statistics about how difficult the levels are.

Please note that the number of moves does not correlate 1:1 to the difficulty of the level. I’m sure there are large levels that are easier for a human to solve than a short level, but in most of the cases I find an L level to be more difficult than an M, which in turn usually is more challenging than the S level.

I considered to use number of pushes instead of moves, but the scatter chart above indicated that the difference would be quite small. (On average 3.8 times more moves than pushes).

It was quite fun to parse, filter, clean, solve and combine all the levels. I wrote the scripts in JavaScript, which is not ideal, but that runs in any browser. If I had known how much time I were to spend on this, I would have used Python to automate the whole chain, but “don’t mess with a working system” ;)

Troubleshooting

The device needs two things to work:

  1. power (a charged battery) and
  2. Wi-Fi connection to internet

If the device doesn’t load a level, it is likely due to one of these errors. Connect it to a 5V USB charger and verify that the Wi-Fi name and password are correct and that the access point is connected to internet.

All levels should be possible to complete (the solution has been simulated). The solution can be found on the emulator. I have solved all the bugs that I have found, but with lots of different scripts handling lots of different levels from different sources in different formats, I wouldn’t be surprised if there are a couple of bugs left. If you find one, let me know!

Improvements

I think the units works quite well the way they are, but there is always room for improvements. Here is a list of things that would make SokoDay even better – feel free to contribute :)

  • Battery meter (display when battery is too low to operate)
  • Ambient light sensor (automatically dim display in low light conditions)
  • Ability to rate levels
  • Best of the best levels, (based on level rating) 
  • Wi-Fi host (to manage Wi-Fi credentials)
  • More games and a game select menu? (note the absence of A and B buttons)

Credits

Sokoban was originally created in 1981 by Hiroyuki Imabayashi. Levels were imported from https://www.sourcecode.se/sokoban/levels together with metadata and credits (readable in the emulator).

Download project files

All files required for this project are available at this GitHub repository:
https://github.com/vonkonow/SokoDay

License

This project is open source under MIT License
(Attribution is optional, but appreciated /Johan von Konow ;)

LEET Linux

Linux based sound synthesis for LEET modules (or any other USB MIDI keyboard).

This project is suited for anyone that wants to build a powerful synthesizer engine. The project is built around the compact and affordable Raspberry Pi Zero (with WiFi) and has a miniature OLED display and six buttons. LEET Linux forms a complete synthesizer together with a USB HUB, a USB soundcard and other LEET devices (see video below).

All LEET devices use 3DPCB – a method where the circuit-board is replaced with a single 3D printed part that keeps all components in place while it also encompasses the case and structure of the product. Integrated wire channels makes it easy and fool prof to assemble and there is no need to pay and wait for a PCB delivery ;)

Demonstration of high-quality sound generation with LEET Linux running FluidSynth with Yamaha Disklavier Pro Grand Piano soundfont.

LEET Linux is part of the LEET synth project. Before continuing with the details below, it’s a good idea to read the main post first (if you haven’t already):

Part list:

  • 1x 3D printed core (3DPCB), uses 20g PLA filament.
  • 1x Raspberry Pi Zero W
  • 1x 128×64 0.96” SPI OLED display (I used the 6 pin version without CS, blue display)
  • 6x 6x6mm 4pin through hole tact switches – preferably with low activation force (50g / 0.5N)
  • 1x USB hub with micro USB cable, or a micro USB OTG adapter
  • 0.3mm copper wires (can be found in RK mains wire or similar)

Equipment:

  • 3D printer (FFF/FDM with PLA filament)
  • Solder station with a narrow tip
  • Basic tools: needle- and cutting pliers, knife, hot-glue

Build it

Print the core using a fff/fdm 3D printer. I used the following settings:

  • 3D printer: Prusa i3 MK3S with 0.4mm nozzle
  • Material: PLA
  • Nozzle temperature: 210deg C
  • Layer height: 0.2mm
  • Infill: 20%
  • Support: None

    The printing time is ~2.5 hours with default speed.

I have not made a step by step building instruction, but if you have built another LEET device, it should be sufficient to look at the illustration below.

Sound Engines

There are lots of different sound engines in Linux. So far, I have tried two different programs (FluidSynth and SamplerBox).

I hope that with the help of other LEET users the installation can be improved (providing ISO images) and more supported engines can be added. It would be nice to have ZynAddSubFX, sunvox and maybe an adaptation of zynthian in the future.

FluidSynth

I have successfully used FluidSynth (without a custom OLED interface). In the video above I used the Yamaha Disklavier Pro Grand Piano soundfont to demonstrate the quality of the sound. LEET sequencer is sending MIDI data to LEET Linux that is rendering the sound using an external USB soundcard and forwarding the MIDI events to the LEET keyboards (using aconnect command). By using pyFluidSynth, an interface can be developed in python that uses the OLED and the buttons to select soundfonts, map instruments and midi channels (3×2 buttons).

Installation of fluidsynth is quite straight forward. Follow the raspberry pi initialization below and type:

sudo apt-get install fluidsynth

Here is the bash script I used to start fluidSynth and map a LEET Keyboard to fluid MIDI:

(sleep 5; aconnect 16:0 128:0)&fluidsynth -a alsa -o audio.alsa.device='hw:1' -C0 -R0 -r48000 ./YDP-Grand.sf2

As you can see, I use plain alsa for sound generation (avoiding jack or pulseaudio that can cause additional delay.)

It is sometimes helpful to test audio to rule out other error sources:

First use this command to find the id of the attached soundcard

cat /proc/asound/modules
speaker-test -c2 -twav -Dhw:1,0  (where 1 is the id I got from the first command)

If you encounter problems, visit the forum to see if someone has found a solution to your problem, if not this is a great place to ask for assistance.

SamplerBox

I have also worked with SamplerBox and adjusted the script to use the OLED and keys to select sampleset. However, I have only got a few samples set to work properly, and haven’t figured out if the others are not working due to memory restrictions, configuration error or something else…

I hope that with the help of other LEET users the supported engines can be improved and expanded. It would be nice to add ZynAddSubFX, sunvox and maybe even adapt zynthian in the future. It would also be nice to provide ISO images for easy installations. Until then this project requires manual configuration and installation of different programs so Linux experience is preferred. But even a novice user should be able to follow the installation procedure of SamplerBox, however – expect to spend time googling for installation and configuration errors…

It was a bit tricky to use Samplerbox with the OLED display since samplerbox is using python2 while the luma library is using python3.

Here is a list of the installation steps I did:

Initialize the raspberry pi

  • Download “Raspberry Pi Imager” from https://www.raspberrypi.org/software/
  • Run and install “Raspberry Pi OS Lite” on empty micro SD card
  • Connect QWERTY keyboard, a MIDI keyboard and usb soundcard to a USB hub, connect the hub to the pi (use a micro USB OTG adapter). Insert micro SD card, Connect a HDMI display and power up the Pi.
  • Logon as default user: pi and password: raspberry
  • type:
sudo raspi-config

and change the following configurations:

  • system options/Wireless LAN (input wifi credentials to the same network as your PC)
    • system options/change password (you don’t want your raspi to become an attack vector to your network)
    • system options/Boot Autologin (select console autologin)
    • interface options/ssh (enable)
    • interface options/spi (enable)
  • unplug the HDMI cable and rebot when exit: (SamplerBox USB audio won’t work if HDMI is connected).
  • it is a good idea to configure your router and give the raspberry pi a static IP.
  • open a terminal and ssh pi@192.168.xxx.xxx (use the static IP). This enables you to cut and paste the long commands below, making installation easier.

Install SamplerBox

The following commands are copied from the merge request regarding Python3 installation of SamplerBox:

Install the required dependencies (Python-related packages and audio libraries):

  sudo apt-get update ; sudo apt-get -y install git python3-dev python3-pip python3-numpy cython3 python3-smbus portaudio19-dev libportaudio2 libffi-dev
  sudo pip3 install rtmidi-python pyaudio cffi sounddevice

Download SamplerBox and build it with:

  git clone https://github.com/josephernest/SamplerBox.git
  cd SamplerBox ; sudo python3 setup.py build_ext --inplace

Install libraries for the OLED display:

  sudo -H pip3 install --upgrade luma.oled
  sudo apt-get install libopenjp2-7
  sudo apt install libtiff5

Add LEET files

use SFTP to copy logo_128x64.png, Linux128x64, pixelmix.ttf, oledTest.py and samplerbox.py to /home/pi/SamplerBox/

Edit sound configuration

  sudo nano /usr/share/alsa/alsa.conf

change defaults.ctl.card 0 to defaults.ctl.card 1

change  defaults.pcm.card 1 to defaults.pcm.card 1

sudo /etc/init.d/alsa-utils stop ; sudo /etc/init.d/alsa-utils restart ; sudo /etc/init.d/alsa-utils start

Test Samplerbox

python3 samplerbox.py

Autostart SamplerBox:

If everything works, you can make SamplerBox autostart by changing this script:

sudo nano /home/pi/.bashrc

add this at the end:

  python3 /home/pi/SamplerBox/samplerbox.py

Download project files

All files required for this project are available at this GitHub repository:
https://github.com/vonkonow/LEET-Synthesizer/tree/main/Linux

License

This project is open source under MIT License
(Attribution is optional, but appreciated /Johan von Konow ;)

3DPCB Wi-Fi Ducky

Inject keystrokes, set up a reverse shell, or install a payload to dump passwords, all from a distance.

This is a 3D printed Wi-Fi version of the well-known USB Rubber Ducky hacking device (featured in Mr Robot). It is a very powerful PEN test tool that bypasses common security protections since it is planted inside the network (requires some social engineering). I want to raise the awareness of this attack vector and encourage anyone to build it, test it and use it for good to improve security (white hat hacking).

30 seconds demonstration

This implementation uses a 3D printed circuit board that provides the following benefits:

  • Quick and easy to build. (takes minutes to assemble)
  • Using standard components that can be found at your local supplier. (or in your drawer)
  • low cost (< $9) allows you to install several expendable units. (spray and pray) 
  • No need to wait for PCB delivery.
  • Integrates the structure of the device.
  • Compact since it stacks components in 3D. (44x30x11mm)

Credits to Darren Kitchen @ HAK5 for the original USB Rubber Ducky, and Stefan Kremser/ Spacehuhn for the WiFi version used in this build: “This is a tool. It’s neither good nor bad.
Use it to do good, to study, and to test. Never use it to do harm or create damage!”

Part list:

  • WeMosD1 mini, or clone (ESP8266 – without pin header). ~$3 on ebay
  • Arduino pro micro 5V, or clone (ATmega32u4 – without pin header). ~$5 on ebay, $4 on Alibaba
  • 3D printed circuit board (7g PLA)
  • Micro USB sync cable (not charge cable) ~$1 on ebay
  • Strands of copper wire 0.3mm

Equipment:

  • 3D printer (FFF/FDM with PLA filament)
  • Solder station with a narrow tip
  • Basic tools: Needle- and cutting pliers, knife
  • Computer to run Arduino IDE and upload firmware (using a Micro USB cable)

Design:

I wanted to test the Wi-Fi ducky and realised that I had all the parts needed at home . To keep it compact – I stacked the PCBs on top of each other and created a 3DPCB to separate and guide the connecting wires. The optional WS2812 LED was removed to keep the design as simple as possible.

Cross section of the device

I extended the unit in length to allow most part of the Wi-Fi antenna to operate freely instead of being dampened by the ground plane of the pro micro (This is the reason why the micro USB port of the WeMosD1 is not near the edge). First version worked great and this became one of those hacks where documentation took longer than the build ;)

Build it:

Here is a step by step building instruction if you want to replicate the build

Rendering showing both sides of the 3DPCB and microcontroller boards (duck yellow ;)

1. Print the 3DPCB

Print the core using a fff/fdm 3D printer. I used the following settings:

  • 3D printer: I used Prusa i3 MK3S with 0.4mm nozzle
  • Material: PLA
  • Nozzle temperature: 210deg C
  • Layer height: 0.2mm
  • Infill: 20%
  • Support: Yes

The printing time is just below one hour. While printing you can program the boards:

2. Program the two boards

  • Download the Arduino code from: https://github.com/spacehuhn/wifi_ducky. You can also find a more detailed installation instruction there.
  • Connect the Arduino pro micro, select board, port, compile and upload the corresponding firmware.
  • Connect the WeMosD1, select board, port, compile and upload the corresponding firmware. Install possible missing libraries (I needed to install SimpleCLI)

3. Assemble the Ducky

  • Remove 3Dprinted supports.
  • Thread four wires through their channels. Start from the smaller pro micro. Each wire goes through three holes. Add some tension to ensure they are tightly routed and don’t protrude any surfaces.
  • Thread four wires through the pro micro, put it in place and solder the wires from the backside of the Arduino board. Cut protruding wires.
  • Thread four wires through the WeMosD1, add some tension and solder it in place. Cut protruding wires.

4. Inspect

  • Verify the build, ensure that the boards are firmly secured and that all solder joints look proper. Rework if anything looks funny.

5. Hack

  • Connect the cable to the smaller pro micro board and connect it to your computer.
  • Connect to the wifiduck WiFi network (password: wifiduck )
  • Open a browser and visit http://wifi.duck or IP: 192.168.4.1
  • Change SSID and password (optional, but recommended).
  • Test this script to run hello world (on windows computers):

DEFAULTDELAY 200
ALT F2
GUI SPACE
GUI r
LEFT DELETE
DELAY 100 
STRING www.vonkonow.com 
ENTER

Visit Spacehuhn for detailed command descriptions and examples.

Note that microcontroller pads are exposed – do not place it on a conductive metal surface (since it might short circuit the device). Once tested you can wrap it with tape, heat shrink tubing or simply put it in the ESD bag that came with one of the microcontrollers.

Needless to say: This is an ethical hacking tool – I strongly disapprove of illegal activity and claim no responsibility nor liability for any use of this device.

Download project files

3D models for this project are available at this GitHub repository: https://github.com/vonkonow/3DPCB-Wi-Fi-Ducky

License

This project is open source under MIT License
(Attribution is optional, but appreciated /Johan von Konow ;)

LEET Control8

The Control8 MIDI unit is part of the LEET Synthesizer project. If you haven’t – It is a good idea to read the main post first before continuing with the details below:

This post describes how the Control8 unit works and what you need to build your own.

Description of the Control8 unit

Product guide. Click here to download high-resolution PDF.

Part list:

  • 1x 3D printed core 3DPCB
  • 8x 3D printed potentiometer knobs (use the version with 0 deg arrow)
  • 1x Arduino pro micro, or compatible clone (5V version. ATmega32U4)
  • WS2812 LED-strip with 8 LEDs (60 LEDs/m. I used IP60, white FPC)
  • 8x 100k trim-potentiometers (10k-500k will work)
  • 1x 25cm RK wire (containing 24 strands of 0.3mm copper wires)

Equipment:

  • 3D printer (FFF/FDM with PLA filament)
  • Solder station with a narrow tip
  • Basic tools: Needle- and cutting pliers, knife, hot-glue
  • Computer to run Arduino IDE and upload firmware (using a Micro USB cable)

Development

The Control8 is the successor to LEET Control.

Control8 has 8 analog inputs and uses the same low-cost trim-potentiometers as LEET Chord and Sequencer. In order to simplify routing, the trim-pots are rotated 90 deg compared to the other devices – so make sure to use the right 3D printed top if you want the arrow to face upward in mid position.
I recorded the process when I designed the 3DPCB for the device if anyone is interested:

Designing a 3DPCB in 10x speed (still boring unless you want to learn how it is done ;)

Build it

I have not made a step by step building instruction, but if you have built another device, it should be sufficient to look at the illustration below. The build process is very similar to the step-by-step instruction for the keyboard.

Backside view showing routing of wires.

Don’t forget to share your build in the forum. The forum is also the best place to share ideas, assist with development and  get support and help other LEET builders

Download project files

All files required for this project are available at this GitHub repository:

License

This project is open source under MIT License
(Attribution is optional, but appreciated /Johan von Konow ;)

LEET Sequencer

The Sequencer is part of the LEET Synthesizer project. If you haven’t – It is a good idea to read the main post first before continuing with the details below:

LEET Sequencer + LEET Control + Mobile phone = Synthesizer

LEET Sequencer is a 16 step, 8 channel sequencer using 16×8 RGB LEDs for visualization. Songs are stored on a microSD card using a custom format (FAT filesystem, MIDI-ish).

Please note two things:

  • The sequencer is working, but all functions are not in place. Live recording, MIDI clock and MIDI tick editing are examples of functions that remains to be implemented in firmware.
  • The sequencer is more complicated to build than the other LEET devices, so it is recommended to build one of those before the sequencer (but the difference is not that big).

This post describes how the sequencer works, what you need to build your own and how it was developed.

Description of the Sequencer

Product guide. Click here to download high-resolution PDF.

Part list:

  • 1x 3D printed core 3DPCB
  • 1x 3D printed knob for the trimpot
  • 1x 3D printed display 3DPCB
  • 1x 3D printed display diffusor (two models: round or square pixels are available)
  • 2x 3D printed stand clips
  • 1x Arduino pro micro, or compatible clone (5V version, ATmega32U4)
  • 11x 6x6mm 4pin through hole tact switches – preferably with low activation force (50g / 0.5N)
  • 1x micro SD card reader (with 3.3V LDO and SPI level conversion)
  • 2x 8×8 WS2812 LED matrixes
  • WS2812 LED-strip with 12 LEDs (60 LEDs/m. I used IP60, white FPC)
  • 1x trim potentiometer 100k (10k-500k will work)
  • 2x 3pin 0.1” pin headers (from SD reader or Arduino pro micro package)
  • 3x jumper cables (15-20cm female-female)
  • 1x 25cm RK wire (containing 24 strands of 0.3mm copper wires)

Equipment:

  • 3D printer (FFF/FDM with PLA & PET filament)
  • Solder station with a narrow tip
  • Basic tools: needle- and cutting pliers, knife, hot-glue
  • Computer to run Arduino IDE and upload firmware (using a Micro USB cable)

Build it

I have not made a detailed step by step building instruction, but look at the illustration below and check out the similar step by step instruction for the keyboard.  Before mounting any components, it is a good idea to fill the symbols on the base 3DPCB with paint to improve readability. You can use a marker and wipe off excess paint with an alcohol wet tissue. For more saturated colors use model paint and sand the top surface slightly with a fine grit sandpaper once the paint has dried.
This device is more complex than the other LEET devices, with more wires to be routed in an intricate way. Solder one at a time and you should be fine. Note that 5 wires are changing side under the SD card module, route those wires before mounting the SD module.  

The micro SD card module I bought had an angled pin header in place that I needed to remove. Desoldering can be done by first solder a piece of wire between all pins on the backside. The wire distributes the heat allowing all pins to be removed at the same time. You can also use a desoldering pump or braid if you prefer that. The pin header can be cut in two and used as contacts for connecting the base to the display.

Note the potentiometer that controls the BPM. It is an ordinary low cost trimpot with a 3D printed knob glued to the top.

The black triangle was made with a sharpie (like the symbols on the base 3DPCB).

When every wire is soldered and the sequencer is tested (especially the display module) – I recommend that the pin headers on the control and display units are secured with epoxy (over the soldered side), to ensure that no wires break when jumper cables are attached or pulled.

Backside view showing routing of wires.

Don’t forget to share your build in the forum. The forum is also the best place to get support and help other LEET builders

Development

After developing the LEET Keyboard, I wanted to be able to record and playback MIDI from the devices. I first designed a single channel mini sequencer that could be used for each instrument – making it super modular. But when I played around with it, I realized that having multiple sequencers increased the number of devices to build, cost, and made working with different songs complicated, as timing, playback and navigation needed to be synchronized. Kill your darlings – a more traditional sequencer that handles several channels seemed like a better approach. But more channels require more resources from the CPU. I considered more powerful architectures (SAMD21, ATMega4809, ESP8266, ESP32 and Raspberry Pi), but pin count, MIDI capabilities, operating voltage, availability, size and cost, complicated the decision. In the end, I decided to try to use the same Arduino micro as in the input devices (ATmega32u4), even if the specification where nowhere near what was needed:

  • Typical file size of a MIDI song: 50kB
  • Total CPU RAM memory: 2kB
  • Time between two MIDI events: 2.5ms (1000bpm & 24 ticks/BPM)
  • Display update (4.3ms)
  • Time for file access on SD card: 10-20ms

With clever programming, buffers and precise control over timing, this can in theory be solved, but it became way more challenging than I expected (once again ;)

I considered using tiny OLED displays and both monochrome and full color LED matrixes for the visual feedback. Since I had blinkenlights as a goal for the project, the full color matrix was the obvious choice, and I think the end result looks great, even if user interface, memory requirement and timing, made the programming rather challenging.

When I built the first version, I realized that only the libraries for MIDI, SD card and RGB LEDs used more that 84% of available RAM and 84% Flash. By carefully testing several different libraries, I eventually managed to reach 50% Flash and 40% RAM. Usually you can pick two of RAM, Flash or performance, at the cost of the third. Optimizing all three at the same time is much more difficult. To make it work I had to develop a custom file system where each beat contains all MIDI events for the different channels in its own file. 16 beats are grouped in a pattern stored in its own directory, and the pattern directories are grouped in a song/ project directory. It’s a lot of files, but each is small enough to fit inside the available RAM. Next problem is that the file access is longer than the MIDI tick, this is solved by using dual buffers where one is used for playback, while the other is fetched from the file. I don’t like using interrupts, but since I didn’t want to rebuild the file access library, I used TMR1 interrupt for playback of the buffer, while the rest is handled in the main loop. The remaining problem is that the timing of updating the 140 RGB LEDs is so critical that the library has to disable global interrupts (playback) for a while… Careful timing is mitigating the issue, but depending on amount of parallel MIDI events, minor delays might occur. When a new pattern is displayed, there is simply not time to parse all 16 positions in order to update the display. Instead, a display cache file (led.txt) is used that contains led index and note (color) for the LEDs. (This file has to be updated when something is edited).

All in all, the code is well over 1000 lines, and even if I have been forced to clean it up on several occasions, it certainly has room for improvements – splitting it up in several files is probably a good idea to make it easier to grasp for others.

It is pretty cool that the songs are stored on a SD-card that can be read by any computer. This allows backups, sharing of songs, and also conversion between different file formats. By compressing the song directory, it is easy to save all files and directories in a single file.

To demonstrate the capabilities, I wrote a Python script that reads a MIDI file and converts it to the sequencer format, with directories, cache files and all. Unfortunately, I didn’t find any MIDI library that works with Python3, so it has to be run in 2.X.

Python script and demo files for the SD card are found in the GitHub repository.

Code description

This text is a copy of the description in leet_sequencer.ino:

  • Each Song contains one or several Patterns.
  • Each Pattern contains 16 positions (beats).
  • Each Position contains 24 curTicks and 8 tracks.
  • Every Position is stored as a separate file containing up to 32 MIDI events with corresponding tick – defining when they are due to be played.

The files are stored in the following directory structure:

  • Song01/Pattern00/Pos12.txt

Each MIDI event in PosXX.txt uses 4 bytes, where the first is curTick (time within the position), followed by three standard MIDI bytes.

example: 0x00,0x93,0x30,0x7f

  • 0x00 – send event at first curTick
  • 0x93 – send “note on” (0x9X) on MIDI channel 4 (0xX3)
  • 0x30 – tone C4
  • 0x7f – Maximum intensity (127)
    (0xff in first byte means empty position, despite the following 3 bytes.)

Due to very tight memory restrictions, only one position is stored in RAM (called midiBuffer). Since loading the position file takes longer than a curTick, the midiBuffer is separated in two halves to play and preload curTicks independently.

The lower part of the midiBuffer contains 16 events and stores events on curTick 0-11, while the upper buffer stores events on curTick 12-23. At curTick 12, the lower buffer of next position is loaded (while playback is done from the upper buffer).

Playback is handled by a timer interrupt (currently using tmr1 @ 1ms) and plays the corresponding event from the midiBuffer (when seqMode == seqPlay). I prefer to avoid interrupts, but did not want to rewrite SdFat library to achieve predictable timing…

When switching to a new pattern, there is not enough time to parse all position files to update the LED display (it takes more than 100ms). Instead, SongXX/PatternXX/LED.txt contains pre-calculated values for each pixel (16×8). This file needs to be updated when a position has been altered.

The sequencer operates in one of the following modes (selected and indicated by the lower part of the control panel):

  • seqStop – Default mode, displays current pattern (16 positions and 8 tracks).
  • seqPlay – Plays the content of each position and moves to the next.
  • seqPgm – Stores incoming midiEvents (note on /off) in current position.
  • seqTrack – Used to select active track (when editing).
  • seqPos  – Displays notes within the current position.
  • seqPattern – Displays the patterns of the song. Used to change pattern.
  • seqSong – Displays the different songs on the SD card. Used to change song.

This program is using the following excellent libraries (I’m standing on the shoulders of giants):

The libraries are the smallest I found (tested several others), but still eat
approximately half the avaliable RAM and Flash on the AtMega32U4…

Future improvements:

The sequencer has reached a working stage, but there are still things that are not implemented (some are crucial for ‘real life’ usage). I have set up a forum post discussing how they are best implemented. Provide feedback, wishes and contribute if you can, all help is appreciated!

https://vonkonow.com/wordpress/forums/topic/sequencer-improvements/

Examples of features to be added in the future:

  • Improved UI (LED key feedback)
  • MIDI tick editing
  • Real time recording with quantization
  • MIDI clock support
  • Error handling using the LED matrix?

Download project files

All files required for this project are available at this GitHub repository:

https://github.com/vonkonow/LEET-Synthesizer/tree/main/Sequencer

 

This project is open source under MIT License
(Attribution is optional, but appreciated /Johan von Konow ;)

LEET Pad

The Pad MIDI keyboard is part of the LEET Synthesizer project. If you haven’t – It is a good idea to read the main post first before continuing with the details below:

This post describes how the pad keyboard works and what you need to build your own.

Description of the Pad

Product guide. Click here to download high-resolution PDF.

Part list:

Component cost is around $6 on eBay October 2020 (will depend on shipping and supplier).

  • 1x 3D printed core 3DPCB
  • 1x Arduino pro micro, or compatible clone (5V version. ATmega32U4) – (~$4)
  • 11x 6x6mm 4pin through hole tact switches – preferably with low activation force (50g / 0.5N) – ($0.2)
  • WS2812 LED-strip with 8 LEDs (60 LEDs/m. I used IP60, white FPC) – ($1.1)
  • 1x 25cm RK wire (containing 24 strands of 0.3mm copper wires) – ($0.1)

Equipment:

  • 3D printer (FFF/FDM with PLA filament)
  • Solder station with a narrow tip
  • Basic tools: needle- and cutting pliers, knife, hot-glue
  • Computer to run Arduino IDE and upload firmware (using a Micro USB cable)

Build it

I have not made a step by step building instruction, but check out the video and illustration below. The build process is very similar to the step by step instruction for the keyboard.

Backside view showing routing of wires.

Development

The pad is literally a smaller version of the LEET keyboard. I rearranged the LEDs and switches, downsized it, rebuilt the 3D model and adjusted the code.

Download project files

All files required for this project are available at this GitHub repository:

https://github.com/vonkonow/LEET-Synthesizer/tree/main/Pad

License

This project is open source under MIT License
(Attribution is optional, but appreciated /Johan von Konow ;)

LEET Chord

The chord MIDI keyboard is one of the devices in the LEET Synthesizer project. If you haven’t – It is a good idea to read the main post first before continuing with the details below:

This post describes how the chord keyboard works and what you need to build your own.

Description of the Chord keyboard

Product guide. Click here to download high-resolution PDF.

Part list:

Component cost is around $6 on eBay October 2020 (will depend on shipping and supplier).

  • 1x 3D printed core 3DPCB. Uses 34g PLA filament ($0.7).
  • 1x 3D printed knob for the trimpot.
  • 1x Arduino pro micro, or compatible clone (5v version. ATmega32U4) – (~$4)
  • 14x 6x6mm 4pin through hole tact switches – preferably with low activation force (50g / 0.5N) – ($0.2)
  • WS2812 LED-strip with 12 LEDs (60 LEDs/m. I used IP60, white FPC) – ($1.1)
  • 1x trimpotentiometer 100k (10k-500k will work)
  • 1x 25cm RK wire (containing 24 strands of 0.3mm copper wires) – ($0.1)

Equipment:

  • 3D printer (FFF/FDM with PLA filament)
  • Solder station with a narrow tip.
  • Basic tools: needle- and cutting pliers, knife, hot-glue
  • Computer to run Arduino IDE and upload firmware (using a Micro USB cable)

Build it

I have not made a step by step building instruction, but the build process is very similar to the keyboard.

Backside view showing routing of wires.

Note the addition of a potentiometer that controls the chord length. It is an ordinary low cost trimpot with a 3D printed knob glued to the top. I used a sharpie to highlight the arrow on the knob and then wiped off the top surface with an alcohol wet tissue.

Development

I wanted to see if I could create a keyboard without disharmonic sounds (no wrong keys ;). I sketched on a keyboard that played chords in different scales, tonics, root and chord length. It was a good learning experience of musical theory and after a few iterations I think I found a user interface that is easy to understand and use (despite the lack of 12 keys to select tonic note).

Embedded code for the Arduino pro-micro.

The code originates from the LEET keyboard, but with the addition of user interface for chord configuration (the upper row of keys and LEDs), and the chord generation. The ‘minor’ array is defining distance between different notes in naural minor scale. Offset the array to get different tonics. By adding an offset of two you get the major scale instead.

Download project files

All files required for this project are available at this GitHub repository:

https://github.com/vonkonow/LEET-Synthesizer/tree/main/Chord

License

This project is open source under MIT License
(Attribution is optional, but appreciated /Johan von Konow ;)

LEET Keyboard

3D printed single octave MIDI keyboard with full color LED feedback.

This single octave MIDI keyboard is part of the LEET synth project. Before continuing with the details below, it’s a good idea to read the main post first (if you haven’t already):

This post describes how the keyboard works, how it was developed, what you need in order to build your own, and a step by step building instruction.

Description of the LEET keyboard

Product guide. Click here to download high-resolution PDF.

Part list:

Component cost is around $6 on eBay (October 2020, depending on shipping and supplier).

  • 1x 3D printed core 3DPCB. Uses 34g PLA filament ($0.7).
  • 1x Arduino pro micro, or compatible clone (5V version. ATmega32U4) – (~$4)
  • 15x 6x6mm 4pin through hole tact switches – preferably with low activation force (50g / 0.5N) – ($0.2)
  • WS2812 LED-strip with 13 LEDs (60 LEDs/m. I used IP60, white FPC) – ($1.1)
  • 1x 25cm RK wire (containing 24 strands of 0.3mm copper wires) – ($0.1)

Equipment:

  • 3D printer (FFF/FDM with PLA filament)
  • Solder station with a narrow tip
  • Basic tools: needle- and cutting pliers, knife, hot-glue
  • Computer to run Arduino IDE and upload firmware (using a Micro USB cable)

Development

The keyboard was the first device I developed in my LEET synth project. I wanted to build a minimalistic MIDI keyboard that could be connected to a computer or mobile phone to make up a basic synth. There are tons of professional keyboards available, but they are quite bulky and expensive compared to what I had in mind. There are some DIY MIDI keyboards online, but the ones I found were either too basic (proto or perfboard without any case) or overly complicated and bulky, with different parts requiring complicated assembly. As always, if you can’t find what you are looking for – build it!

Since I wanted to have LEDs for feedback, I decided to use WS2812b addressable LED-strips to provide full color feedback, minimum wiring and only a single I/O on the Arduino. I selected a LED-strip with 60 LEDs/m since the distance between each LED roughly matches a piano.

Each switch on the keyboard goes to a dedicated I/O of the Arduino pro micro. This way, there is no risk of key ghosting, and no need for decoder ICs or diodes; simplifying design, cost, program and assembly. Two extra switches are used to select octave, and a third switch is used to select MIDI channel. I did not include pitch bend and volume potentiometers, but it should be quite easy to add, since two I/Os are unused (but switch pinout to ensure that potentiometers are connected to AD inputs).

The keyboard is quite compact and robust. I initially made it thinner, but it looked fragile and unbalanced, so I increased the thickness to 8mm. To keep the design clean, I kept all wires on the backside, but exposed the components on the front. They could of course be covered by a front, but I like the techy appearance and having a single 3D printed part that integrates the whole product.

Embedded code for the Arduino pro-micro.

screenshot of main loop

The program of the keyboard is straight forward thanks to the use of MIDIUSB and NeoPixelBrightnessBus libraries. The main loop reads the switches, sends corresponding MIDI commands and listens to incoming MIDI for the LED feedback. If the incoming MIDI package correlates to the selected channel, the corresponding LED is enabled and the color of the LED is derived from the pitch of the note. The global constant ‘echoLED’ controls if the LEDs are lit up on keypresses and incoming MIDI (if true) or only  MIDI (if false). When adjusting octave or MIDI channel; the number of lit LEDs indicate the selection and then fades rather quickly. Since the keyboard only has 13 LEDs – channels 14-16 are not shown, but can be selected. To make setup easy – a change of MIDI channel is stored in EEPROM and thus remembered the next time the keyboard is powered up.

Step by step building instructions

This instruction describes the assembly process step by step on a level suitable for most people. Building the keyboard is quite easy thanks to the wire channels in the 3DPCB which indicate how the components shall be connected.

Building a LEET Pad in 10x speed. The Keyboard is built in a similar way.

1. 3DPCB:

Download the latest version of the 3D model here (the .stl file is suited for 3D printing.)

Print the core using a fff/fdm 3D printer.  I recommend beginning with the smaller leet_test part to verify that your printer is calibrated before starting the 3-4 hour print.

I used the following settings:

  • 3D printer: Prusa i3 MK3S with 0.4mm nozzle
  • Material: PLA
  • Nozzle temperature: 210deg C
  • Layer height: 0.2mm
  • Infill: 20%
  • Support: None

    The printing time is 3-4 hours with default speed. Once the print is done, you can trim any defects with a fine sandpaper if needed.

2. Arduino program

While printing you can download, set up and program the microcontroller:

  • Install the Arduino IDE and download the latest LEET keyboard firmware here.
  • Download and install MIDIUSB and NeoPixelBrightnessBus libraries.
  • Connect the keyboard to your computer with a micro USB cable.
  • Select Arduino pro micro as board, and select corresponding com port (if the Arduino is not appearing with a com port, try another cable, since some charging cables lack data wires and won’t work).
  • Compile and upload the code.

3. Wires:

Strip 25cm of RK wire (the multi stranded cable used for internal wiring in electrical 230V cabinets) to get the 24 pcs of 0.3mm copper strands inside.

4. Microcontroller:

Secure the Arduino pro micro (without pin headers) in place with a dab of hot melt adhesive (glue gun) on the backside. Ensure that the holes are aligned.

5. Switches:

Insert the switches and fold the pins on the backside to lock them in place. I recommend a small flat screwdriver.

6. LED strip 1:

Cut a section of LED strip with 7 LEDs.

Backside view of LED strip with marked pads.
  • Remove the protective liner and the double sided adhesive that covers the three connections on each end on the backside of the section of the LED strip.
  • Solder two strands of wire to “DIN” and “GND” on the exposed pads of the backside (note that one end of the LED strip is “DIN” and the other is “DO”).
  • Solder three strands of wire to the other side (DO, 5V & GND).
  • Thread the 5 wires through the 3DPCB, remove the liner and press the LED strip in place.
  • Thread the DIN wire through the wire channel to the microcontroller, ensure it’s tight and solder it in place on the front side. Cut away excess wire close to the solder.
  • Thread the neighboring GND through the channel, stretch, solder it to the Arduino board and trim.
  • Thread the three remaining wires on the other end through their channels to each dedicated opening.

7. LED strip 2:

Backside view of LED strip with marked pads.
  • Cut a section of LED strip with 6 LEDs.
  • Remove the protective liner and the double sided adhesive that covers the three connections on the “DIN” side.
  • Solder three strands of wire to “DIN”, “GND” & “5V” to the exposed pads on the backside.
  • Thread the 3 wires through the 3DPCB, remove the liner and press the LED-strip in place.
  • Thread the 5V wire through the channel, stretch and solder it with the wire from the other LED strip in the dedicated opening. Trim the wire from the other LED strip.
  • Continue to thread it to the microcontroller, stretch it and solder in place.
  • Thread the DIN wire through the wire channel to the opening where it meets the “DO” wire from the other LED strip. Ensure both wires are tight, solder them together and trim the ends.
  • Thread the GND wire and solder it together with the other GND wire at the dedicated opening. Trim the wire from the other LED strip and continue to thread the wire through its channel to each of the 12 switches. Tighten it and solder the wire to each switch (24 pins) along the way.

8. Connect the switches

Solder a wire to both available pins of a switch. Insert it in its wire channel, thread it through the Arduino, add some tension, solder it and cut the remains.
Repeat for all 15 switches. Don’t forget to take a break every now and then to stay focused.

9. Inspect

Check the solder joints, ensure that the wire is secured and tight within its channel and that everything is flush against the backside. If anything is loose, protrudes, looks funny or sharp – re-solder until it’s perfect.
Good job – Give yourself a well-deserved high five.

10. Power up and play

Connect the keyboard to a computer or a mobile phone with a USB micro cable. The startup animation should turn on every LED and the device should appear as MIDI in your DAW. Insert a coin and start playing!

Download project files

All files required for this project are available at this GitHub repository:

https://github.com/vonkonow/LEET-Synthesizer/tree/main/Keyboard

License

This project is open source under MIT License
(Attribution is optional, but appreciated /Johan von Konow ;)