3
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()用のライブラリを作ってみた

Last updated at Posted at 2016-04-14

Arduino(?)に繋いだ可変抵抗を本当に回した時だけ値を受けとるには?にアイディアをいただいてanalogRead()用の関数作ってみた5 もっと関数までやってきた、その続きです。

その後、配列が好きなサイズで作れたらいいな...なんて思ったのが運のつき、c++の深みにハマってしまい、どうせならと思ってライブラリにしてみました。ふう。SmoothFunc for Arduino

使い方

ZIPファイルをダウンロードして、スケッチ>ライブラリをインクルード>.ZIP形式のライブラリをインストール... でインストールします。

三つの関数オブジェクトがあります。

  • "GetAverage" : 引数と内部の履歴から合計を計算し、引数を履歴に記憶しつつ一番古い値を捨て、平均を返す。
  • "IsNewInRecents" : 引数が履歴に含まれていないかを計算し、引数を履歴に記憶しつつ一番古い値を捨て、計算結果を返す。
  • "IsUniqueInUniques" : 引数が履歴に含まれていないかをを計算し、含まれていない場合のみ引数を履歴に記憶しつつ一番古い値を捨て、計算結果を返す。

この関数を使って、

  • 平均をとり(これだけでもかなり安定する場合があります)
  • 更にそれを直近の平均の履歴の中で新しいかどうかのふるいにかけ、
  • 新しいときだけ必要な処理をする

という戦略です。

#include <SmoothFunc.h> //ライブラリを読み込む

GetAverage getAverage;  //関数オブジェクトをインスタンス化
IsNewInRecents isNew;      

const int ANA_PIN = 5;  //アナログ入力に使用するピン番号を設定

void setup(){
//...
}
void loop(){
  const int RAW_DATA = analogRead(ANA_PIN);         //入力ピンの値を読み込んでRAW_DATAを生成
  const int SMOOTHED_DATA = getAverage(RAW_DATA);   //平均を計算してその値でSMOOTHED_DATAを作成
  if (isNew(SMOOTHED_DATA)) {                       //SMOOTHED_DATAが新しければ

    //...その場合にしたい処理をここに書きます。  

    }
  delay(10);
}

IsUniqueInUniquesIsNewInRecents のバリエーションです。
IsNewInRecents を使っても動作が安定しない場合にお使いください。使い方は同じです。
より小さいサイズの履歴で動作を安定させられる場合があります。
一方で履歴のサイズが大きいと出力データが不連続になる傾向があります。調整してお使いください。

デフォルトの履歴サイズは GetAverage が 8, IsNewInRecents,IsUniqueInUniques が 3 になっています。
単体の場合は
GetAverage foo(5);
配列の場合は
GetAverage bar[3]={10,20,30};
のようにすれば他の値を指定して作ることができます。

使用例

今までの、複数のアナログ入力を受け取ってMIDIコントロールチェンジを返すスケッチがどうなるかというと

#include <MIDIUSB.h>
#include <SmoothFunc.h>

GetAverage getAverage[2];
IsNewInRecents isNewInRecents[2];
const int ANAPIN[2] = {0,1};
const byte CHANNEL = 0;
const byte CC[2] = {25,26};

void setup() {
  Serial.begin(115200);
}

void loop() {
  for (int i = 0; i < 2; i++) {
    const int SMOOTHED_DATA = getAverage[i]( analogRead(ANAPIN[i]) >> 3 );
    if ( isNewInRecents[i](SMOOTHED_DATA) ) {
      controlChange( CHANNEL, CC[i], SMOOTHED_DATA );
      MidiUSB.flush();
    };
  delay(10);
  };
}

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

どうですか? なかなか見た目スッキリでいいんじゃない?と自画自賛。やってることは今までと同じですが...

まとめ

よろしければお使いください。
おかしな英語のREADME作文ともども、おかしなところがあればコメントおねがいします。

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