スポンサーサイト

上記の広告は1ヶ月以上記事の更新がないブログに表示されます。
新しい記事を書くことで、こちらの広告の表示を消すことができます。  
Posted by ミリタリーブログ at

2023年02月01日

クエーサ ジェルブラスターのエアガン化(改造編その1)

クエーサジェルブラスターをエアガンに改造していきます。
撃てないと話にならないので、弾が出る程度に改造します。
まずはマガジンから手を加えます。



Mac10多連マガジンを分解し、給弾機構の羽根車を取り出し、中身をくり抜き、底板を溶接しました。


ゼンマイばねを羽根車の中に入るように加工しました。


歯車の穴を拡大し、ピンを取り付けました。
これらを組み込むことで羽根車を直接回さず、ゼンマイばねを介して回すようにしています。


マガジン中仕切りを加工します。
給弾機構の仕切りを切除し、羽根車に合うように線を引きます。
新たな仕切りを取り付けていきますが、この銃の素材はナイロンのようで、素材としての入手、接着が困難です。



そこでインシュロックを素材として使い、はんだごてによる溶接で接合します。



適当なプラ板で蓋を作りました。
弾の出口付近に突起を設けてあります。
マガジンの加工はこれで終わりです。


特に必要なさそうですが、モーターを交換してみます。
タミヤのミニモーターセットです。


このモーターはマブチのFP030-KN/13125というモーターです。
サイズが若干大きく、完全な互換ではありませんが、少し削れば入ります。
モーターのパワーは少し強いような気がします。

次は本体の改造を行います。



コンパクトサブマシンガンのチャンバーとインナーバレルを取り付けます。
今回はMP7のチャンバーセットを使っていますが、Mac10かVz61用が適しています。
本体の給弾経路との隙間は元のチャンバーから切り出した部品で埋めます


メカボックスとの干渉箇所を削りました。


ホップダイヤルも削ってしまったので、インシュロックを溶接し、タップを立て、ネジで押すように加工しました。


アルミパイプでアウターバレルを作り、本体に合わせてインナーバレルを短縮しました。


ノズルの先端をチャンバーに入るよう削り、給弾しやすくなるよう下部を平らに削りました。


これでようやくBB弾を撃てるようになりました。


ただ、初速が低すぎるのでまだまだ改造は必要です。   

Posted by 名無しのナナシ at 23:33Comments(0)エアガンカスタムエアガン

2022年12月30日

クエーサ ジェルブラスターのエアガン化(検証編)

かっこいい形のジェルブラスターが売っていたので、エアガン化できるかやってみようと思います。

中身は本体、マガジン、バッテリー、充電器、ジェルボール弾、ゴーグル、説明書。


バッテリーは7.4Vリポバッテリーで、サイズは長さ63mm、幅20mm、厚さ11mm。
容量は驚異の1400mAh
サイズ的に300mAh程度だと思います。
充電用コネクターはJST-XHで、付属以外のバランス充電器でも充電できます。



バッテリースペースは本体後部にあります。
接続はJST-SMコネクターで、ヒューズはなく、空間には余裕はあまりなさそうです。
エアガン用はまず入らないので、バッテリーを変えるならドローン用のバッテリーから探す必要がありそうです。


早速分解していきます。
赤丸部分のネジを外します。


バッテリー部分のパーツを内側から押して外し、赤丸部分のネジを外します。


アッパーレシーバー部分のパーツを左右に分割して外します。


赤丸部分のネジを外します。


これで本体を分割できます。
中のメカボックスはコンパクトサブマシンガンに酷似しています。



電子回路がついていますが、これはカットオフ制御用の回路で、無接点化はされていません。
トリガーのマイクロスイッチが押されている間通電されます。



メカボックスとセレクター付近に磁気センサーがついています。


モーター端子に変な配線がついています。
電動マガジン用の配線のようです。


電動マガジン用端子とスイッチです。
スイッチを押すかメカボックスモーター作動時に通電します。


メカボックスを分解しました。
メカボックスケースとギアがプラスチック製です。
軸受は金属製です。


セクターギアに磁石がついています。


カットオフの制御は、セレクター側の磁気センサーが磁気を検知している時に有効になり、
セクターギアの磁気を検知するまでモーターに通電し、磁気を検知するとトリガーを戻すまで停止します。


電動マガジンの分解をします
赤丸のネジを外し、分割します。


マガジン前側の機関部は引っ張れば外れます。



弾送り部分はギアを介してモーターで直接動いています
試しにBB弾を入れて動かしたら、噛みこんで動かなくなりました。


マガジンのモーターはFA-130モーターより小さなモーターが入っていました。
内部スペースはぎりぎりなのでFA-130モーターの流用は不可能です。




コンパクトサブマシンガンMac10の部品と比較してみました。
干渉部分の小加工と、カットオフの制御をどうにかすれば流用できそうです。
ただマガジンにかなり問題があるので、エアガン化は大変そうです。  

Posted by 名無しのナナシ at 22:33Comments(0)エアガンカスタムエアガン

2022年06月26日

M14カービンカスタム

近距離向けの銃が欲しくなったので、作ってみました。

装備とマガジンを共有できるようにM14をベースにカスタムしました。


M14をショート化する場合、構造上バレルをガスシリンダーの位置より短くすることができません。
このままではM14 SOCOM買っておしまいなので、構造を変更して更なる短縮化を目指します。



オペレーティングロッドAss’yを取り外すのが手っ取り早いですが、あえてコッキングアクションを残すため加工します。
カシメ部をドリルで削ってパイプを外します。



外径9mmのアルミパイプをスプリングガイドにして、スプリングを取り付けました。
スプリングは電動ガン用スプリングを使用しています。



ガスシリンダーを切断してぎりぎりまで下げられるようにしました。



アウターバレルを切断し、オペレーティングロッドブラケットとバレル基部取付用の穴を開けました。


スプリングガイドを固定するための部品を切断したアウターバレルで作ります。
内径が少し小さいので削って圧入しました。


タップを切ってネジで固定できるようにしました。


本体側の加工はこれで完了です。
コッキングはフルストロークはできませんが、ここまで引くことができます。

次はストックを加工します。


短縮化以外にピストルグリップと直銃床化を行うので、ストック部を切断します。


切断したらはんだごてを使って溶接します。


ピストルグリップ部分は電動AK用グリップを使います。


母材同士を溶け合わせるようにくっつけて、穴や凹みを切り取った端材やABS板を溶かして埋めます。



補強と凹み埋めを兼ねたパテを切粉とプラリペアリキッドを使って作ります。


溶接面や裏側にパテを塗り、固まるまで置きました。
固まるまで1日ほど必要のようです。



ストック前側とハンドガードも同じように切り詰めました。


あとはレールを取り付けたり、塗装をして完成です。



長さ865mm、重さ3.6kgになりました。   

Posted by 名無しのナナシ at 20:51Comments(2)エアガンカスタムエアガン

2022年06月22日

側面吸気ピストンヘッドの自作

側面吸気ピストンヘッドを自作してみました。

使うのはマルイ純正ピストンヘッド。


ピストンヘッド前側に、はんだごてを使って四方に溝を掘りました。
あとは組みなおして完成。
  

Posted by 名無しのナナシ at 00:10Comments(0)エアガンカスタムエアガン

2019年05月08日

電子トリガーを作る その4

その3の続き。
ヒューズが飛ぶ問題への対処を行います。
どんな感じに飛ぶというと、撃っていると突然ショートしたようになってヒューズが飛びます。
色々と調べてみるとこういったページを見つけました。
ページに書いてあることによるとアンダーシュートが原因と思われます。


アンダーシュートによって2つのFETが同時にオンになりショートしてしまい、ヒューズが飛んでしまうようです。

そこで対策として、
1.ブートストラップコンデンサの容量を再計算、470μF→47μFへ変更。
2.Vcc端子とCOM端子の間に470μFの電解コンデンサを追加。
3.ゲート抵抗を33Ω→47Ωへ変更。
その他に、バッテリー電圧を測定する分圧抵抗を追加したり
センサー用の電源をマイコンと別にしました。
最終的な回路はこちらです。



マガジンに磁石を仕込んで、これを磁気センサーで検出してボルトストップするようにしました。


ボルトストップはチャージングハンドルを引くことで解除できるようにしています。


プログラムは以下の通り。

