2017年2月27日月曜日

arduino リズムボックス

Arduino UNOMultifunction shield を使ったリズムボックスを紹介します。


Arduinoリズムボックスの使い方

ARDUINOリズムボックスの使い方を説明します。

  • LED リズム:1/4, 2/4, ….. 9/8 まで拍子ができる
    • 3-- プッ・プッ・ピッ と3/4で変化する。
  • LED  ビート:1分間のビート数
    • 120 -- 1分に120回の音がでる。
  • スイッチ S1: リズムを変える
    • 1-->2--> …… -->9 -->1
  • スイッチ S2:ビートを早くする
  • スイッチ S3:ビートを遅くする
回路図
これは回路図ですが、8セグLEDとスイッチはMultifunction shield のを使います、そしてピエゾスピーカーをA5ピンとGNDピンに接続しました。他の部品は使っていません。


  • スピーカー 赤線:Pin A5, 黒線: GND
  • スイッチ  S1: Pin A1、S2: Pin A2, S3: Pin A3
  • 8セグLED  SDI: Pin 8, CLK: Pin 7, LAT: Pin 4



プログラム構造
MsTimer2割り込みを2msインターバルで使います。ここでは8セグLEDの表示とスイッチ(S1,S2,S3)をチェックしています。
LOOP内ではTone時間と無音時間の設定を変数beatpatternで行います。






デモビデオ



ソースコード

#include <mstimer2 .h>
#define S1 A1   // Switch S1
#define S2 A2   // Switch S2
#define S3 A3   // Switch S3
#define SDI 8   // Serial data in pin
#define CLK 7   // Clock Pin 
#define LAT 4   // Latch Pin
#define SPEAKER A5 // Speaker Pin

int s1Latch;      //Switch S1 Latch
int s2Latch;      //Switch S2 Latch
int s3Latch;      //Switch S3 Latch
int beat = 120;   //BEAT parameter
int pattern = 1;  //RYTHM parameter
int count;


void Display (byte digit4, byte digit3, byte digit2, byte digit1);

unsigned char NUM_pattern[] = {
  0b00000011, // 0
  0b10011111, // 1
  0b00100101, // 2
  0b00001101, // 3
  0b10011001, // 4
  0b01001001, // 5
  0b01000001, // 6
  0b00011011, // 7
  0b00000001, // 8
  0b00011001  // 9

};

unsigned char Digit_pattern[] = {

  0b00010000,
  0b00100000,
  0b01000000,
  0b10000000

};

void tick(void) {
  int d3, d2, d1;
  d3 = beat / 100;
  d2 = (beat - d3 * 100) / 10;
  d1 = beat % 10;
  Display(pattern, d3, d2, d1);

  if (digitalRead(S1) == LOW) {
    if (s1Latch == LOW) {
      s1Latch = 1;
      pattern++;
      if (pattern > 9) pattern = 1;
    }
  } else s1Latch = 0;

  if (digitalRead(S2) == LOW) {
    if (s2Latch == 0) {
      s2Latch = 1;
      beat++;
      if (beat > 240) beat = 240;
    }
  } else s2Latch = 0;

  if (digitalRead(S3) == LOW) {
    if (s3Latch == 0) {
      s3Latch = 1;
      beat--;
      if (beat < 30) beat = 30;
    }
  } else s3Latch = 0;


}


void setup() {
  pinMode(SDI, OUTPUT);
  pinMode(CLK, OUTPUT);
  pinMode(LAT, OUTPUT);
  pinMode(S1, INPUT);
  pinMode(S2, INPUT);
  MsTimer2::set(2, tick); // tick のコール
  MsTimer2::start();
}

void loop() {

  if (count % pattern == 0) tone(A5, 3830    , 20);
  else tone(A5,  2864   , 20);

  count++;
  delay(60000 / beat - 20);


}
void Display(byte digit4, byte digit3, byte digit2, byte digit1) {
  static int Seg_count = 0;
  Seg_count++;
  switch (Seg_count) {
    case 1:
      digitalWrite(LAT, LOW);
      shiftOut(SDI, CLK, LSBFIRST, NUM_pattern[digit1]);
      shiftOut(SDI, CLK, LSBFIRST, Digit_pattern[0]);
      digitalWrite(LAT, HIGH);
      break;
    case 2:
      digitalWrite(LAT, LOW);
      shiftOut(SDI, CLK, LSBFIRST, NUM_pattern[digit2]);
      shiftOut(SDI, CLK, LSBFIRST, Digit_pattern[1]);
      digitalWrite(LAT, HIGH);
      break;
    case 3:
      digitalWrite(LAT, LOW);
      shiftOut(SDI, CLK, LSBFIRST, NUM_pattern[digit3]);
      shiftOut(SDI, CLK, LSBFIRST, Digit_pattern[2]);
      digitalWrite(LAT, HIGH);
      break;
    case 4:
      digitalWrite(LAT, LOW);
      shiftOut(SDI, CLK, LSBFIRST, NUM_pattern[digit4] - 1);
      shiftOut(SDI, CLK, LSBFIRST, Digit_pattern[3]);
      digitalWrite(LAT, HIGH);
      Seg_count = 0;
      break;
    default:
      break;
  }
}