From NYC Resistor Wiki
Jump to: navigation, search

Megascroller's smaller, cooler cousin.

If something goes wrong[edit]

Hexascroller is based on a Raspberry Pi. If power goes out unexpectedly, it is possible that the SD card will be corrupted.

If Hexascroller does not come back up when power is restored, shell into Hexascroller as described below and try to restore the service manually. If you can't shell into Hexascroller, make sure that the ethernet cable is plugged in and that the hub on top of cubesville is still connected to the network. If you still can't reach Hexascroller, turn off power, swap in the backup SD card (located next to the Pi on Hexascroller), and try booting it up and shelling into it as described below.

If the replacement SD card works, please take the old SD card and reimage it so it can be the new backup SD card. The image can be found on golden at [1]. Once you have this image, you can (on Linux at least) use dd to copy the image to the card.

Login and startup information[edit]

Arch linux IP: Login: root/same pw as cam

If the service isn't running:

  1. cd Hexascroller/hexaservice
  2. nohup python2 service.py &
  3. logout

SD card setup[edit]

  1. Get the latest arch linux for RPi
  2. dd if=arch.img of=/dev/mmcblk0
  3. remount card
  4. set static IP as per https://wiki.archlinux.org/index.php/Network_Configuration#Static_IP_address
  5. install card in pi and boot, login is root/root
  6. change password
  7. pacman -Syu
  8. pacman -S git python2-pyserial python2-pillow
  9. git clone https://github.com/nycresistor/Hexascroller.git
  10. timedatectl set-timezone America/New_York

Hardware overview[edit]

Currently, hexascroller consists of:

  • six LED panels
  • three Teensy 2s
  • a Raspberry Pi (booooo)
  • a 9V supply powering the panels, and the mega through a 7805
  • a little speaker driven by a mosfet

There's a 74ls04 inverter driving the clock and data lines going into panels, which are arranged in three chains of two. The inverters were necessary to source enough current to drive the lines.

Use cases[edit]

Ideally, hexascroller should support the following operations:

  • clock: hexascroller should be able to tell the time.
  • attention: you should be able to beep to draw attention to a hexascroller message
  • messaging: you should be able to scroll a message


All of Hexascroller's source is in the NYCResistor "Hexascroller" repository.

Hexascroller on github


The XBee is one of the old school v1s listening on address 0x01. The other end of the connection is 0x02, which is hooked up to the bug.


The server is Golden (net.nycr.us) The current control script should be accessible through port 666 on Golden.

telnet net.nycr.us 666
nc net.nycr.us 666

should connect you to hexascroller.

The server is running two upstart scripts, hexascroller-producer and hexascroller-consumer.

  • hexascroller-producer: Runs /opt/hexascroller/scripts/hexascrollerQueueProducer.py. Long running process that listens on port 666 for incoming TCP connections. Data received is put into the redis key command:unix_timestamp. The key name is then RPUSH'd into the redis list key cmdQueue. Producer will wait one second, then look for a response in the form of redis key response:unix_timestamp and pass that back to the user.
  • hexascroller-consumer: Runs /opt/hexascroller/scripts/hexascrollerQueueConsumer.py. Long running process that waits for a value to be pushed onto the redis list key cmdQueue, then gets the value that corresponds to that value as a key. The value represented by command:unix_timestamp is then sent to hexa's xbee via the serial port at ttyUSB0. If the command is not a special hexascroller "!" command, then !A0 (the light flashing command) is also sent to hexa. Hexa's response (or an error) is added to the key response:unix_timestamp where unix_timestamp matches the timestamp of the original command.

The benefit is that other programs can interface with hexascroller by setting a command string to a redis key, then right-pushing that key name onto the cmdQueue list.


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.


Currently only some of these commands are implemented. Give me time.

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:


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

LED Strips commands[edit]

The third UART connects to a Teensy that controls the RGB LED strip. It accepts the following commands:

  • M0: Flash the lights
  • M2: Disco-chase mode for a few seconds
  • M4: Smooth color fading
  • M5: Turn off all the lights
  • Crgb: Set and hold a constant RGB value. The input should be in the range 0-7 for each color.
  • R!: Reset the Teensy and await a new program load (do not use unless you have a programmer connected to the spare USB cable! Otherwise the Teensy will need to be power cycled to restart)

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.

Other hacks[edit]

Get status! At the very least the controller should be able to query hexascroller to see if it's on.

  • suggested protocol: hexascroller responds to !S with "0" if it is turned off. No need to respond if it's turned on, because that's the expected default state.

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