Развлекательный информер. Читаем анекдоты на ESP8266.
Простой проект развлекательного информера. Скачивание свежих анекдотов, историй, афоризмов и тому подобного с сайта РжуНеМогу.ru и вывод на tft экран.
Развлекательный информер. Читаем анекдоты на ESP8266.
Версия для печати

Развлекательный информер. Читаем анекдоты на ESP8266.

logo

Хочу представить вашего вниманию  простой проект развлекательного информера. Суть его работы такова. Каждую минуту он будет скачивать свежий анекдот, историю, афоризм и тому подобное с сайта РжуНеМогу.ru и выводить его на tft экран. Не смотря на кажущуюся простоту в коде проекта есть несколько интересных моментов. Это использование русского шрифта в библиотеке AdafruitGFX, которая с русским языком изначально работать не умела и постраничный вывод большого текста на экран. Так что данный проект может быть полезен и новичкам в образовательных целях.

Необходимые компоненты

Схема соединений

Соединяем все компоненты по схеме

scheme

Прошивка устройства

После сборки устройства по схеме переходим к прошивке ESP8266. Для начала вам необходимо установить в Arduino IDE ядро ESP8266 версии 3.0 и выше. Как это сделать можно узнать в статье Ядро ESP8266 для ArduinoIDE. Установка и обзор библиотек.

Установка дополнительных библиотек

Также вам необходимо скачать и установить дополнительные библиотеки, необходимые для работы программы.
 

  • Adafruit_GFX - 1.1.13 и выше
  • Adafruit_ST7735 - 1.9.3 и выше
  • Adafruit_ST7789 - 1.9.3 и выше
  • EncButton2 - 2.0.0 и выше
  • SPI.h - входит в стандартную поставку Arduino IDE

Следующие библиотеки будут установлены автоматически вместе с ядром ESP8266 для Arduino IDE.

  • ESP8266WiFi
  • ESP8266HTTPClient
  • WiFiClient

Русификация библиотеки Adafruit GFX

В программе для отображения текста на TFT экране используется популярная библиотека Adafruit GFX. Но, как оказалось, она не умеет работать с русским шрифтом. Добавить его  несложно: нужно лишь заменить в файле glcdfont.c из Adafruit-GFX некоторые символы на русские буквы (в нужной кодировке). Готовый файл glcdfont.c с русским шрифтом находится в архиве проекта

Код программы и описание настроек

После установки всех необходимых библиотек, откройте файл из вложения в Arduino IDE, либо создайте новый проект и скопируйте в него все содержимое из блока ниже

#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <<Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SPI.h> 
#include <ESP8266WiFi.h> 
#include <ESP8266HTTPClient.h> 
#include <WiFiClient.h> 
#include <EncButton2.h>> 

//Инициализация дисплея
#define TFT_CS D8 
#define TFT_RST D6 
#define TFT_DC D1
#define BTN_PIN D0
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);



//Настройки WiFi 
const char* ssid = "ssid"; //Данные для подключения к WiFi
const char* password = "pass";

//настройки сервера
const String api = "http://rzhunemogu.ru/RandJSON.aspx?CType=";
byte category = 1; //категория


String dataText=""; //переменная для хранения текста анекдота
bool scrollflag=false;//флаг необходимости прокрутки

// Инициализация таймеров
// по умолчанию анекдоты обновляются раз в 60 секунд, если весь текст не влезает на экран, то следующая страница подгружается через 30 секунд. Можно период обновления выставить меньше, но сервер может забанить за слишком частые обращения
unsigned long lastTime = 0;
unsigned long scrollLastTime = 0;
unsigned long timerDelay = 60000; //время обновления анекдота 60 секунд
unsigned long scrollDelay = 30000; //время на чтение одной страницы 30 секунд

EncButton2 butt1(INPUT, BTN_PIN); //Инициализация кнопки

