3
4

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()用の関数作ってみた3

Last updated at Posted at 2016-03-04

Arduino(?)に繋いだ可変抵抗を本当に回した時だけ値を受けとるには?
analogRead()用の関数作ってみた
analogRead()用の関数作ってみた2の続きです。

すっきりいかない感じ、わかりました。
変にオブジェクト的にしなくちゃと考えすぎてました。
間違っていました。
自分の欲しいのは、記憶しておいてくれるちょっと賢い関数でした。

クラスを分割する

っていうか違う考えで作りなおしたほうが良い。
何となく可変抵抗(VR)というモノでひとくくりにしてたけど、データの流れで見れば、getAverage()はデータをフィルタで加工しているし、isChanged()は出力メータを監視しているようなものだ。
で、FilterとMeterに分割してみました。

#include <MIDIUSB.h>
class Filter
{
  static const int MODULUS_AVERAGE = 8;
  private:
    int val_hist[MODULUS_AVERAGE];
    int sum;
    byte i_average;
  public:
    Filter();
    int getAverage(int val);
};
Filter::Filter(){
  for(int i = 0; i < MODULUS_AVERAGE; i++) val_hist[i] = 0;
  sum = 0;
  i_average = 0;
}
int Filter::getAverage(int val){
  sum += ( val - val_hist[i_average] );
  val_hist[i_average] = val;
  i_average = ++i_average % MODULUS_AVERAGE;
  return sum / MODULUS_AVERAGE;
}

class Meter
{
  static const int MODULUS_CHANGED = 4;
  private:
    int val2_hist[MODULUS_CHANGED];
    byte i_changed;
  public:
    Meter();
    boolean isChanged(int val);
};
Meter::Meter(){
  for(int i=0;i < MODULUS_CHANGED; i++) val2_hist[i] = 0;
  i_changed = 0;
}
boolean Meter::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;
}

字数は多くなったものの、名前と機能が何となく関連付いているように見えてきて、見易くなったような気がする...

使い方

FilterとMeterを必要な数だけインスタンス化して、あとは同じ考えです。

Filter filter[4];
Meter meter[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( meter[i].isChanged( temp = filter[i].getAverage( analogRead(ANAPIN[i]) >> 3 ))){
      controlChange(CHANNEL,CC[i],temp);
      MidiUSB.flush();
    };
  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);
}

これだったら後で見ても、何をしたかったか読みとれそう...

3
4
1

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
3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?