【STA22】F9P+F9H+M9N同時受信テストPgm<Teensy4.1凄く便利>

STA22システム 配線しました。左右で仕様が違うのですが、今回は、M9Nで補間するIPsystem用の配線と3個のGNSSボードからの同時受信試運転まで確認できました。
MovingBaseシステム等複数個のGNSSボードを使うシステムを開発される方は、
マイコンにTeensy4.1を採用することをお勧めします。
開発効率と将来性でESP32系、M5Stack系より断然有利です。
※2023年2月 このシステムを更にコンパクトにしてFusion IMU BNO055を追加して成果がでました。
スキーターンの測定実験に成功しました。シリアルポート4個、I2C1個、SPI1個でRTKとMovingabaseとIMUとSDログとBlueTooth送受信するシステムをコンパクトにして、スキー装備に装着してデータログできました。データもFusion IMU BNO055とRTKの高精度データの同期がぴったり合って、スキー操作とターンの挙動が定量的に観察できるようになりました。
カテゴリ STA23をご覧ください。 http://shinshu-makers.net/shinshu_makers/?s=STA23

●配線
3個のGNSSボード(F9P、F9H,M9N)、IMU、BlueToothSPPの5か所からマイコンTeensy4.1に
データをログ、無線送信させるシステムです。
足に実装するので、新しい試みを検討中です。3個のBOXとバッテリーをどうやって格納取付るかが、STA22の最難関課題です。

■STA21から新しくなった点
新規1:M5シリーズからTeensy4.1に変更して、性能を桁違いにアップさせてプログラムが作りやすくなりました。             <プログラム生産性は桁違いに向上しました。中国と欧米のIT技術の差を感じた>
新規2:Uart1をPixhawkコネクタで通信するようにしました。<コンパクトと半田個所減少しました>
新規3:M9N補間機能をいれました。<未確認ですが高速ターン時の精度補間できるはずです>
新規4:IMUで足の姿勢角度を計測します。<スキー板の角付け角が重要なので、ブーツにIMUを取り付けます>

 

●3GNSSボード同時受信テストプログラム
https://gist.github.com/dj1711572002/f0977877d8b2ad03b86ea74075926433
Teensy4.1のハードウェアシリアルを使ってるので、バッファが指定値までになるまで、CPUは、仕事をしないですむので、周期が何種類も違うデバイスでも、読み込みは一瞬1msec以内で完了します。
①ハードウェアシリアルのグローバルでの設定
メモリーにバッファを割り付けるので、下記宣言をsetup()の上のグローバル領域に書き込みます。
staticで宣言して、メモリー上に固定します。バッファなので、32ビットの倍数で宣言します。
F9PのMovingBaseのubx出力は、NAV-PVT(100byte)+NAV-RELPOSNED(72byte)=172byteなので、192byteで宣言
M9Nの出力は、NAV-PVT(100byte)だけなので、128byteで宣言します。
バッファからデータ配列へ格納するので、データ配列を宣言します。
※配列サイズは、データサイズそのものでいいです。バッファは、大き目ですが、読み取り時にバッファがデータサイズになった瞬間にデータサイズだけ読み取りますので、バッファがフルになることがありません。

//—-Hardware Serial Set—————
//受信データ配列宣言
static uint8_t dBuf0[172], dBuf4[172],dBuf5[100];//バッファなので32の倍数でないといけない
//32の倍数でバッファ配列宣言
static uint8_t serialbuffer1[192];//Base PVT+RELPOS172bytes
static uint8_t serialbuffer2[256];//BlueTooth
static uint8_t serialbuffer4[192];//Rover PVT+RELPOS172bytes
static uint8_t serialbuffer5[128];//M9N PVT100bytes

②setup()内で、HardwareSerial用バッファの設定を行います。
Teensy独自の命令 Serial.addMemoryForRead(buffer,size)でハードウェアシリアル用のバッファサイズが設定できます。普通のマイコンだとバッファは、32バイトとか64バイト固定なので、大きなデータセット受信だと満杯になるにで、中途半端な読み込み動作をプログラムにいれないといけませんので、大変面倒なことになります。
Teensyだと、データ数より大きいバッファを指定できるので、1回の読み込み動作で完了するのでプログラムが簡単で、速くなります。

setup() {

//Serial1 def Base
Serial1.begin(115200);//RX1(p0)-TX1(p1) PVT+RELPOS from Base UART2 rcv=ubx ,tx=RTCM3
Serial1.addMemoryForRead(serialbuffer1, sizeof(serialbuffer1));
//Serial2 def Bluetooth
Serial2.begin(115200);//Rx2(p7)-Tx2(p8) from BlueTooth
Serial2.addMemoryForRead(serialbuffer2, sizeof(serialbuffer2));
//Serial4 def Rover
Serial4.begin(115200);//Rx4(p16)-Tx4(p17) PVT+RELPOS from RoverF9P uart1
Serial4.addMemoryForRead(serialbuffer4, sizeof(serialbuffer4));
//Serial5 def m9N
Serial5.begin(115200);//Rx5(p21)-Tx5(p20) PVT from M9N uart1
Serial5.addMemoryForRead(serialbuffer5, sizeof(serialbuffer5));

}

 

③読み込み動作部分

void loop() {
//===Serial1Base dataread=================

 if(Serial1.available()>171){ //バッファ1が172バイトになるまで処理しない
  i=0;
  while(i<172){ //Serial1バッファ空になるまで一挙に読み込む
                   digitalWrite(ledPin, HIGH); // set the LED on
Serial.printf(“Base:%d,”,millis());
     while(Serial1.available()){  //SerialPortアイドル時に読む
                        dBuf0[i]=Serial1.read();//read from serialbuffer1[]
                         i++;
                   }
Serial.println(millis());
digitalWrite(ledPin, LOW); // set the LED on
   }

//===Serial4 Rover read=================
if(Serial4.available()>171){ //バッファ4が172バイトになるまで処理しない
   j=0;
           while(j<172){ //Serial4バッファ空になるまで一挙に読み込む
digitalWrite(ledPin, HIGH); // set the LED on
Serial.printf(“Rover:%d,”,millis());
                    while(Serial4.available()){ //SerialPortアイドル時に読む
                                dBuf4[j]=Serial4.read();
         j++;
                     }
           }
Serial.println(millis());
digitalWrite(ledPin, LOW); // set the LED on
}

//===Serial5 M9N read================================

 if(Serial5.available()>99){ //バッファ5が100バイトになるまで処理しない
   k=0;
   while(k<100){
digitalWrite(ledPin, HIGH); // set the LED on
Serial.printf(“M9N:%d,”,millis());
while(Serial5.available()){
        dBuf5[k]=Serial5.read();
        k++;
       }
    }   
Serial.println(millis());
digitalWrite(ledPin, LOW); // set the LED on
 }//if end

}//loop end

●動作結果
上記プログラムを動作させた結果
Base=>M9N=>M9N=>Rover=>M9Nの順序で受信できてました。
数値は、処理に入った時刻と処理を終了した時刻のmillis()です。
順序は、場合によって、ずれますが、周期120msecでBase1回、Rover1回、M9N3回入っていればOKです。しかし、GNSデータとしては、itow値でチェックが必要なので、次回からitowでのチェック機能をいれて、SDログとBluetooth通信に渡します。

 

●以降
SDログとIMU測定機能いれます。カルマンフィルターを回しながら、全LOOPデータ落ちなくできるかどうかポイントとなります。

コメントを残す

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