Счетчик лайков с конфетами
- Платформы: Arduino
- Языки программирования: Arduino (C++), PHP
- Тэги: IoT Arduino, лайки, интернет вещей, facebook
Что это
Соберём счетчик отметок «Нравится» для страницы Facebook, выдающий конфету за каждый новый лайк.
Видеообзор
Что понадобится
- Штырьковые соединители угловые (1×40)
- Оргстекло: 400×300×3 мм
- Фанера ФК: 600×400×6 мм
- Фанера ФК: 400×300×18 мм
- Крепёжные материалы: винты и гайки
- Конфеты «Skittles»
Как собрать
Сборка устройства состоит из аппаратной и программной части.
Hardware-часть
- Подключите Wi-Fi (Troyka-модуль) к Troyka Slot Shield:
- пин
TX
Wi-Fi модуля к цифровому пину0
Troyka Slot Shield
- Вставьте Четырёхразрядный индикатор (Troyka-модуль) на Troyka Slot Shield:
- пин
CS
дисплея к цифровому пину9
Troyka Slot Shield
Переходите к программной части.
Software-часть
Социальные сети: Facebook, VK и другие работают через протокол HTTPS. Микроконтроллер ESP8266 на борту платы Wi-Fi (Troyka-модуль) в исходной конфигурации работает через АТ-команды. В результате работа напрямую с HTTPS-протоколом не возможна.
Для решения проблемы используем небольшой php-скрипт, который необходимо разместить на хостинге. В качестве примера воспользуемся бесплатным хостингом «000webhost»
- Зарегистрируйтесь на хостинге. В результате прохождение всех процедур регистрации хостинга и домена приведет к следующим результатам: наличие полного доменного имени и доступа к файловой системе на предоставленном сервере. В нашем случае:
- Полное доменное имя:
http://amperkalikes.000webhostapp.com
- Доступ авторизованного пользователя к файловой системе по адресу:
https://files.000webhost.com
- Скачайте и откройте php-скрипт. Данный скрипт позволяет открыть целевую страницу «facebook», получить искомое количество лайков на странице и выгрузить его в формате:
fan_count=xxxx
.
Чтобы скрипт выдавал количество лайков вашей страницы, его требуется изменить. Для этого нужно внести изменения в переменную $id
, определенную в третьей строке кода скрипта. Значение переменной следует заменить на значение id
вашей страницы «facebook». Чтобы узнать значение id
вашей страницы, нужно перейти на интересующую нас страницу и проанализировать ее адрес.
В качестве примера возьмем адрес facebook-страницы Амперки:
https://www.facebook.com/amperka.ru/?fref=ts
id
страницы расположено между слешами после домена www.facebook.com
, следовательно, id-страницы
— «amperka.ru» Присвоим это значение переменной $id='amperka.ru'.
Теперь разместим наш модифицированный скрипт на сервере. В нашем случае нужно перейти по адресу:
https://files.000webhost.com
и простым перетягиванием ярлыка файла скрипта (drag-and-drop) перенести файл getLikes.php
в файловую систему сервера.
В заключении проверьте успешность работы скрипта. Для этого перейдите по адресу:
http://amperkalikes.000webhostapp.com/getLikes.php
Если при этом веб-браузер отобразит пустое окно с единственной строкой: fan_count=4,218
(число может быть иным), то все сделано верно.
Исходный код
Программа для Arduino
- counter-like.ino
// библиотека для работы с сервоприводами #include <Servo.h> // библиотека для работы с дисплеем #include "QuadDisplay2.h" #include "TimeCheck.h" // буффер запроса char serialbuffer[100]; // создаём объект класса QuadDisplay и передаём номер пина CS QuadDisplay qd(9); // создаём объект для работы с сервоприводом Servo srv; TimeCheck butTime(500); TimeCheck timeOut(5000); TimeCheck autoRun(1000); int but = 2; int srvPin = 3; int ang0 = 110; int ang1 = 140; String wifi = "nameWiFi"; String passwordWifi = "passwordWiFi"; String host = "amperkalikes.000webhostapp.com"; String link = "getLikes.php"; String cmdWifi; String cmdHost; String cmdLink; int pIndex = -1; boolean autoRunOn = false; int fanReceived = -1; int fanMemory = -1; String makeWifi() { String toReturn = "AT+CWJAP=\""; toReturn += wifi; toReturn += "\",\""; toReturn += passwordWifi; toReturn += "\""; return toReturn; } String makeGet() { String toReturn = "GET /"; toReturn += link; toReturn += " HTTP/1.1\r\nHost:"; toReturn += host; toReturn += "\r\n\r\n\r\n"; return toReturn; } String makeHost() { String toReturn = "AT+CIPSTART=\"TCP\",\""; toReturn += host; toReturn += "\",80"; return toReturn; } void setup() { Serial1.begin(115200); Serial.begin(115200); qd.begin(); qd.displayInt(-42); pinMode(but, INPUT); srv.write(ang0); srv.attach(srvPin); srv.write(ang0); cmdWifi = makeWifi(); cmdHost = makeHost(); cmdLink = makeGet(); qd.displayInt(-3); Serial.print("cmdWifi = "); Serial.println(cmdWifi); Serial.print("cmdHost = "); Serial.println(cmdHost); Serial.print("cmdLink = "); Serial.println(cmdLink); } void loop() { if(timeOut.check() && pIndex != -1) { Serial.print("timeOut.check() : last pIndex = "); Serial.println(pIndex); pIndex = -1; } if(buttCheck()) { autoRunOn = !autoRunOn; } switch(pIndex) { case -1: if(autoRun.check() && autoRunOn) { Serial.println("autoRun ON +++++++++++++"); pIndex = 0; } break; case 0: checkStatConn(); pIndex++; timeOut.defer(); break; case 10: startTCP(); pIndex++; timeOut.defer(); break; case 20: requestLikes(); pIndex++; timeOut.defer(); break; case 30: qd.displayInt(fanReceived); fanCheck(); pIndex = -1; autoRun.defer(); break; } while(Serial1.available() > 0) { String tmp = Serial1.readStringUntil('\n'); if (true) { Serial.println(tmp); } int valueStat = getStatus(tmp); switch(valueStat) { //got IP, TCP connection next case 2: pIndex = 10; break; //TCP is good, getLikes next case 3: pIndex = 20; break; //got IP, TCP connection next case 4: pIndex = 10; break; //Problems with WiFi connection case 5: Serial.println("Check Wi-Fi settings"); Serial.print("Wifi settings now : "); Serial.println(cmdWifi); Serial1.println("AT+CWMODE=3"); delay(2000); Serial1.println(cmdWifi); pIndex = -1; break; } if (getConnect(tmp)) { pIndex = 20; } if(getFanCount(tmp) > 0) { pIndex = 30; } } } boolean buttCheck() { if(!digitalRead(but) && butTime.check()) { return true; } else { return false; } } void checkStatConn() { Serial1.println("AT+CIPSTATUS"); } void startTCP() { Serial.println("startTCP"); Serial1.println(cmdHost); } int getStatus(String input) { if (!input.startsWith("STATUS:")) return -1; input.replace("STATUS:",""); return input.toInt(); } boolean getConnect(String input) { if (!input.startsWith("CONNECT")) { return false; } return true; } void doRequest(String input) { Serial1.print("AT+CIPSEND="); Serial1.println(input.length()); if(Serial1.find(">")){ Serial.println(">"); } else { Serial1.println("AT+CIPCLOSE"); Serial.println("Connect timeout"); return; } Serial1.print(input); } void requestLikes() { doRequest(cmdLink); } int getFanCount(String input) { if (!input.startsWith("fan_count=")) { return -1; } input.replace("fan_count=",""); input.replace(",",""); fanReceived = input.toInt(); Serial.print("getFanCount() : fanReceived = "); Serial.println(fanReceived); return input.toInt(); } void giveCandy() { srv.write(ang1); delay(2000); srv.write(ang0); delay(2000); } void fanCheck() { if (fanReceived - fanMemory > 20 || fanReceived < fanMemory) { fanMemory = fanReceived; } else { while (fanMemory < fanReceived) { giveCandy(); ++fanMemory; } } }
PHP-скрипт
- getLikes.php
<?php $id='amperka.ru'; $opts = array( 'http'=>array( 'method'=>"GET", 'header'=>"Accept-language: en\r\n" . "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n", "Cookie: foo=bar\r\n" ) ); $context = stream_context_create($opts); // Open the file using the HTTP headers set above $file = file_get_contents('https://www.facebook.com/plugins/fan.php?connections=100&id='.$id, false, $context); //echo $file; $target = '_1drq'; $target1 = ';">'; $target2 = ' '; $pos = strstr($file, $target); $pos = strstr($pos, $target1); $pos = strstr($pos, $target2, true); $pos = substr($pos, strlen($target1)); print('fan_count='); print_r($pos); //echo $pos; ?>
Ресурсы
- Библиотека TimeCheck для работы выше приведённого скетча.