5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

analogRead()用の関数作ってみた2

Last updated at Posted at 2016-03-04

analogRead()用の関数作ってみたの続きです。
複数の可変抵抗を付けるときにはどうしたらいいか考えてみました。
前回と同じことをクラスを使ってしてみます。
#クラスを作る

class VR
{
  static const int MODULUS_AVERAGE = 8;
  static const int MODULUS_CHANGED = 4;
  private:
    int val_hist[MODULUS_AVERAGE];
    int sum;
    byte i_average;
    int val2_hist[MODULUS_CHANGED];
    byte i_changed;
  public:
    VR();
    int getAverage(int val);
    boolean isChanged(int val);
};

VRクラスを作って、前回使ってた定数、変数を、全部ぶちこみました。
最後のセミコロンが重要らしいです。打ち忘れててコンパイルエラー出ました。
#コンストラクタ


VR::VR(){
  for(int i = 0; i < MODULUS_AVERAGE; i++) val_hist[i] = 0;
  sum = 0;
  i_average = 0;
  for(int i=0;i < MODULUS_CHANGED; i++) val2_hist[i] = 0;
  i_changed = 0;
}

変数を0で初期化しました。

#移動平均を出力する関数

int VR::getAverage(int val){
  sum += ( val - val_hist[i_average] );
  val_hist[i_average] = val;
  i_average = ++i_average % MODULUS_AVERAGE;
  return sum / MODULUS_AVERAGE;
}

この辺は前のと同じです。
#値が変ったかを判定する関数

boolean VR::isChanged(int val){
  val2_hist[i_changed] = val;
  i_changed = ++i_changed % MODULUS_CHANGED;
  for(int j = 0; j < MODULUS_CHANGED - 1; j++){
      if( val == val2_hist[(i_changed + j) % MODULUS_CHANGED] ) return false;
  };
  return true;
}

#使い方
最近使えるようになった32u4,ARM用のMIDIUSBを使ってみます。
まず、頭にこいつを書きます。

#include <MIDIUSB.h>
...

可変抵抗を四つ、A0~A3に付けて、それぞれCC25~28を出力するとします。

VR vr[4];
const int ANAPIN[4]={0,1,2,3};
const byte CHANNEL = 0;
const byte CC[4] ={25,26,27,28};
 
void setup() {
  Serial.begin(115200);
}

void loop() {
  int temp;
  
  for(int i=0;i < 4; i++){
    if( vr[i].isChanged( temp = vr[i].getAverage( analogRead(ANAPIN[i]) >> 3 ) ) ){
      controlChange(CHANNEL,CC[i],temp);
    };
    
  delay(10);
  };
}

//controll value or velocity
// First parameter is the event type (0x0B = control change).
// Second parameter is the event type, combined with the channel.
// Third parameter is the control number number (0-119).
// Fourth parameter is the control value (0-127).

void controlChange(byte channel, byte control, byte value) {
  midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
  MidiUSB.sendMIDI(event);
}

核心部分がこみいってますが、

  • ピンをanalogRead()して
  • 3だけ右シフト(=8で割る)して
  • 移動平均を求めて
  • tempに入れて
  • もし値が変化してたら
  • tempをCCの値としてMIDI OUTする

という目論見です。

手元にあったastar32u4単体で試してみました。
良さげな可変抵抗がなかったからですが、ふらふら出ているデータを見るとちゃんと動いている感じです。
#まとめ
普段使ってない脳みそを使って疲れました。
ちょっと関数が値を覚えておいてくれるだけでいいのに...
もっと楽なやりかたがきっとあるんだろうな...

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?