Skip to content

Instantly share code, notes, and snippets.

@PhirePhly
Created June 25, 2017 20:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save PhirePhly/5fba25a794cbf2e4aca457d3645b8226 to your computer and use it in GitHub Desktop.
Save PhirePhly/5fba25a794cbf2e4aca457d3645b8226 to your computer and use it in GitHub Desktop.
YouTube API to MAX7219 display Widget
// YouTube Channel View Counter
// Kenneth Finnegan, 2017
//
// Given a WiFi SSID + password, and YouTube API key + channel ID, displays the
// current total views count on an attached MAX7219 eight digit display
#include <YoutubeApi.h>
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
//------- Replace the following! ------
char ssid[] = "WIFISSIF"; // your network SSID (name)
char password[] = "WIFIPASSWORD"; // your network key
#define API_KEY "INSERTYOURAPPSAPIKEYHERE" // your google apps API Token
#define CHANNEL_ID "INSERTCHANNELIDHERE" // makes up the url of channel
// This depends on which pins you've wired the MAX7219 driver to.
#define DISP_CS 12
#define DISP_CLK 14
#define DISP_DATA 13
WiFiClientSecure client;
YoutubeApi api(API_KEY, client);
// The total channel view count is updated very rarely (daily?) so we don't need to check regularly
unsigned long api_mtbs = 5 * 60 * 1000; // Desired update interval in milliseconds
unsigned long api_lasttime = 0-api_mtbs; //last time api request has been done
// Note that we're pre-loading the "last update" variable to an interval before zero so the
// display updates immediately on boot
////////////////////////////
// DISPLAY DRIVER SECTION //
////////////////////////////
// Soft implementation of SPI because I don't even know if the ESP-12 has SPI hardware available
// [TODO: insert rant about how much Arduino platform documentation sucks these days]
// This only sends eight bits, which is half a MAX7219 command
void disp_send(uint8_t data) {
int i;
for (i=0; i<8; i++) {
// Send the most significant bit first
digitalWrite(DISP_DATA, !!(data & (1<<(7-i))));
delay(1); // These delays might not be needed, but I like the visual effect of the slow update
// Then toggle the clock line
digitalWrite(DISP_CLK, HIGH);
delay(1);
digitalWrite(DISP_CLK, LOW);
delay(1);
}
}
// Sends two bytes, the register select and the payload for that data
// See the datasheet for the full memory map:
// https://datasheets.maximintegrated.com/en/ds/MAX7219-MAX7221.pdf
void disp_cmd(uint8_t reg, uint8_t data) {
digitalWrite(DISP_CS, LOW);
disp_send(reg);
disp_send(data);
digitalWrite(DISP_CS, HIGH);
}
// Given an integer, write it to the display
void disp_number(int data) {
int i;
for (i=1; i<=8; i++) {
int output = data % 10;
// Turn on the decimal place at 4 and 7 to make it easier to read
if (i == 4 || i == 7) output |= 0x80;
// Blank leading zeros if we've run out of data and we're not the first digit
if (data == 0 && i != 1) output = 0x0F;
disp_cmd(i,output);
data = data / 10;
}
}
// When we aren't working, display "00000000" then "--HELP--"
void disp_error() {
int i;
for (i=8; i>0; i--) {
disp_cmd(i,0x00);
}
disp_cmd(0x08,0x0A); // -
disp_cmd(0x07,0x0A); // -
disp_cmd(0x06,0x0C); // H
disp_cmd(0x05,0x0B); // E
disp_cmd(0x04,0x0D); // L
disp_cmd(0x03,0x0E); // P
disp_cmd(0x02,0x0A); // -
disp_cmd(0x01,0x0A); // -
}
////////////////////////////////
// MAIN SETUP AND MASTER LOOP //
////////////////////////////////
void setup() {
Serial.begin(115200);
// Set up the MAX7219 display and load the command registers
pinMode(DISP_CS, OUTPUT);
pinMode(DISP_CLK, OUTPUT);
pinMode(DISP_DATA, OUTPUT);
disp_cmd(0x0C,0x01); // Leave shutdown
delay(30);
disp_cmd(0x0F,0x00); // Leave display test
delay(30);
disp_cmd(0x09,0xFF); // Use B code on all eight digits
delay(30);
disp_cmd(0x0A,0x02); // Set software intensity 0-15
delay(30);
disp_cmd(0x0B,0x07); // Scan all eight digits (blank individual digits with 0xF)
delay(30);
disp_error();
// Set WiFi to station mode and disconnect from an AP if it was Previously
// connected
WiFi.mode(WIFI_STA);
WiFi.disconnect();
delay(100);
// Attempt to connect to Wifi network:
Serial.print("Connecting Wifi: ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
IPAddress ip = WiFi.localIP();
Serial.println(ip);
}
void loop() {
if (millis() - api_lasttime > api_mtbs) {
Serial.println("Trying to query API");
if(api.getChannelStatistics(CHANNEL_ID)) {
Serial.println("---------Stats---------");
Serial.print("Subscriber Count: ");
Serial.println(api.channelStats.subscriberCount);
Serial.print("View Count: ");
Serial.println(api.channelStats.viewCount);
Serial.print("Comment Count: ");
Serial.println(api.channelStats.commentCount);
Serial.print("Video Count: ");
Serial.println(api.channelStats.videoCount);
Serial.println("------------------------");
disp_number(api.channelStats.viewCount);
api_lasttime = millis();
} else {
// Something went wrong, so try again in 30s
Serial.println("YOUTUBE API ERROR!");
disp_error();
api_lasttime += 30 * 1000;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment