IceCube display
LED display to show IceCube event data
Modular IceCube event display

The IceCube LED display built at UGent was based on the mechanical designs of the UW River Falls displays, but uses the icecube-display firmware instead of the Teensy's Arduino interface used in the original design. It is a scale 1:500 display, so is approximately \((2m)^3\) in size, and is driven by three Teensy 3.2 ARM microcontroller development boards.

Display segmentation

The full IceCube detector was broken up into three display modules to facilitate transport, each containing a Teensy board. Provided there is a way to mechanically support the upper part of the module, each of the modules can be controlled as an independent display that supports part of the IceCube detector.

  • Front module: strings 1-30
  • Center module: strings 31-50, optionally also contains the DeepCore strings (79-86)
  • Back module: strings 51-78
Display segment assembly


Power and data distribution

A single module contains roughly one third of the IceCube strings. At 60 DOMs per string, this equates to up to 1800 RGB LEDs that can draw 60mA at 5V when set to full brightness. Therefore two 5V-60A power supplies (HRP-300-5) are used in each module to power the LEDs.

To reduce the number of cables running to the fully assembled display, the front and back modules can get their USB connection to the PC via the center module. To achieve this, the center module contains a USB hub whose upstream port is accessible from the side of the module. Two downstream USB ports are provided facing the front and back modules. A multi-TT hub was used to provide optimal throughput on the high-speed USB connection leading to the hub.

All the electronics are located in the bottom part of the module. The top part only contains a small amount of cabling to connect data lines of the LED strips (see next section).

Display segment connections

The Teensy controllers use an 8-bit port to send serial data to 8 LED strips simultaneously. To make these output pins easily accessible, the Teensys are seated in a OctoWS2811 adaptor. The two RJ45 connectors are then each fed to a splitter board using CAT5e cables to provide 8 strip ports. Since 8 ports is smaller than the corresponding number of IceCube strings per display segment, the data lines of up to four LED strips are connected in series, resulting in a strip with 60 to 240 LEDs. The data lines for the first and third strip run from bottom to top, while the data lines for the second and fourth strip run from top to bottom. Connections between the strips are made inside the display segment boxes and do not change between different assemblies of the display. Each strip of 60 LEDs is powered through the bottom case and is equipped with a circuit breaker, rated to 4A, to prevent one short circuit from taking down half the display segment.

Display segment strip cabling

LED strip layout configuration

The way the LED strips are grouped is not predetermined and depends on the length of the available connecting cables, location of the microcontroller inside the module's bottom box, and of course personal preferences of the person doing the cabling. Therefore, the strip configuration is stored in the microcontroller's EEPROM such that the same firmware can be used in different displays. The below figure shows an example layout of the center module, with the corresponding JSON snippet that can be used to generate the EEPROM data.

Display segment strip layout

The full JSON file may look as the example provided below. Note that not all display segments use all 8 output ports, and not all ports have 4 strips connected in series. If ports with less than 4 strips are present, the available ports should be populated starting with the longest strips. In the example below, the 'front' module's first seven ports have four strips, and the last port only has two. The 'center' and 'back' modules respectively have four and seven ports used for four strips, and none on the last port(s).

"front" : [
[ 8, 2, 1, 7],
[16, 24, 25, 17],
[15, 23, 22, 14],
[ 9, 3, 4, 10],
[12, 6, 5, 11],
[20, 28, 29, 30],
[19, 27, 26, 18],
[13, 21]
"center" : [
[34, 33, 32, 31],
[44, 43, 42, 41],
[35, 45, 46, 36],
[37, 38, 39, 40],
[47, 48, 49, 50]
"back" : [
[61, 52, 51, 60],
[70, 71, 78, 77],
[69, 68, 75, 76],
[62, 53, 54, 63],
[64, 55, 56, 65],
[66, 74, 73, 72],
[67, 59, 58, 57]
"devices" : {
"ICD-IC-001-0001" : "front",
"ICD-IC-001-0002" : "center",
"ICD-IC-001-0003" : "back"

A utility is provided (teensy/ to generate and upload the EEPROM data starting from this JSON file. Note that after uploading a new configuration, the device should be power cycled for changes to take effect.


Development requirements

To build the firmware, arm-none-eabi-gcc is required. It also uses the newlib C library implementation and a few headers provided by the upstream Teensy repositories for compatibility with some avr-libc functionality.

EEPROM usage

5 bytes of EEPROM are used to store the display specific properties. The first and last supported string number denote a continous, inclusive range of IceCube strings that can be displayed by the device.

Address offset Description
0x20 + 0x0 Supported LED type: see display_led_type_t
0x20 + 0x1 LED RGB order: see display_led_color_order_t
0x20 + 0x2 First supported IceCube string number (in range 1-78)
0x20 + 0x3 Last supported IceCube string number (in range 1-78)
0x20 + 0x4 Support for DeepCore strings (boolean)

Starting from offset 0x30, \(4\times(1+8)\) bytes are used to store the LED strip mapping. The first of each of these nine bytes indicates how many values in the following 8-byte array are valid. Although the number of valid strip segments is stored in the array, care should be taken that mappings for non-existent LED strip segments don't go outside of the supported IceCube string count. In case the firmware would want to read out these offsets anyway, it would re-use LED data from other strings and be prevented from reading possibly invalid data.

The EEPROM segment below corresponds to the above center display segment. The first LED strip on the second port maps to IceCube string \(44=31+\text{D}_{16}\). Note that the EEPROM segment is essentially a transpose of the table provided in the configuration file segment. The three last bytes (unused) of the segment mappings are shown here as '00', as per the recommendation not to use non-existent buffer offsets.

Display segment strip buffer offset map
Address offset Data (hexadecimal)
Ports used Buffer mapping
0x30 + 00503 0D 04 06 10 00 00 00
0x30 + 90502 0C 0E 07 11 00 00 00
0x30 + 180501 0B 0F 08 12 00 00 00
0x30 + 270500 0A 05 09 13 00 00 00

Firmware flashing

To update the firmware on the Teensy, just press the program button. lsusb should now show the Halfkay bootloader:

$ lsusb | grep -e "Teensy"
Bus 003 Device 102: ID 16c0:0478 Van Ooijen Technische Informatica Teensy Halfkay Bootloader

The new firmware can now be uploaded via make upload when building from source, or using the teensy_loader_cli utility when programming a compatible .hex file:

# Only one device can be programmed at a time
teensy_loader_cli --mcu=mk20dx256 -w icecube_display.hex

Initial programming

When a new Teensy is used to run this firmware, or the Teensy has been used for other applications before, the EEPROM will not yet be properly initialised. After programming the device firmware, the upload_eeprom target can be used to upload the device's EEPROM file. After a reset, the device will now be able to read out sensible EEPROM values and be ready for use.

Cost estimate

The prices list below do not include VAT. Total estimate (without labor costs) for the UGent display is ~€3000. The UW River Falls cost estimate was $4000, mainly due to more expensive LED strips.

  • Custom PCBs (EuroCircuits): €300
  • Electronics (Mouser, Farnell): €1200
    • Cables: 4 core, 6 core, 2 core (0.88mm²/18AWG)
    • Connectors: 4P4C, 6P6C, terminal blocks, a few case mount USB plugs
    • Power supplies
    • Teensys
  • LED strips: €750 + €150 import customs (shipping from China)
    • 32× 5m WS2812B
    • Silicone sleeving, endcaps
  • Plywood 5.5mm × (2500mm × 1220mm (?)): cost unknown. UW-River Falls states $400 (8 sheets 5mm, 4 sheets 12mm inch)
  • Black backdrop curtain: €70