void setup() {
 Serial.begin(115200);
 // Инициализация дисплея
 tft.initR(INITR_BLACKTAB); // Init ST7735S chip, black tab
 tft.cp437(true);
 tft.setRotation (1);
 tft.fillScreen(ST77XX_BLACK);
 tft.setCursor(0,0);
 //Подключение к WiFi
 WiFi.begin(ssid, password);
 Serial.println("Connecting");
 while(WiFi.status() != WL_CONNECTED) {
 delay(500);
 Serial.print(".");
 }
 Serial.println("");
 Serial.print("Connected to WiFi network with IP Address: ");
 Serial.println(WiFi.localIP());

 
 dataText=getData(api,category);//вызов функции скачивания анекдота и добавление текста в строковую перемнную 
 datacheck(); //Проверка длины строки и в случае не обходимости разделение текста на 2 экрана
 }

//Функция скачивания свежего анекдота. Входные параметра адрес API сайта и номер категории
String getData(String api, byte cat){
 if(WiFi.status()== WL_CONNECTED){
 WiFiClient client;
 HTTPClient http;
 http.begin(client,api + String(category));
 int httpCode = http.GET();
 Serial.println(httpCode);
 String rawstring=http.getString();
 http.end();
 return (rawstring.substring(12,rawstring.length()-3));
 }
 else {
 Serial.println("WiFi Disconnected");
 return ("Данные не получены");
 }
}

//Обработка нажатия кнопки
void btn_read(){
 if (butt1.click()) {
 category++;
 if (category==7 || category==17) category++;
 if (category==9) category=11;
 if (category==19) category=1;
 dataText=getData(api,category);
 lastTime = millis();
 datacheck();
 }
 }

//Вывод текста анекдота на экран
void tftprint(String showtext) {
// tft.setFont(&TimesNRCyr10pt8b); // выбор шрифта
 tft.fillScreen(ST77XX_BLACK);
 tft.setTextColor(ST77XX_GREEN,ST77XX_BLACK);
 tft.setCursor(40,0);
 //Отображение названия категории в соответсвии с параметром выбранным в API
 String catname;
 switch (category) {
 case 1 : catname="Anekdots";
 break;
 case 2 : catname="Stories";
 break;
 case 3 : catname="Lyric";
 break;
 case 4 : catname="Aforizm";
 break;
 case 5 : catname="Quotes";
 break;
 case 6 : catname="Tosts";
 break;
 case 8 : catname="Status";
 break;
 case 11: catname="Anekdots (18+)";
 break;
 case 12 : catname="Stories 18+";
 break;
 case 13 : catname="Lyric (18+)";
 break;
 case 14 : catname="Aforizm";
 break; 
 case 15 : catname="Quotes (18+)";
 break;
 case 16 : catname="Tosts (18+)";
 break;
 case 18 : catname="Status (18+)";
 break; 
 }
 tft.println(utf8rus(catname));
 tft.setCursor(0,8);
 //Serial.println(showtext);
 tft.setTextColor(ST77XX_WHITE,ST77XX_BLACK);
 //далее идет вывод текста на экран. Для русских букв выполняется перевод кодировки из UTF-8 в Windows-1251 
 tft.println(utf8rus(showtext));
 //tft.setFont();
}

//Проверка длины строки с текстом. Если не влезает на экран, то разбиваем ее на 2 части и запускаем таймер для вывода второй части сообщения
void datacheck()
{
 dataText=getData(api,category);
 if (dataText.length()>429) {
 tftprint(dataText.substring(0,429));
 scrollLastTime=millis();
 scrollflag=true;
 } else tftprint(dataText);
 
}

//Преобразование 2 байтовой кодировки русских символов в 1 байтовую
String utf8rus(String source)
{
 int i,k;
 String target;
 unsigned char n;
 char m[2] = { '0', '\0' };

 k = source.length(); i = 0;

 while (i < k) {
 n = source[i]; i++;
 if (n >= 0xBF){
 switch (n) {
 case 0xD0: {
 n = source[i]; i++;
 if (n == 0x81) { n = 0xA8; break; }
 if (n >= 0x90 && n <= 0xBF) n = n + 0x2F;
 break;
 }
 case 0xD1: {
 n = source[i]; i++;
 if (n == 0x91) { n = 0xB7; break; }
 if (n >= 0x80 && n <= 0x8F) n = n + 0x6F;
 break;
 }
 }
 }
 m[0] = n; target = target + String(m);
 }
return target;
}

