N.Y.Cityのまちかど

3-3-7_Beat_Machine

(作例)3-3-7拍子マシン

経緯

ちょっとした必要があって、Studino(Arduino)と圧電ブザー・LED・サーボモータを使って 3-3-7拍子マシンを作りました。

とりあえず動けばOK!くらいのノリで、短時間で適当に作ったのでプログラムもかなり荒っぽいですが参考として掲載します。

動作

決まったテンポで3-3-7拍子を奏でます。圧電ブザーが鳴らすビートに合わせてLEDが点灯し、サーボモータが旗を振ります。

動画:https://youtu.be/e9Om9A3y4m4

設計

部品表

  • Studuino
  • 圧電ブザー(他励式)
  • LED(赤)
  • 炭素被膜抵抗
  • サーボモータ(ミニスタジオ有限会社 RB303)
  • DCジャック付ケーブル(先端を半田あげしてブレッドボードに差せるようにしています)
  • 5VACアダプタ
  • 各種配線材

回路図

3-3-7Circuit.png

ソースコード

/*
 * Studuino_Demo.c
 *
 * Created: 2019/08/14 21:30:50
 * Author : Nao.Y
 */

/*** ヘッダインクルード ***/
#include <avr/io.h>
#include <avr/interrupt.h>

/*** ポート定数設定 ***/
//ブザー制御ポート
//Studuino D12 ATmega168 PB4
#define BUZZER_DDR DDRC
#define BUZZER_DDRBIT DDRC0
#define BUZZER_PORT PORTC
#define BUZZER_PORTBIT PORTC0

//LED制御ポート
//Studuino D13(オンボードLED) ATmega168 PB5
#define LED_DDR DDRB
#define LED_DDRBIT DDRB5
#define LED_PORT PORTB
#define LED_PORTBIT PORTB5

//サーボ制御ポート
//Studuino D2 ATmega168 PD2
#define SERVO_DDR DDRD
#define SERVO_DDRBIT DDRD2
#define SERVO_PORT PORTD
#define SERVO_PORTBIT PORTD2

/*** プロトタイプ宣言 ***/
void timer_init(void);        //タイマ初期化
void io_init(void);            //入出力初期化
void beat_update(void);        //ビート更新処理

/*** 定数宣言 ***/
static long TIME_BUZZER = 28; //880Hz×2=1760Hz=568.1818usec を20usec単位で表現
static long TIME_BEAT = 10000; //2.5Hz×2=5Hz=200000usec  を20usec単位で表現
static long TIME_SERVO = 1000; //20msec=20000usec  を20usec単位で表現

/*** グローバル変数宣言 ***/
volatile long Counter_buzzer = 0;    //ブザー制御時間計測
volatile long Counter_beat = 0;        //ビート制御時間計測
volatile long Counter_servo = 0;    //サーボ制御時間計測

int Flg_buzzer = 0;                    //ブザー鳴動フラグ(0で停止)
int Flg_led = 0;                    //LED点灯フラグ(0で停止)
int Flg_servo = 1;                    //サーボ制御フラグ(0で停止)

long Ctrl_servo = 0;                //サーボ角度制御値



/*****************************************/
/*        main関数                       */
/*****************************************/
int main(void)
{
    /* Replace with your application code */
    timer_init();        //タイマ初期化
    io_init();            //入出力初期化

    sei();                //割込み許可

    //メインループ
    while (1)
    {
        //ビート制御
        if(Counter_beat > TIME_BEAT){
            //ビート更新時間になったら次拍の制御へ移る
            beat_update();

            //LED更新
            if(Flg_led != 0){
                LED_PORT ^= (1 << LED_PORTBIT);
                }else{
                LED_PORT &= ~(1 << LED_PORTBIT);
            }
            Counter_beat = 0;
        }

        //ブザー制御
        if(Counter_buzzer > TIME_BUZZER){
            if(Flg_buzzer != 0){
                BUZZER_PORT ^= (1 << BUZZER_PORTBIT);
                }else{
                BUZZER_PORT &= ~(1 << BUZZER_PORTBIT);
            }
            Counter_buzzer = 0;
        }

        //サーボ制御
        if(Counter_servo > TIME_SERVO){
            Counter_servo = 0;
            SERVO_PORT ^= (1 << SERVO_PORTBIT);
        }else{
            if(Flg_servo != 0){
                if(Counter_servo > Ctrl_servo){
                    SERVO_PORT &= ~(1 << SERVO_PORTBIT);
                }

                /*
                if(Counter_servo < Ctrl_servo){
                    SERVO_PORT ^= (1 << SERVO_PORTBIT);
                }else{
                    SERVO_PORT &= ~(1 << SERVO_PORTBIT);
                }
                */
            }
        }


    }
}

