Summary: Via Nano 33 IoT, display the follower count of a given Twitter account and its current follower status - STABLE, DEC, or INC.
I have a gradually growing Twitter account for my website to showcase my projects and articles. Most of the time, I forget to check if there is a change in the follower count of my Twitter account to discern the account growth chronologically. Thus, I decided to create this apparatus placed on my desk, which displays information of my Twitter account:
First of all, to manage to glean information from Twitter by avoiding any authentification process pertaining to the Twitter API, I chose to use a content delivery network (CDN) - cdn.syndication.twimg - to obtain the number of followers of a selected Twitter account by its screen name. When I managed to get information from Twitter, I programmed a web application in PHP, named Twitter Follower Tracker, running on Raspberry Pi to print a data packet containing:
Then, I used an Arduino Nano 33 IoT to get my Twitter account information and follower count transferred by the PHP web application and display them with a Nokia 5110 Screen.
Finally, I added a COM-09032 analog joystick and two buttons to control the menu options and scroll text.
After completing wiring on a breadboard and testing the code, I designed a PCB (Twitter Follower Tracker) having the Twitter logo carved at its center. It became a stylish and fitting addition to my desk as an efficient apparatus to track the follower count of my account :)
In addition to displaying information, the device:
Step 1: Designing and soldering the Twitter Follower Tracker PCB
Before prototyping my PCB design, I tested all connections and wiring with the Arduino Nano 33 IoT on the breadboard.
Then, I designed the Twitter Follower Tracker and Status Notifier PCB by using KiCad. I attached the Gerber file of the PCB below, so if you want, you can order this PCB from PCBWay to create a stylish and fitting apparatus to display the follower count of a selected account and get notified when there is a change, inspired by the Twitter logo :)
First of all, by using a soldering iron, I attached headers (female), COM-09032 analog joystick, buzzer, 5mm common cathode RGB LED, 6x6 pushbuttons, 1K resistors, and the power jack.
Component list on the PCB:
A1 (Headers for Arduino Nano 33 IoT)
S1 (Headers for Nokia 5110 Screen)
U1 (COM-09032 Analog Joystick)
BZ1 (Buzzer)
D1 (5mm Common Cathode RGB LED)
K1, K2 (6x6 Pushbutton)
R1, R2, R3, R4, R5 (1K Resistor)
J1 (Power Jack)
Step 2: Setting up a LAMP web server on Raspberry Pi
If you are a novice in programming with Raspberry Pi, you can inspect well-explained instructions and tutorials on the official Raspberry Pi website.
To go to the official Raspberry Pi setting up tutorial, click here.
⭐ Open a terminal window by selecting Accessories > Terminal from the menu.
⭐ Install the apache2 package by typing the following command into the terminal and pressing Enter:
sudo apt-get install apache2 -y
⭐ To test the server, open Chromium by selecting Internet > Chromium Web Browser from the menu and enter http://localhost.
⭐ If you want, you can use the IP address of your Raspberry Pi as well.
hostname -I
⭐ Install the PHP package with the following command:
⭐ Do not forget to update the Pi.
sudo apt-get update
sudo apt-get install php -y
⭐ To be able to obtain information from the cdn.syndication.twimg (CDN), install the php-curl package:
sudo apt-get install php-curl
⭐ Then, restart the apache server to be able to use the installed packages on the localhost:
sudo service apache2 restart
Step 3: Developing the Twitter Follower Tracker web application in PHP to elicit information from the CDN
Although Twitter provides an API to collate information on Twitter accounts, tweets, replies, etc., I decided to use a content delivery network (CDN) in this project since the Twitter API requires an authentification process and key.
CDN: cdn.syndication.twimg
⭐ CDN uses screen names of Twitter accounts to collect and return this information in JSON:
https://cdn.syndication.twimg.com/widgets/followbutton/info.json?screen_names=<Enter_Screen_Name>
The web application consists of one file - index.php. You can download the web application below to install it on your Raspberry Pi - Twitter_Follower_Tracker.zip.
💻 index.php
⭐ Define the twitter_follower_tracker class and its functions.
⭐ In the __init__ function, define the screen name of the Twitter account, such as ThAmplituhedron.
⭐ In the get_followers function, print information of the given Twitter account.
⭐ Syntax:
%follower_count%account_name%account_ID%
%339%TheAmplituhedron%968893436744085505%
⭐ Define the twitter class object.
// Define the twitter_follower_tracker class and its functions:
class twitter_follower_tracker{
public $account;
public function __init__($account){
$this->account = $account;
}
public function get_followers(){
$url = "https://cdn.syndication.twimg.com/widgets/followbutton/info.json?screen_names=".$this->account;
$data = json_decode(file_get_contents($url, true));
echo "%".$data[0]->followers_count."%".$data[0]->name."%".$data[0]->id."%";
}
}
// Define the new 'twitter' class object:
$twitter = new twitter_follower_tracker();
$twitter->__init__("ThAmplituhedron");
// Print information that of the given Twitter account.
$twitter->get_followers();
Step 3.1: Setting up the web application on Raspberry Pi
⭐ First of all, extract the Twitter_Follower_Tracker.zip folder and move the application folder (Twitter_Follower_Tracker) to the apache server (/var/www/html) by using the terminal since the apache server is a protected location.
sudo mv /home/pi/Downloads/Twitter_Follower_Tracker /var/www/html/
⭐ Go to the web application:
http://localhost/Twitter_Follower_Tracker/
Step 4: Setting up the Arduino Nano 33 IoT
If you are a novice in programming with the Arduino Nano 33 IoT, follow the steps below to program it with the Arduino IDE.
⭐ Download the required drivers - Arduino SAMD Core - as explained here.
⭐ To be able to connect to the WiFi, download the WiFiNINA library from here.
Step 5: Programming the Arduino Nano 33 IoT
Download the required libraries to be able to control the modules:
Nokia 5110 Screen | Library
⭐ Include required libraries and define the WiFi settings.
// Include required libraries:
#include <SPI.h>
#include <WiFiNINA.h>
#include <LCD5110_Graph.h>
char ssid[] = "<SSID>"; // your network SSID (name)
char pass[] = "<PASSWORD>"; // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0; // your network key Index number (needed only for WEP)
int status = WL_IDLE_STATUS;
// Enter the IPAddress of your Raspberry Pi.
IPAddress server(192, 168, 1, 20);
// Initialize the Ethernet client library
WiFiClient client; /* WiFiSSLClient client; */
⭐ Define the Nokia 5110 screen settings and the graphics (monochrome images).
⭐ To create different graphics (monochrome images), go to Monochrome Image Converter.
// Define screen settings.
LCD5110 myGLCD(2,3,4,5,6);
extern uint8_t SmallFont[];
extern uint8_t MediumNumbers[];
// Define the graphics:
extern uint8_t twitter[];
⭐ Initiate the screen and check for the WiFi module to verify the connection.
// Initiate screen.
myGLCD.InitLCD();
myGLCD.setFont(SmallFont);
// Check for the WiFi module:if (WiFi.status() == WL_NO_MODULE) { myGLCD.print("Connection Failed!", 0, 8); myGLCD.update(); while (true); }
// Attempt to connect to the WiFi network:while (status != WL_CONNECTED) {
myGLCD.print("Waiting...", 0, 8);
myGLCD.print("Attempting to", 0, 16);
myGLCD.print("connect to", 0, 24);
myGLCD.print("WiFi !!!", 0, 32);
myGLCD.update();
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);
// Wait 10 seconds for connection:
delay(10000);
}
⭐ In the read_controls function, read joystick and control button values.
void read_controls(){
// Joystick:
joystick_x = analogRead(VRX);
joystick_y = analogRead(VRY);
joystick_sw = digitalRead(SW);
// Buttons:
_right = digitalRead(right);
_left = digitalRead(left);
}
⭐ In the change_menu_options function:
⭐ Increase or decrease the menu option number (selected) using the Y-axis of the analog joystick.
⭐ Depending on the menu option number (selected), change the boolean status.
void change_menu_options(){
// Increase or decrease the option number using the joystick (VRY).if(joystick_y >= 900) selected--;
if(joystick_y <= 45) selected++;
if(selected < 0) selected = 4;
if(selected > 4) selected = 1;
delay(100);
// Depending on the selected option number, change the boolean status.switch(selected){
case 1:
followers = true;
entries = false;
graphics = false;
_sleep = false;
break;
case 2:
followers = false;
entries = true;
graphics = false;
_sleep = false;
break;
case 3:
followers = false;
entries = false;
graphics = true;
_sleep = false;
break;
case 4:
followers = false;
entries = false;
graphics = false;
_sleep = true;
break;
}
}
⭐ After being selected, if the followers menu option is activated by pressing the joystick button (SW):
⭐ Get the Twitter account information from the REST API (CDN).
⭐ Check the current follower status using registered status variables:
⭐ If there is an increase or decrease in the follower count, notify the user.
⭐ Update the last entries (follower counts) list.
⭐ Print the Twitter account information and status.
⭐ Scroll the fetched information by using the X-axis of the analog joystick.
⭐ If the Left button is pressed, halt notification (buzzer).
⭐ If the Right button is pressed, return to the interface.
if(followers == true){
do{
myGLCD.invertText(true);
myGLCD.print("A. Followers", 0, 16);
myGLCD.invertText(false);
myGLCD.update();
adjustColor(255, 0, 255);
delay(100);
if(joystick_sw == false){
myGLCD.clrScr();
myGLCD.update();
activated = true;
// Get the Twitter Account Information from the REST API (CDN):
make_a_get_request("/Twitter_Follower_Tracker/");
// Check the follower status using registered status variables:
int _followers = follower_count.toInt();
if(_followers != previous_count){
// If there is an increase or decrease in the follower number, notify the user:if(_followers > previous_count){ _status = "INC"; adjustColor(0, 255, 0); tone(buzzer, 500); }
if(_followers < previous_count){ _status = "DEC"; adjustColor(255, 0, 0); tone(buzzer, 500); }
// Change the last entries list:
previous_count = _followers;
entry_3 = entry_2;
entry_2 = entry_1;
entry_1 = _followers;
}else{
_status = "STABLE";
adjustColor(0, 0, 255);
}
myGLCD.clrScr();
myGLCD.update();
while(activated == true){
read_controls();
myGLCD.print("Status: " + _status, 0, 0);
myGLCD.print(follower_count, CENTER, 16);
scrolling_text(" Name: " + account_name + " ", 32);
scrolling_text(" ID:" + account_id + " ", 40);
// Halt notification.if(_left == false) noTone(buzzer);
// Exit.if(_right == false){ activated = false; x = 0; myGLCD.clrScr(); myGLCD.update(); noTone(buzzer); }
}
}
}while(followers == false);
}
⭐ After being selected, if the entries menu option is activated by pressing the joystick button (SW):
⭐ Print the registered entries list - last three follower counts.
⭐ If the Left button is pressed, reset the entries list.
⭐ If the Right button is pressed, return to the interface.
if(entries == true){
do{
myGLCD.invertText(true);
myGLCD.print("B. Entries", 0, 24);
myGLCD.invertText(false);
myGLCD.update();
adjustColor(0, 255, 255);
delay(100);
if(joystick_sw == false){
myGLCD.clrScr();
myGLCD.update();
activated = true;
while(activated == true){
read_controls();
// Print the entries list:
myGLCD.print("Entries: ", 0, 0);
myGLCD.print("1 => : " + String(entry_1), 0, 16);
myGLCD.print("2 => : " + String(entry_2), 0, 24);
myGLCD.print("3 => : " + String(entry_3), 0, 32);
myGLCD.update();
// RESET THE ENTRIES LIST:if(_left == false){ entry_1 = 0; entry_2 = 0; entry_3 = 0; myGLCD.clrScr(); myGLCD.update(); }
// Exit.if(_right == false){ activated = false; myGLCD.clrScr(); myGLCD.update(); }
}
}
}while(entries == false);
}
⭐ After being selected, if the graphics menu option is activated by pressing the joystick button (SW):
⭐ Display the monochrome image (twitter) as the screensaver.
⭐ If the Right button is pressed, return to the interface.
if(graphics == true){
do{
myGLCD.invertText(true);
myGLCD.print("C. Graphics", 0, 32);
myGLCD.invertText(false);
myGLCD.update();
adjustColor(255, 255, 0);
delay(100);
if(joystick_sw == false){
myGLCD.clrScr();
myGLCD.update();
activated = true;
while(activated == true){
read_controls();
// Define and print monochrome images:
myGLCD.drawBitmap(20,0,twitter,45,45);
myGLCD.update();
// Exit.
if(_right == false){ activated = false; myGLCD.clrScr(); myGLCD.update(); }
}
}
}while(graphics == false);
}
⭐ After being selected, if the sleep menu option is activated by pressing the joystick button (SW):
⭐ Activate the sleep mode in 10 seconds.
⭐ Print the remaining seconds.
⭐ Display the color pattern while sleeping - red, green, blue, purple, white.
⭐ If the Right button is pressed, return to the interface.
if(_sleep == true){
do{
myGLCD.invertText(true);
myGLCD.print("D. Sleep", 0, 40);
myGLCD.invertText(false);
myGLCD.update();
adjustColor(255, 69, 0);
delay(100);
if(joystick_sw == false){
// Activate the sleep mode in 10 seconds.
myGLCD.clrScr();
myGLCD.print("Entering", CENTER, 0);
myGLCD.print("Sleep Mode", CENTER, 8);
myGLCD.print("in", CENTER, 16);
myGLCD.print("Seconds", CENTER, 40);
myGLCD.update();
// Print remaining seconds.
myGLCD.setFont(MediumNumbers);
for (int s=10; s>=0; s--){ myGLCD.printNumI(s, CENTER, 24, 2, '0'); myGLCD.update(); delay(1000); }
myGLCD.enableSleep();
activated = true;
while(activated == true){
// Color Pattern:
adjustColor(255,0,0);
delay(500);
adjustColor(0,255,0);
delay(500);
adjustColor(0,0,255);
delay(500);
adjustColor(255,0,255);
delay(500);
adjustColor(255,255,255);
delay(500);
// Exit.
read_controls();
if(_right == false){ activated = false; myGLCD.clrScr(); myGLCD.disableSleep(); myGLCD.setFont(SmallFont); adjustColor(0,0,0); }
}
}
}while(_sleep == false);
}
Step 5.1: Getting information from the web application and using the analog joystick to scroll text
⭐ In the make_a_get_request function:
⭐ Connect to the web application named Twitter Follower Tracker.
⭐ If the connection is successful, make a Get request to obtain the Twitter account information:
⭐ If there are incoming bytes available, get the response from the web application.
⭐ Split the response string by the predefined delimiter (%) to glean information as substrings - follower_count, account_name, and account_id.
void make_a_get_request(String application){
// Connect to the web application named Twitter_Follower_Tracker. Change '80' with '443' if you are using SSL connection.if(client.connect(server, 80)){
// If successful:
myGLCD.print("Connected to", 0, 8);
myGLCD.print("the server!!!", 0, 16);
myGLCD.update();
// Make an HTTP Get request:
client.println("GET " + application + " HTTP/1.1");
client.println("Host: 192.168.1.20");
client.println("Connection: close");
client.println();
}else{
myGLCD.print("Connection", 0, 8);
myGLCD.print("Error!!!", 0, 16);
myGLCD.update();
}
delay(2000); // Wait 2 seconds after connection...// If there are incoming bytes available, get the response from the web application.
String response = "";
while (client.available()) { char c = client.read(); response += c; }
if(response != "" && response.endsWith("%")){
// Split the response string by a pre-defined delimiter in a simple way. '%'(percentage) is defined as the delimiter in this project.int delimiter_1, delimiter_2, delimiter_3, delimiter_4;
delimiter_1 = response.indexOf("%");
delimiter_2 = response.indexOf("%", delimiter_1 + 1);
delimiter_3 = response.indexOf("%", delimiter_2 + 1);
delimiter_4 = response.indexOf("%", delimiter_3 + 1);
// Glean information as substrings.
follower_count = response.substring(delimiter_1 + 1, delimiter_2);
account_name = response.substring(delimiter_2 + 1, delimiter_3);
account_id = response.substring(delimiter_3 + 1, delimiter_4);
}
}
⭐ In the scrolling_text function:
⭐ Scroll a given string using the X-axis of the analog joystick on a given y coordinate (row).
void scrolling_text(String text, int y){
int len = text.length();
// Scroll text using the joystick (VRX).if(joystick_x <= 45) x--;
if(joystick_x >= 900) x++;
if(x>84) x = 84;
if(x<=-(len*6)) x = -(len*6);
// Print.
myGLCD.print(text, x, y);
myGLCD.update();
delay(25);
}
Connections and Adjustments
// Connections
// Arduino Nano 33 IoT :
// Nokia 5110 Screen
// D2 --------------------------- SCK (Clk)
// D3 --------------------------- MOSI (Din)
// D4 --------------------------- DC
// D5 --------------------------- RST
// D6 --------------------------- CS (CE)
// JoyStick
// A0 --------------------------- VRY
// A1 --------------------------- VRX
// D9 --------------------------- SW
// 5V --------------------------- 5V
// GND --------------------------- GND
// Button (Right)
// A3 --------------------------- S
// Button (Left)
// A2 --------------------------- S
// RGB LEB (RCGB)
// D12 --------------------------- R
// D11 --------------------------- G
// D10 --------------------------- B
// Buzzer
// D8 --------------------------- +
After completing and uploading the code, I attached all required components to the board via headers - the Arduino Nano 33 IoT and the Nokia 5110 Screen.
Modes and Features
📊🔄 First of all, the device checks for a successful WiFi connection. Then, if connected, it displays the interface (menu).
📊🔄 The device shows four different modes on the interface:
📊🔄 The device allows the user to select a mode (option) on the interface via the analog joystick:
📊🔄 While selecting a mode on the interface with the Y-axis of the analog joystick, the device turns the RGB LED to a different color for each mode:
📊🔄 After activating any modes, the device lets the user return to the interface by pressing the Right button.
📌 A. Followers
📊🔄 The device connects to the web application (Twitter Follower Tracker) to obtain the Twitter account information:
📊🔄 The device checks the current follower status in comparison to the previously registered follower count:
📊🔄 Then, the device displays the current follower status, the current follower count, the account name, and the account ID.
📊🔄 If the current follower status is STABLE, which means no change in the follower count, the device turns the RGB LED to blue.
📊🔄 If the current follower status is INC, which means an increase in the follower count, the device turns the RGB LED to green and notifies the user via the buzzer.
📊🔄 If the current follower status is DEC, which means a decrease in the follower count, the device turns the RGB LED to red and notifies the user via the buzzer.
📊🔄 If the Left button is pressed, the device halts the buzzer (notification) and keeps displaying the account information.
📊🔄 The device allows the user to scroll the fetched account information with the X-axis of the analog joystick.
📌 B. Entries
📊🔄 The device displays the last three registered follower counts (entries) chronologically.
📊🔄 If the Left button is pressed, the device resets the entries (follower counts) list.
📌 C. Graphics
📊🔄 The device shows the Twitter logo (monochrome image) as the screensaver.
📌 D. Sleep
📊🔄 The device activates the sleep mode in 10 seconds while printing the remaining seconds.
📊🔄 The device displays the color pattern - red, green, blue, purple, white - during the sleep mode.
Videos and Conclusion
After completing all steps above, I placed the device on my desk by utilizing a plastic easel as a fitting and stylish decoration for my room. It works stupendously :)
Code and Downloads
You can inspect and download all mentioned code files and Gerber files from here.