Introduction: Live Instructables Followers Counter
Hi! Some time ago I saw this project, it is pretty awesome and you should check it out. I liked it but, my youtube channel is not so popular (at least not yet :D) and I wanted to display other data than just YT subscribers. Bekathwia used in her project youtube API which make getting subcibers views and some other info very simple. And what if I want to display info from other pages (like instructables, instagram, or my own website). I thought that with very basic and short PHP script we can get those information from any website even if there is no API for it. Then using arduino and ENC28J60 we can get this information form server. Of course the biggest downside of it is that we need a server to handle this PHP script, but don't worry I will show you some free hostings. Because I like Instructable so much I decided to make live counter of instructable followers. Additionally because I always wanted to make some woodwork I decided to make like my own frame for it. In this project we will use ENC28J60 ethernet module which is very simple and great to deal with. The biggest advantage of this module is that you don't need to change any password, or username to your WI-FI, you can just plug it in and enjoy your counter. So when you change your router or password to it you don't need to worry about reprogramming your arduino.
That's the perfect project for begginers not only with arduino but also with woodworking and soldering!
Tomorrow I will add my youtube video I am so sorry but I haven't a microphone right now to record sound so I will do it tomorrow. If you want you can subscribe to my youtube channel to stay up to date with this and other my videos.
I just created my facebook page, if you want o be informed about new projects and see what I am doing, feel free to like it:
https://www.facebook.com/Nikodem-Bartnik-1891157704439330/
Thanks! :)
Step 1: What You Will Need?
Ther are not so much things that we will need to make it work, list with links:
- Arduino uno (or other) - because I made my frame a little to small I have to use arduino pro mini instead of uno. You can also use pro mini, it is smaller and cheaper but you will need an USB->UART converter to upload program to pro mini. Those arduinos are not original but they are much cheaper. You will also need 3,3V stabilizer because arduino pro mini haven't one. Arduino pro mini: GearBest Arduino UNO: GearBest
- Ethernet module ENC28J60 -that's very simple and very popular ethernet module, it is easy to deal with Gearbest
- LCD 7 segment display 4 characters (color doesn't matter, but because instructeble is yellow I bought yellow one)
- Some cables - you can buy computer twisted pair and get cables from it
- Ethernet cable and phone charger - normal etherent cable and old smartphone charger everybody have one Gearbest
- Some wood or photo frame - this will be an enclosure for our project
- Some tools
Step 2: Connection
To most of my project I made PCB (printable circuit borad) but this time I thought that for begginers it will be much simpler to make it with arduino uno and some cables. You can connect it with breadboard cables or solder if you wish but it's not necessary. Resistors in above fritzing circuit has 100 Ohms. Remember to connect ENC28J60 to 3.3V not to 5V.
Because I found my enclosure a little bit to small to fit arduino uno I decided to use pro mini, it is smaller and cheaper so that's also a big plus. Above you can find both connection schema
Step 3: PHP Script
You can say that this script is not optimized, and I could do something better, like finding span element by id or by DOM. But I wanted to keep it as simple as possible. So here it is I hope you will understand it. I wrote some comments to make it more transparent. It just search in source of website for specific string and search it's positions and then return followers number with $%# before number to make it easier for arduino to find number in HTTP response. You just need to change link to one of your instructables inside file_get_contents().
<p><?php<br--></p><p><?php</p><p>$html = file_get_contents('https://www.instructables.com/id/555-Useless-Machine/'); // here you can add link to your instructable, no matter which one $startposition = strpos($html, "<span class="\"callout" follower-count\"="">");//here we are searching for span element in page source which holds our followers number $endposition = strpos($html, "</span>", $startposition + 37); echo "$%#"; // we print this as start reference point echo substr($html, $startposition +37, $endposition - $startposition -37); // here we prints our followers number echo "$%#"; // we print this as end reference point </p><p>?></p>
Step 4: Few Words About Hosting
A lot of you may have problem with where to find a place to hold PHP script. If you have any website just put it over there, if not, keep reading. The simplest and cheapest (but not the best) option is free hosting on hostinger. It's not the best hosting in this universe but it's free and works fine for just one script (even for a small website, I had my website right there for over a year). The big plus is also that they provide free subdomains so you don't need to spend money for a domain. Here is link to hostinger:
It's completly free and you just need to create an account, if you have any problem don't waste your time for contacting their help center and just post a comment right there instead (it should be much faster). Despite all downsides I think that this hosting is the best option for this project.
Step 5: Arduino Code
Arduino code is reading data from PHP script thanks to our markers it know where followers number is starting and where it ends. It also has very basic code for segment display. To get your instructable number you have to change link of mine to one of yours instructables also remember to change link to your server in arduino code (at the beggining) and in the middle of arduino code you have to change this:
ether.browseUrl(PSTR("/"), "counter.php", website, my_callback)
"counter.php" to your php script name.
Here is the whole code and also in .zip below
// Demo using DHCP and DNS to perform a web client request.
// 2011-06-08 http://opensource.org/licenses/mit-license.php#include
#define LED_A A0 #define LED_B A1 #define LED_C A2 #define LED_D 2 #define LED_E 3 #define LED_F 4 #define LED_G 5 //#define LED_DP 7
#define LED_CHAR1 6 #define LED_CHAR2 7 #define LED_CHAR3 8 #define LED_CHAR4 9
String followers;
// ethernet interface mac address, must be unique on the LAN static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
byte Ethernet::buffer[500]; static uint32_t timer; //add www before domain name without subdomain //const char website[] PROGMEM = "www.nikodembartnik.pl";
//when you use subdomain don't use www befor subdomain name const char website[] PROGMEM = "livecounter.esy.es";
// called when the client request is complete static void my_callback (byte status, word off, word len) { Ethernet::buffer[off+400] = 0; String res = (const char*) Ethernet::buffer + off; Serial.println(res); int start_position = res.indexOf("$%#"); String followers_number = res.substring(start_position + 3); followers_number = followers_number.substring(0, followers_number.indexOf("$%#")); followers_number.trim(); followers = followers_number; Serial.print(followers_number); Serial.println();
//Serial.println("..."); }
void setup () {
pinMode(LED_A, OUTPUT); pinMode(LED_B, OUTPUT); pinMode(LED_C, OUTPUT); pinMode(LED_D, OUTPUT); pinMode(LED_E, OUTPUT); pinMode(LED_F, OUTPUT); pinMode(LED_G, OUTPUT); pinMode(LED_CHAR1, OUTPUT); pinMode(LED_CHAR2, OUTPUT); pinMode(LED_CHAR3, OUTPUT); Serial.begin(57600);
if (ether.begin(sizeof Ethernet::buffer, mymac) == 0) Serial.println("Failed to access enc28j60"); if (!ether.dhcpSetup()) Serial.println(F("DHCP failed"));
ether.printIp("IP: ", ether.myip); ether.printIp("GW: ", ether.gwip); ether.printIp("DNS: ", ether.dnsip);
//#if 1 // use DNS to resolve the website's IP address if (!ether.dnsLookup(website)) Serial.println("DNS failed"); Serial.println("#1"); /* #elif 2 // if website is a string containing an IP address instead of a domain name, // then use it directly. Note: the string can not be in PROGMEM. char websiteIP[] = "95.211.80.4"; ether.parseIp(ether.hisip, websiteIP); Serial.println("#2"); #else // or provide a numeric IP address instead of a string byte hisip[] = { 95,211,80,4 }; ether.copyIp(ether.hisip, hisip); Serial.println("#3"); #endif */ ether.printIp("SRV: ", ether.hisip); }
void loop () { ether.packetLoop(ether.packetReceive()); if (millis() > timer) { //update every 5 minutes timer = millis() + 1000 * 60 * 5; ether.browseUrl(PSTR("/"), "counter.php", website, my_callback); } for(int a = 0; a < 4; a++){ show_number(a+1, followers.substring(a, a+1).toInt(), 0); delay(1); } }
void show_number(int char_number, int number, int decimal_point){
//turning off all segments of display
digitalWrite(LED_A, HIGH); digitalWrite(LED_B, HIGH); digitalWrite(LED_C, HIGH); digitalWrite(LED_D, HIGH); digitalWrite(LED_E, HIGH); digitalWrite(LED_F, HIGH); digitalWrite(LED_G, HIGH);
digitalWrite(LED_CHAR1, LOW); digitalWrite(LED_CHAR2, LOW); digitalWrite(LED_CHAR3, LOW);
//turning leds on
if(number == 0 || number == 2 || number == 3 || number == 5 || number == 6 || number == 7 || number == 8 || number == 9){ digitalWrite(LED_A, LOW); } if(number == 0 || number == 1 || number == 2 || number == 3 || number == 4 || number == 7 || number == 8 || number == 9){ digitalWrite(LED_B, LOW); } if(number == 0 || number == 1 || number == 3 || number == 4 || number == 5 || number == 6 || number == 7 || number == 8 || number == 9){ digitalWrite(LED_C, LOW); } if(number == 0|| number == 2 || number == 3 || number == 5 || number == 6 || number == 8 || number == 9){ digitalWrite(LED_D, LOW); } if(number == 0|| number == 2 || number == 6 || number == 8){ digitalWrite(LED_E, LOW); } if(number == 0 || number == 4 || number == 5 || number == 6 || number == 8 || number == 9){ digitalWrite(LED_F, LOW); } if(number == 2 || number == 3 || number == 4 || number == 5 || number == 6 || number == 8 || number == 9){ digitalWrite(LED_G, LOW); } /* if(decimal_point > 0){ LED_DP_PORT &= ~LED_DP; } */ if(char_number == 1){ digitalWrite(LED_CHAR1, HIGH); }else if(char_number == 2){ digitalWrite(LED_CHAR2, HIGH); }else if(char_number == 3){ digitalWrite(LED_CHAR3, HIGH);
}else if(char_number == 4){ digitalWrite(LED_CHAR4, HIGH);
} }
Attachments
Step 6: Woodworking
I have never done anything in wood, expect bird feeder but it was so long ago. And that's the reason that I decided to create wooden frame for this project. Additionally the look of raw wood, it's so beautifull! And this type of wood matches everything :)
I started by grinding out all wood that I have for this project. This frame wasn't designed in any way I just grab some wood and check how big it should be to fit all of the things inside. It's very simple, just 4 scantlings cuted at 45 degrees and glued together. Then, on the top I put a pice of 4mm plywood, but previously I have milled a hole not at the outlet I just lived here so small amount of wood to let the display illuminate through it. It was so easy to do with CNC mill, but if you don't have one and you are manually talented you can try to make it with a dremel tool or something like that but it will be very hard I think (more about my cnc machine you can read here). When everything was ready I glued plywood to frame and put display and all electronics inside it. At the end I stick instructable stripe on the plywood, looks amazing :D
Bellow is GCODE for milling. You can mill hole for display if you want. I use 4mm plywood for it and milling depth is 3.6mm. X = 0 and Y = 0 is in the center of display.
During this small wooden project for me the most useful tools was dremel, drill and saw. Also this plastic thing to cut perfect 45 degrees angles, without them it can be pretty tricky
Step 7: Finishing
Above the display I add this instructable sew-on badge which I won in contest (Thanks Instructable). Because I love raw wood I decided to not painting it with anything and leave it as it is. This instructable logo on the top looks so good :) I also drilled small holes on the bottom of my frame to put ethernet and power cables in it. Hole for display is so tight that I didn't use any glue or something like that to put it in place, arduino and ENC28J60 just lays in frame.
Step 8: Conclusion
At the end I just want to thank you for reading. Remember to leave a comment, follow me and vote for my project! Thank you so much! If you have any question leave a comment or write a message to me and I will replay as soon as possible.

Participated in the
Woodworking Contest 2017

Participated in the
Microcontroller Contest 2017

Participated in the
Lights Contest 2017
18 Comments
4 years ago
I just followed you! Did the counter go up?
Question 4 years ago on Step 3
Could i modify this to work on instagram, how would i do this and could someone modify the php to do this and link it below. Thanks in advance.
6 years ago
Hey Nikus, cool project!
I'm the author of the library that Bekathwia used in her project and I have actually been working on a library for this aswell.
https://github.com/witnessmenow/arduino-instructab...
Instructables has an API that it uses for their website, but they do not publically advertise it. It currently works the get the statistics of the user or get the statistics of an instructable post.
It works on the ESP8266 but it should also be possible to get it working using the ethernet shield as it does not use HTTPS. I created a branch of the library to test out the ethernet shield changes, I had it working for the post stats, but I think the user stats might use up too much memory to use the json library, but maybe the data could be parsed out manually instead
https://github.com/witnessmenow/arduino-instructab...
Hopefully you might find it useful!
Reply 6 years ago
That's really impressive, Witnessmenow! I stumbled upon the stats API by looking at http get requests in the chrome "network" tab that were made when a instructable page is refreshed. I searched "Stats" If it's of any interest to you, the ID can also be found by looking at the "Category Timer" cookie. I hadn't thought of your method of using "Log Hit('"
Reply 6 years ago
Thanks! Yeah it's very obvious on the inscrutable page but I was very happy to see user stats were also available.
Yeah it's a pity it kinda complicated to get the Post ID but its not too bad I guess.
Reply 6 years ago
Thanks for informing. Do you mean this API:
https://market.mashape.com/dev132/instructables
Reply 6 years ago
No it's actually indestructible's own API. As mentioned my Maker Saga, you can see it being called on the Chrome network tab when you refresh the page. The post stat one is the most obvious one that is called as if you refresh a instructable page you can see the views and likes load as one thing and then change to something else.
6 years ago
Could this be used to display a live Twitch follower count?
Reply 6 years ago
If you can obtain this number without logging in the service then it is possible.
Reply 6 years ago
Thanks Nikus,
I am going to attempt using the text documents from Stream Labs in the code since they are already set up to give a live follower count within OBS
6 years ago
This is really cool! Your PHP code is nice and concise!
I have an instructable for something like this except it uses a Python Bot as a command line app for monitoring view (or favorite) increases on any instructable tutorial. It can send a detailed email alert, plays a notification bell sound, displays the increase in views in big red text, and announces the increase aloud like Siri at programmable view intervals. The only bug I've had so far is when my microwave oven runs, it causes my WiFi connection to drop out and the Python Bot shuts down due to the loss of internet connection.
By all means, take a look!
https://www.instructables.com/id/Instructable-Hit-...
I started with trying to make and Arduino and PHP version just like what you made here months ago, but I wasn't able to figure out http get requests with my Arduino (nodemcu), so I went with Python.
I also spent a lot of time trying to make a PHP web app that does this using a tidy user friendly UI that is web based, but I found out I needed to learn AJAX first and some other stuff that I set aside for some other time.
Is there a way to adapt your code for a WiFi enabled Arduino ESP8266? (not ethernet)?
Reply 6 years ago
Yes of course there is a way to adapt it for ESP8266 but I don't like this module so I decided to use ENC28J60. Your project is great :) Thanks for sharing!
6 years ago
I need this NOW!
Reply 6 years ago
JUST DO IT :)
6 years ago
Sweet! Even though you posted it today, you have 3 more subscribers than it says!
Reply 6 years ago
Thanks! :)
6 years ago
Really neat! Thank you for sharing.
Reply 6 years ago
Thanks!