Hexascroller

From NYC Resistor Wiki

Hexascroller is the large, hexagonal LED display in the middle of the front room. It ordinarily displays the current local time and Internet Time (in @beats).

Hardware overview[edit]

Hexascroller is composed of six 60x7 LED panels. Each pair of panels is controlled by a single Teensy 2.0. Power is supplied to the panels from a PSU that can be switched on and off by a relay attached to a single Teensy (so we can put Hexascroller in low-power mode if we wish).

All three Teensies are controlled by the Home Assistant Raspberry Pi in the mezzanine, using a Home Assistant add-on. The Pi has its own dedicated 5V power supply. The three Teensy 2.0s are connected to a powered USB hub.

Software overview[edit]

All software and firmware for Hexascroller can be found in a git repository hosted at [1]. The "hexascroller" directory contains the Arduino sketch that runs on the Teensy 2.0s; the "hexaservice" directory contains the software that runs on the Pi.

Connecting to Hexascroller[edit]

Hexascroller runs as a Home Assistant add-on. The logs can be viewed in Settings -> Add-Ons -> Hexascroller -> Logs.

If something goes wrong[edit]

  • Check if the add-on is running in Home Assistant. Check the logs.
  • Restart the add-on
  • Restart the teensies by unplugging and replugging the USB hub in hexascroller, then restart the add-on.

MQTT protocol[edit]

MQTT topics hexascroller subscribes to[edit]

  • hexascroller/power/set: set the power state of the display.
    The payload should be "ON" or OFF"
  • hexascroller/invert/set: set the invert state of the display.
    The payload should be "ON" or OFF"
  • hexascroller/message: set the message to display.
    The payload should be a string of text to display. Easter egg: the tilde character `~` shows the Resistor logo.

MQTT topics this service publishes[edit]

  • hexascroller/power: the current power state of the display.
    The payload will be "ON" or OFF"
  • hexascroller/invert: the current invert state of the display.
    The payload will be "ON" or OFF"

The service also publishes an availability topic:

  • hexascroller/available: the availability of the service.
    The payload will be "online" or "offline"

Extending the font[edit]

The font is an Nx7 pixel png bitmap. Black elements represent pixels in the character; white elements are blank space. Red pixels (255,0,0) are the character delimiters. If you're adding a character, you'll also need to add it to the inventory string in the conversion script (convert-font.py in the Grab-Bag/Hexascroller directory). To generate the font itself, run convert-font like so:

./convert-font.py >hexascroller/hfont.c

This will regenerate the hfont.c file that contains the converted font data. We keep hfont.c checked in, so be sure to run this after making your modifications.

Obsolete information[edit]

Too old to be useful; too charming to delete altogether. Note that Hexascroller no longer has audio capabilities!

Old Protocol[edit]

This is the old protocol; it may not apply to anything!

Hexascroller accepts newline-terminated strings.

Any string that does not start with an exclamation point is considered a "message" and is scrolled for approximately a minute before timing out.

Strings that begin with an exclamation point are "commands" which modify the behavior of hexascroller. Commands can include scroll speeds, wipe types, default messages, etc.

Commands[edit]

format function implemented?
!s[STRING] Set default message to STRING Yes!
!d[udlr][SPEED] Set direction and speed of scrolling. Yes!
!b[hz]:[duration] Attention beep Yes!
!tNOTE[,NOTE...] Play a tune (see below) Yes!
!S Get hexascroller's current status Yes, currently the message
!Dr Read the current date in the format YY/MM/DD HH:MM:SS Yes
!DwYY/MM/DD HH:MM:SS Set the current date in the format YY/MM/DD HH:MM:SS Yes
!A[messsage] Emit the given message at 9600 B on the third UART; these will be routed to the LED strip controller Yes
!C Set clock mode Yes

Tune format[edit]

Tunes are expressed as a series of notes of the format: [octave][note][duration], seperated by commas. Notes with the value "r" are rests. For example, here's a recognizable tune expressed as a tune command:

t3e4,r1,3e4,r5,3e4,r5,3c4,r1,3e4,r5,3g5,r15,2g5,r5

Sharps and flats are expressed by appending '#' and 'b', respectively. "2c#" is a C-sharp, and "3bb" is a B-flat.

Song repository[edit]