//F2000用FCUプログラムVer.1.03
//改訂記録============================================================================
//Ver.1.01 モーターロック保護処理の追加
//Ver.1.02 ボルトストップ時にピストンを前進位置で停止するよう変更
//Ver.1.03 ボルトストップ解除時に発射されてしまう不具合を修正
//入出力ピンの名称変更=================================================================
#define SEMI_SW A0 //セミオートスイッチ
#define VAL_IN A1 //電圧測定入力
#define FULL_SW 4 //フルオートスイッチ
#define SAFETY_SW 2 //セーフティスイッチ
#define CUTOFF_SW 3 //カットオフスイッチ
#define NO_AMMO_SW 6 //残弾無し検知スイッチ
#define COCKING_FOWARD_SW 7 //コッキングハンドル前進検知スイッチ
#define COCKING_BACK_SW 8 //コッキングハンドル後退検知スイッチ
#define MOTOR 9 //モーター制御出力
#define INDICATOR 10 //インジケーターLED
#define LED 13 //マイコンLED
//定数の宣言===========================================================================
const byte PWM = 254; //フルオートサイクル調整用定数、254まで
const unsigned int PRECOCK = 30;//プリコック時間(ミリ秒)
const unsigned int DECOCK = 0; //デコック時間(ミリ秒)
const unsigned int SW_ON = 280; //セミオートスイッチオン閾値
const unsigned int SW_OFF = 90; //セミオートスイッチオフ閾値
const unsigned int CHATA_SEMI = 0; //セミオートスイッチチャタリング防止(マイクロ秒、1/1000ミリ秒)
const unsigned int CHATA_FULL = 5000; //フルオートスイッチチャタリング防止(マイクロ秒、1/1000ミリ秒)
const unsigned int CHATA_CUTOFF = 0; //カットオフスイッチチャタリング防止(マイクロ秒、1/1000ミリ秒)
const bool ON = LOW, OFF = HIGH; //スイッチ用定数、混乱防止のため
const bool SEMI = false, FULL = true; //フル・セミ切り替え用定数
const unsigned int V_R1 = 1000;     //電圧検知VIN側抵抗値(Ω)
const unsigned int V_R2 = 1000;     //電圧検知GND側抵抗値(Ω)
const unsigned int LIMIT_VAL_S = 740; //待機時電圧下限値(V×100)
const unsigned int LIMIT_VAL_M = 610; //稼働時電圧下限値(V×100)
const unsigned int VF = 70; //ダイオード順方向降下電圧値(V×100)
//変数の宣言===========================================================================
volatile int Fire = 0; //発射制御用変数
volatile unsigned int Semi_Sw = 0; //セミオートスイッチ用変数
volatile bool Cutoff = LOW, Old_Cutoff = LOW; //カットオフセンサー用変数
volatile bool SemiTrg = OFF, Old_SemiTrg = OFF; //セミオート処理用変数
volatile bool FullTrg = OFF, Old_FullTrg = OFF; //フルオート処理用変数
volatile bool Shot_Mode = SEMI;//フル/セミ切り替え用変数
volatile bool No_Ammo = LOW;//残弾無し検知用変数
volatile bool Bolt_Stop = false;//ボルトストップ処理用変数
volatile bool Cocking_Fowad = LOW;//コッキングハンドル前進検知用変数
volatile bool Cocking_Back = LOW;//コッキングハンドル後退検知用変数
volatile bool Fast_Shot = true;//ファストショット処理用変数
bool Battery_Low = false;//バッテリー低下処理用変数
float Vcc = 0; //基準電圧(V)
unsigned int Val = 0;//測定電圧(V×100)
unsigned long Time = 0, Old_Time = 0; //電圧測定時間記録(ミリ秒)
unsigned long M_Time = 0 ,Old_M_Time = 0; //モーター駆動時間記録(ミリ秒)
//セットアップ=========================================================================
void setup() {
//入出力ピンの設定=====================================================================
  pinMode(FULL_SW,INPUT);
  pinMode(CUTOFF_SW,INPUT);
  pinMode(NO_AMMO_SW,INPUT);
  pinMode(COCKING_FOWARD_SW,INPUT);
  pinMode(COCKING_BACK_SW,INPUT);
  pinMode(SAFETY_SW,INPUT);
  attachInterrupt(digitalPinToInterrupt(SAFETY_SW),SAFETY_MODE,LOW);
  pinMode(LED,OUTPUT);
  pinMode(INDICATOR,OUTPUT);
//起動処理============================================================================
  digitalWrite(INDICATOR,HIGH);
  analogWrite(MOTOR,0);
  delay(1000);             //1秒待つ
}
//メインプログラム====================================================================
void loop() {
  digitalWrite(INDICATOR,LOW);
  Time = millis();        //現在の時間を取得(バッテリー電圧測定用)
  M_Time = millis();      //現在の時間を取得(モーターロック保護処理用)
//現在の各スイッチの状態を検知========================================================
  Cutoff = digitalRead(CUTOFF_SW);
  Semi_Sw = analogRead(SEMI_SW);
  /*セミオートスイッチに光センサーを使うため
   *オン・オフの処理を追加
   */
  if(Semi_Sw >= SW_ON){
    SemiTrg = ON;
    /*光センサーの数値が定数SW_ONの閾値以上の場合
     *セミオートスイッチをオンとする
     */
  }
  if(Semi_Sw <= SW_OFF){
    SemiTrg = OFF;
    /*光センサーの数値が定数SW_OFFの閾値以下の場合
     *セミオートスイッチをオフとする
     */
  }
  FullTrg = digitalRead(FULL_SW);
  No_Ammo = digitalRead(NO_AMMO_SW); 
  Cocking_Back = digitalRead(COCKING_BACK_SW);
   
  //カットオフスイッチの状態をLEDで表示
  if(Cutoff == HIGH){
    digitalWrite(LED,HIGH);
  }
  if(Cutoff == LOW){
    digitalWrite(LED,LOW);
  }
//モーター動作処理==================================================================== 
  if(Fire >= 1){
    //変数Fireが1以上のときモーター作動
    switch (Shot_Mode == FULL){
    //モーターの出力変更
      case FULL:
        if(Fast_Shot == true){
          analogWrite(MOTOR,254);
        }
        else{
          analogWrite(MOTOR,PWM);
        }
        break;
        /*フルオート時、最初の1発は最大出力
         *それ以降、変数PWMの値の出力
         */
        default:
        analogWrite(MOTOR,254);
        //セミオート時、最大出力
      }
//モーターロック保護処理================================================================
      while(M_Time - Old_M_Time >= 200){
        analogWrite(MOTOR,0);
        digitalWrite(INDICATOR,HIGH);
        delay(100);
        digitalWrite(INDICATOR,LOW);
        delay(100);
        /*トリガーが押されてから、または
         *カットオフスイッチを検出してから200ミリ秒以上
         *新たなカットオフスイッチを検出しなかった場合
         *モーターを停止し、インジケーターLEDを点滅する
        */
      }
//残弾無し処理=========================================================================
      if(No_Ammo == HIGH){
         Fire = 1;
        /*残弾無し検知スイッチがオンの時、
         *変数Fireの値を1にする
         */
      }
  }
//カットオフ処理=======================================================================
  if(Fire > 1){
    if(Cutoff == HIGH && Old_Cutoff == LOW){
        Fire = Fire - 1;
        Fast_Shot = false;
        Old_M_Time = M_Time;                          //カットオフ検出の時間を記録(モーターロック保護処理用)
        Val = GetVal(analogRead(VAL_IN));             //電圧を取得
        if(Val < LIMIT_VAL_M){                        //稼働時下限値を下回ったとき
          Battery_Low = true;                         //変数Battery_Lowをtrueにし、
          Fire = 1;                                   //変数Fireの値を1にする
        }
        /*カットオフスイッチがLOWからHIGHなったときに
         *変数Fireの数字を1引き、変数Fast_Shotをfalseにする
         */
    }
    Old_Cutoff = Cutoff;
  }
  if(Fire == 1){
    if(Cutoff == HIGH && Old_Cutoff == LOW){
      analogWrite(MOTOR,254);
      Val = GetVal(analogRead(VAL_IN));               //電圧を取得
        if(Val < LIMIT_VAL_M){                        //稼働時下限値を下回ったとき
          Battery_Low = true;                         //変数Battery_Lowをtrueにする
        }
      if(Cocking_Back == ON || No_Ammo == HIGH){
        delay(DECOCK);
      }else{
        delay(PRECOCK);
      }
      analogWrite(MOTOR,0);
      Fire = 0;
      Shot_Mode = SEMI;
      Fast_Shot = true;
      Time = millis();
      Old_Time = Time;                               //モーターが停止した時間を記録(バッテリー電圧測定用)
      /*変数Fireが1に等しい場合、
       *カットオフスイッチがLOWからHIGHになった時に
       *コッキングハンドル検知スイッチがオフの時
       *定数PRECOCKミリ秒後、モーターを停止し、
       *コッキングハンドル検知スイッチがオンの時、
       *あるいは残弾無し検知スイッチがオンの時、
       *定数DECOCKミリ秒後、モーターを停止する
       */
       
      if(No_Ammo == HIGH){
        //残弾無し処理
        Bolt_Stop = true;
        /*残弾無し検知スイッチがオンの時、
         *ボルトストップを行う
         */
      }
    }
    Old_Cutoff = Cutoff;
  }
  if(Cutoff == LOW && Old_Cutoff == HIGH ){
    delayMicroseconds(CHATA_CUTOFF);
    /*カットオフスイッチがONからOFFになったとき
     *チャタリング防止のため
     *定数CHATA_CUTOFFマイクロ秒停止する
     */  
  }
    
//トリガー処理=========================================================================
  /* 変数Bolt_Stopがfalseの時
   * かつ、変数Battery_Lowがfalseの時のみ
   * トリガー入力を受け付ける
   */
  if(Bolt_Stop == false && Battery_Low == false){
//セミオート処理=======================================================================
    if(Fire == 0 ){
      analogWrite(MOTOR,0);
      Shot_Mode = SEMI;
      /*変数Fireの値が0の時
       *セミオート入力を受け付ける
       */
      if(SemiTrg == ON && Old_SemiTrg == OFF){
        Fire = 1;
        Shot_Mode = SEMI;
        /*セミオートスイッチがOFFからONになったとき
         *変数Fireに1を代入する
         */
        Old_M_Time = M_Time;          //セミオートトリガーが押された時間を記録(モーターロック保護処理用)
      }
  
      if(SemiTrg == OFF && Old_SemiTrg == ON){
        delayMicroseconds(CHATA_SEMI);
        /*セミオートスイッチがONからOFFになったとき
         *チャタリング防止のため
         *定数CHATA_SEMIマイクロ秒停止する
         */
      }
    }   
//フルオート処理=======================================================================
    if(SemiTrg == ON && No_Ammo == LOW){
      if(FullTrg == ON){
        Fire = 2;
        Shot_Mode = FULL;
        /*セミオートスイッチがONのままの場合フルオートスイッチを受け付け
         *フルオートスイッチがONになっている間
         *変数Fireに2を代入し続ける
         */
        if(Old_FullTrg == OFF){
          Old_M_Time = M_Time;         //フルオートトリガーが押された時間を記録(モーターロック保護処理用)
         }
      }
      if(FullTrg == OFF && Old_FullTrg == ON){
        Fire = 1;
        delayMicroseconds(CHATA_FULL);
        /*フルオートスイッチがONからOFFになったとき
         *変数Fireに1を代入し、 
         *チャタリング防止のため
         *定数CHATA_FULLマイクロ秒停止する
         */
      }  
    }
  }
//フル・セミオートスイッチの状態を記録する=============================================
  Old_SemiTrg = SemiTrg;
  Old_FullTrg = FullTrg;
//待機時電圧測定処理===================================================================
  if(Fire == 0 && Time - Old_Time >= 500){        //Fireが0かつ、発射後500msおきに
    Val = GetVal(analogRead(VAL_IN));             //電圧を取得
    if(Val < LIMIT_VAL_S){                        //待機時下限値を下回ったとき
      Battery_Low = true;                         //変数Battery_Lowをtrueにする
    }
    Old_Time = Time;                              //測定した時間を記録
  }
//オートカット処理===================================================================== 
  while(Fire == 0 && Battery_Low == true){        //バッテリー電圧の低下を検出した場合、動作を停止し、
    analogWrite(MOTOR,0);                         //インジケーターLEDを点滅する
    digitalWrite(INDICATOR,HIGH);
    delay(100);
    digitalWrite(INDICATOR,LOW);
    delay(1000);
  }
  noInterrupts();
//ボルトストップ処理===================================================================
  while(Bolt_Stop == true){
    Fire = 0;
    SemiTrg = OFF, Old_SemiTrg = OFF;
    FullTrg = OFF, Old_FullTrg = OFF;
    analogWrite(MOTOR,0);
    digitalWrite(INDICATOR,HIGH);
    while(Cocking_Back == OFF){
      Cocking_Back = digitalRead(COCKING_BACK_SW);
    }
    Cocking_Fowad = digitalRead(COCKING_FOWARD_SW);
    if(Cocking_Fowad == ON){
      No_Ammo = digitalRead(NO_AMMO_SW);
      switch(No_Ammo == LOW){
        case true:
          Bolt_Stop = false;
          digitalWrite(INDICATOR,LOW);
          break;
        default:
          Cocking_Back = OFF;
      }
      
    }
    /*コッキングハンドル後退検知スイッチがオンになった後、
     *残弾無し検知スイッチがオフかつ、
     *コッキングハンドル前進検知スイッチがオンになった時、
     *ボルトストップを解除する
     *コッキングハンドル前進検知スイッチがオンになった時、
     *残弾無し検知スイッチがオンの場合はやり直し
     */
  }
  interrupts();
  if(Fire < 0){
    Fire = 0;
  }
}
//セーフティモード=====================================================================
void SAFETY_MODE() {
  analogWrite(MOTOR,0);
  Fire = 0;
  Semi_Sw = 0;
  Cutoff = LOW, Old_Cutoff = LOW;
  SemiTrg = OFF, Old_SemiTrg = OFF;
  FullTrg = OFF, Old_FullTrg = OFF;
  Shot_Mode = SEMI;
  Fast_Shot = true;
  Cocking_Fowad = LOW;
  Cocking_Back = LOW;
  /*セーフティスイッチがオンの時、
   *モーターを停止し、変数の初期化を行う
   */
}
//センサーの値から電圧を計算===========================================================
unsigned int GetVal(unsigned int A){
  float V,Vcc;
  Vcc = cpuVcc(); //基準電圧の取得
  V = A * Vcc / 1024.0 /V_R2 * (V_R1 + V_R2); 
  return(unsigned int)(V * 100.0+ VF);//100倍して整数にする
}
// 電源電圧(AVCC)測定関数==============================================================
float cpuVcc(){
  unsigned long sum=0;
  adcSetup(0x4E);                    // Vref=AVcc, input=internal1.1V
  for(int n=0; n < 10; n++){
    sum = sum + adc();               // adcの値を読んで積分
  }
  return (1.1 * 10240.0)/ sum;       // 電圧を計算して戻り値にする
}
// ADコンバーターの設定================================================================
void adcSetup(byte data){
  ADMUX = data;                      // ADC Multiplexer Select Reg.
  ADCSRA |= ( 1 << ADEN);            // ADC イネーブル
  ADCSRA |= 0x07;                    // AD変換クロック CK/128
  delayMicroseconds(500);            // 安定するまで待つ
}
// ADCの値を読む=======================================================================
unsigned int adc(){                  
  unsigned int dL, dH;
  ADCSRA |= ( 1 << ADSC);            // AD変換開始
  while(ADCSRA & ( 1 << ADSC) ){     // 変換完了待ち
  }
  dL = ADCL;                         // LSB側読み出し 
  dH = ADCH;                         // MSB側
  return dL | (dH << 8);             // 10ビットに合成した値を返す
}
  

