ESP32 デュアルコア ( マルチタスク )で、4つの News 記事を取得する電光掲示板を作ってみた

記事公開日:2017年8月5日
最終修正日:2017年8月14日

スポンサーリンク

こんばんは。

今回は、ESP32 ( ESP-WROOM-32 )のDual Core ( Multi Task ) を更に応用して、4種類の Web ニュース記事を取得して、電光掲示板スクロールしてみました。
有機EL ( OLED )ディスプレイは、SPI通信の フルカラー SSD1331 モジュールで、SSD1351 よりも速度は遅いのですが、4つの記事を十分な速度でスクロールさせることができました。

この記事および自作ソースコードの公開について、Yahoo! Japan さんにお問い合わせして、趣味や研究範囲と判断でき、問題無いとの回答を得ております。
(2017/8/11)

まずは以下の動画をご覧ください。

いかがでしょうか。
東スポWeb 記事が少々カクカクしてますが、4つの記事を別々にスクロールさせていることが分かると思います。

EPP8266の時は、4つの記事をこれだけのスピードでスクロールさせることはとても無理だったのですが、かなり高速でスクロールしてくれますね。
それに加えて、裏の CPU でスクロールを止めずに記事を GET できているのがスバラシイ!!
しかも、今回選んだニュース記事は、以前までの記事で使っていた Yahoo! Japan RSS ニューストピックストップ記事よりも格段に多い文字列を取得しています。
取得した記事は以下の通りです。

●EDN Japan
●日刊スポーツ
●東スポWeb
●日経トレンディネット

日経トレンディネットが最も多い文字数で、全角で 1000文字弱ありました。
SRAM メモリをかなり消費してしまいますが、ESP32 ( ESP-WROOM-32 )は問題無く動作しますね。
素晴らしい!!

では、これの方法を説明します。
前回、前々回の記事と重複しているところがあるので、すっ飛ばして説明させていただきます。

使っているもの

使用している主なデバイスは以下の通りです。

ESPr Developer 32 または、ESP32-DevKitC

ESPr_Developer32_12

ESPr Developer 32 参考記事

フルカラーOLED SSD1331 SPI モジュール


その他の細かい物品については、前回の記事を参照してください。

事前に、Arduino core for ESP32設定、ライブラリインストール、フォント、ルート証明書を保存しておく

Arduino IDE は ver 1.8.3 を使用し、Arduino core for ESP32 は最新版をダウンロードしてインストールしてください。

Arduino core for the ESP32 のインストール方法

また、ライブラリ等は以下の記事を参照して、私の自作ライブラリのインストールしておき、micro SDカードにフォントや Yahoo! Japan RSS ルート証明書を保存しておいてください。

Yahoo ニュース、天気予報、NTP時計ガジェットを ESP32 マルチタスク ( デュアルコア )で動かしてみた

ESP32 マルチタスク(デュアルコア)で、電光掲示板スクロールを止めずに、別のCPUで Web GET できました

Arduino – ESP32 WiFiClientSecure ライブラリで、安定して https ( SSL )記事をGETする方法

【外部使用ライブラリ】

ESP32_SD_SSD1331_Gadgets  ( beta ver 1.1 )
ESP32_SD_ShinonomeFNT  ( beta ver 1.21 )
ESP32_SD_UTF8toSJIS  ( beta ver 1.21 )
ESP32_SSD1331 ( beta ver 1.3 )
ESP32_WebGet ( beta ver 1.1 )
Time ライブラリ ( Arduino 標準ライブラリ ver 1.5 )

【micro SD カードへ保存するファイル】

Utf8Sjis.tbl  (UTF-8 → Shift_JIS 変換テーブル)
shnmk16.bdf (全角東雲フォント)
shnm8x16.bdf (半角東雲フォント)
yahoo.cer ( Yahoo! Japan RSS ルート証明書 )

スケッチの入力

では、以下のスケッチを入力してみてください。

#include "ESP32_SD_SSD1331_Gadgets.h"

const char* ssid = "xxxx"; //ご自分のルーターのSSIDに書き換えてください。
const char* password = "xxxx"; //ご自分のルーターのパスワードに書き換えてください。

const char* UTF8SJIS_file = "/font/Utf8Sjis.tbl"; //UTF8 Shift_JIS 変換テーブルファイル名を記載しておく
const char* Shino_Zen_Font_file = "/font/shnmk16.bdf"; //全角フォントファイル名を定義
const char* Shino_Half_Font_file = "/font/shnm8x16.bdf"; //半角フォントファイル名を定義
const char* MyFont_file = "/font/MyFont.fnt"; //自作フォントファイル名を定義
const char* Yahoo_rootca_file = "/root_ca/yahoo.cer"; //Yahoo! Japan RSS ルート証明書ファイル

const uint8_t CS_SD = 5; //SD card CS ( Chip Select )

const uint8_t SCLK_OLED =  14; //SCLK
const uint8_t MOSI_OLED =  13; //MOSI (Master Output Slave Input)
const uint8_t MISO_OLED =  12; //これは実際は使っていない。MISO (Master Input Slave Output)
const uint8_t CS_OLED = 15;
const uint8_t DC_OLED =  16; //OLED DC(Data/Command)
const uint8_t RST_OLED =  4; //OLED Reset