SMB !t4e5,4e5,r6,4e5,r6,4c5,4e5,r6,4g5,r42,4c5,r12,3g5,r12,3e5,r12,4a5,r6,4b5,r6,4a#5,4a5,r6,3g5,4e5,4g5,r6,5a5,r6,4f5,4g5,r6,4e5,r6,4c5,4d5,4b5,r12,4c5,r12,3g5,r12,3e5,r12,4a5,r6,4b5,r6,4a#5,4a5,r6,3g5,4e5,4g5,r6,5a5,r6,4f5,4g5,r6,4e5,r6,4c5,4d5,4b5,r24,4g5,4f#5,4f5,4d#5,r6,4e5,r6,3g#5,4a5,4c5,r6,4a5,4c5,4d5,r12,4g5,4f#5,4f5,4d#5,r6,4e5,r6,5c5,r6,5c5,5c5,r30,4g5,4f#5,4f5,4d#5,r6,4e5,r6,3g#5,4a5,4c5,r6,4a5,4c5,4d5,r12,4d#5,r12,4d5,r12,4c5,r54,4g5,4f#5,4f5,4d#5,r6,4e5,r6,3g#5,4a5,4c5,r6,4a5,4c5,4d5,r12,4g5,4f#5,4f5,4d#5,r6,4e5,r6,5c5,r6,5c5,5c5,r30,4g5,4f#5,4f5,4d#5,r6,4e5,r6,3g#5,4a5,4c5,r6,4a5,4c5,4d5,r12,4d#5,r12,4d5,r12,4c5,r42,4c5,4c5,r6,4c5,r6,4c5,4d5,r6,4e5,4c5,r6,4a5,3g5,r18,4c5,4c5,r6,4c5,r6,4c5,4d5,4e5,r48,4c5,4c5,r6,4c5,r6,4c5,4d5,r6,4e5,4c5,r6,4a5,3g5,r18,4e5,4e5,r6,4e5,r6,4c5,4e5,r6,4g5,r42,4c5,r12,3g5,r12,3e5,r12,4a5,r6,4b5,r6,4a#5,4a5,r6,3g5,4e5,4g5,r6,5a5,r6,4f5,4g5,r6,4e5,r6,4c5,4d5,4b5,r12,4c5,r12,3g5,r12,3e5,r12,4a5,r6,4b5,r6,4a#5,4a5,r6,3g5,4e5,4g5,r6,5a5,r6,4f5,4g5,r6,4e5,r6,4c5,4d5,4b5,r12,4e5,4c5,r6,3g5,r12,3g#5,r6,4a5,4f5,r6,4f5,4a5,r18,4b5,5a5,5a5,r6,5a5,4g5,4f5,r6,4e5,4c5,r6,4a5,3g5,r18,4e5,4c5,r6,3g5,r12,3g#5,r6,4a5,4f5,r6,4f5,4a5,r18,4b5,4f5,r6,4f5,4f5,4e5,4d5,r6,4c5,r42,4e5,4c5,r6,3g5,r12,3g#5,r6,4a5,4f5,r6,4f5,4a5,r18,4b5,5a5,5a5,r6,5a5,4g5,4f5,r6,4e5,4c5,r6,4a5,3g5,r18,4e5,4c5,r6,3g5,r12,3g#5,r6,4a5,4f5,r6,4f5,4a5,r18,4b5,4f5,r6,4f5,4f5,4e5,4d5,r6,4c5,r42,4c5,4c5,r6,4c5,r6,4c5,4d5,r6,4e5,4c5,r6,4a5,3g5,r18,4c5,4c5,r6,4c5,r6,4c5,4d5,4e5,r48,4c5,4c5,r6,4c5,r6,4c5,4d5,r6,4e5,4c5,r6,4a5,3g5,r18,4e5,4e5,r6,4e5,r6,4c5,4e5,r6,4g5,r42,4e5,4c5,r6,3g5,r12,3g#5,r6,4a5,4f5,r6,4f5,4a5,r18,4b5,5a5,5a5,r6,5a5,4g5,4f5,r6,4e5,4c5,r6,4a5,3g5,r18,4e5,4c5,r6,3g5,r12,3g#5,r6,4a5,4f5,r6,4f5,4a5,r18,4b5,4f5,r6,4f5,4f5,4e5,4d5,r6,4c5