Posted by 名無しのナナシ at 22:24Comments(0)エアガンカスタムエアガンマイコン

2019年05月04日

電子トリガーを作る その3

その2の続き。
電動ガンへの実装を行います。

今回取り付けるのは、G&GのF2000。
ETUが搭載されていない旧式です。


テスト基板を少し変更した実装基板を作りました。



この基板はメカボックスのスイッチが付いていた所に取り付けました。


マイコン基板はバッテリースペース下に入れました。


トリガースイッチは、元の仕様通りフルセミの選択をトリガーストロークで行い、
セミをフォトリフレクタ、フルをマイクロスイッチで検出するようにしました。



そのほか、セーフティスイッチなどを取り付け。


これで実装完了ですが、テストしたところヒューズが飛ぶ問題が起こったので、
次回はその対処とプログラムの改良を行います。  

Posted by 名無しのナナシ at 22:22Comments(0)エアガンカスタムエアガンマイコン

2019年04月09日

電子トリガーを作る その2

その1の続き。
今回はセミオート射撃をできるようにします。

セミオート射撃のために、カットオフを検出できるようにします。
セクターギアに開いている穴に直径5mmの磁石を埋め込み、これをホールICで検出します。



メカボックス越しでは磁力を検出できなかったので、穴を開けます。


ユニバーサル基板にホールICを半田付けし、取り付けのためにメカボックスにネジを切りました。



プログラムは以下の通り。
//カットオフテスト用
//入出力ピンの名称変更
#define SEMI_SW 4 //セミオートスイッチ
#define CUTOFF_SW 3 //カットオフセンサー
#define MOTOR 9 //モーター制御出力
#define LED 13 //マイコンLED
//定数の宣言
const int Chata = 0; //チャタリング防止(マイクロ秒)
const bool ON = LOW; //スイッチ用定数、混乱防止のため
const bool OFF = HIGH;
//変数の宣言
int Fire = 0; //発射制御用変数
bool Coff = LOW; //カットオフセンサー用変数
bool Old_Coff = LOW;
bool SemiTrg = HIGH; //セミオートスイッチ用変数
bool Old_SemiTrg = HIGH;

