M5Stack で、Wi-Fi 接続して、Yahoo! ニュースを4記事同時スクロールしてみた

M5Stack,で,Yahoo,ニュース記事を4行同時スクロール表示させてみた M5Stack

Arduino – ESP32 の設定、東雲フォントダウンロード、SDカード用ライブラリ、SPIFFS用ライブラリをインストールしておく

まず、以下の記事を参照していただき、Arduino core for the ESP32 のインストール、および東雲フォントをダウンロードしておいてください。
Arduino IDE は 1.8.5 で動作確認しております。
Arduino core for the ESP32 は最新版をインストールしておいてください。

また、最初でも述べましたが、東雲フォントについては開発者に敬意を表するためにも元サイトを訪問してダウンロードしていただきたいと思います。

日本語漢字ビットマップフォント、東雲フォントについて

そして、ライブラリは私の自作です。
素人コードですので、動作保証はしません。
無駄が多く、誤っている場合もありますので、それをご了承の上インストールしてみてください。
インストール方法は以下の記事を参照してください。
SDカード用と SPIFFS 用の両方を掲載していますが、どちらか好きな方をセットアップしてください。
micro SD カードを使った方が簡単です。

Arduino – ESP32 ( SPIFFS およびmicro SD) 自作Fontライブラリインストール方法

micro SD または SPIFFS に保存するフォントファイル群は以下の通りです。
micro SD を使う場合は、ルートに /font/ フォルダを新たに作成して、以下のファイルをコピーしておいてください。

Utf8Sjis.tbl
shnmk16.bdf
shnm8x16.bdf (※shnm8x16r.bdf を名前変更する)

SPIFFS の場合は、スケッチのフォルダに /data/font/ フォルダを作成して、そこにコピーして SPIFFS アップローダープラグインを使ってアップロードします。

また、今回から ESP32_SD_UTF8toSJIS ライブラリと、 ESP32_SD_ShinonomeFNTライブラリをバージョンアップし、Beta ver 1.22 としました。

M5Stack への micro SD カード挿入方向

micro SD カードにフォントファイル類をコピーしたら、M5Stack に挿入しておいてください。
その場合、必ずUSB-TypeC ケーブルを抜いて電源を切ってください
またはバッテリーマウントを外しても良いと思います。
その後 micro SD カードを挿入してください。
挿入方法は下図の方向です。
M5Stack は裏側から見る場合、micro SD カードは表面になります。
カチッと音がするまで差し込んでから、USBケーブルを接続します。

バージョンアップした LCD ライブラリ等その他ライブラリのインストール

前回の記事で紹介した、自作の LCD ILI9341 ライブラリを更にバージョンアップしました。
現在、beta ver 1.2 となっていますので、それを再インストールしてください。
再インストールする場合は、ライブラリ内のフォルダごと削除してからインストールしてください
Windows10 の場合、Arduino IDE のデフォルト設定では以下のパスになると思います。
User-Name のところがご自分のユーザー名です。

C:\Users\User-Name\Documents\Arduino\libraries

その中の、
ESP32_LCD_ILI9341_SPI-master
というフォルダごと削除すれば良いです。

以下のGitHub リンクから ZIP ファイルをダウンロードしていただき、Arduino IDE にインストールしてください。
インストール方法は以下の記事を参照してください。

GitHubにある ZIP形式ライブラリ のインストール方法 ( Arduino IDE )

ESP32_LCD_ILI9341_SPI ライブラリ

M5Stack の TFT LCD ディスプレイ ILI9341 用の自作ライブラリです。
現在 beta ver 1.2 です。
前回と異なるのは、micro SD カードと LCD 動作が可能になったことです。
特に、フォント関連関数を使う時に、毎回 SPI 周波数と SPI_MODE を切り替えるようにしました。

https://github.com/mgo-tec/ESP32_LCD_ILI9341_SPI

ESP32_Button_Switch ライブラリ

自作のシンプルなボタンスイッチライブラリです。

https://github.com/mgo-tec/ESP32_Button_Switch

