2015年12月21日 星期一

DIY藍芽遙控的飛彈發射炮台


最近DIY上身, 不知為何, 在DIY的過程總能療愈白天上班的辛苦...廢話不多說, 進入主題

先來張很威的照片





藍芽是用2片HC05的模組, 右邊的M代表是Master, 左邊的S代表是Slave, 已設定成開機自動對連, 省去開機還要連線的麻煩



控制板是用Arduino Nano, 沒什麼週邊線路就是控制3路的servo而已, 加上一個HC05的藍芽模組


飛彈發射裝置是路過LEGO店時買的, 拿來做這個飛彈發射裝置真是剛剛好, 旁邊加一個servo, 是負責發射炮彈的



也滿威的45度角照片, 看起來賞心悅目, 自己DIY的很開心



全體照, 中間的藍芽搖控模組, 如果有人想DIY, 請參考這篇DIY自己的藍芽手把



飛彈發射炮台的完整程式碼

#include <Servo.h>
#include <SoftwareSerial.h>

#define MissileFortXStartLocation 66
#define MissileFortYStartLocation 66
#define MissileFortRightLimit 162
#define MissileFortUpLimit 18
#define MissileFortDownLimit 162
#define MissileFortLeftLimit 18
#define MissileFortShootOn 25
#define MissileFortShootOff 50

//** 指令動作代碼 *****************************************************************
#define _US 0x5553
#define _DS 0x4453
#define _LS 0x4C53
#define _RS 0x5253
#define _SS 0x5353
#define _ST 0x5354
#define _NO 0x4E4F

Servo MissileFortX, MissileFortY, MissileFortShoot;
SoftwareSerial BT(8,7); //RX=8 , TX=7

unsigned long Rot_delayInterval=50;
unsigned long Rot_previousMillis=0;
int RotAngel_X=MissileFortXStartLocation;
int RotAngel_Y=MissileFortYStartLocation;
boolean debug=1;

//** UART *************************************************************************
unsigned int InstructionCode;
unsigned char r_buffer[4];
unsigned char InstructionCharCounter=0;
unsigned char UartCommand;

void setup() {
  Serial.begin(38400);  
  BT.begin(38400);
  //Serial.println("attach servo");

  MissileFortX.write(MissileFortXStartLocation);
  MissileFortY.write(MissileFortYStartLocation);
  MissileFortShoot.write(MissileFortShootOff);

  MissileFortX.attach(9);
  MissileFortY.attach(11);
  if(debug) Serial.println("MissileFort is ready...");
  delay(1000);
  MissileFortX.detach();
  MissileFortY.detach();
}

void loop() {
  CheckUart();
  CheckUartCommand();
  } // EOF- Loop

//** 解碼指令 *********************************************************************
void CheckUartCommand() {
    if(UartCommand==1)
        {
        UartCommand=0;
        switch(InstructionCode)
            {        
            case _SS:   StopServo();break;
            case _NO:   DoNoThing();break;      
            case _ST:   DoST();break;  
            case _RS:   MissileFortTurnRight();break;
            case _LS:   MissileFortTurnLeft();break;
            case _US:   MissileFortTurnUp();break;
            case _DS:   MissileFortTurnDown();break;
            }
        } //EOF - command
}

void DoNoThing() { }

void MissileFortTurnDown() {
  if(debug) {
    Serial.print("MissileFortTurnDown...RotAngel_Y = ");
    Serial.println(RotAngel_Y);
    }
  if(RotAngel_Y >= MissileFortDownLimit) {
    RotAngel_Y=MissileFortDownLimit;
    Serial.println("Down Limit");
    }
  else {
    MissileFortY.attach(11);
    RotAngel_Y=RotAngel_Y+1;
    MissileFortY.write(RotAngel_Y);
    }
  }

void MissileFortTurnUp() {
  if(debug) {
    Serial.print("MissileFortTurnUp...RotAngel_Y = ");
    Serial.println(RotAngel_Y);
    }
  if(RotAngel_Y <= MissileFortUpLimit) {
    RotAngel_Y=MissileFortUpLimit;
    Serial.println("Up Limit");
    }
  else {
    MissileFortY.attach(11);
    RotAngel_Y=RotAngel_Y-1;
    MissileFortY.write(RotAngel_Y);
    }
  }

void MissileFortTurnRight() {
  if(debug) {
    Serial.print("MissileFortTurnRight...RotAngel_X = ");
    Serial.println(RotAngel_X);
    }
  if(RotAngel_X <= MissileFortLeftLimit) {
    RotAngel_X=MissileFortLeftLimit;
    Serial.println("Right Limit");
    }
  else {
    MissileFortX.attach(9);
    RotAngel_X=RotAngel_X-6;
    MissileFortX.write(RotAngel_X);
    }
  }

void MissileFortTurnLeft() {
  if(debug) {
    Serial.print("MissileFortTurnLeft...RotAngel_X = ");
    Serial.println(RotAngel_X);
    }
  if(RotAngel_X >= MissileFortRightLimit) {
    RotAngel_X=MissileFortRightLimit;
    Serial.println("Left Limit");
    }
  else {
    MissileFortX.attach(9);
    RotAngel_X=RotAngel_X+6;
    MissileFortX.write(RotAngel_X);
    }
  }

void StopServo() {
  MissileFortX.detach();
  MissileFortY.detach();
  MissileFortShoot.detach();
  }

void DoST() {
  MissileFortShoot.attach(10);
  MissileFortShoot.write(MissileFortShootOn);
  delay(500);
  MissileFortShoot.write(MissileFortShootOff);
  delay(500);
  }

//** 檢查UART *******************************************************************
void CheckUart() {
  if(BT.available())
    {
    unsigned char readbuf = BT.read();
    r_buffer[InstructionCharCounter]=readbuf;
    InstructionCharCounter++;
    if(readbuf==0x3B) {
      if(InstructionCharCounter==3) {
        InstructionCode = (r_buffer[0]<<8) | (r_buffer[1]);
        }
      InstructionCharCounter=0;
      UartCommand=1;
      }
    }
  }



實際動作影片

目前的問題是servo在移動時會有卡卡的怪動作, 還找不出問題在哪裡?如果有人知道的話, 請分享一下, 感恩~~~

2 則留言:

歡迎大家來討論交流一下~~~