カイワレスタイル

ゲーム、アニメ、プログラム、興味のあることをツラツラと。

Raspberry Pi 2でミサイルを発射する

※物騒なタイトルですが、オモチャのミサイルです。

Raspberry Pi 2で玩具のミサイルランチャーを制御してみた。


ミサイルランチャー

Raspberry Piを使ってラジコンを作ろうと思っているが、ただのラジコンじゃ面白く無い。
何か発射できると面白そうだなぁとググっていたら、クアッドコプター用のオモチャのミサイルランチャーというものを見つけた。

www.amazon.co.jp

これは、ミサイルランチャーの本体にモーターが付いていて、モーターを回すことで中のトリガーを弾いてミサイルが発射される仕組みらしい。

ミサイルランチャーには4本線のコネクタが付いていて、そのうち黄色と白がモーターの電源用で、赤と黒は用途不明だった。
今回は黄色と白しか使わないので、コネクタを取り除き、黄色と白だけ2.54mmピンヘッダにハンダ付けした。

f:id:kaiware007:20150722011033j:plain

黄色をRaspberry PiのGPIOに、白をGNDに接続した。
おそらくモーターの+ーなのでどっちに接続しても回転方向が変わるだけだと思う。


プログラム

#include <vector>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/joystick.h>
#include <wiringPi.h>
#include <unistd.h>
#include <cstdio>

#define TURRETOUT1 26

#define JOY_DEV "/dev/input/js0"

using namespace std;

int main(void) {
    int i = 0;

    // Initialize GPIO
    if ( wiringPiSetupGpio() == -1) {
        printf("setup error");
        return -1;
    }

    pinMode(TURRETOUT1, OUTPUT);
    digitalWrite(TURRETOUT1, 0);

    // Initialize Joystick
    int joy_fd = -1;
    int num_of_axis = 0;
    int num_of_buttons = 0;

    char name_of_joystick[80];
    vector<char> joy_button, old_button;
    vector<int> joy_axis;
    
    int fire_interval = 0;

    if((joy_fd = open(JOY_DEV, O_RDONLY)) < 0) {
        printf("Failed to open %s", JOY_DEV);
        return -1;
    }

    ioctl(joy_fd, JSIOCGAXES, &num_of_axis);
    ioctl(joy_fd, JSIOCGBUTTONS, &num_of_buttons);
    ioctl(joy_fd, JSIOCGNAME(80), &name_of_joystick);

    joy_button.resize(num_of_buttons, 0);
    joy_axis.resize(num_of_axis, 0);
    
    old_button.resize(num_of_buttons, 0);
    
    printf("Joystick: %s axis: %d buttons: %d\n", name_of_joystick, num_of_axis, num_of_buttons);

    fcntl(joy_fd, F_SETFL, O_NONBLOCK); // using non-blocking mode

    while(true) {
        js_event js;

        read(joy_fd, &js, sizeof(js_event));
        
        switch(js.type & ~JS_EVENT_INIT) {
            case JS_EVENT_AXIS:
                joy_axis[(int)js.number] = js.value;
                break;
            case JS_EVENT_BUTTON:
                joy_button[(int)js.number] = js.value;
                break;
        }

        if ( num_of_buttons > 1 ) {
            if ( fire_interval == 0 ) {
                if (( joy_button[0] == 1 )&&
                    ( old_button[0] == 0 )) {
                    fire_interval++;
                    digitalWrite(TURRETOUT1, HIGH);
                }
            }else{    
                fire_interval++;
            }

            if ( fire_interval > 5000 ) {
                fire_interval = 0;
                digitalWrite(TURRETOUT1, LOW);
            }

            printf("BUTTON %d FireInterval %3d\n", joy_button[0], fire_interval);
        }

        for ( int i = 0; i < num_of_buttons; i++ ) {
            old_button[i] = joy_button[i];
        }

        usleep(100);
    }
    
    close(joy_fd);
    return 0;
}

例によってコントローラーで制御している。
ボタンを押すと一定時間ミサイルランチャーのモーターが回転してミサイルを連射する。
一定時間回す理由は、ミサイルのトリガーに物理的な間隔があるため、モーターをトリガーの位置まで回さないと発射されないから。
今回モーターを回す時間をやけに長めにしているのは、回路的な問題のため(後述)


動作確認

ラズパイでミサイルランチャー!

一応発射はできたが、モーターを回す時間を短くしてボタンを連打すると途中でモーターが回らなくなる。
原因はよくわからないけど、モーターの小刻みな停止と回転で逆起電力やノイズが発生しておかしくなるっぽい。
手元にトランジスタダイオードがないので対処ができない…。
そろそろちゃんと電子回路の勉強をしないとなぁ。


参考資料

www.instructables.com

www.instructables.com