ESP32_WebGet ライブラリ

Yahoo! Japan RSS サイトからニュース記事を GET したり、NTP サーバーから現在時刻を取得する自作ライブラリです。

https://github.com/mgo-tec/ESP32_WebGet

Time ライブラリ

Arduino IDE 標準の Time ライブラリです。

https://github.com/PaulStoffregen/Time

※このブログをご覧になっている方々は、あまり文章をじっくり読まずにスルーされることが多いので、前項と重複しますが、ここでも東雲フォントライブラリを掲載しておきます。

ESP32_SD_UTF8toSJIS ライブラリ

文字コード UTF-8 からSDカード内の Utf8Sjis.tbl ファイルを読み込んで Shift_JISコードに変換するライブラリです。
beta ver 1.22 以降を使用してください。

https://github.com/mgo-tec/ESP32_SD_UTF8toSJIS

ESP32_SD_ShinonomeFNT ライブラリ

東雲フォントを読み込むライブラリです。
beta ver 1.22 以降を使用してください。

https://github.com/mgo-tec/ESP32_SD_ShinonomeFNT

micro SDカード用 Arduino IDE スケッチ入力

では、Arduino IDE を起動し、スケッチ(プログラム)を入力します。
micro SD の場合とSPIFFS の場合とで少々異なるプログラムになります。
この項では、micro SD カード用のスケッチを紹介します。

【ソースコード】 (※無保証 ※PCの場合、ダブルクリックすればコード全体を選択できます)

#include "ESP32_LCD_ILI9341_SPI.h" //beta ver 1.2-
#include "ESP32_Button_Switch.h"
#include "ESP32_SD_ShinonomeFNT.h" //beta ver 1.22-
#include "ESP32_SD_UTF8toSJIS.h" //beta ver 1.22-
#include "ESP32_WebGet.h" //beta ver 1.12-
#include "TimeLib.h" //Use Arduino time library ver1.5-

const int8_t sck = 18; // SPI clock pin
const int8_t miso = -1; // MISO(master input slave output) don't using
const int8_t mosi = 23; // MOSI(master output slave input) pin
const int8_t cs = 14; // Chip Select pin
const int8_t dc = 27; // Data/Command pin
const int8_t rst = 33; // Reset pin
const int8_t LCD_LEDpin = 32;

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

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

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"; //半角フォントファイル名を定義

ESP32_LCD_ILI9341_SPI LCD(sck, miso, mosi, cs, dc, rst, LCD_LEDpin);
ESP32_SD_ShinonomeFNT SFR(CS_SD, 40000000); //SPI 24MHz
ESP32_Button_Switch BTN;
ESP32_WebGet _EWG;

//------文字表示系 引数初期化------------
const uint8_t MAX_TXT_NUM = 4; //ニュース表示最大数
uint8_t max_txt = 40; //1x1倍 最大文字表示数
uint8_t news_sj_txt[ MAX_TXT_NUM ][ 400 ] = {}; //Shift_JIS文字コード格納
uint16_t news_sj_length[ MAX_TXT_NUM ];
uint8_t news_font_buf[ MAX_TXT_NUM ][2][16] = {}; //16x16フォント全角1文字格納バッファ
uint8_t Scl_Buf[ MAX_TXT_NUM ][ 16 ][ 640 ] = {}; //文字列スクロールpixelバッファ
//red (0-31), green (0-63), blue (0-31)
uint8_t red = 31, green = 63, blue = 31;
uint8_t V_size = 3, H_size = 3; //V_size(垂直方向文字サイズ)、H_size(水平方向サイズ)
uint16_t X0 = 0, Y0 = 0;
int32_t scl_speed = 0; //スクロール速度(0が最速)
bool scl_pause = true;
//-----Yahoo記事取得 引数初期化------------
const char *yahoo_host = "news.yahoo.co.jp";
uint32_t NewsGetLastTime = 0;
bool News_first_get = true;
bool NewsGet = false;
int8_t Scl_Cnt[MAX_TXT_NUM] = {}; //文字スクロールカウント
uint16_t Fnt_Cnt[MAX_TXT_NUM] = {}; //フォント半角1文字スクロールカウント
uint8_t Zen_or_Han[MAX_TXT_NUM] = {}; //フォント読み取り時に関数から返ってきた全角または半角かの数値を格納
//-----ボタンスイッチ 引数初期化-----------
const uint8_t buttonA_GPIO = 39;
const uint8_t buttonB_GPIO = 38;
const uint8_t buttonC_GPIO = 37;
uint8_t btn_stateA = _Release;
uint8_t btn_stateB = _Release;
uint8_t btn_stateC = _Release;
boolean V_size_down = false;

//***********セットアップ****************************
void setup() {
  Serial.begin(115200);
  delay(1000);
  pinMode(buttonA_GPIO, INPUT); //GPIO #39 は内部プルアップ無し
  pinMode(buttonB_GPIO, INPUT); //GPIO #38 は内部プルアップ無し
  pinMode(buttonC_GPIO, INPUT); //GPIO #37 は内部プルアップ無し

  SFR.SD_Shinonome_Init3F(UTF8SJIS_file, Shino_Half_Font_file, Shino_Zen_Font_file); //ライブラリ初期化。3ファイル同時に開く

  LCD.ILI9341_Init(false, 40000000); //microSDを使う場合、必ず false にする
  LCD.Display_Clear();
  LCD.Brightness(0); //LCD LED Full brightness
  //++++++++++++++++++++++++++++++++++++++++++
  String test_str[ MAX_TXT_NUM ] ;
  test_str[0] = "M5stack";
  test_str[1] = "やふ~にゅ~す";
  test_str[2] = "電光掲示板";
  test_str[3] = "by microSD";

  uint8_t test_buf[ MAX_TXT_NUM ][ 14 ][ 16 ] = {};
  uint16_t test_sj_len[ MAX_TXT_NUM ] = {};
  uint8_t num = 0; //文字列番号

  for( num = 0; num < MAX_TXT_NUM; num++ ){
    test_sj_len[ num ] = SFR.StrDirect_ShinoFNT_readALL(test_str[ num ], test_buf[ num ]);
    Serial.printf("test_sj_len = %d\r\n", test_sj_len[ num ]);
  }
  num = 0, X0 = 48;
  LCD.HVsizeUp_8x16_Font_DisplayOut(2, 3, test_sj_len[ num ], X0, num * 48, red, green, blue, test_buf[ num ]);
  num = 1, X0 = 48;
  LCD.HVsizeUp_8x16_Font_DisplayOut(2, 3, test_sj_len[ num ], X0, num * 48, red, green, blue, test_buf[ num ]);
  num = 2, X0 = 80;
  LCD.HVsizeUp_8x16_Font_DisplayOut(2, 3, test_sj_len[ num ], X0, num * 48, red, green, blue, test_buf[ num ]);
  num = 3, X0 = 80;
  LCD.HVsizeUp_8x16_Font_DisplayOut(2, 3, test_sj_len[ num ], X0, num * 48, red, green, blue, test_buf[ num ]);
  X0 = 0;
  for( int i = 0; i < 256; i++){
    LCD.Brightness(i);
    delay(10);
  }
  //--------メッセージウィンドウ表示---------
  red = 31, green = 63, blue = 31;
  LCD.Display_Clear(0, 4 * 48, 319, 239);
  LCD.Draw_Rectangle_Line(0, 4 * 48, 319, 239, red, green, blue);
  red = 31, green = 0, blue = 0;
  Message(" WiFi Connecting...");
  //--------Wi-Fiアクセスポイント接続---------
  _EWG.EWG_AP_Connect(ssid, password); //Wi-Fi ルーターと接続
  delay(1000);
  _EWG.EWG_NTP_TimeLib_init(9, "time.windows.com"); //NTPサーバー取得初期化
  _EWG.NTP_OtherServerSelect(9); //NTPサーバーと接続できなかった場合、他のNTPサーバーと接続できるか試す関数

  //ニュース記事文字列のセットアップ
  num = 0, red = 31, green = 63, blue = 31;
  LCD.Scrolle_Font_SetUp(num, max_txt, red, green, blue);
  num = 1, red = 0, green = 63, blue = 0;
  LCD.Scrolle_Font_SetUp(num, max_txt, red, green, blue);
  num = 2, red = 31, green = 0, blue = 31;
  LCD.Scrolle_Font_SetUp(num, max_txt, red, green, blue);
  num = 3, red = 31, green = 63, blue = 0;
  LCD.Scrolle_Font_SetUp(num, max_txt, red, green, blue);

  Serial.printf("Free Heap Size = %d\r\n", esp_get_free_heap_size());

  TaskHandle_t th; //マルチタスクハンドル定義
  xTaskCreatePinnedToCore(Task1, "Task1", 8192, NULL, 5, &th, 0); //マルチタスク起動
}
//***********メインループ****************************
void loop() {
  uint8_t num = 0; //文字列番号
  YahooNewsGET(60000); //60秒毎に記事取得

  for(num = 0; num < MAX_TXT_NUM; num++){
    X0 = 0, Y0 = num * 48;
    if( LCD.Scrolle_Inc_HVsizeUp_8x16_Font_DisplayOut(num, Zen_or_Han[num], scl_speed, H_size, V_size, &Scl_Cnt[num], news_sj_length[num], X0, Y0, news_font_buf[num], Scl_Buf[num]) ){
      Zen_or_Han[num] = SFR.Sjis_inc_FntRead(news_sj_txt[num], news_sj_length[num], &Fnt_Cnt[num], news_font_buf[num]);
    }
  }
  //ボタン操作の Task1 で、文字サイズダウンした場合、
  //LCDはVSPI接続でmicroSDと共用のため、同じループタスクで画面消去を行う。
  if( V_size_down == true ) {
    LCD.Display_Clear( 0, 0, 319, 4 * 48 - 1);
    V_size_down = false;
  }
}
//************ マルチタスクループ ****************************
void Task1(void *pvParameters) {
  while(1){
    button_action();
    delay(1); //most important
  }
}
//******** ニュース記事取得中、待機メッセージ表示*******
void Message(String str){
  uint8_t f_buf[ 40 ][ 16 ] = {};
  uint16_t len = SFR.StrDirect_ShinoFNT_readALL(str, f_buf);
  X0 = 1, Y0 = 4 * 48 + 1;
  LCD.Display_Clear(1, Y0 + 1, 318, 238);
  LCD.HVsizeUp_8x16_Font_DisplayOut(2, 2, len, X0, Y0 + 10, red, green, blue, f_buf);
}
//************** Yahoo RSS ニュースガジェット ************************
void YahooNewsGET(uint32_t get_interval){
  if( (News_first_get == true) || ((millis() - NewsGetLastTime) > get_interval) ){
    scl_pause = true;
    red = 31, green = 0, blue = 0;
    Message(" News Getting Wait");
    String news_str;
    uint8_t num = 0; //文字列番号
    num = 0;
    news_str = WebGet(yahoo_host, "/rss/topics/top-picks.xml");
    NewsStrFontConv( num, news_str );
    num = 1;
    news_str = WebGet(yahoo_host, "/rss/topics/sports.xml");
    NewsStrFontConv( num, news_str );
    num = 2;
    news_str = WebGet(yahoo_host, "/rss/topics/it.xml");
    NewsStrFontConv( num, news_str );
    num = 3;
    news_str = WebGet(yahoo_host, "/rss/topics/entertainment.xml");
    NewsStrFontConv( num, news_str );

    News_first_get = false;
    NewsGet = true;
    scl_pause = false;
    red = 0, green = 63, blue = 0;
    Message( " Get OK! " + String( hour() ) + ":" + String( minute() ) );
    NewsGetLastTime = millis();
  }
}
//**************************************
void NewsStrFontConv(uint8_t num, String news_str){
  Fnt_Cnt[num] = 0;
  news_sj_length[num] = SFR.UTF8toSJIS_convert(news_str, news_sj_txt[num]);
  Zen_or_Han[num] = SFR.Sjis_inc_FntRead(news_sj_txt[num], news_sj_length[num], &Fnt_Cnt[num], news_font_buf[num]);
  Serial.printf("news_sj_length[%d] = %d\r\n", num, news_sj_length[num]);
  Scl_Cnt[num] = 0;
}
//**************************************
String WebGet(const char *host, String target_url){
  char web_get_time[6];
  sprintf(web_get_time, "%02d:%02d", hour(), minute()); //ゼロを空白で埋める場合は%2dとする
  String news_str = "◆ " + String(web_get_time) + " ";
  news_str += _EWG.EWG_https_Web_Get(host, target_url, '\n', "</rss>", "<title>", "</title>", "◆ ");
  Serial.printf("News Get = %s\r\n", news_str.c_str());
  return news_str;
}
//****************************************
void button_action(){
  btn_stateA = BTN.Button(0, buttonA_GPIO, true, 10, 300);
  switch( btn_stateA ){
    case _MomentPress:
      Serial.println("Button A Moment Press");
      V_size--;
      if(V_size < 1) V_size = 1;
      Serial.printf("V_size =%d\r\n", V_size);
      V_size_down = true;
      break;
    case _ContPress:
      Serial.println("-------------Button A Cont Press");
      V_size++;
      if(V_size > 3) V_size = 3;
      Serial.printf("V_size =%d\r\n", V_size);
      break;
    default:
      break;
  }

  btn_stateB = BTN.Button(1, buttonB_GPIO, true, 10, 300);
  switch( btn_stateB ){
    case _MomentPress:
      Serial.println("Button B Moment Press");
      H_size--;
      if(H_size < 1) H_size = 1;
      Serial.printf("H_size =%d\r\n", H_size);
      break;
    case _ContPress:
      Serial.println("-------------Button B Cont Press");
      H_size++;
      if(H_size > 15) H_size = 15;
      Serial.printf("H_size =%d\r\n", H_size);
      break;
    default:
      break;
  }

  btn_stateC = BTN.Button(2, buttonC_GPIO, true, 10, 300);
  switch( btn_stateC ){
    case _MomentPress:
      Serial.println("Button C Moment Press");
      scl_speed++;
      if(scl_speed > 100) scl_speed = 100;
      Serial.printf("scl_speed =%d\r\n", scl_speed);
      break;
    case _ContPress:
      Serial.println("-------------Button C Cont Press");
      scl_speed--;
      if(scl_speed < 0) scl_speed = 0;
      Serial.printf("scl_speed =%d\r\n", scl_speed);
      break;
    default:
      break;
  }
}

