Created
June 25, 2017 20:25
-
-
Save PhirePhly/5fba25a794cbf2e4aca457d3645b8226 to your computer and use it in GitHub Desktop.
YouTube API to MAX7219 display Widget
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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