Some home automation projects take years to get off the bench, sometimes finally. This was mine. This project took about five years from conception to completion. Not for lack of trying, but simply due to complexity and competing attention, the Sports Ticker project sat on my workbench collecting dust. But that all changed recently with the advent of ESPHome and the incredible Home Assistant Custom Component called ha-teamtracker.

The Concept

I wanted an LED digit display in my basement home theater below our projection screen. The display would be used for when we watch sports, and I liked the current scores and any other information to be displayed on the digit display as the game went on. You would see one of those scrolling tickers in areas or on the stock market. Technically, you can display anything you want on it.

The hard part, naturally, was getting text to appear on the LED digit panels and then getting live sports data during games in real-time... now you can probably imagine why it took so long to accomplish.

First, let's build a working Sports Ticker and connect it to Home Assistant!

The living room Sports Ticker used 8 MAX7219 Modules

The Parts

  • ESP8266 development board of your choice. Note: Depending on how long you want to build your ticker, having more RAM helps. (Ask me how I know). I ended up making two—a mini Sports Ticker for our living room TV and a larger one for the home theater. The mini ticker uses a NodeMCU ESP8266, and the larger one needs the ESP32 to handle the additional display units.
  • MAX7219 Dot Matrix Modules. You can get as many as you want. They are commonly available in arrangements of single modules, quad modules, or octo modules. I prefer the 8-module boards as there is less soldering.
  • You will need an appropriate power supply and miscellaneous. Supplies for soldering and mounting. Also, jumper cables to attach the MAX units to the ESP.
  • Optional: I needed to power my Sports Ticker and ESP from a far-away power source. I use a 12v DC Power Supply along with this (amazing) 12v - 5v buck converter that takes 12v in and gives you a Micro USB 5v connection for your ESP8266 board - this was such a useful tool to power both my Sports Ticker ESP board and a second ESP board for WLED. (You'll see these pictured below)

ESPHome

ESPHome was a revelation for me. I don't do a lot of ESP projects, but they got exceptionally more accessible once I got the hang of ESPHome. When I started this journey, I thought I could use MQTT directly from the ESP to fetch and display text on the screens. It's not that I couldn't still do that, but I would need to write that code in C from scratch. ESPHome made it effortless.

Flash your ESP Board with ESPHome, then use the following YAML to set it up for your Sports Ticker:

Note: This YAML gives you a few sensors like IP Address and Wifi signal strength in Home Assistant, as well as two switches- one for display On/Off and whether or not to scroll the text. You will also need to set up two helper entities in Home Assistant -input_number, used for Brightness and input_text for the text you want to display on the ticker.

esphome:
  name: "sportsticker1"

# Edit for your board
esp8266:
  board: nodemcuv2

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:

web_server:
  port: 80

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esphome-sportsticker"
    password: "mypass"

captive_portal:


spi:
  clk_pin: D5
  mosi_pin: D6 # Digital In

display:
  - platform: max7219digit
    cs_pin: D7
    num_chips: 8
    intensity: 3
    scroll_speed: 100ms
    update_interval: 100ms
    lambda: |-
      if(id(power_on_off).state) {
        it.printf(0, 0, id(digit_font), TextAlign::TOP_LEFT, "  %s", id(hatxt).state.c_str());
        it.intensity(atoi(id(habri).state.c_str()));
        if(id(scroll_on_off).state) 
        { 
          it.scroll_left(); 
          }
      }
time:
  - platform: homeassistant
    id: hass_time

binary_sensor:
  - platform: template
    name: "Power State"
    id: power_on_off
    internal: true
  - platform: template
    name: "Scroll State"
    id: scroll_on_off
    internal: true


switch:
  - platform: template
    name: "Sports Ticker Power Switch"
    icon: mdi:dots-grid
    optimistic: true
    restore_mode: RESTORE_DEFAULT_OFF
    turn_on_action:
      - binary_sensor.template.publish:
          id: power_on_off
          state: ON
    turn_off_action:
      - binary_sensor.template.publish:
          id: power_on_off
          state: OFF
  - platform: template
    name: "Sports Ticker Scroll"
    icon: mdi:dots-grid
    optimistic: true
    restore_mode: RESTORE_DEFAULT_OFF
    turn_on_action:
      - binary_sensor.template.publish:
          id: scroll_on_off
          state: ON
    turn_off_action:
      - binary_sensor.template.publish:
          id: scroll_on_off
          state: OFF

font:
  - file: "pixelmix.ttf"
    id: digit_font
    size: 8
    glyphs:
    - ' '
    - '@'
    - '*'
    - '!'
    - '"'
    - '%'
    - (
    - )
    - +
    - ','
    - '-'
    - .
    - '0'
    - '1'
    - '2'
    - '3'
    - '4'
    - '5'
    - '6'
    - '7'
    - '8'
    - '9'
    - ':'
    - A
    - B
    - C
    - D
    - E
    - F
    - G
    - H
    - I
    - J
    - K
    - L
    - M
    - N
    - O
    - P
    - Q
    - R
    - S
    - T
    - U
    - V
    - W
    - X
    - Y
    - Z
    - _
    - a
    - b
    - c
    - d
    - e
    - f
    - g
    - h
    - i
    - j
    - k
    - l
    - m
    - n
    - o
    - p
    - q
    - r
    - s
    - t
    - u
    - v
    - w
    - x
    - y
    - z
    - °

text_sensor:
  - platform: wifi_info
    ip_address:
      name: "SportsTicker IP Address"
    ssid:
      name: "SportsTicker Connected SSID"
    bssid:
      name: "SportsTicker Connected BSSID"
  - platform: homeassistant
    name: "HA Txt"
    id: hatxt
    entity_id: input_text.sportstickertext
  - platform: homeassistant
    name: "HA Brightness"
    id: habri
    entity_id: input_number.sportsticker_bri
    
sensor:
  - platform: wifi_signal
    name: "SportsTicker WiFi Signal Sensor"
    update_interval: 60s
  - platform: uptime
    name: "SportsTicker Uptime Sensor"

Save and upload your ESPHome configuration to your ESP. Connect your MAX digit displays to pins D5 D6 and D7 as outlined in the YAML above to their corresponding pins on the MAX module input. Ensure you also set up your helper entities in Home Assistant and connect the ESP to your Home Assistant via the Devices Page.

Once your ESP reboots and runs the configuration, you should get a web interface that looks something like this on its IP address:

These two switches should also appear in Home Assistant once you have it connected like so:

Perfect! Let's also set up the necessary helper entities- these are specified in the YAML in ESPHome, so the ESP module will connect to Home Assistant and look for these- you can set them whatever you like as long as they match.

Since I have two sports tickers, I have two sets of Helper Entities!

Getting something to show up!

Here's the fun part.

If you look near the end of the YAML configuration where we're looking for a text helper entity in Home Assistant, we assigned it an ID of hatxt

  - platform: homeassistant
    name: "HA Txt"
    id: hatxt
    entity_id: input_text.sportstickertext

and in the lambda section of the MAX Digit Display configuration, we use the hatxt ID is essentially a variable to insert the text from the input_text.sportstickertext entity, which will be displayed on our Sports Ticker

it.printf(0, 0, id(digit_font), TextAlign::TOP_LEFT, "  %s", id(hatxt).state.c_str());

So, anything we put into this entity from Home Assistant will automatically just appear on the ticker!

Let's try it:

You should see Test appear on your MAX display!

This picture shows a second ESP8266 for WLED to drive the LED strip around my projection screen.

You now have a functioning LED Digit Display for Home Assistant! You can use it for all sorts of things like displaying weather, drive time from Waze, or my favorite use:

Click here for Part 2 - Showing live sports scores and data.