エアガン測定

エアガンに関する色々を測定しています http://www.eonet.ne.jp/~daisaku-tech/index.html

弾速計試作その2:エアガン機能拡張

銃に取り付けるタイプの弾速計試作その2を作成しました。初速だけでなく、次の4つのデータを表示します。

  • 発射弾数
  • 初速(m/s)
  • ターゲットまでの距離(m)
  • 銃口の方位(deg)


エアガン機能拡張器試作

 

初速を測定するための赤外線センサーは、ホントはサイレンサーに埋め込んできれいな見た目にしたかったのですが、とりあえずプラスチックのパイプに取り付けてあります。基板や部品の配置をきれいにしてケースに収めたかったのもありますが、試作ってことでむき出しのままです。

 

制御に使用しているマイコンはBlue Pill(STM32F103)で、2つ使用しています。ソフトウェアを手抜きしたので、一つは初速の測定専用で、もう一つで距離・方位の測定や液晶ディスプレイへの表示を行っています。

 

使用している銃は、WE SCAR-L(ガスブローバック)です。本体を上面のレールに取り付けているため、この状態ではサイトでねらえない状態です。透明なヘッドアップディスプレイにしたいところですが、無機ELとかはかなり高額なため手が出せず。

 

サイドレールに取り付けられるようにすればよかったですね。

Blue Pill/STM32duinoで電子コンパスHMC5883Lを動かす

Blue Pill+Arduino_STM32(Roger Clark氏作成版stm32duino環境)

Arduino_STM32(Roger Clark氏作成版)環境のBlue Pillでは、電子コンパスHMC5883Lが動作しません。

2019/03/17時点のmaster

https://github.com/rogerclarkmelbourne/Arduino_STM32

 

注:Arduino_STM32のWebサイトは http://www.stm32duino.com/ となっていますが、 https://github.com/stm32duino とは別物です。

 

このArduino_STM32環境で電子コンパスHMC5883L用ライブラリを使用し、スケッチ例のQMC5883_compassをビルドして実行すると、電子コンパスを動かしても値が変化しません。

2017/12/04コミット版

https://github.com/DFRobot/DFRobot_QMC5883

 

注:ライブラリ名はQMC5883ですが、HMC5883L/QMC5883両対応となっています。

 

このライブラリの、次の2行を削除すると動作します(HMC5883Lのみ)。

DFRobot_QMC5883/DFRobot_QMC5883.cpp:482 行目 DFRobot_QMC5883::readRegister16()

 Wire.beginTransmission(HMC5883L_ADDRESS); ←削除
 Wire.requestFrom(HMC5883L_ADDRESS, 2);
 while(!Wire.available()) {};
 #if ARDUINO >= 100
  uint8_t vha = Wire.read();
  uint8_t vla = Wire.read();
 #else
  uint8_t vha = Wire.receive();
  uint8_t vla = Wire.receive();
 #endif
 Wire.endTransmission(); ←削除

QMC5883では未確認です。

原因:Data Outputレジスタread後に不要なwriteがあるため

直接の原因は、HMC5883Lレジスタのoffset+03~+08のData OutputレジスタX/Y/Zの2バイトずつに対して、それぞれをI2Cでreadしたあと、そのreadした同じ値を2バイトwriteしてしまうことです。

 

理由は不明ですが、上記readRegister16()内でWire.write(reg)でreadするアドレスを指定した後、Wire.read()する際にWire.beginTransmission/endTransmisstionで囲んであるとreadした値をそのままwriteします。

f:id:daisaku_tech:20190318214727p:plain

BluePillの場合

Wire.requestFrom()/Wire.read()するだけならWire.beginTransmission/endTransmissionで囲む必要はないように思えます。

 

ただし、ArduinoUNOでは、上記の2行を削除しなくても正常に動作します。ArduinoUNOの場合は、Data Outputレジスタread後、I2Cのwriteでデータなし(I2CスレーブアドレスとR/Wビットのみ)の状態となり、おかしな値をwriteしないためです。正常に動作するといっても、このように不要なwrite(データなし)が行われます。

f:id:daisaku_tech:20190318214813p:plain

ArduinoUNOの場合

推測ですが、Blue Pillで動作しない原因は次の2つの組み合わせで発生しているように思えます。

  • DFRobot_QMC5883::readRegister16()内の不要なWirte.beginTransmission/endTransmission実行。
  • Arduino_STM32のWire(I2C)ライブラリの不具合。

 

BluePillでLIDAR-Lite v3

BluePillで、レーザー距離センサのLIDAR-Lite v3動作しました。

www.switch-science.com

BluePillはArduino互換環境で、LIDAR-Lite Arduino Libraryがそのままビルドでき、サンプルのGetDistanceI2cが動作しました。ライブラリにもサンプルスケッチにも、何も手を加えずそのまま。