【解説】

先ほども述べたように、1行目でインクルードしている、LCD ライブラリは今回バージョンアップし、micro SD カードと併用できるようにしました。
また、その他のライブラリもバージョンアップしていますので、最新版を使用してください。

このプログラムでは、分かりやすくするため、多くの変数をグローバル領域で宣言しています。
メモリを節約したい場合は、関数の引数に直接数値を入力してください。

●16行目:
M5Stack ドキュメントページによると、micro SD カード用の CS ( Chip Select )ピンは GPIO #4 となっています。
その他、SCK や MOSI , MISO 端子は共通 VSPI なので、LCD ILI9341 と同じです。

●18-19行目:
ここは、ご自分の Wi-Fi ルーターの SSID とパスワードに書き換えてください。

●21-23行目:
ここでは、micro SD カードの/font/フォルダに保存したフォントファイル名を指定しています。
半角フォントファイル名は、原本ファイルのファイル名の”r” 文字をカットして、拡張子以外を8文字で収めているので注意してください。

●25-28行目:
自作ライブラリのクラス名を定義しています。
26行目のESP32 の場合、micro SD カードの SPIモードクロック周波数は 24MHz が限界のはずですが、40MHz でも問題無く動作しましたので、ここで指定しています。

●31-42行目:
Yahoo! Japan RSS ニュース記事は、トップニューストピックス記事だけ取得しています。
それは半角300文字前後ですから、33行のように 400 文字と配列サイズを決めておきます。
ニュース記事は最大4記事まで取得できます。
それ以上はメモリオーバーになってしまい、再起動を繰り返してしまいます。
32行目の最大文字表示数は 1×1倍角の場合で指定しているので、倍率によって画面に表示する文字数が変わって来ます。
ここは自動計算するようにしていないので、とりあえず画面一杯に表示したい場合は40にしておきます。

