How to make a live YouTube sub counter with MicroPython. Beginner-friendly, no soldering needed.
Published: | Sun, July 6, 2025, 13:00 |
Updated: | Sun, July 6, 2025, 18:45 |
Category: |
Hardware
|
Tags: |
Guide
DIY
Internet of Things
|
When a family member wanted a live YouTube sub counter for his desk, I saw an opportunity; a chance to teach, to learn, and to encourage making things β not just consuming. I haven't done much hardware before, so this was the perfect project for me.
I started out with a list of requirements for the hardware and the project.
I wanted something that I could get my hands on quickly (i.e. not sent from abroad, and in stock). I ended up using the ESP8266 microcontroller.
The Joy-it NodeMCU ESP8266 comes with Lua support, but I didn't want to learn a new programming language for this project. Instead, I decided to flash the board to run MicroPython - which calls itself "Python for microcontrollers".
I used esptool to flash the ESP8266 microcontroller. Then I found the download link for the ESP8266 firmware to support MicroPython.
# Optional: Setting up virtual environment for Python python3 -m venv micropython-env source micropython-env/bin/activate # Installing esptool pip install esptool # Finding the address for the plugged-in microcontroller ls /dev/tty.* /dev/tty.Bluetooth-Incoming-Port /dev/tty.usbserial-0001 # Downloading the MicroPython ESP8266 firmware wget https://micropython.org/resources/firmware/ESP8266_GENERIC-20250415-v1.25.0.bin # Erasing and flashing the microcontroller esptool.py --port /dev/tty.usbserial-0001 erase_flash esptool.py --port /dev/tty.usbserial-0001 --baud 460800 write_flash --flash_size=detect 0 ESP8266_GENERIC-20250415-v1.25.0.bin esptool.py v4.8.1 Serial port /dev/tty.usbserial-0001 Connecting.... Detecting chip type... ESP8266 Chip is ESP8266EX Features: WiFi Crystal is 26MHz [...output cut for readability...] Leaving... Hard resetting via RTS pin...
I now had the board up and running MicroPython.
I downloaded and installed Thonny - an excellent, very simple IDE for programming Python and running the code on the board.
Before connecting the LED matrix I just tested out that my setup worked at all so far by running the following program blinking the on-board LED light.
from machine import Pin import time led = Pin(2, Pin.OUT) for _ in range(5): led.off() time.sleep(1) led.on() time.sleep(1)
Connecting the LED matrix was pretty straightforward. Instead of hunting down the documentation, I got the connection setup from my friend, GPT.
MAX7219 pin | NodeMCU ESP8266 pin | Comment |
---|---|---|
VCC | 3V3 | Power |
GND | GND | Ground |
DIN | D7 | Data In (SPI MOSI) |
CS | D6 | Chip Select (SPI CS) |
CLK | D5 | Clock (SPI SCK) |
To easily display on the LED matrix I used the script from https://github.com/mcauser/micropython-max7219.
With the script saved to the microcontroller as max7219.py
I used the following script to print out TEST
on the LED matrix.
import max7219 from machine import Pin, SPI import time spi = SPI(1, baudrate=10000000, polarity=0, phase=0) cs = Pin(12, Pin.OUT) # D6 (GPIO12) display = max7219.Matrix8x8(spi, cs, 4) display.brightness(1) display.fill(0) display.show() time.sleep(2) display.text('TEST', 0, 0, 1) display.show()
To fetch the subscriber count you can set up YouTube Data API v3.
With the API key in hand you just need the channel ID. The ID is not the same as the channel name. You can go to a YouTube channel (e.g., my channel URL would be https://www.youtube.com/roysolberg) and search the source code for youtube.com/channel/
(my ID would then be UCC9FCNnwLWtfV0W5pqhfsoQ
).
The URL https://www.googleapis.com/youtube/v3/channels?part=statistics&id=YOUTUBE_CHANNEL_ID&key=YOUTUBE_API_KEY
can be used to fetch the subscriber count in JSON format.
With all the pieces in hand, it's time to write a script that does the following:
You can also find the script on GitHub in main.py
at https://github.com/roys/python-micro-youtubecounter.
Here's what the full script looks like:
import max7219 from machine import Pin, SPI import time import urequests import network WIFI_SSID = "FILL_IN_YOUR_WIFI_NETWORK_NAME" WIFI_PASSWORD = "FILL_IN_YOUR_WIFI_PASSWORD" YOUTUBE_API_KEY = "FILL_IN_YOUR_YOUTUBE_API_KEY" YOUTUBE_CHANNEL_ID = "FILL_IN_YOUR_YOUTUBE_CHANNEL_ID" MAX7219_NUM_OF_MODULES = 4 MAX7219_PIXELS_PER_MODULE = 8 MAX7219_TOTAL_WIDTH = MAX7219_NUM_OF_MODULES * MAX7219_PIXELS_PER_MODULE display = None def init_display(): global display spi = SPI(1, baudrate=10000000, polarity=0, phase=0) cs = Pin(12, Pin.OUT) # D6 of NodeMCU display = max7219.Matrix8x8(spi, cs, MAX7219_NUM_OF_MODULES) display.brightness(3) # 0-15 display.fill(0) # Clear the display display.show() def scroll_text(text, delay=0.05, scroll_off_screen=False): if scroll_off_screen: text += " " width = len(text) * 8 for pos in range(-MAX7219_TOTAL_WIDTH, width): display.fill(0) display.text(text, MAX7219_TOTAL_WIDTH - pos, 0, 1) display.show() time.sleep(delay) def display_text(text): display.fill(0) display.text(text, 0, 0, 1) display.show() def connect_wifi(): try: access_point = network.WLAN(network.AP_IF) access_point.active(False) # No need for an access point wlan = network.WLAN(network.STA_IF) # wlan.config(pm=network.WLAN.PM_POWERSAVE) # Makes the whole device go sluggish wlan.active(True) wlan.connect(WIFI_SSID, WIFI_PASSWORD) scroll_text(WIFI_SSID, delay=0.03, scroll_off_screen=True) for _ in range(50): if wlan.isconnected(): break time.sleep(0.1) if wlan.isconnected(): ip = wlan.ifconfig()[0] scroll_text(ip) else: scroll_text(f"Could not connect to Wi-Fi. Restart.") except Exception as e: scroll_text(f"Error: {str(e)}.") def print_sub_count(): url = ( "https://www.googleapis.com/youtube/v3/channels" "?part=statistics" f"&id={YOUTUBE_CHANNEL_ID}" f"&key={YOUTUBE_API_KEY}" ) last_sub_count = None error_count = 0 while True: try: status = None response = urequests.get(url) data = response.json() status = response.status_code # print(status) # print(data) # print(url) response.close() count = str(int(data["items"][0]["statistics"]["subscriberCount"])) error_count = 0 if count != last_sub_count: last_sub_count = count while len(count) < 4: count = " " + count scroll_text(count) time.sleep(60) except Exception as e: error_count += 1 if error_count >= 10: scroll_text(f"Error: {status} - {str(e)}.") print(e) last_sub_count = None time.sleep(60) init_display() scroll_text("Starting...", scroll_off_screen=True) connect_wifi() print_sub_count()
The script running on the ESP8266 microcontroller - showing the YouTube sub count.
For now, we decided to use a simple picture frame I had lying around. The parts are so small that they are easy to attach with some tape. I think the end result looks really cool.
The script has been running just perfectly for weeks now, but there are of course always some improvements that could be made. For example: