【RTK22】超高速マイコンCortex-M7搭載Teensy4.1いじる その5<HardwareSerial 超便利>

 

Teensy4.1使い初めて半年経過して、もう、ESP32,M5Stackには、戻れなくなりました。
★Teensyいじるシリーズ
その1(導入とSD速度) その2(USBHOST初め) その3(USBHOST3ポート)
その4(USBHOST事例) その5(ハードウェアシリアル便利)

理由1:コンパイル速度が桁違いに速い(M5系は数分かかるが、teensy4.1は、数十秒以内)
理由2:多センサ、ばらばらな周期データを複数ファイルでSD記録が高速で可能
理由3:USB HOSTが使えるので、USB出力の複数デバイスのデータを受信ログできる。
理由4:ハードウェアシリアルが超便利です。CPUとは独立に動作しているので、バッファサイズを大きめに32の倍数に設定しておけば、所望量までため込んでくれるので、その間他の仕事ができるので、ハードウェアシリアルを使うことでリアルタイム処理プログラムが作り易くなります。しかもハードウエアシリアルが8ポートもあるので鬼に金棒です。
(バッファサイズは指定しなければ64バイトですが、1周期で受信するサイズが多い場合は大き目に指定したほうが読み込み処理が一瞬で済むようになります、遅いデバイスを複数接続する場合など非常に便利です)
※私の場合、RTK GPSチップを2-3個接続で1周期でそれぞれ数百から1Kバイトくらいのデータを受信して変換処理して複数FILEをSD記録して、モニターに無線送信しなければいけないので、衛星電波の受信状態で出力タイミングがばらつくGPSチップのお相手をハードウェアシリアルにお任せして他の仕事ができるので、超便利です、Teensyのハードウェアシリアルがなければ、システムが作れなかったです。昨年まで使っていたESP32,M5Stack系では逆立ちしてもできないシステムです。

 

■Teensyのシリアル解説ページ

https://www.pjrc.com/teensy/td_uart.html

独自の命令が用意されてます。ボーレートとCPU別のデータロス率の表もあって至れり尽くせりです。


Serial1.addMemoryForRead(buffer,size) が凄く便利です。

Serial1.addMemoryForRead(buffer, size)

Increase the amount of buffer memory between reception of bytes by the serial hardware and the available() and read() functions. This is useful when your program must spend lengthy times performing other work, like writing to a SD card, before it can return to reading the incoming serial data.

The buffer array must be a global or static variable.

この命令は、計測1周期で送信されてくるデータバイト数が一定数の場合に便利です。
=>計測1周期分のデータのバッファがたまるまで受信しないので、相手のデバイスの通信遅延をプログラムに持ち込まずに済みます。
バッファが規定数になったときに一挙に読み込むので、プログラムは1msec以内にデータを取得できるので、他の機能ブロックの負担になりません。マルチタスクでシリアル受信しているESP32の場合、裏で動いているので、プログラム全体に影響がでる場合があって、
複数のシリアル受信でこける場合が多いです。

●addMemoryForReadの使い方

・計測周期が違う2ポート受信の例
Serial1が172バイトSerial2が100バイトを受信する場合、
バッファなので32の倍数で大きめに決めてSerial1は192バイトとSerial2は128バイトに設定します。

大きめでも、所定数までif文で待って、読み込めば一瞬で読み込み完了できます。

Teensyでハードウェアシリアルのバッファサイズを指定するのは、setup()内で行います。
解説ページは、https://www.pjrc.com/teensy/td_uart.html 
命令文は、これだけです。bufferは、クラス直下でグローバル変数として static uint8_t buffer[size];であらかじめ宣言しておきます。
//===============Teensyの場合のシリアル受信Pgmサンプル==============
//クラス直下でグローバル変数としてバッファ変数配列を宣言しておきます。
static uint8_t   s1bufsize[192];//Bufferとして使うメモリー配列大きめに設定32の倍数
static uint8_t   s2bufsize[128];//Bufferとして使うメモリー配列 大きめに設定32の倍数

static uint8_t  dbuf1[172]; //読み込んだデータ格納配列
static uint8_t dbuf2[100];//読み込んだデータ格納配列
int  size1=172;
int  size2=100;


void setup(){

—————–
Serial1.begin(115200);
Serial1.addMemoryForRead(s1bufsize, 192);//Serial1バッファサイズ設定
Serial2.addMemoryForRead(s2bufsize, 128);//Serial2バッファサイズ設定

—————–
}// setup end

void loop(){
—————

if(Serial1.available()>171){     //172bytになったら読み込む
i=0;
    while(i<172){
         dbuf1[i]=Serial1.read();
i++;
}

}//Serial1終了:1msec以内で済んでしまいます。size=172の場合

if(Serial2.available()>99){     //100byteになったら読み込む
i=0;
    while(i<100){
         dbuf2[i]=Serial2.read();
i++;
}

}//Serial2終了:1msec以内で済んでしまいます。size=100の場合

}// loop end
//======================================================

●addMemoryForReadに感謝
2個のGPSから周期が100msec,40msecのデータが入ってきて、1周期終了後に、受信データをソートして
コードを変換して、SDファイルに書き込んで、Bluetoothにモニターデータを送信する作業を
毎周期40msec以内に行うプログラムの場合、GPSがたらたらと不規則にデータを送ってくるので、
プログラムで待っていると、プログラムは、後処理ができなくなってしまいました。
対策として、addMemoryForReadで設定すると、プログラム上では、シリアル受信は1msec以内しか
食わないので、シリアル受信部分は、時間浪費してなくなるので、他の処理部分に時間をさけるので
プログラム全体の機能向上に大きく貢献してくれる命令でした。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です