●Arduinoでエアソフトガンの弾速を計る

実際にBB弾でセンサが動作するかどうかを試しただけであり、測定値が正しいかどうかは不明です。
そもそも、計算方法が違っているかもしれないので信用しないでください。
エアソフトガンのBB弾の速度を計るためにはタマが通り過ぎると反応する二つのセンサを置いて、 その間をタマが通り過ぎる時間を測定すれば速度が計算できるはずです。

そこでこのような装置を作りタマの速度を計りたいと思います。


■速度を計る部分の作成

なにか良い材料が無いかと物色していたら、ちょうど水道管と思われる直径15ミリほどの塩ビのパイプがありましたので、それを使いタマの速度を計る部分を作成します。


まずは、適当な二か所に貫通する穴を開けます。


この穴の部分をタマが通過すると時間を計測するようにします。
あまり間隔が狭いと精度が落ちますし、斜めに穴を開けてしまうと誤差が大きくなると考えられます。


適当に開けた二つの穴の距離を計った所、134ミリでした。


次に、BB弾が通過した時に反応するセンサーを取り付けます。
KKHMF LM393 IR赤外線障害物回避センサモジュール Arduino用
BB弾センサーなんて物はあるわけでもないですから、赤外線障害物回避センサーを代用してBB弾を検出します。
このセンサーは片方が発光ダイオードでもう片方がフォトダイオードであり、 障害物がセンサの前に来ると発光ダイオードの光が反射して光センサであるフォトダイオードが受け取る事で反応する仕組みになっています。
このセンサーを常時反応しっぱなしにしておいて、BB弾が光をさえぎるとOFFになることにより検出したいと思います。


まずは、赤外線発光ダイオードを取り外します。


赤外線発光ダイオードの線をびょ〜んと伸ばしました。


フォトダイオードを下向きに向けて、外からの光が入らないように外周にビニールテープを巻き付けておきます。


先ほど作成したパイプの穴の上下に向かい合うように発光ダイオードとフォトダイオードを設置します。


ちなみに、発光ダイオードを取り付けている赤い部品は100均で売っている瞬間接着剤のキャップの先端を切断して使用しました。


二つのセンサーを取り付ける事によりBB弾のタマの速度を計る部分を作成しました。



■Arduinoとの接続

まずは、センサーのVCCにプラス極、GNDにマイナス極を接続します。
一度電気を流して動作させて、センサーの感度の調整を行います。
センサーを単独で動作させたら、センサについている可変抵抗を回して、反応するか反応しないかギリギリのONになる位置に調整しておきます。

センサーのOUT端子はArduinoの割り込みが出来るデジタルピン2番3番に接続します、 Arduinoで割り込みを使うで使用したピンを使用します。
とりあえず2番ピン側がBB弾が進入する方向で3番ピンが出ていく方向とします。
データを表示する液晶画面は、Arduinoで1602 LCDを使うと同じものを作成しました。

動作確認のためにBB弾をセンサー部分に自由落下させて速度を計った所



▼Arduinoにはこのようなプログラムを書き込みました。
センサーの距離は134mmとしていますが、適当な値に書き換えてください。
#include <LiquidCrystal.h>

LiquidCrystal lcd( 8, 9, 4, 5, 6, 7);

void setup() {
  lcd.begin( 16, 2 );
  lcd.clear();
  attachInterrupt(digitalPinToInterrupt(2),test,FALLING);
  attachInterrupt(digitalPinToInterrupt(3),test2,FALLING);
}

volatile unsigned long int time1,time2;
void loop() {
    double pos=((double)134/(double)(time2-time1))*1000;
    if(time1){
      lcd.setCursor(0, 0);
      lcd.print(String(pos,3)+" m/s           ");

      double j2,j25;
      j2=(pos*pos*0.2)/2000;
      j25=(pos*pos*0.25)/2000;
      
      lcd.setCursor(0, 1);
      lcd.print(String(j2,3)+"J "+String(j25,3)+"J         ");
    }else{
      lcd.setCursor(0, 0);
      lcd.print("Ready!!  m/s");
      lcd.setCursor(0, 1);
      lcd.print("0.2g/J   0.25g/J");
    }
    delay(100);
}

void test(){
  time1 = micros();
}
void test2(){
  time2 = micros();
}


▼速度の計算方法

速さ = 距離 / 時間
時間 = 距離 / 速さ

速さと時間の公式で計算しています。
16MHz動作のArduinoではmicros()関数の値の分解能は4マイクロ秒であり、BB弾の程度の速度なら十分な精度でしょう。
詳しくはこちらへ、Arduinoで時間を測定する
念のため計算すると
134mmの距離を4μ秒で通過したとすると、134 / 4 * 1000 = 33500 m/s
つまり、秒速335メートルのタマを1%の誤差で計測できるという事です。