/*****************************************/
/*        タイマ初期化処理               */
/*音は440Hz 割込み間隔は880Hz=1136usec  */
/*クロックは8MHz                         */
/*プリスケーラ 8分周           */
/*****************************************/
void timer_init(void){

    TCNT0=0;
    OCR0A=20;
    OCR0B=0;//使用しない

    TCCR0A = 0x02;//0000 0010
    TCCR0B = 0x02;//0000 0010

    TIMSK0 = 0x02;//0000 0010
}


/*****************************************/
/*        入出力初期化処理               */
/*****************************************/
void io_init(void){
    //D12=PB4 OUTPUT
    BUZZER_DDR = 0x00;
    BUZZER_PORT = 0x00;

    LED_DDR = 0x00;
    LED_PORT = 0x00;

    SERVO_DDR = 0x00;
    SERVO_PORT = 0x00;

    BUZZER_DDR |= (1 << BUZZER_DDRBIT);
    BUZZER_PORT &= ~(1 << BUZZER_PORTBIT);

    LED_DDR |= (1 << LED_DDRBIT);
    LED_PORT &= ~(1 << LED_PORTBIT);

    SERVO_DDR |= (1 << SERVO_DDRBIT);
    SERVO_PORT &= ~(1 << SERVO_PORTBIT);


}

/*****************************************/
/*        ビート更新処理                 */
/*****************************************/
void beat_update(void){
    static int beat_counter = 0;

    //LEDと音のコントロール
    switch(beat_counter){
    case 0:
    case 2:
    case 4:
    case 8:
    case 10:
    case 12:
    case 16:
    case 18:
    case 20:
    case 22:
    case 24:
    case 26:
    case 28:
        Flg_led = 1;        //LED点灯
        Flg_buzzer = 1;        //ブザー鳴動
    break;

    default:
        Flg_led = 0;        //LED消灯
        Flg_buzzer = 0;        //ブザー停止
    break;


    }

    //サーボコントロール
    switch(beat_counter){
        case 0:
        case 1:
        case 8:
        case 9:
            Ctrl_servo = 71;    //3拍のうち1つ目
        break;

        case 2:
        case 3:
        case 10:
        case 11:
            Ctrl_servo = 83;    //3拍のうち2つ目
        break;

        case 4:
        case 5:
        case 12:
        case 13:
            Ctrl_servo = 94;    //3拍のうち3つ目
        break;

        case 16:
        case 17:
            Ctrl_servo = 66;    //7拍のうち1つ目
        break;

        case 18:
        case 19:
            Ctrl_servo = 71;    //7拍のうち2つ目
        break;

        case 20:
        case 21:
            Ctrl_servo = 77;    //7拍のうち3つ目
        break;

        case 22:
        case 23:
            Ctrl_servo = 83;    //7拍のうち4つ目
        break;

        case 24:
        case 25:
            Ctrl_servo = 89;    //7拍のうち5つ目
        break;

        case 26:
        case 27:
            Ctrl_servo = 94;    //7拍のうち6つ目
        break;

        case 28:
        case 29:
            Ctrl_servo = 100;    //7拍のうち7つ目
        break;

        default:
            Ctrl_servo = 60;    //基準位置
        break;


    }


    beat_counter++;

    //休符込み16拍(ON/OFFで倍になるから32)で一回り
    if(beat_counter > 31){
        beat_counter = 0;
    }




}

/*****************************************/
/*        タイマ割込みハンドラ           */
/*****************************************/
SIGNAL( TIMER0_COMPA_vect ){
    Counter_beat++;
    Counter_buzzer++;
    Counter_servo++;
}

現在ご覧のページの最終更新日時は2019/08/16 18:08:50です。

Copyright (C) N.Y.City ALL Rights Reserved.

Email: info[at]nycity.main.jp