void loop() {
 butt1.tick();
 btn_read();
 if ((millis() - lastTime) > timerDelay) {
 // Check WiFi connection status
 datacheck();
 lastTime = millis();
 }
 if ((millis() - scrollLastTime)> scrollDelay and scrollflag) 
 {
 tftprint(dataText.substring(430,dataText.length()-1));
 scrollflag=false;
 }
 
}
 

Настройки

Перед компиляцией и прошивкой скетча в ESP8266 необходимо провести некоторые настройки

//Настройки WiFi 
const char* ssid = "ssid"; //Данные для подключения к WiFi
const char* password = "pass";

//настройки сервера
const String api = "http://rzhunemogu.ru/RandJSON.aspx?CType=";
byte category = 1; //категория

ssid и pass - учетные данные для подключения к вашей сети Wifi. Замените на свои

category = 1. Категория по умолчанию. Может принимать следующие значения: 1 - Анекдот; 2 - Рассказы; 3 - Стишки; 4 - Афоризмы; 5 - Цитаты; 6 - Тосты; 8 - Статусы; 11 - Анекдот (+18); 12 - Рассказы (+18); 13 - Стишки (+18); 14 - Афоризмы (+18); 15 - Цитаты (+18); 16 - Тосты (+18); 18 - Статусы (+18);

unsigned long timerDelay = 60000; //время обновления анекдота 60 секунд
unsigned long scrollDelay = 30000; //время на чтение одной страницы 30 секунд

timerDelay = 60000. Таймер, по истечении которого будет загружен следующий анекдот. По умолчанию стоит 1 минута. Во время тестирования устанавливал на 10 секунд, но через какое-то время анекдоты переставали загружаться. Возможно внутренняя защита сервера от DDOS атак. С интервлом в 1 минуту работает стабильно

На этом настройки программы завершены и можно компилировать и прошивать ее в ESP8266

scrollDelay = 30000. Таймер прокрутки страницы. При загрузке длинных текстов, которые не помещаются на один экран, сообщение разбивается на 2 части. Сначала отображается первая часть сообщения, а при срабатывании таймера вторая. По умолчанию таймер равен 30 секунд.

Замечания по русификации библиотеки Adafruit GFX.

Для русификации библиотеки в файл glcdfont.c со стандартным шрифтом были добавлены русские буквы. Но шрифт рассчитан на однобайтовую кодировку букв, а Arduino IDE использует (для русских букв) двухбайтовую кодировку UTF-8.

Однако оказалось, что в русской кодировке UTF-8 прослеживается определенная последовательность. И она позволяет несложным путем перекодировать из UTF-8 в однобайтовую русскую кодировку Windows-1251, которая и была выбрана для замены букв.

Функция utf8rus() получает исходную строку, символы с кодами 0x00-0xBF пропускает без изменения в выходную строку, а в оставшихся кодах отбирает русские буквы и перекодирует их.

Ниже расположен код данной функции.

String utf8rus(String source)
{
 int i,k;
 String target;
 unsigned char n;
 char m[2] = { '0', '\0' };

 k = source.length(); i = 0;

 while (i < k) {
 n = source[i]; i++;
 if (n >= 0xBF){
 switch (n) {
 case 0xD0: {
 n = source[i]; i++;
 if (n == 0x81) { n = 0xA8; break; }
 if (n >= 0x90 && n <= 0xBF) n = n + 0x2F;
 break;
 }
 case 0xD1: {
 n = source[i]; i++;
 if (n == 0x91) { n = 0xB7; break; }
 if (n >= 0x80 && n <= 0x8F) n = n + 0x6F;
 break;
 }
 }
 }
 m[0] = n; target = target + String(m);
 }
return target;
}

Работает все, как и было задумано, но по непонятной причине на экране не отображаются заглавные буквы Р и С. Причину этого так и не удалось выяснить.

Фото устройства и особенности управления.

Все управление устройством осуществляется одной кнопкой, при нажатии на которую меняются категория анекдотов и производится их загрузка и вывод на экран.

Проект собран на макетной плате и на данный момент имеет такой вид

фото устройства

Материал также доступен на моем канале: Яндекс Дзен и в группе ВК
Категория: ESP8266 | Добавил: | Теги: информер, ESP8266, TFT дисплей
Просмотров: 812 | Загрузок: 48 | Рейтинг: 0.0/0
Поделиться:
Всего комментариев: 0
avatar