void setup() {
   //入出力ピンの設定
   pinMode(SEMI_SW,INPUT);
   pinMode(CUTOFF_SW,INPUT);
   pinMode(LED,OUTPUT);
}
void loop() {

   //現在の各スイッチの状態を検知
   Coff = digitalRead(CUTOFF_SW);
   SemiTrg = digitalRead(SEMI_SW);
   
   //カットオフスイッチの状態をLEDで表示
   if(Coff == HIGH){
      digitalWrite(LED,HIGH);
   }
   if(Coff == LOW){
      digitalWrite(LED,LOW);
   }

   if(Fire >= 1){
      analogWrite(MOTOR,254); //変数Fireが1以上のときモーター作動
   }
   if(Fire > 1){
      //カットオフ処理
      if(Coff == HIGH && Old_Coff == LOW){
         Fire = Fire - 1;
         /*カットオフスイッチがLOWからHIGHなったときに
          *変数Fireの数字を1引く
          */
     }
     if(Coff == LOW && Old_Coff == HIGH){
        /*物理スイッチを使用する際のチャタリング防止用      
         */
     }
     Old_Coff = Coff;
   }
   if(Fire == 1){
      if(Coff == HIGH && Old_Coff == LOW){
         analogWrite(MOTOR,0);
         Fire = 0;
         /*変数Fireが1に等しい場合、
          *カットオフスイッチがLOWからHIGHになったとき
          *モーターを停止する
          */
      }
      if(Coff == LOW && Old_Coff == HIGH ){
        /*物理スイッチを使用する際のチャタリング防止用      
         */
      }
      Old_Coff = Coff;
   }
    
   if(Fire == 0){
      /*トリガー処理、変数Fireの値が0の時のみ
       *トリガー入力を受け付ける
       */
      analogWrite(MOTOR,0);
      if(SemiTrg == ON && Old_SemiTrg == OFF){
         Fire = 1;
         /*トリガーがOFFからONになったとき
         *変数Fireに1を代入する
         */
      }
      
      if(SemiTrg == OFF && Old_SemiTrg == ON){
         delayMicroseconds(Chata);
         /*トリガーがONからOFFになったとき
          *チャタリング防止のため
          *変数chataマイクロ秒停止する
          */
      }
      Old_SemiTrg = SemiTrg;
   }
    
   if(Fire < 0){
      Fire = 0;
   }
}
動かすとこんな感じ。
  

Posted by 名無しのナナシ at 22:11Comments(0)エアガンカスタムエアガンマイコン

2019年04月08日

電子トリガーを作る その1

電子トリガーに興味を持ち、色々と調べてみたら
こんなものを見つけて、自分でも作れそうだったので
作ってみることにしました。

以前、ガスガン内蔵ヒーター制御装置を作る際、テストに使ったArduino Nano互換機。
これを使います。
プログラム用のソフト他はこちらを参照してください。


まずはモーターを動かすモータードライバを作ります。
見つけた回路図をほぼそのまま流用して作りました。
詳細についてはこちらを参照してください。


回路図のマイコンVINと出力PINの所をスイッチで繋ぐとそのまま動かせます。


次はマイコンを繋いでテストします。
プログラムは以下の通り。

//モータードライバーテスト用
void setup() {
  pinMode(2,INPUT);
  pinMode(3,INPUT);
  pinMode(4,INPUT);
}

void loop() {
 if(digitalRead(2)==HIGH){
    analogWrite(5,255);   //出力100%、しばらくすると動かなくなる
 }
 else if(digitalRead(3)==HIGH){
    analogWrite(5,123);   //出力50%
 }
 else if(digitalRead(4)==HIGH){
    analogWrite(5,254);   //出力99%、連続使用できる限界
 }
 else{
 analogWrite(5,0);
 }
}
このプログラムをマイコンに書き込み、マイコンのD2,D3,D4にスイッチ、D5に出力PINの所を繋ぎ
動かすとこんな感じです。
このモータードライバーは連続して動かすことができないので、
PWM出力でブートストラップコンデンサを充電する時間を作る必要があります。


次回から電動ガンへの実装を行います。  

Posted by 名無しのナナシ at 23:26Comments(0)エアガンカスタムエアガンマイコン

2019年03月20日

A&K SVDにダブルイーグルM905用マガジンを流用する方法

A&KのSVDを実戦投入するためにマガジンを確保しようとしましたが、
マガジンがどこにも売っていません。
流用できそうなマガジンを探していたら、ダブルイーグルM905用マガジンを見つけました。

右がA&K、左がダブルイーグル。
ぱっと見、よく似ています。



早速マガジンを装着しようとしましたが、案の定入りません。


よく見てみると、前側の出っ張りが少し大きいようなのでヤスリで削りました。
(右がダブルイーグル、左がA&K)



マガジンが入るようになりましたが、今度は給弾されません。
マガジンが小さいようで後ろ側に隙間ができていて、ストッパーを押し切れていないようです。


マガジンの後ろ側にプラ板を接着してストッパーを押せるようにしました。
メカボックスを外した状態で試したら、給弾されるようになりました。



しかし、メカボックスを取り付けた状態で試したら、マガジンキャッチが掛からなくなりました。
メカボックスを避ける凹みの深さが足りていないようです。


へこみの深さはA&Kが15mm、ダブルイーグルは12mm。
3mm削る必要があります。



マガジンの中身を出して、凹みの上側を切除、ヤスリで削ります。



外側もヤスリで削ります。
鉄製で、少し厚みがあるので苦労しました。


装着して給弾することを確認して完了です。   

Posted by 名無しのナナシ at 22:00Comments(0)エアガンカスタムエアガン

2019年03月19日

はじめての流速カスタム(A&K電動SVD)

大分前に購入していた、A&K電動SVD。


一応撃てるようにいじっていますが、M14との差別化ができずに放置していました。
そこで流速カスタムの実験台に使うことにしました。
流速カスタムで0.28g弾を飛ばせるようにし、遠距離特化にします。
まず、分解してメカボックスを取り出します。

本体右側の六角ネジを外します。


マガジンキャッチ付近のピンを左側から抜き出します。


トリガーガードを取り外し、レシーバー下の部品を取り外します。



チャンバーブロック両脇の芋ネジを緩めて取り外します。
チャンバーは同社製ミニミと同様の構造で、同じような改良をしてあります。
ついでに長掛けホップにしてあります。


メカボックスを後ろに引きながら、前側を下から押し上げて取り外します。




メカボックス後ろからスプリングを取り外せます。


タペットスプリングは外に露出しているので取り外します。


メカボックスのプラスネジを外して分割します。


流速カスタムの原理などは検索すればいっぱい出てくるので省略。
ピストンに重りをつけて重くして、強めのスプリングを入れます。

ピストンに鉛シートで作った重りを入れて、35g程にします。
スプリングはKM企画の0.9Jスプリングを入れます。



このままでは法定初速をオーバーするので、インナーバレルを切断して調整します。
588mm→200mmに切断しました。




ついでにモーターを交換し、FETを取り付けます。
モーターはSHSのハイトルクモーターに交換します。


モータ軸が少し長いので切断して調整しました。



FETはXCORTECHのデュアルFETをグリップ内の空洞に入るように取り付けました。


レスポンスを向上させるため、11.1Vリポバッテリーを使います。


コネクターはXT60コネクターに交換しました。



これでカスタム完了です。
初速をマルイ0.20、0.25、0.28gの弾を使い、ホップ最弱時の初速と初速最大値を測ります。

0.20gホップ最弱 81.1m/s


0.20g初速最大 93.2m/s


0.25gホップ最弱 76.8m/s


0.25g初速最大 83.4m/s


0.28gホップ最弱 75.7m/s


0.28g初速最大 79.6m/s


どの弾でも0.9J以下でちょうどいいぐらいです。  

Posted by 名無しのナナシ at 23:35Comments(0)エアガンカスタムエアガン

2018年11月25日

ガスガン内蔵ヒーター制御装置を作る その4

ヒーター制御装置の実装をします。




マイコンボードは更に小型のものを使います。

Digisparkというマイコンボードの互換機で
マイコンの仕様についてはこちら

このマイコンを使うときは、こちらの手順にしたがって開発環境を インストールする必要があります。
ただ、不具合があるようなのでインストールパッケージ定義をこちらのものに変更してください。

プログラムは入出力関係を少し変更する必要があります。

//ヒーター制御プログラムテスト(Digispark用)
//入出力ピンの名称変更
#define HEATER 0          //ヒーター制御出力
#define Temp_Input A1    //サーミスタ入力
#define Val_Input A2     //電圧測定入力
#define LED 1            //マイコンLED