ESP32_SD_SSD1331_Gadgets ESSG;
ESP32_SD_UTF8toSJIS u8ts;
ESP32_SSD1331 _ssd1331(SCLK_OLED, MISO_OLED, MOSI_OLED, CS_OLED, DC_OLED, RST_OLED); //HSPI 接続
ESP32_SD_ShinonomeFNT _SFR(CS_SD, 24000000); //SPI 24MHz
ESP32_WebGet _EWG;

//Yahoo! Japan RSS トピックス以外のニュースは2048バイト以上の配列確保必要
uint8_t sj_txt[4][2048] = {}; //Shift_JIS コード文字列を格納
uint16_t sj_length[4] = {}; //Shift_JIS コード文字列長

int32_t NewsGetLastTime = 0; //起動時にすぐGETするようにマイナスにしている
bool WebGet[4] ={false, false, false, false}; //記事をGETした場合はtrue

//***************** Arduino Setup **********************************
void setup() {
  _EWG.EWG_AP_Connect(ssid, password); //Wi-Fi ルーターと接続
  delay(1000);

  _ssd1331.SSD1331_Init(); //OLED SSD1331 初期化
  //UTF-8→S_JIS変換テーブル、東雲フォント全角、半角ファイル、合計3つのファイルを同時に開く
  if(!_SFR.SD_Shinonome_Init3F(UTF8SJIS_file, Shino_Half_Font_file, Shino_Zen_Font_file)){
    return;
  }

  //EDN Japan 初回GET
  WebGet[0] = Yahoo_RSS_GET("headlines.yahoo.co.jp", "/rss/it_edn-c_sci.xml", Yahoo_rootca_file, sj_txt[0], &sj_length[0]);
  //日刊スポーツ 初回GET
  WebGet[1] = Yahoo_RSS_GET("headlines.yahoo.co.jp", "/rss/nksports-c_spo.xml", Yahoo_rootca_file, sj_txt[1], &sj_length[1]);
  //東スポWeb 初回GET
  WebGet[2] = Yahoo_RSS_GET("headlines.yahoo.co.jp", "/rss/tospoweb-c_ent.xml",  Yahoo_rootca_file, sj_txt[2], &sj_length[2]);
  //日経トレンディネット 初回GET
  WebGet[3] = Yahoo_RSS_GET("headlines.yahoo.co.jp", "/rss/trendy-all.xml", Yahoo_rootca_file, sj_txt[3], &sj_length[3]);
  NewsGetLastTime = millis();

  TaskHandle_t th; //ESP32 マルチタスク ハンドル定義
  xTaskCreatePinnedToCore(Task1, "Task1", 4096, NULL, 5, &th, 0); //マルチタスク core 0 実行
}
//***************** メインループ **********************************
void loop() {
  if((millis() - NewsGetLastTime) > 180000){ //180秒毎に記事更新
    //EDN Japan
    WebGet[0] = Yahoo_RSS_GET("headlines.yahoo.co.jp", "/rss/it_edn-c_sci.xml", Yahoo_rootca_file, sj_txt[0], &sj_length[0]);
    //日刊スポーツ
    WebGet[1] = Yahoo_RSS_GET("headlines.yahoo.co.jp", "/rss/nksports-c_spo.xml", Yahoo_rootca_file, sj_txt[1], &sj_length[1]);
    //東スポWeb
    WebGet[2] = Yahoo_RSS_GET("headlines.yahoo.co.jp", "/rss/tospoweb-c_ent.xml", Yahoo_rootca_file, sj_txt[2], &sj_length[2]);
    //日経トレンディネット
    WebGet[3] = Yahoo_RSS_GET("headlines.yahoo.co.jp", "/rss/trendy-all.xml", Yahoo_rootca_file, sj_txt[3], &sj_length[3]);
    NewsGetLastTime = millis();
  }
}

//************* マルチタスク ****************************************
void Task1(void *pvParameters){
  while(1){ //red(0-7), green(0-7), blue(0-3)
    ESSG.Scroll_1_line(0, 0, 0, 7, 0, 1, sj_txt[0], sj_length[0], &WebGet[0]);
    ESSG.Scroll_1_line(16, 1, 1, 1, 3, 4, sj_txt[1], sj_length[1], &WebGet[1]);
    ESSG.Scroll_1_line(32, 2, 7, 0, 1, 7, sj_txt[2], sj_length[2], &WebGet[2]);
    ESSG.Scroll_1_line(48, 3, 7, 7, 3, 11, sj_txt[3], sj_length[3], &WebGet[3]);
  }
}
//************* Yahoo! Japan RSS GET ********************************
bool Yahoo_RSS_GET(const char * Host, String t_ip, const char *Rootca_File, uint8_t sj[], uint16_t *sj_len){
  char root_ca[2048];
  ESSG.Root_CA_SDcard_Read(Rootca_File, root_ca);
  String news_str = _EWG.EWG_https_Web_Get(root_ca, Host, t_ip, '\n', "</rss>", "<title>", "</title>", "◆ ");
  *sj_len = u8ts.UTF8_to_SJIS(news_str, sj);
  Serial.println(news_str);
  Serial.flush();
  return true;  
}