また、前回記事でも述べましたが、36行目が一番メモリを食うところです。
ディスプレイの1pixel は 65Kカラーの場合、2byte 必要なので、これだけの配列を確保して文字表示をスクロールさせています。
他にいい方法が無いかいろいろ考えましたが、この方法しか思い浮かびませんでした。
ただ、1文字分スクロールする度に micro SD から読み込んだフォントを1文字分格納するための配列は35行目だけで済ませました。
ここからスクロールする配列へ代入していくので、前回よりは大幅に節約できたと思います。

●64-66行:
M5Stack のボタン設定です。
以下の記事を参照してください。
M5Stack ボタンスイッチの、チャタリング、誤作動防止、感度調整、長押し設定を考えてみる

●70行目:
ここが重要です。
micro SD カードと LCD ディスプレイ ILI9341 を切り替えて駆動するためには、ハードウェア CS が使えません。
そこで、初期設定で false にして解除して、ライブラリ内で digitalWrite 関数を使って CS ピンを切り替えています。
そして、ILI9341 は本来 10MHz が限界周波数ですが、40MHz でも動作することが分かりましたので、そうしています。
ただ、これは動作保証外ですが、超高速です。

●74-100行:
ここでは文字列を固定表示しています。
85行目の関数で、String文字列から一気に micro SD カードのフォントを読み込んで変換する関数です。