//定数の宣言
const int V_R1 = 1000;     //電圧測定VIN側抵抗値(Ω)
const int V_R2 = 1000;     //電圧測定GND側抵抗値(Ω)
const int B = 4100;       //サーミスタB定数
const long T_R1 = 10000;   //サーミスタ基準抵抗値[Ω]
const long T_R2 = 10000;    //サーミスタバランス抵抗[Ω]
const int T0 = 298;       //サーミスタ基準温度[K]
const int Limit_Val = 740;    //測定電圧下限値[V×100]
const int Limit_L_Temp = -200,Limit_H_Temp = 400;  //正常温度閾値[℃×10]
const int L_Temp = 280;  //温度下限値[℃×10]
const int H_Temp = 300;  //温度上限値[℃×10]
//変数の宣言
float Vcc = 0;            //基準電圧[V]
int Val = 0;              //測定電圧[V×100]
int Temp = 0;             //測定温度[℃×10]

void setup () {
  //入出力ピンの設定
  pinMode(HEATER, OUTPUT);
  pinMode(LED, OUTPUT);
}

void loop () {
  Vcc = cpuVcc();                                //基準電圧の取得
  Temp = GetTemp(analogRead(Temp_Input));        //温度の取得
  Val = GetVal(analogRead(Val_Input));           //電圧を取得

  while (Temp > Limit_H_Temp || Temp < Limit_L_Temp){   //測定温度が正常な範囲内から外れると
    digitalWrite(HEATER, LOW);                          //ヒーターをオフにし、マイコンLEDが短い間隔で点滅する
    digitalWrite(LED, HIGH);
    delay(100);
    digitalWrite(LED, LOW);
    delay(100);
  }
  while (Val < Limit_Val) {                      //測定電圧が下限値を下回るとヒーターをオフにし、
    digitalWrite(HEATER, LOW);                   //マイコンLEDが長い間隔で点滅する
    digitalWrite(LED, HIGH);
    delay(100);
    digitalWrite(LED, LOW);
    delay(1000);
  }
  
  if (Temp <= L_Temp) {                         //測定温度が下限値以下になると
    digitalWrite(HEATER, HIGH);                 //ヒーターをオンにする
  }
  
  if (Temp >= H_Temp) {                         //測定温度が上限値以上になると
    digitalWrite(HEATER, LOW);                  //ヒーターをオフにする
  }
  delay(100);                                    //0.1s待つ
}
//センサーの値から温度を計算
float GetTemp (int raw) {
  float V_R2 ;
  float R ;
  float t;

  V_R2 = raw * Vcc / 1.024;                                         //バランス抵抗の消費電圧を算出
  R = Vcc * 1000.0 / V_R2 * T_R2 - T_R2;                            //サーミスタの抵抗値を算出
  t = (1000 / (1 / (0.001 * T0) + log(R / T_R1) * 1000 / B) - 273); //温度の計算
  return (int)(t * 10.0);                                           //10倍にして整数にする
}
//センサーの値から電圧を計算
int GetVal(int A) {
  float V;
  V = A * Vcc / 1024.0 / V_R2 * (V_R1 + V_R2);                      //電圧の計算
  return (int)(V * 100.0);                                //100倍して整数にする
}

float cpuVcc() {                     // 電源電圧(AVCC)測定関数
  long sum = 0;
  adcSetup(0x0C);                    // Vref=Vcc, input=internal1.1V
  for (int n = 0; n < 10; n++) {
    sum = sum + adc();               // adcの値を読んで積分
  }
  return (1.1 * 10240.0) / sum;      // 電圧を計算して戻り値にする
}

void adcSetup(byte data) {           // ADコンバーターの設定
  ADMUX = data;                      // ADC Multiplexer Select Reg.
  ADCSRA |= ( 1 << ADEN);            // ADC イネーブル
  ADCSRA |= 0x07;                    // AD変換クロック CK/128
  delayMicroseconds (500);             // 安定するまで待つ
}

unsigned int adc() {                 // ADCの値を読む
  unsigned int dL, dH;
  ADCSRA |= ( 1 << ADSC);            // AD変換開始
  while (ADCSRA & ( 1 << ADSC) ) {   // 変換完了待ち
  }
  dL = ADCL;                         // LSB側読み出し
  dH = ADCH;                         // MSB側
  return dL | (dH << 8);             // 10ビットに合成した値を返す
}




アナログ入力に干渉するため、
マイコンボードについているツェナーダイオードを取り外しています。



前回試した回路に取り付けて問題ないか確認しました。



実装する回路図はこちら。
ヒューズと電源スイッチ、プログラムを書き込むときに回路を切り離すスイッチを追加しました。





これをケースの中に入れて完成です。

最終的なプログラムはこちら。

//ヒーター制御プログラムVer.1.00(Digispark用)
//入出力ピンの名称変更=================================================================
#define HEATER 0          //ヒーター制御出力
#define Temp_Input A1    //サーミスタ入力
#define Val_Input A2     //電圧測定入力
#define LED 1            //マイコンLED
//定数の宣言===========================================================================
const int V_R1 = 1000;     //電圧測定VIN側抵抗値(Ω)
const int V_R2 = 1000;     //電圧測定GND側抵抗値(Ω)
const int B = 4100;       //サーミスタB定数
const long T_R1 = 10000;   //サーミスタ基準抵抗値[Ω]
const long T_R2 = 10000;    //サーミスタバランス抵抗[Ω]
const int T0 = 298;       //サーミスタ基準温度[K]
const int Limit_Val_S = 740;    //待機時電圧下限値[V×100]
const int Limit_Val_M = 730;    //稼働時電圧下限値[V×100]
const int Limit_L_Temp = -200,Limit_H_Temp = 400;  //正常温度閾値[℃×10]
const int L_Temp = 280;  //温度下限値[℃×10]
const int H_Temp = 300;  //温度上限値[℃×10]
//変数の宣言===========================================================================
float Vcc = 0;            //基準電圧[V]
int Val = 0;              //測定電圧[V×100]
int Temp = 0;             //測定温度[℃×10]
bool Battry_Low = false;  //オートカット用変数
bool Heater_sw = LOW;     //ヒータースイッチ
//セットアップ=========================================================================
void setup () {
//入出力ピンの設定=====================================================================
  pinMode(HEATER, OUTPUT);
  pinMode(LED, OUTPUT);
//起動処理============================================================================
  digitalWrite(HEATER, LOW);
  digitalWrite(LED, LOW);
}
//メインプログラム=====================================================================
void loop () {
//各センサーの数値を取得===============================================================
  Vcc = cpuVcc();                            //基準電圧の取得
  Temp = GetTemp(analogRead(Temp_Input));    //温度の取得
  Val = GetVal(analogRead(Val_Input));       //電圧を取得
//温度異常セーフティ処理===============================================================
  while (Temp > Limit_H_Temp || Temp < Limit_L_Temp){   //測定温度が正常な範囲内から外れると
    digitalWrite(HEATER, LOW);                          //ヒーターをオフにし、マイコンLEDが短い間隔で点滅する
    digitalWrite(LED, HIGH);
    delay(100);
    digitalWrite(LED, LOW);
    delay(100);
  }
//オートカット判定=====================================================================
  switch(Heater_sw == HIGH){
    case true:
      if (Val < Limit_Val_M){          //ヒーターがオンの時、稼働時下限値以下の時、
        Battry_Low = true;             //変数Battry_Lowをtrueにする
      }
      break;
    default:
      if (Val < Limit_Val_S){            //ヒーターがオフの時、待機時下限値以下の時、
        Battry_Low = true;             //変数Battry_Lowをtrueにする
      }
  }
//オートカット処理=====================================================================
  while (Battry_Low == true){         //変数Battry_Lowをtrueの時、ヒーターをオフにし、
    digitalWrite(HEATER, LOW);         //マイコンLEDが長い間隔で点滅する
    digitalWrite(LED, HIGH);
    delay(100);
    digitalWrite(LED, LOW);
    delay(1000);
  }
//ヒーター制御処理=====================================================================
  if (Temp <= L_Temp) {               //測定温度が下限値以下になると
    Heater_sw = HIGH;                 //ヒーターをオンにする
  }
  
  if (Temp >= H_Temp) {               //測定温度が上限値以上になると
    Heater_sw = LOW;                  //ヒーターをオフにする
  }
  digitalWrite(HEATER,Heater_sw);
  delay(100);                         //0.1s待つ
}
//センサーの値から温度を計算===========================================================
float GetTemp (int raw) {
  float V_R2 ;
  float R ;
  float t;

  V_R2 = raw * Vcc / 1.024;                                         //バランス抵抗の消費電圧を算出
  R = Vcc * 1000.0 / V_R2 * T_R2 - T_R2;                            //サーミスタの抵抗値を算出
  t = (1000 / (1 / (0.001 * T0) + log(R / T_R1) * 1000 / B) - 273); //温度の計算
  return (int)(t * 10.0);                                           //10倍にして整数にする
}
//センサーの値から電圧を計算===========================================================
int GetVal(int A) {
  float V;
  V = A * Vcc / 1024.00 / V_R2 * (V_R1 + V_R2);            //電圧の計算
  return (int)(V * 100.0);                                //100倍して整数にする
}
//電源電圧(AVCC)測定関数===============================================================
float cpuVcc() {
  long sum = 0;
  adcSetup(0x0C);                    // Vref=Vcc, input=internal1.1V
  for (int n = 0; n < 10; n++) {
    sum = sum + adc();               // adcの値を読んで積分
  }
  return (1.1 * 10240.0) / sum;      // 電圧を計算して戻り値にする
}
//ADコンバーターの設定===================================================
void adcSetup(byte data) {           
  ADMUX = data;                      // ADC Multiplexer Select Reg.
  ADCSRA |= ( 1 << ADEN);            // ADC イネーブル
  ADCSRA |= 0x07;                    // AD変換クロック CK/128
  delayMicroseconds (500);          // 安定するまで待つ
}
//ADCの値を読む==========================================================
unsigned int adc() {
  unsigned int dL, dH;
  ADCSRA |= ( 1 << ADSC);            // AD変換開始
  while (ADCSRA & ( 1 << ADSC) ) {   // 変換完了待ち
  }
  dL = ADCL;                         // LSB側読み出し
  dH = ADCH;                         // MSB側
  return dL | (dH << 8);             // 10ビットに合成した値を返す
}