github.com

ただし、BluePillは3.3V、LIDAR-Liteは5Vなので、レベル変換は必要。

メーカーは680μFのキャパシタを推奨していますが、SparkfunのHookup Guideに記載されているように、1000μFのものを使用しました。

f:id:daisaku_tech:20190204220927j:plain

BluePillとLIDAR-Lite_v3を接続

 

電子コンパス比較

電子コンパスのHMC5883LとQMC5883Lの精度を比較してみました。

起動後、8の字を描くようにグネグネさせた後、南方向に向けて水平にし、そのままにしておいた時の方位を取得しました。

HMC5883Lが安定して183.5度前後で推移しているのに対し、QMC5883Lは185~191度ぐらいとかなり揺れています。

f:id:daisaku_tech:20190114192439p:plain

HMC5883LとQMC5883の比較

使用したセンサーはそれぞれ次の通り。

・GY-271 QMC5883L 3軸磁気センサー 磁場センサー 電子 デジタル コンパス モジュール 地磁気センサー

www.amazon.co.jp

・3軸磁気電子コンパス&気圧センサーモジュールSEN315-652-16WI

eleshop.jp

Arduino UNOに接続し、ライブラリとして次のものを使用しました。

github.com

Arduino UNOとBlue PillのLCD描画速度

コントローラとしてILI9341が使用されているLCDの描画速度を比較しました。一つはArduino UNOで、もう一つはBlue Pill(STM32F103)です。

youtu.be

Adafruitライブラリに含まれるスケッチ例、graphictestを実行しています。Blue Pillの場合も同様です。

Blue Pillの方が高性能であるため、それがそのまま描画速度に反映されています。

BluePillはUSB不具合対策しなくてもスケッチ書き込みできるものがある

BluePill(STM32F103ボード)にはUSB関連で不具合があります。R10抵抗値が間違っており、1.5KΩであるべきところが、10KΩまたは4.7KΩが実装されています。そのため、USB接続でArduino IDEからスケッチを書き込もうとすると、エラーになって書き込めません。対策は次のいずれかになります。

  • R10を1.5KΩに取り換える
  • 3.3VとPA12間に1.8KΩの抵抗を接続してプルアップ

が、同じBluePillでも、シルクやリセットスイッチなどが異なるものが存在し、R10が10KΩのまま、不具合対策なしでもスケッチ書き込みできるものがありました。ただし、私の環境でたまたま書き込めただけ、という可能性があり、必ず同じ状態とは限りません。

f:id:daisaku_tech:20180912184400p:plain

Amazon.co.jpでSTM32F103を検索すると、複数のメーカーのものがヒットします。HiLetgoの2個セットのものと、Homylのものを2個、USB不具合がないBlackPillも2個購入しました。

HiLetgoのものは2個とも、不具合対策なしではスケッチ書き込みできませんでした。それに対してHomylのものは2個とも、不具合対策なしでスケッチ書き込みできました。

 

Blue Pill(STM32duino)のanalogRead実行時間は約7μs

STM32duino環境のBlue Pillボード(STM32F103)によるanalogRead実行速度は約7μsです。次のsketchで実行時間を見てみました。

int val[10];
unsigned long startTime;
unsigned long endTime;

void setup() {
  pinMode(PA0, INPUT_ANALOG);
  Serial.begin(115200);
}

void loop() {
  delay(1000);

  startTime = micros();

  val[0] = analogRead(PA0);
  val[1] = analogRead(PA0);
  val[2] = analogRead(PA0);
  val[3] = analogRead(PA0);
  val[4] = analogRead(PA0);
  val[5] = analogRead(PA0);
  val[6] = analogRead(PA0);
  val[7] = analogRead(PA0);
  val[8] = analogRead(PA0);
  val[9] = analogRead(PA0);

  endTime = micros();

  Serial.println(endTime - startTime);
}

analogReadを10回実行し、その時間(μs)を出力しています。forループにしていないのは、ループ処理の時間を含まないようにするためです。 

実行結果は、次のような感じです。1秒ごとに結果出力。

70
70
71
70
70
70
70
71
70
70
70  

 arduino UNOでは、標準状態ではanalogRead実行時間は約100μsで、高速化(ADCの分周値16に変更)して約16μsぐらい。arduino M0 proも、標準の実行時間は約100μsと合わせられており、高速化(ADCの分周値64に変更)して、こちらも約16μsぐらいなので、Blue PillはUNOやM0に比べるとanalogReadがだいぶ高速です。ただし、精度については未確認。

おそらく、UNOやM0でも分周値をさらに小さくしてADCのクロックを速くすれば高速化できると思いますが、精度が悪くなると思われます。そのため、ググって見つかるanalogRead高速化では分周値16(UNO)になっていると思われます。