●114-121行:
スクロールする文字列を事前に設定する関数です。

●123行:
ESP32 のヒープメモリがどこまで圧迫されているかをシリアルモニタで確認しています。

●125-126行:
文字スクロールをスムースにさせるためにマルチタスクを実行させます。
その為のハンドル定義と初期化です。
ボタン操作だけをTask1 で動作させ、CPU コアは 0 です。
メインループはコア 1 です。
マルチタスクについては以下の記事を参照してください。
Arduino – ESP32 のマルチタスク ( Dual Core ) を試す

●130-144行:
メインループ内で、Web記事Get とディスプレイ文字スクロールをさせています。
先ほども述べたように、M5Stack の LCD とフォント読み込みが別タスクのマルチタスクでできなかったので、同じループ内で動作させています。
記事取得中はスクロールが停止します。

また、135行で文字をスクロールしていき、1文字スクロールし切ったら true を返し、136行目でフォントを1文字読み込むようにしています。
全角の場合 2 を返し、半角の場合 1 を返します。

141-144行では、ボタン操作で、垂直方向サイズダウンしたらディスプレイを消去していますが、ボタン操作が Task1 なので、これも Task1 で実行すれば良いと思ってしまいがちです。
しかし、そうしてしまうと、画面がフリーズしたり、変なノイズが出たりします。
要するに、LCD 制御は同じタスク内でやらないとうまくいかないということです。

●162-189行:
ニューストピックス記事を変えたい場合はここの URL を変えてください。
ただし、トックストップ以外の記事は、文字数が多く、ハングアップしてしまいますので、ご注意ください。

ちょっと長く説明し過ぎて疲労困ぱいしてしまいました。
あとは省略させていただきます。
過去の記事を参照してください。

では、次のページでは SPIFFS 用スケッチについて紹介します。