稼働時間を少しでも延ばすため、
ヒーター稼動時と待機時で電圧下限値を変えてあります。



使うときはベルトに取り付けたラジオポーチに入れて使います。  

Posted by 名無しのナナシ at 23:50Comments(0)エアガンカスタムエアガンマイコン

2018年11月11日

ガスガン内蔵ヒーター制御装置を作る その3

前回テストした回路を実装していきます。
まずはガスガン側から。



ガスガン~制御回路の配線は4芯カールコードを使います。



ガスガンと制御回路を切り離せるようにコネクターを取り付けます。



サーミスタはフィルムヒーターに直接接着します。
これはマガジンが装着されていない状態でも温度が上がり過ぎないようにするためです。




万が一の保険に72℃の温度ヒューズを取り付けました。



テストして問題ないか確認。
次回は制御回路の実装を行います。  

Posted by 名無しのナナシ at 23:35Comments(0)エアガンカスタムエアガンマイコン

2018年11月10日

ガスガン内蔵ヒーター制御装置を作る その2

ヒーター制御装置の回路とプログラムを作っていきます。

まずテスト用の回路図を作成しました。



NTCサーミスタを使った分圧回路で温度を検知し、FETでヒーターのオン・オフを行います。
バッテリーの電圧は固定抵抗を使った分圧回路を用いて検知します。



これをブレッドボード上で組み立て、テストを行います。

プログラムの方は、まず温度と電圧を読み取り、シリアルモニタに表示するプログラムを作成しました。

//ヒーター制御入力テスト用
//定数の宣言
const int V_R1 = 1000;     //電圧測定VIN側抵抗値[Ω]
const int V_R2 = 1000;     //電圧測定GND側抵抗値[Ω]
const int B = 4100     //サーミスタB定数
const int T_R0 = 10000;     //サーミスタ基準抵抗値[Ω]
const int T_R1 = 10000;     //バランス抵抗[Ω]
const int T0 = 298;     //サーミスタ基準温度[K]
//変数の宣言
float Vcc = 0;     //基準電圧[V]
int Val = 0;     //測定電圧[V×100]
int Temp = 0;     //測定温度[℃×10]

