Color Sorter LEGO GBC Module With Arduino

The color sorting module is finally finished! Time for a more in-depth demonstration.

Demonstration video of my color sorting module.

I made a lot of modifications since the last video, the colors are now more thought out and consistent, the DC and servo motors are not integrated to the build and are removable, and most importantly, the output was elevated a bit so it's finally GBC compliant [1].

The Build

The base is a standard GBC Ball Pump [2]. The output part features a piston that holds the balls in front of the color sensor, and a turning bucket that make the balls proceed to the appropriate lane after the piston releases. They are both driven by the same servo motor. Notice in the video how the bucket turns back a bit before turning to the output lane. That's when the piston releases the current ball, but since they are not driven separately, it must deal with the piston first, and then quickly turn the bucket while the ball is still falling.

The build.

The servo motor is driven by an Arduino Uno [3] microcontroller using a custom shield [4] that I made especially for this job.

This is the Arduino Shield I made specifically for this project, sitting on an Arduino Uno. It handles the color reading and drives the servo motor. It features an HC-06 Bluetooth module for the calibration and feedback.

The Arduino shield, sitting on an Arduino Uno microcontroller. It handles the color reading and drives the servo motor. It also features an HC-06 Bluetooth module [5] for the calibration and feedback.

The Sensor

I went with the cheapest solution possible: I have a single photo-resistor with an RGB LED. A photo-resistor is just like any resistor, except it changes its resistance value in relation to light, and this can be measured with the Arduino.

The 3-color light source and the light sensor.

But it can only measure brightness, not color, and this is where the RGB comes in. RGB stands for Red, Green and Blue, and these are the basic colors the human eye can see. To get the full color spectrum, these 3 channels must be measured separately. First the red light is lit, it takes a measurement, then switches to green, takes a measurement again, and then the same for blue.

Measuring the full color spectrum with a single brightness sensor and an RGB light source in 3 steps.

The ball falls into a dark chamber where the measurements are taken and is held there until it's done. The LED lights up the side of the ball, and the sensor gets only the reflected light.

Both the LED and the sensor are 1 stud deep in their holes to prevent any stray light from getting in when there is no ball in place. This setup also allows for just detecting the presence of the ball, because when the chamber is empty, the sensor sees darkness, even when the LED is fully lit.

The measurement chamber.

Calibration and Setup

I have realized that for it to work I will need proper calibration options that can be done on the spot, without the need for a computer, and with the ability to calibrate on a large set of samples. I needed some kind of interface. But instead of putting a bunch of obscure buttons and feedback beeps on the Arduino, I added a Bluetooth module [5] which I can connect to from my mobile phone. With that, I only need to install a serial terminal app (of which are plenty in the Play Store) on my phone and all is set.

Typing "help" lists all possible commands that exist on the device. To issue a command I just have to type it in, then the device leads me through a series of dialogues and instructions.

Calibration works by first defining what white is. White is all the colors at the same brightness, but since the sensor has different sensitivity to different colors, I have to use several glossy white balls that it can measure for reference, and then it can correct any future readings accordingly.

The balls used in calibration to define "white".

The second part is setting up the actual ball groups. After providing a name and the desired output lane, a specific number of balls has to be cycled through in order to calculate an average color, along with the spread. This is then saved to the internal EEPROM, which can hold this information indefinitely.

Training on a new set, using 25 balls to calculate an average and spread.

Recognizing Balls

Recognizing a ball works by calculating the current measurement's distance to all saved samples, and then choosing the one that is closest. It also has to be within the allowed spread for each color channel, otherwise it's not a match.

List of ball groups. Each sample has a name, an average color reading in HSL format, and a spread (±).

Feedback on the readings while in operation. It prints the name of the detected ball, and how close it was.


With the terminal in place, adding a statistics option is simple. It counts the number of balls of each type since it was powered on. From the running time and total ball count, a general balls per minute can be calculated as well.

Statistics shown after running for some time. Along with the official LEGO balls, I'm using some cheap beads that I ordered on eBay.

This one was running at a steady pace. The actual top speed is around 50 Balls per Minute.

Picture Gallery

See image captions for commentary.

Bonus Work In Progress Footage

These are some shots from early versions of the Color Sorter, including the part where I only started to figure out how to control the servo motor with Arduino, and setting up the color sensor.


  1. Standard - The Great Ball Contraption Wiki
  2. GBC workshop module instructions - The Great Ball Contraption Wiki
  3. Arduino Uno - Wikipedia
  4. What are Arduino Shields - learn.sparkfun.com
  5. Arduino and HC-06 (ZS-040)