質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.58%

【Arduino】ロータリーエンコーダの使い方

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 4,893

Alyn

score 40

 実現したいこと

ロータリーエンコーダから来る値を読み取ってシリアル通信で表示する。
下記プログラムを実行するとロータリーエンコーダを触っていないにも関わらずA,Bの値が変化してしまいます。
ロータリーエンコーダを動かした時だけ、A,Bの値が変化するようにするにはどうしたらよいでしょうか?

 ソースコード1

int EnPinA = 3;
int EnPinB = 4;
int ledPin12 = 12;
int ledPin13 = 13;

void setup()
{
  pinMode(EnPinA, INPUT);
  pinMode(EnPinB, INPUT);
  pinMode(ledPin12, OUTPUT);
  pinMode(ledPin13, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
  int A = 0;
  int B = 0;

  A = digitalRead(EnPinA);
  B = digitalRead(EnPinB);

  Serial.print("A : ");
  Serial.print(A);
  Serial.print(" / ");
  Serial.print("B : ");
  Serial.println(B);

  digitalWrite(ledPin12, A);
  digitalWrite(ledPin13, B);
  delay(100);
}

 回路

ロータリーエンコーダはD3,D4,GNDと繋がっている。
LEDは2つあり、1つ目はD12とGND、2つ目はD13とGNDと繋がっている(間に抵抗器あり)。

.【ロータリーエンコーダ】
.  A   B   G
.  │  │  │
.  D3  D4  GND
.【   Arduino   】
.  D12 GND D13 GND
.  │  │ │  │
.  抵抗 │ 抵抗 │
.  │  │ │  │
. 【LED 1】【LED 2】

 追記1

申し訳ありません。実機が手元になくて動作確認できていません。

シリアル通信の速度は9600で大丈夫なのでしょうか?

 追記2

ソースコードを改良致しました。
0,1の値が操作なしに変化することはなくなりました。
ありがとうございました。

 ソースコード2

int EnPinA = 3;
int EnPinB = 4;
int pos = 0;
void Position(int, int);

void setup()
{
    pinMode(EnPinA, INPUT_PULLUP);
    pinMode(EnPinB, INPUT_PULLUP);
    Serial.begin(57600);
    Serial.print("pos : ");
    Serial.println(pos);
}

void loop()
{
    int A = 0;
    int B = 0;
    A = digitalRead(EnPinA);
    B = digitalRead(EnPinB);
    Position(A, B);
}

void Position(int A, int B)
{
    static int bA = 1;
    static int bB = 1;
    static int bpos = 0;

    if((bA == A) && (bB == B))
    {
        // 何もしない
    }
    else
    {
        // bAbB == 00 or 11
        if(bA == bB)
        {
            if((bA != A) && (bB == B))
            {
                pos++;    // 右
            }
            else if((bA == A) && (bB != B))
            {
                pos--;    // 左
            }
        }
        // bAbB == 01 or 10
        else
        {
            if((bA != A) && (bB == B))
            {
                pos--;    // 左
            }
            else if((bA == A) && (bB != B))
            {
                pos++;    // 右
            }
        }

        if(bpos != pos)
        {
            Serial.print("pos : ");
            Serial.print(pos);
            if(bpos < pos)
            {
                Serial.println(" →");
            }
            else
            {
                Serial.println(" ←");
            }
            bpos = pos;
        }
        bA = A;
        bB = B;
    }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • YOshim

    2018/11/04 00:02

    エンコーダー信号のH/L切り替えの時間はどの程度でしょうか。エンコーダーの仕様がわかれば、シリアル通信の速度が十分かどうかが判断できます。1回転あたりのpulse数と1秒あたりの回転数から、1pulseの時間が算出できます。

    キャンセル

  • Alyn

    2018/11/05 10:10

    恐らくこのロータリーエンコーダだと思います。(8F2ではなく、2H2と書かれている) http://akizukidenshi.com/catalog/g/gP-00292/

    キャンセル

回答 4

checkベストアンサー

0

A相、B相それぞれのレベルを覚えておいて、立ち上がり/立ち下がりのエッジを捉えてカウントしていく操作をする必要がありますね

右回転の検出でカウントUP、左回転でカウントDOWN、それをどう判断するか考えてみてください


なんかまだ解決してないようで、、
まず、
pinMode(EnPinA, INPUT_PULLUP);
pinMode(EnPinB, INPUT_PULLUP);
としてください。
これでレベルが勝手に変わる、ということはなくなります

で、ここで言うロータリエンコーダとはダイヤルタイプの接点出力のヤツだと思いますが、これをきちんと動かそうとするとちとめんどくさいです
こっちでやったのは、1msほどのタイマ割り込みでA相B相を取り込み、チャタリング処理&エッジ検出してカウントさせるってことをやってました。
これだとArduinoNanoでもきちんとカウント動作ができます

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/02 22:59

    具体的にどうしたら良いのでしょうか?

    キャンセル

  • 2018/11/02 23:02

    まずは別回答を実行して、ちゃんと値が出るようにしてください

    キャンセル

  • 2018/11/03 00:16

    ロータリーエンコーダーって結構なスピードで信号のH/Lが切り替わるので
    回転スピードによってはArduinoでは難しいかも。
    仕様書と回転速度から信号のH/Lの周期を確認してみてください。

    とりあえずdelayはdelayMicrosecondsにしてみましょう。

    キャンセル

0

とりあえずINPUTをINPUT_PULLUP

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/02 22:56

    どう違うのですか?

    キャンセル

  • 2018/11/02 23:00

    入力が内部抵抗介してハイレベルに繋がるようになる

    キャンセル

  • 2018/11/03 13:19

    確かに定番エラーですね。 昔、それで失敗した。

    Pull Upしておかないと、出力が不安定になるので、Hi/Lowも不安定となる。
    回路が分からないので、なんともですが、可能性の一つ。

    キャンセル

0

既に回答が付いていますが、実際の結線はどうなっているのでしょうか?
出力が安定しない件は、Pullupかな、という気もしますが、相手機器との接続が分かっていないと不明です。

検索したら、   意外と知られていない?INPUT_PULLUP とか、pinMode (pin, mode) とかありました。

あと、別の方も触れていますが、 ロータリエンコーダ出力を シリアル通信で取得するのは無理があるかもです。 (変化が早すぎる)  LED点滅は、動いているが分かるレベルと思います。

参考情報として。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

仕様書に一回転で24パルスと書いています。
これはご自身の手で回転させるつもりでしょうか。
そうであれば、仮に1秒最大1回転として、4逓倍エンコーダーであることを考慮し、
24 x 4パルス/秒 => 10ms/pulse。
シリアル通信の9600bpsのときの1charの通信速度はおおよそ1000回/s => 1ms/回なので、
9600でもエンコーダーの状態を取りこぼすことはないと思います。
エンコーダーを早く動かした際に値が狂うようならボーレート上げてみてください。

また仕様書の4.3のfig.2にテスト回路が記載されています。
この内容を真似してプルアップ抵抗10kohmを接続してください。
*5V(or 3.3V)電源ラインとエンコーダーのA/B端子間に接続してください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.58%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る