【解説】

●1行目:
自作ライブラリのインクルードです。
UTF-8 → Shift_JISライブラリや、東雲フォントライブラリをインクルードしなくても、ESP32_SD_SSD1331_Gadgetsライブラリ内でインクルードされています。

●3-4行目:
ご自分のルーターの SSID とパスワードに書き換えてください。

●6-10行目:
micro SD カードに保存してあるフォントファイルや、Yahoo! Japan RSS ルート証明書のファイル名を定義しています。

●21-25行:
私の自作ライブラリのクラス名を定義しています。

●28行:
Yahoo! Japan RSS ニュース記事を取得した後、Shift_JISコードに変換しますが、その変換された Shift_JISコード文字列を格納しておく配列です。
「日経トレンディネット」記事の場合は、1000文字近くなるので、Shift_JISコードに変換すると2倍になります。
その直近の最大数ということで、2048としました。

●32行:
46行目などの、Yahoo_RSS_GET関数などでWeb記事をGETしたら、trueを返します。それを格納しておきます。

●41行:
ここで、UTF-8→Shift_JIS変換テーブルファイルや、フォントファイルを同時に3つ開きます。
ESP32 では、1タスク中に同時に開けるファイル数の最大値は4つまでです。

●46-52行:
Yahoo! Japan RSS ニュースサイトから、記事タイトルだけを取得します。
83-91行で関数化しています。
今回取得しているのは、以下の記事です。

EDN Japan
日刊スポーツ
東スポWeb
日経トレンディネット

これらの記事取得後は、sj_txtという変数にShift_JISコードが返ってきます。
これは、前回記事のような 1024バイトでは足りません。
2048バイト以上無ければ取得できませんので要注意です。
と言っても、多いのは日経トレンディネットですが・・・。

●55行:
以前の記事でも述べましたが、ESP32 の FreeRTOS マルチタスク用の TaskHandle_t 型の定義です。
th にはタスクハンドルが格納されます。

●56行:
ここで、ESP32 デュアルコアの core 0 で、74-81行のタスクが実行されます。
つまり、有機EL ( OLED )ディスプレイの文字スクロールを、while無限ループで実行させます。

●59-71行:
Arduino 関数のメインループです。
ESP32 のマルチタスクでは、core 1 で実行されます。
前回記事でも述べましたが、WifiClientSecure などの WiFi系ライブラリは、core 1 のメインループ関数内で実行させる方がトラブルが少ないです。

180秒毎に Yahoo! Japan RSS 記事を取得しています。

●74-81行:
マルチタスク、core 0 で実行する関数です。
Scroll_1_line は自作ライブラリの関数で、OLED SSD1331 ディスプレイの1行をスクロールさせる関数です。

●83-91行:
Yahoo! Japan RSS サイトからニュース記事のタイトルをGET する関数です。
85行で micro SD カードに保存してあるルート証明書を読み込んで、それを86行の関数へ代入して、SSL ハンドシェイクを実行しています。
記事は String型の UTF-8 コードで返って来るので、87行目で Shift_JISコードに変換しています。

コンパイル書き込み実行

では、上記のスケッチをコンパイル書き込み実行させてみてください。

最初に紹介した動画のように表示されればOKです。

また、シリアルモニターではこんな感じに表示されます。

ESP32_4LineGet01

まとめ

以上、うまく動きましたでしょうか?

ESP8266 ではなかなか実現できなかった4つ異なる記事の同時スクロールが、問題無くできるようになって、改めて ESP32 ( ESP-WROOM-32 )のポテンシャルの高さに驚かされます。
しかもデュアルコア(マルチタスク)で、文字スクロールが停止しないというのがスゴイですよね。
それに、結構高速でスクロールしてくれています。

これは、OLED SSD1331 のグラフィックアクセラレーションコマンドのおかげなのですが、それでもスゴイです。
電子工作の幅が本当に広がりますね。

今、高校野球の時季ですが、その結果もこの電光掲示板スクロールで絶えず表示できそうです。

と、いうことで、今回はここまでです。

ではまた・・・。

mgo-tec電子工作 関連コンテンツ ( 広告含む )

スポンサーリンク

Amazon.co.jp 当ブログのおすすめ







投稿者:

mgo-tec

Arduino , ESP32 ( ESP-WROOM-32 ) , ESP8266 ( ESP-WROOM-02 )等を使って、主にスマホと連携した電子工作やプログラミング記事を書いてます。ライブラリも作ったりしてます。趣味、独学でやってますので、動作保証はしません。 電子回路やプログラミングの専門家ではありません。 畑違いの仕事をしてます。 でも、少しだけ電気の知識が必要な仕事なので、電気工事士や工事担任者等の資格は持ってます。

コメントを残す

メールアドレスが公開されることはありません。

*画像の文字を入力してください。(スパム防止の為)