Vol.940 10.Apr.2026

関数電卓 M5A)_シリアル(ターミナル)入出力

F 関数電卓 〜fx-JP900CW-N

by fjk

 今更と思うが、16進数の計算用として関数電卓のfx-JP900CW-N(カシオ、@4.427)を購入した。
 マイコンのアドレス計算をExcelでn進数の変換や計算をしているが、その都度Excelを起動せねばならず面倒である。また、n進数の計算ができる古い電卓を持ってはいるが、「10進数に変換」→「計算」→「16進数に変換」など計算手順が複雑である。
 CLASSWiZシリーズはJP500/700/900と3機種があり、n進数の計算はどの機種でも可能で、数値の前に基数を付けて入力できるので、基数が異なる数値が混在していても簡単に計算できる。JP900CWは旧機種より、「OK」キーの採用や「数式通り入力」などユーザーインターフェース(UI)が大幅に変更され、さらにMathBoxや真偽判定機能が追加された。
 旧機種のfx-JP900やfx-375ES Aなら、A-F入力はワンタッチボタンなので、n進数計算に絞るなら旧機種の方が良いかな(で、fx-375ES A[@2,222]も入手)。
 なお、プログラムやカラーグラフ表示もできるfx-CG100-Nもあるが、価格が2万円を超えており、グラフ表示は必要ないので今回はパスした。


fx-JP900CW-N
 
CWシリーズ
 
fx-375ES A

【計算例】
 @アドレス0x1FDから20×8バイト後のアドレス(n進数計算)
     
 A8:00から1230秒後の時刻(度分秒計算)
     
 B3/4インチをセンチに(単位換算)
     


M M5_Atomシリーズ(6) 〜シリアル(ターミナル)入出力

by fjk

 M5AtomS3からターミナルなどにシリアル通信(送信)を行うことはSerial.print()関数などで簡単に行えるが、ターミナルからM5AtomS3にシリアル通信(受信)を行ってみた。
ARDUINO DOCSのページを参考に、以下の2つの関数の例(Example)を使ってみた。[Board:M5Stack AtomS3、Libraries:M5Unified]


	Serial.readStringUntil(終端文字);

	Serial.readBytesUntill(終端文字、格納文字列、読込バイト数)

 すると、どちらの関数もデータを文字列として受信できず、1文字ずつ改行付で受信された。これは、タイムアウト時間をオリジナルより短く(10mS)したので、キー入力が間に合っていないことが原因で、タイムアウト時間をオリジナルの1000mS(で、キー入力間隔が1秒以内)にすれば、チャンと文字列データを取得でき、上記の関数は問題なく使える。
 そこで、キー入力間隔の時間制限をなくすため、「文字列シリアル受信関数」 int getSerialLine();  を作製した。
 この関数は「改行(\n)」を受信するまでは、受信バッファー(rBf)にデータを順に格納し続け、その間は0を返す。「改行」を受信したら受信文字数を返す(オーバランエラーには注意)。入力文字はターミナルにリアルタイムでエコーバックされ、バックスペース(BS)で受信データの最後尾の1文字を消せます。


1文字ずつ改行(?)

getSerialLine() を使うと

PlatformIo.ini

AtomS3_Serial.cpp(zip)

/***************************************************************
 *      M5AtomS3_Serial Test
 ***************************************************************/
#include <M5Unified.h>                  // M5Unifiedライブラリー使用

#difine BFSIZE 20                       // サイズ超データは受信しない 

// 初期設定 -------------------------------------------
void setup() {
  auto cfg = M5.config();               // 本体初期設定
  M5.begin(cfg);
  Serial.begin(115200);                 // シリアル通信初期化
  Serial.setTimeout(10);                // 受信タイムアウト時間(10ms)
  // 液晶表示内容設定
  M5.Lcd.init();
  M5.Lcd.setTextWrap(true);             // テキストの折り返し有り
  M5.Lcd.setRotation(0);                // 画面向き
//   M5.Lcd.clear(M5.Lcd.color565(20, 0, 0));  // 背景色
  M5.Lcd.setTextColor(TFT_WHITE);       // 文字色
  M5.Lcd.fillScreen(0);                 // 表示クリア
  M5.Lcd.setTextFont(4);                // フォントサイズ
  M5.Lcd.setCursor(0, 0);               // 表示開始位置左上角(X,Y)
  M5.Lcd.println("Hellow!");
  Serial.println("ATOM S3 Serial Test"); // シリアル出力
}

// グローバル変数--------------------------------
char rBf[BFSIZE];                       // シリアル受信データバッファ

// 文字列シリアル受信 ---------------------------
int getSerialLine() {                   // シリアル文字列取得
  static int  rPt = 0;                  // 受信データポインタ

  if (Serial.available()) {
    char ch = Serial.read();            // 1文字受信取得
    if (ch == '\n'){                    // CR?
      rBf[rPt] = '\0';                  // 文字列終端文字セット
      int i = rPt;
      rPt = 0;
      Serial.print('\n');
      return i;
    }else if((ch == '\b')&&(rPt > 0)){  // BS?
      Serial.print('\b');
      rPt--;
    } else{
      if(rPt < BFSIZE−1){              // バッファサイズ以内なら
        rBf[rPt++] = ch;                // 文字列に追加
        Serial.print(ch);
      }
    }
  }
  return 0;
}

//  メインループ処理 ---------------------------
void loop() {
 
  if(getSerialLine()){                  // 受信文字列があれば
    if(rBf[0]=='!'){                    // 文字列の先頭が'!'なら
      M5.Lcd.fillScreen(0);             // 表示クリア    
      M5.Lcd.setCursor(0, 0);           // 表示開始位置左上角(X,Y)
    }else{
    	M5.Lcd.println(rBf);
    }
  }
  
/*-------- ARDUINO DOC の Exsample 使用例 -------
//---- readStringUntil -----
  if(Serial.available()){               // .setTimeout(1000);に
    String str = Serial.readStringUntil('\n'); // \n付
    Serial.println(str);
    M5.Lcd.println(str);
  }
//---- readBytesUntil------ 
  if(Serial.available()){                // .setTimeout(1000);に
    int rb = Serial.readBytesUntil('\n',rBf,19);
    rBf[rb]='\0';
    Serial.println(rBf);
    M5.Lcd.println(rBf);
  }
*/
}


【おまけ】
 前述のシリアル受信関数で、改行コードとして「\r\n」を受信すると、「\r」が受信文字列の中に残ってしまい、以後のstrlen関数で正しい文字数が得られない場合がある。
 そこで、以下のように、if文で「\r」の処理もすると、strlen関数で正しい文字数が得られる。

    if ((ch == '\n')|(ch == '\r')){

 上記の例は、改行コードが「\r」のみでも対応できるが、「\r\n」で改行が2回認識されることが困る場合は、以下の記述を、elseの前に追加。

    }else if(ch == '\r'){
        RcvBf[rPt] = '\0';


※プログラムのリストをハイライト付きのスタイルで見る場合はここをクリック


※ 本レポートの参考・利用は、あくまでも自己責任でお願いします。


関数電卓 M5A)_シリアル(ターミナル)入出力