コメント

  1. あいむ より:

    2つのスケッチ(SPIFFSとSD-Card)が、問題なく動作したので報告します。M5Stack用のソフトは、ハードを配線しなくて良いので楽ですよね。

    SD-Cardの方は、私のパソコンにはESP32_SD_ShinonomeFNTとESP32_SD_UTF8toSJISの2つのライブラリーが入っていないのでエラーが出ましたが、検索して見つけたページからダウンロードしたものを使いました。また、最初SD-Cardにフォントファイル(fontフォルダー)をコピーしなかったので、何も表示されませんでしたので、ちゃんとSD-Cardを入れたら動きました。

    例のごとく、このブログ内容とソースコード+ライブラリーはまだ全然読んでいないので、またM5Stackをいじるときにじっくりみてきます。現在頭が本業のiPhoneソフトの開発モードなので。

    • mgo-tec mgo-tec より:

      あいむさん

      いつも動作確認報告ありがとうございます。
      m(_ _)m
      一応、記事中に ESP32_SD_UTF8toSJIS と ESP32_SD_ShinonomeFNTライブラリ は別記事を参照してインストールするように促していましたが、やっぱり長い文章なのでスルーされてしまうかもしれませんね。
      私自身もそうですが、やっぱりユーザー目線で見ると、パッと見て分かる方が良いのかもしれません。
      いろいろ考え直してみます。

      ソースコードを見られるのは、突っ込まれる要素満載なので、iPhone ソフト開発されている方々に見られるのは辛いものがあります。
      何か気付いたことがあればコメント頂けると助かります。
      iPhoneソフト開発がんばってください。

  2. マッキー より:

    こんにちわ

    さっそく動作確認させていただきました。
    とりあえずご報告まで

    • mgo-tec mgo-tec より:

      マッキーさん

      いつもご報告感謝いたします。
      動いてくれるとウレシイですね。
      ありがとうございます。

  3. H.W より:

    mgo−techさん、H.Wです。

    以下の報告、上手くUP出来なかった様ですので再度UPさせて頂きます。

    1.Yahoo!ニュース4行記事同時スクロールの件
    1)画面最下部の「Get OK!」以降の時分表示ですが、一桁の時に直前に’0’が挿入されないので、表示に多少違和感があります。
    →シリアルモニターの表示と同様に、#186行を以下のように書き換えられた方がよいのではないでしょうか?
    #186 : Message( ” Get OK! ” + String(web_get_time ) );
    (その前に以下の宣言文を2行追加)
    char web_get_time[6];
    sprintf(web_get_time, “%02d:%02d”, hour(), minute()); //ゼロを空白で埋める場合は%2dとする

    2)タクトSWの’C’を短押し&長押ししてもスクロール速度が殆ど変化しない。
    →SWITCH文内の#250行のインクリメント文と#256行のディクリメント文が逆になっていないでしょうか?

    2.その他の件
    1)当初から、どのスケッチのFlash時にも、’connection …—…—…—’が永遠に続いて書き込みができませんでした。
    →EN端子とGND端子間にコンデンサ(0.22~2.2μF)を入れる対処Tipsが出されており、取り合えず手元にあった1.5μFのフィルムコンを挿入すると書き込みができるようになりました。(再現性あり…)
    この対応策は妥当でしょうか? それともM5stackのロットによるものなのでしょうか?

    尚、本体側にチップセラミックコンを実装対応されてる方もおられるようですが、 mgo-techさん含めて他の方々はどうされてるのでしょうか?

    以上、宜しくご検討お願い致します。

    • mgo-tec mgo-tec より:

      H.Wさん

      いつも当ブログをご覧いただき、ありがとうございます。

      まず、回答です。
      1-1) の件は把握しておりましたが、これは要は私の手抜きです。
      メッセージの受信時間さえ把握できれば良いだけのメッセージなので、あまり表示はこだわりませんでした。
      確かに、シリアルモニターにはちゃんと出力しているんだったら、こちらの方をちゃんとやれば良いのにというお話ですね。
      私もそう思いましたので、早速直しました。
      今後のスケッチも所々手抜きがありますが、その辺は個人ブログなので何卒ご容赦ください。

      1-2) スクロール速度あまり目立った変化はありませんが、確実に変化していると思います。
      瞬時押しが減速、長押しが加速ですので、スケッチは問題ないと思います。
      ただ、scl_speed は増加で減速、減少で加速という値になっています。
      実は、これは、scrolle interval 値に名前を変えた方が良かったかもしれません。
      これは変数名が良くありませんね。
      趣味独学だと、こういうところが適当でスミマセン。
      今後新たにプログラムを組む時には気を付けたいと思います。
      因みに、記事を4つもスクロールさせると、速度は遅いのであまり変化しないと思います。
      それよりも、文字サイズを変えた方がスクロール速度は劇的に変わりますね。
      それはブログ記事にも書いてある通り、あまり意味がない操作ボタンとなってしまいました。
      その辺は販売品のように作り込んでいないので、あとは皆さんで改良していっていただければと思います。

      2-1) は SPIFFS データではなく、スケッチを M5stack に書き込むという認識でお話します。
      1~2年前の ESP32 ( ESP-WROOM-32 )関連開発ボードは、ESP32 の Revision が 0 が殆どでした。
      その場合は、USBシリアルの書き込みバグが Espressif 公式でも発表されました。
      そこで、EN端子にコンデンサを追加するという方法が有効だったのですが、Arduino core for the ESP32 のソフトウェア上でかなり改善され、Rev 0 でも特に問題無く書き込みできるようになりました。
      M5stack は殆ど Rev 1 なので、改善された ESP32 が使われているはずですので、あまり書き込みできないという情報は私は聞いておりません。
      Mac の場合は、USBドライバをまずインストールしなければうまくいかないようです。
      Windows 10 の場合は接続した時点で自動的にドライバインストールされます。
      もし、気になるようでしたら、Facebook のESP8266/ESP32環境向上委員会に質問してみてはいかがでしょうか?
      そちらの方がプロフェッショナルが沢山いらっしゃるので、確実な情報が得られると思います。

      別件ですが、Wi-Fi が接続できない問題は一つ原因が見つかりました。
      私のESP32_WebGetライブラリの EWG_AP_Connect 関数内に、Serial.begin(115200); があり、Serial.beginが二重使用されていたことが原因でした。
      これについさっき気付きました。
      随分昔にこの症状に気付いていたのですが、しばらくこの関数を使うブランクがありすぎて、思い出すのに時間がかかりました。
      まだ完全解決ではないのですが、これも一つの原因です。
      大変失礼しました。
      m(_ _)m

  4. H.W より:

    mgo-techさん、H.Wです。
    ご多忙中、余計なお世話に早速対応して頂き有難うございます。
    時間表示の前の’0’はなくてもよいかと思いますが、分表示の前にはやはり’0’挿入があった方がよい様に思いましたので、敢えて提案させて頂きました。

    スクロールの件については、シリアルモニターを見ながら、数値が増えた方が速度が増すものと勝手に思い込んでいたものですから、的外れな指摘となってしまい大変失礼致しました。

    また、m5stack(というかESP32)のスケッチ書き込み時の不具合対応経緯についてご説明頂き有難うございます。
    ということは、現時点では本来EN端子とリセット端子間にコンデンサー等を追加しなくてもよい仕様に改善されている筈なんですね?
    (確かに、この商品の’開発システム’という性格があるとは言え、ユーザ側で前記の様な対応をしなければならない様では多少問題ですものね?)
    何れにしても、購入したスイッチサイエンスさんに先ずその旨問い合せしてみようと思います。
    ご教示有難うございました。

    • mgo-tec mgo-tec より:

      H.Wさん

      いろいろご指摘ありがとうございます。
      何かと手抜きが多いかと思いますが、今後とも気楽に作っていきたいと思いますので、どうかご容赦くださいませ。

      M5stackについては、確かに正規代理店のスイッチサイエンスさんにお問い合わせするのが一番良いと思いますね。
      原因が判明するといいですね。

タイトルとURLをコピーしました