void setup () {
  Serial.begin(9600);     // 9600 bpsで接続
  Serial.println("READ_START");     // 最初に1度だけ Start を表示

void loop () {
  Vcc = cpuVcc();      //基準電圧の取得
  Temp = GetTemp(analogRead(A0));     //温度の取得
  Val = GetVal(analogRead(A1));      //電圧を取得
  Serial.print("Vcc=");     //基準電圧の表示
  Serial.print(Vcc);
  Serial.print(" TEMP=");     //温度の表示
  Serial.print(Temp);
  Serial.print(" V=");     //電圧の表示
  Serial.println(Val);
  delay(50);     // 0.05s 待つ
}
//センサーの値から温度を計算
float GetTemp (int raw){
  float V_R0 ;
  float R ;
  float t;
   
  V_R0 = raw * Vcc / 1.024;     //回路内抵抗の消費電圧を算出
  R = Vcc * 1000.0 / V_R0 * T_R1 - T_R1;     //サーミスタの抵抗値を算出
  t = (1000 / (1 / (0.001 * T0)+log(R / T_R0)*1000 / B) - 273);     //温度の計算
  return(int)(t * 10.0);     //10倍にして整数にする
}
//センサーの値から電圧を計算
int GetVal(int A){
  float V;
  V = A * Vcc / 1024.0 /V_R2 * (V_R1 + V_R2);     //電圧の計算
  return(int)(V * 100.0);     //100倍して整数にする
}

float cpuVcc(){     // 電源電圧(AVCC)測定関数
  long sum=0;
  adcSetup(0x4E);     // Vref=AVcc, input=internal1.1V
  for(int n=0; n < 10; n++){
    sum = sum + adc();     // adcの値を読んで積分
  }
  return (1.1 * 10240.0)/ sum;     // 電圧を計算して戻り値にする
}
 
void adcSetup(byte data){     // ADコンバーターの設定
  ADMUX = data;     // ADC Multiplexer Select Reg.
  ADCSRA |= ( 1 << ADEN);     // ADC イネーブル
  ADCSRA |= 0x07;     // AD変換クロック CK/128
  delayMicroseconds (500);     // 安定するまで待つ
}
 
unsigned int adc(){     // ADCの値を読む
  unsigned int dL, dH;
  ADCSRA |= ( 1 << ADSC);     // AD変換開始
  while(ADCSRA & ( 1 << ADSC) ){     // 変換完了待ち
  }
  dL = ADCL;     // LSB側読み出し 
  dH = ADCH;      // MSB側
  return dL | (dH << 8);     // 10ビットに合成した値を返す
}

以上のプログラムを書き込み、バッテリーを接続後、シリアルモニタを表示すると下のように表示します。
(このプログラムを使う際、マイコンVINの接続を切っておかないと、バッテリー電圧が高く表示されてしまいます。)


うまく表示できたら、今度はヒーターを動かしてみます。



プログラムは以下の通り。

//ヒーター制御プログラムテスト
//入出力ピンの名称変更
#define HEATER 2     //ヒーター制御出力
#define Temp_Input A0     //サーミスタ入力
#define Val_Input A1     //電圧測定入力
#define LED 13     //マイコンLED

//定数の宣言
const int V_R1 = 1000;     //電圧測定VIN側抵抗値(Ω)
const int V_R2 = 1000;     //電圧測定GND側抵抗値(Ω)
const int B = 4100;     //サーミスタB定数
const int T_R0 = 10000;     //サーミスタ基準抵抗値[Ω]
const int T_R1 = 10000;     //サーミスタバランス抵抗値[Ω]
const int T0 = 298;     //サーミスタ基準温度[K]
const int Limit_Val = 740;     //測定電圧下限値[V×100]
const int Limit_L_Temp = -200,Limit_H_Temp = 400;     //正常温度閾値[℃×10]
const int L_Temp = 280;     //温度下限値[℃×10]
const int H_Temp = 300;     //温度上限値[℃×10]
//変数の宣言
float Vcc = 0;     //マイコン電源電圧[V]
int Val = 0;     //測定電圧[V×100]
int Temp = 0;     //測定温度[℃×10]

void setup () {
  //入出力ピンの設定
  pinMode(HEATER, OUTPUT);
  pinMode(LED, OUTPUT);
  delay(1000);     //電源投入時1s待つ
}

void loop () {
  Vcc = cpuVcc();     //マイコン電源電圧の取得
  Temp = GetTemp(analogRead(Temp_Input));     //温度の取得
  Val = GetVal(analogRead(Val_Input));      //電圧を取得

  while (Val < Limit_Val) {     //測定電圧が下限値を下回るとヒーターをオフにし、
    digitalWrite(HEATER, LOW);     //マイコンLEDが長い間隔で点滅する
    digitalWrite(LED, HIGH);
    delay(100);
    digitalWrite(LED, LOW);
    delay(1000);
  }

  while (Temp > Limit_H_Temp || Temp < Limit_L_Temp){     //測定温度が正常な範囲内から外れると
    digitalWrite(HEATER, LOW);     //ヒーターをオフにし、マイコンLEDが短い間隔で点滅する
    digitalWrite(LED, HIGH);
    delay(100);
    digitalWrite(LED, LOW);
    delay(100);
  }

  digitalWrite(13, LOW);
  
  if (Temp <= L_Temp) {     //測定温度が下限値以下になると
    digitalWrite(HEATER, HIGH);     //ヒーターをオンにする
  }
  
  if (Temp >= H_Temp) {     //測定温度が上限値以上になると
    digitalWrite(HEATER, LOW);     //ヒーターをオフにする
  }
  delay(100);     //0.1s待つ
}
//センサーの値から温度を計算
float GetTemp (int raw) {
  float V_R0 ;
  float R ;
  float t;

  V_R0 = raw * Vcc / 1.024;     //バランス抵抗の消費電圧を算出
  R = Vcc * 1000.0 / V_R0 * T_R1 - T_R1;     //サーミスタの抵抗値を算出
  t = (1000 / (1 / (0.001 * T0) + log(R / T_R0) * 1000 / B) - 273);     //温度の計算
  return (int)(t * 10.0);     //10倍にして整数にする
}
//センサーの値から電圧を計算
int GetVal(int A) {
  float V;
  V = A * Vcc / 1024.0 / V_R2 * (V_R1 + V_R2);     //電圧の計算
  return (int)(V * 100.0);     //100倍して整数にする
}

float cpuVcc() {     // 電源電圧(AVCC)測定関数
  long sum = 0;
  adcSetup(0x4E);     // Vref=AVcc, input=internal1.1V
  for (int n = 0; n < 10; n++) {
    sum = sum + adc();     // adcの値を読んで積分
  }
  return (1.1 * 10240.0) / sum;     // 電圧を計算して戻り値にする
}

void adcSetup(byte data) {     // ADコンバーターの設定
  ADMUX = data;     // ADC Multiplexer Select Reg.
  ADCSRA |= ( 1 << ADEN);     // ADC イネーブル
  ADCSRA |= 0x07;     // AD変換クロック CK/128
  delayMicroseconds (500);     // 安定するまで待つ
}

unsigned int adc() {     // ADCの値を読む
  unsigned int dL, dH;
  ADCSRA |= ( 1 << ADSC);     // AD変換開始
  while (ADCSRA & ( 1 << ADSC) ) {     // 変換完了待ち
  }
  dL = ADCL;     // LSB側読み出し
  dH = ADCH;     // MSB側
  return dL | (dH << 8);     // 10ビットに合成した値を返す
}

プログラムの動きとしては、
電源接続後、1秒待ってから動作開始。

温度、電圧の取得。

電圧が下限値(7.4V)を下回ると無限ループで停止、LEDを1秒間隔、0.1秒点灯させる。

温度が異常な値(40℃を超え、-20℃を下回る)を示すと無限ループで停止、LEDを0.1秒間隔、0.1秒点灯させる。

温度が下限値(28℃)以下になるとヒーターをオンにする。

温度が上限値(30℃)以上になるとヒーターをオフにする。

以下繰り返し。

テストの結果うまくいったので、次からは実装を行います。  

Posted by 名無しのナナシ at 21:13Comments(0)エアガンカスタムエアガンマイコン

2018年11月10日

ガスガン内蔵ヒーター制御装置を作る その1

以前、このようなものを作りましたが、
問題があり、改良することにしました。

問題点としては、
1.モバイルバッテリーを使用しているので準備に手間と資金がかかる。
2.電圧が5Vでは25℃前後の保温が精一杯。

これらを解決するため、電動ガン用の7.4V LiPoバッテリーを使用したいと思いますが、
これの問題点として、
1.現状のままLiPoバッテリーを繋ぐと非常に高温となり危険。
2.バッテリーが過放電してしまい使用不能になってしまう。

これを解決するためヒーターの制御装置を作ることにしました。



初めはこのような既存の温度センサースイッチとオートカットを使うつもりでしたが、
この回路は動作電圧が12Vで、扱いが難しく頓挫していましたが、
いいものを見つけたのでそれを使います。




Amazonで売っていたマイコンボードです。
Arduino Nanoというマイコンボードの互換機で、
7V~12Vで動作するので7.4V LiPoバッテリーで使うことが出来ます。
これにセンサー類を取り付け、プログラムを書き込めばヒーターの制御装置を作ることが出来ます。



先ほどの温度センサースイッチと比べてとても小型です。

プログラムを書き込むにはArduino IDEという物が必要です。
こちらからダウンロードできます(英語のページ)。
インストール方法などの詳細はこちらから 互換機をそのままPCに接続しても認識しないので、CH340Gというドライバが必要です。
こちらからダウンロードできます(中国語のページ)。



とりあえずLEDを光らせることは出来たので、これから制御回路やプログラムを作っていきます。  

Posted by 名無しのナナシ at 00:15Comments(0)エアガンカスタムエアガンマイコン

2018年08月28日

次世代AK47 木製ストック取り付け他

次世代AK47に木製ストック取り付けます。


取り付けるのはMULE(CAW)製の木製ストックです。

まずは純正パーツを取り外します。


ハンドガードの取り外しは説明書P25のヒューズ交換のしかたを参照してください。


ハンドガードについている金属パーツを取り外します。
金属パーツは木製ハンドガードに接着剤を使って取り付けます。
取り付けネジは使わないので純正パーツと一緒に保管します。


グリップは下のネジを取り外せば外れます。
このネジも使わないので純正パーツと一緒に保管します


モーターはEG1000が付いています。


木製グリップは付属のネジで取り付けます。
ネジの頭は黒く塗りました。




ストックは根元のネジを3つ外します。
このネジは木製ストックの取り付けに使います。
木製ストックにはネジ穴が開いていないのでドリルで穴を開けます。
バットプレートは取り外して木製ストックに取り付けます。




取り外したパーツの合計重量は281g。




取り付けるパーツの合計重量は493g。
交換後は重量が212g増加します。


交換後の見た目。
ハンドガードとグリップが純正より太くなっているので、手が小さい人は握りにくくなるかもしれません。

バッテリーは問題無く入りました。


スリングはKM企画のAK用コットンスリングを取り付けます。


銃本体のスイベルの前から後ろにスリングのフック側を通します。


スリングを折り返してバンドを通します。



アジャスターを通して銃身のスイベルにフックを取り付けて完成です。


ガンカメラ取り付け用にバレルマウントを取り付けます。



クリーニングロッドが邪魔になったので外しました。
取り外しはクリーニングロッド先端を下に曲げながら引き出します。


マガジンは8本購入、付属の1本と合わせて9本携行します。



M14用のチェストリグを使ってゲームをしましたが、使いにくかったので
AK用のチェストリグを購入しました。  

Posted by 名無しのナナシ at 22:59Comments(0)エアガンカスタムエアガン

2018年08月19日

A&K M1ガーランド 調整、手直し

A&K M1ガーランドの調整、手直しを行ないます。
ゲームで使用しながら調整したので少し時間がかかりました。

まずは内部の調整から。

メカボックスはピストンをSHSピストン+マルイ純正ピストンヘッドに、シリンダーをフルシリンダーに交換。


スプリングはKMの0.8Jスプリングに交換。


配線はシリコンコードに交換。
モーターにSBDを取り付け。


インナーバレルは長すぎるので500mmに切断。

チャンバーは色々と難ありなので手間がかかりました。

2重給弾対策に給弾口直上(赤丸の場所)に弾止まりの窪みをつけます。


ホップクッションが入るようにホップ窓を拡張します。


ホップ窓にはいる大きさにホップクッションを切ります。


元から付いていたホップパーツをホップクッションの高さに合わせて調整します。


上の2つを接着して1つにします。


ホップパッキンをマルイ純正に交換、ガタ取りにテープを巻きました。


初速は91~93m/s前後になりました。

内部の調整は終わり、今度は外装の手直しです。


ストックの塗装が良くなかったので、サンダーで全て削り落としました。



塗装はワトコオイルのマホガニー、ダークウォルナットを使いました。


こんな感じで仕上がりました。


レシーバー左の忌まわしいセレクターをオミットします。
セレクター自体はネジを外せば取れます。
あとは削ってパテで埋めて再塗装するので、他の部品を取り外します。




リアサイトは左のネジを取り外し、シャフトを右から取り外すと全て外せます。



ボルトリリース(マガジンキャッチ)はレシーバーを裏返し、前に付いている芋ネジを取り外し、
シャフトを前に押し出すと取り外せます。
だた、構造がおかしいのでシャフトを押し出すのが難儀です。
細いマイナスドライバーをねじ込んで押し出しました。



元の塗装を塗装はがし剤を使って剥がします。
あまり強い塗装ではないようで簡単に剥がれました。



削りとパテ埋めした後、ラッカースプレーのつや消し黒で塗装しました。
あとは元通りに組んで本体は完了です。

最後にマガジンの手直しを行ないます。



弾薬ポーチに入れるのにマガジンに付いているプレートが邪魔なので取り外します。
マガジンに引っかかっているだけなので簡単に外せます。



弾薬ポーチに入れるとこんな感じです。


プレートを外したままだと見た目が悪いので、マガジン交換時にプレートを付け替えることにしました。
ただ、リロードはやり難くなってしまいます。


マガジンを傾けるとプレートが自重で脱落してしまうので、
プレートにアルミテープを貼って脱落しないようにしました。


わずかな衝撃で弾をぶちまけたので、プラリペアでストッパーを延長しました。

これで全て完了です。  

Posted by 名無しのナナシ at 20:09Comments(0)エアガンカスタムエアガン

2018年08月15日

サマトリウム・コバルトモーター試してみた

夏のボーナスが出たので、サマトリウム・コバルトモーターを買ってみました。



巷ではすごいと評判のモーターですが、正直「モーターごときに1万円も出せるか!」と思って今まで手を出さずにいました。



M14に入れるのでフォートレスのショート加工済みのものを買いました。



M14にはEG1000を入れていたのでそれと比較をします。
それぞれの発射音を録音してみました。
なお、M14にはライラクスのダブルトルクギアが組み込まれているのでサイクルが純正より遅くなっています。

EG1000モーター発射音


サマトリウム・コバルトモーター発射音


音を聞いた感じだとなんとなく変わったような気がするのですが、よく分からないので
編集ソフトを使って視覚化してみました。

セミオートの発射音(クリックで大きく表示します)

上の数字はフレーム数で、速度を10%にしてあるので600フレーム/秒です。
赤い線が発射音の先頭を示しています。
サマトリウム・コバルトモーターが約4フレーム早いのが分かります。


フルオートの発射音(クリックで大きく表示します)

こちらは速度を100%にしてあるので60フレーム/秒です。
どちらも約11発/秒で、立ち上がりはサマトリウム・コバルトモーターの方が早く
次第にEG1000モーターに追い越されています。

比較した感想は
セミオートでは確かに違いは出ますが、かなりの僅差です。
ただ、今回試したM14は低負荷型なので高負荷のカスタムなら違いは大きくなると思います。
フルオートでは3発ほどのバースト射撃なら有利です。
じっくり狙って撃つ銃に適したモーターだと思います。   

Posted by 名無しのナナシ at 12:02Comments(0)エアガンカスタムエアガン

2017年08月19日

マルゼンM870フルメタル化

マルゼンのM870はバレルとフレームがプラ製で見た目が安っぽいのが欠点です。



そこでG&Pのメタルアウターバレルとメタルフレームを組み込みます。
これはCA870用ですが互換性があるらしいです。
アウターバレルに付属している
インナーバレル、チューブマガジン、フォアグリップは使えません。



まず、本体の分解をします。
ストック内のプラスネジを外します。


ストック内部のガスチューブを外します。



これでストックが外せます。



フレームのネジ2つとピンを外し、トリガーガードを下に外します。



トリガーユニットを下に引っ張り出します。



バレル根元の芋ネジ、チューブマガジン先端のキャップを外して、バレルを引き抜きます。



フレームをバレル側からプラハン等で叩いてストック側に引き抜きます。
内部パーツが脱落しないように注意。
分解は完了です、メタルパーツを組み込んでいきます。



メタルフレームをストック側から挿入します。



純正トリガーガードについている銀色のパーツとスプリングを移植します。



取り付けはこんな感じです。



トリガーガードを取り付けます。
加工が必要と言う話ですが、
私の場合は叩き込んだら入りました。


メタルバレルに付いているカラーを銃口側に叩き出します。



純正バレルに付いているカラーを根元側に叩き出してメタルバレルに移植します。
あとは外したパーツを元に戻しますが、
マガジンチューブリングがフォアグリップに干渉するので削る必要があります。



ついでに長すぎるガスチューブを切り詰めておきました。



サイトが無いのでマルイM870のビーズサイトを接着しました。




これで完成です。  

Posted by 名無しのナナシ at 23:32Comments(0)エアガンカスタムエアガン

2017年07月03日

ナインボール デザートイーグル用マガジンバンパー取り付け

久しぶりの投稿。

ナインボールのデザートイーグル用マガジンバンパーを取り付けます。



取り付けることでスムーズなマガジンチェンジをアシストし、
不意な落下によるマガジン破損を回避する実用的なパーツです。
ただ、デザートイーグルに実用性を求めるべきなのだろうか?

取り付けはノーマルのベースプレートを外して、代わりに取り付けるだけです。
画像左がノーマル、右がマガジンバンパーを取り付けた状態です。




銃にマガジンを挿入した状態。
画像上がノーマル、上がマガジンバンパーを取り付けた状態です。



ツーハンドで構えた時に左手小指の収まりが良くなり、構えやすくなります。
しかし、ガスを注入する際、ライラクスのハイバレットガスは問題ありませんでしたが、
ウッドランドBBガスはノズルの長さが足らず、使用できませんでした。
  

Posted by 名無しのナナシ at 23:24Comments(0)エアガンカスタムエアガン

2016年01月02日

S&T M1903 分解、小改修

S&T M1903を分解して内部を確認します。



着剣ラグのネジを外し、スリングスイベルとともに前方にずらし、ハンドガードを取り外します。



側面前方の-ネジ左右1本、下側の-ネジ1本外してトリガーガードを外します。
側面後方のネジは飾りネジです。



これでストックから本体を外せます。



芋ネジ2つ外し、レシーバーとバレルを分離します。



ボルトリリースレバー、トリガーブロックを取り外し、シリンダーを抜き出します。



手持ちのL96シリンダーと比較。(下がL96)
シリンダー外径が22mmと同じでVSRより細い。
切り欠きはL96より後ろでシリンダー容量は大きい。VSRと同じか?
シリンダーヘッドはノズルの長さは短い、ネジピッチは細かく互換性なし。
ピストンは径が同じで全長が長い。長さはVSRと同じか?



コッキングハンドル付近を分解。
シリンダー後部はL96と全く異なります。



ピストンにはピストンカップが付いていましたが、
グリスを塗ると初速が落ちます。
ただ写真のようにOリングを取り付けることもできるようです。



これで組みなおしても初速は出ます。
今回はこれで行ってみます。



シリンダーヘッドにOリングを接着しておきました。

次はチャンバー付近を見てみます。



レンチを使ってアウターバレルを分割できます。



チャンバーブロックを外します。
このパーツには弾ポロを防ぐためのストッパーが付いています。
そのためマガジンを外しても弾が2発残ります。



ホップアジャスターを外しチャンバーを後ろに押し出します。



ホップはアジャスターが直接押す方式です。



チャンバーは4つのネジを外して分割します、



分割するとこんな感じです。
VSRに似ていますが、全く互換性はありません。



インナーバレルは電動ガンと同じで、VSRのものと異なります。



ホップパッキンも異なり、外の突起が無く、
外径は同じですが、入り口側の内径が小さくなっています。



ゴムの肉厚も違います。



インナーバレルに取り付けたときの位置も異なります。
このままでは取り付けができず、磨耗したときに困ります。



と言うことで入り口側を切り詰めて無理やり合わせます。
外の突起はそのまま使えます。



ホップパッキンの内径が大きくなった分はシリンダーヘッドのノズルの外径を太くします。
この熱収縮チューブを使います。



長さを合わせて、ライターであぶって収縮させたあと接着剤で固定します。


ホップアジャスターが貧弱で押さえ切れていないようなので、 針金とプラリペアで補強しました。


インナーバレルにシールテープを巻き、ガタ取りします。



初速が少し落ちたのでPDIのVSR細径スプリングを入れました。



初速はこんな感じです。



給弾不良が見られたのでマガジンを少し加工します。



ストッパーを削りました。
削りすぎてもプラリペアで補修可能です。

内部の補修はこんな感じです。
次は外装です。


ストックのお色直しをします。
紙やすりで表面をならします。



ワトコオイルのマホガニーを使います。



満遍なく塗りこんで、30分後にふき取り、1日乾燥させます。



仕上がりはこんな感じ。



スコープを取り付けます。
まずリアサイトを取り外し、マウントベースを取り付けます。



今回取り付けるのは密林に1000円で売ってあった、
外径が19mm、15mmマウントという謎スコープ。
普通なら使えないゴミですが、古い銃にはこの細さが合うかなと思って使ってみようと思います。



マウントが合うようにベースを削りました。



本体には元から開いているネジ穴で取り付けます。
削った箇所はつや消し黒の塗料でタッチアップします。



取り付けるとこんな感じ。



スコープを覗くとこんな感じ。

あとは実戦を待つのみです。  

Posted by 名無しのナナシ at 17:10Comments(3)エアガンカスタムエアガン