0

いつものように、いくつかの醜いパッチ作業でこの問題を回避する方法は知っていますが、それをエレガントにしたいと思います: Arduino によってコマンドされるモーター用の小さなラッパーを作成したいと思います。速度を決定するために、右のステップ カウンター (モーター クラスのメンバー変数) を変更する必要があるためです。ただし、これらの関数は明らかに同じ処理を行います...私の質問は、固有の割り込みルーチンで変更するカウンターをどのように決定できますか?

これが私がこれまでに持っているものです。ユーザーからの割り込みを隠したいと思います。

class Motor {
        volatile int counter;
        unsigned long lastUpdate; //Last timestamp update (for calculating the rate)

        static const unsigned int RESOLUTION = 1024; //Number of steps in one rev
        static const unsigned int RPMS_TO_RPM = 60000; //Convers rev/ms to rpm

    public:
        Motor() : counter(0)
        {
            lastUpdate = millis();
        }

        void encoderInput(bool pinA, bool pinB)
        {
            counter += (pinA ^ pinB)*(-1)+!(pinA ^ pinB);
        }

        int getRate() {
            int ret = float(counter)/RESOLUTION/(millis() - lastUpdate)*RPMS_TO_RPM;
            lastUpdate = millis();
            counter = 0;
            return ret;
        }
};

/* Example:
 * Motor motor1;
 *
 * void motor1_isr(void) {
 *    motor1.encoderInput(PIN_A, PIN_B);
 * }
 *
 * void setup() {
 *    attachInterrupt(PIN_I, motor1_isr, CHANGE);
 *    Serial.begin(9600);
 * }
 *
 * void loop() {
 *    Serial.println(motor1.getRate());
 *    delay(1000);
 * }
 */   

助けてくれてありがとう、それが終わったら他の人にも役立つと思います:)

よろしく、 ミスター・ミステール

4

1 に答える 1

1

あなたは根本的な問題に直面しています: ISR がデータなしで呼び出されます。つまり、ISR 関数には、割り込みのソースを示すデータは提供されません。

基本的なアプローチは、コードを書く人が関数をハードコーディングすることによって入力とアクションの間のリンクを提供することです。あなたが探しているトリッキーなアプローチは、ISR がソースが何であったかを把握できる方法です。

したがって、直交エンコーダからの 2N 入力を備えた N 個のモーターが必要です。CHANGE 条件では、すべての入力ピンに 1 つの割り込みハンドラが接続されます。N 個のモーターすべてに対して同じハンドラが呼び出されます。入力ピンを最後に呼び出されたときの値と比較することで、更新するモーターを特定できます。入力ピンが変更された場合は、そのモーターを呼び出します。ここに疑似コードがあります

Motor motor1;
Motor motor2;

onSomethingChanged() {
  static int in1aprev, in1bprev;
  static int in2aprev, in2bprev;
  int in1a, in1b;
  int in2a, in2b;
  in1a = digitalRead(....
  same for other in's

  if( (in1a!=in1alast) || (in1b!=in1blast)) {
    motor1.encoderInput(in1a,in1b);
    in1alast = in1a;
    in1blast = in1b;
  }

  if( (in2a!=in2alast) || (in2b!=in1blast)) {
    motor2.encoderInput(in2a,in2b);
    in1a2ast = in2a;
    in1b2ast = in2b;
  }

  return;
} 

少し前まで、このタイプの機能はチップ全体で処理されていました (プログラマブル割り込みコントローラを参照)。チップは、割り込みのソースをトリガーしてキャプチャするためのすべてのロジックを実装しています。メインCPUは「何かが起こった」というトリガーを取得します。ハンドラーはチップをポーリングして、「何が起こったのか」を尋ねます。

この方法を提供したので、お勧めできるかどうかわかりません。コードで何が起こっているかを隠すことはできません。モーターは正しいピンに物理的に配線する必要があります。あなたは希少な資源を消費してしまいました -- 人々に伝えなければなりません。

于 2013-06-18T05:52:35.497 に答える