▼BB弾のジュールの求め方

(タマの重さ×速さ×速さ)/2000
で求めています、詳しくはよくわかりません。
0.2gと0.25gのBB弾が標準のようなので、その重さで計算しています。


■実際に測定してみた所

エアソフトガンからこのようにBB弾を発射して測定してみました。


正しいかどうかわかりませんがとりあえず測定できるようです。



■センサーを大きくする

現在のセンサーではパイプが細く使いづらいという事で、パイプ径を太くしたいと思います。
基盤に30ミリの穴を開けて、3個のLEDと一つのフォトダイオードを取り付けました。
赤外線発光ダイオードが手元に無かったため、白色LEDで代用しました。
そのため、赤外線フォトダイオードを可視光フォトダイオードに入れ替えました。



しかし、このままではうまく動作しませんでした。
一つ目の問題として、LEDが明るすぎるとフォトダイオードの感度の上限に達してしまいうまく動作しません、 そのためLEDに可変抵抗をかませて明るさを調整する必要がありました。
二つ目の問題として、3つのLEDのうち真ん中のLEDの光のみが強力にフォトダイオードに入るため、真ん中のLEDしかセンサーとして動作しません。
LEDを一つ一つ光をさえぎってみても、3つのLEDが同時に動作する事が無く、このままの状態で3個のLEDが同時にセンサーとして動作するには、 真ん中のLEDの明るさをシビアに調整する必要がありました。
そこで、色々試行錯誤した結果、可視光フォトダイオードの受光部分には光が透ける程度の紙(ティッシュペーパーなど)を張り付ける事により、
LEDの光が紙に当たって、紙が光り、その光をフォトダイオードで受け取る事により、3個のLEDが各々BB弾を捉えるセンサーとして動作するようになりました。


▼外部の光の影響

センサーが大きくなると外部の光の影響を受けます、そこで感度の自動調整を行うように改良しました。


可変抵抗を取り外して、コンデンサを取り付けました。


自動調整のテストために、1KΩの抵抗を取り付けてArduinoのデジタルピン3番に接続します。
センサーのOUT端子はとりあえずArduinoのデジタルピン5番に接続しました。

詳細は、PWMによる疑似アナログ出力 にて書いてあります。
今回作成したセンサーのテストを行うために作成したプログラム
void setup() {
  Serial.begin(9600);
  pinMode(5, INPUT);

  int first=0,middle,last=0xFF;
  check(last);//PWMの電圧を安定させるため空で呼び出す

  //バイナリサーチをイメージしてセンサーの最適な値を検出
  while(!((last-first)<=1)){
    middle=first+(last-first)/2;
    if(check(middle)){
          Serial.print("on ");
          Serial.println(middle,DEC);
          last=middle;
    }else{
          Serial.print("off ");
          Serial.println(middle,DEC);
          first=middle;
    }
  }
  
  //ONの値が2秒ほど安定するまで感度を上げる処理
  for(unsigned long t=millis()+2000;t > millis();){
    if(digitalRead(5)){
        check(++middle);
        Serial.println(middle,DEC);
        t=millis()+2000;
    }
  }

  Serial.print("completion ");
  Serial.println(middle,DEC);
}

int check(int i){
  analogWrite(3,i);
  delay(100);
  return !digitalRead(5);
}

void loop() {
}

周囲の明るさを拾ってもセンサーが自動調整されて動作することが確認できました。
しかし、外部の光、特に昼間の太陽光の影響は調整できるレベルを超えていてうまく動作しませんでした。
実際に作成するときにはパイプの中など、光が入りにくい状態で作成した方が良いです。


▼二つのセンサーを作成する

単独のセンサーでは動作する事がわかりましたので、センサーを二つ作り間隔を置いて配置します。
同一の物を二つ作成して針金とストローで止めました、センサーの間隔は適当です。
ちなみに真ん中の基盤は補強です。


センサーの配線をして動作確認

この時点で各々のセンサーが動く事を確認しておきます。


▼Arduinoとの配線

Arduinoには1602LCDを直接接続している以上、4番から9番のデジタルピンが埋まっています。
割り込みが出来るのは2番と3番のデジタルピンと決まっていますので、そこにOUT端子を接続します。
感度調整はピンが空いていてPWMが可能な10番、11番のデジタルピンで行うしかありません。
以上の事柄により、このように配線しました。




後は、プログラムを書くと動作するようになると思います。
まだ、ハードウエアにバグがあるかもしれません。
現在作成中ですが、新しいセンサーを取り付ければもっと完成度が上がると思います。


▲トップページ > マイコンなど