ロータリーエンコーダでLチカの明るさをコントロール【マイコンLチカ道場 Arduino編 2-3】

Arduino nanoでロータリーエンコーダのテスト Arduino
当サイトのリンクにはアフィリエイト広告が含まれています。

今回は、久々にマイコンボードArduino Nanoとロータリーエンコーダを使って、LEDの明るさを調整してみようという試みです。

ロータリーエンコーダの出力でPWM値を変化させて、その値を使ってLEDの明るさを変化させてみます。

このページは「マイコンLチカ道場 Arduino編」の「2-3:ロータリーエンコーダでLチカの明るさをコントロール」に対応するページです。

スポンサーリンク

ロータリーエンコーダとは

ロータリーエンコーダとは、回転による機械的変位を電気信号に変換し、位置や速度を検出するセンサです。

今回使うのはインクリメンタル型とよばれるもので、回転に応じてパルスを出力するタイプです。

通常のボリューム(可変抵抗)は、一定の角度まで回しきると止まりますが、無限にクルクル回転するようなものが今回使うロータリーエンコーダです。
マウスのホイールなど、身近な物によく使われていますね。

今回使用するロータリーエンコーダ

アルプス電気製:EC12E2420801(24クリックタイプ)
秋月電子で購入しました。

秋月電子で購入したロータリーエンコーダ(アルプス電気製:EC12E2420801)
秋月電子で購入したロータリーエンコーダ(アルプス電気製:EC12E2420801)裏面

ブレッドボードに挿せるようにリード線をはんだ付けしています。
ピン配列は左からA、C、Bです。

動作時の波形をオシロスコープで確認してみました。

右回り時の波形
A相(上側)がLoに変化時、B相(下側)はHiになっています。

時計回し時の波形

左回り時の波形
A相(上側)がLoに変化時、B相はLoになっています。

反時計回り時の波形

このようなA相とB相の位相の違いを見て、回転方向を検出します。

※上記の波形は、フィルタ回路は無しの状態です。時間軸を拡大するとチャタリングが見られるため、メーカー推奨のフィルタ回路を入れてみました。

チャタリング波形
スポンサーリンク

回路図

今回の実験での回路図は下記になります。

ロータリーエンコーダのテスト回路図

マイコンボードはArduino nanoを使用。
ロータリーエンコーダの回路は、5Vへのプルアップ抵抗と、
メーカーホームページ記載の推奨フィルタ回路(R3、R4とC1、C2)を入れています。

部品リスト

品名参照名数量数値・仕様
マイコンボードA11Arduino nano
LEDD11青色LED
ロータリーエンコーダSW11アルプス電気製
EC12E2420801
抵抗器R1、R2210kΩ
抵抗器R3、R4210kΩ
抵抗器R51220Ω
コンデンサC1、C220.01μF(103)

プログラム(スケッチ)

【やりたいこと】
・ロータリーエンコーダを回してPWM値を可変
・ロータリーエンコーダ用のライブラリ「Encoder.h」(Encoder by Paul Stoffregen)を使用
・PWM値でLEDを点灯
・確認用に、シリアルモニタでPWM値とロータリーエンコーダの値を表示させる

上記の内容でプログラムを作ってみました。

//ライブラリ読み込み
#include <MsTimer2.h> //タイマー割込み用ライブラリ
#include <Encoder.h> //ロータリーエンコーダ用ライブラリ

//ロータリーエンコーダのA相とB相を接続するピン番号を設定
const int pinA = 2;
const int pinB = 3;
Encoder myEnc(pinA, pinB);

//ロータリーエンコーダの現在位置と前回位置を保持する変数
volatile long oldPosition  = 0; 
volatile long newPosition  = 0;

//LEDを接続するピン番号を設定
const int ledPin = 9;

// LEDの明るさ(PWM値)を保持する変数
volatile int brightness = 0;

//ロータリーエンコーダの割り込み処理関数
//ライブラリから得た数値を保存
void rotEnc() { 
  newPosition = myEnc.read();
}

void setup() {
  //3ms毎にロータリーエンコーダ関数を実行
  MsTimer2::set(3, rotEnc); 
  MsTimer2::start();

  //デバッグ用のシリアル通信
  Serial.begin(115200);
}

void loop() {

   //ロータリーエンコーダの数値が変化した場合
   if (newPosition != oldPosition) {

   //回転方向が正方向だった場合brightness(明るさ)を1増やす
   //負方向だった場合brightnessを1減らす
    if (newPosition > oldPosition) {
      brightness++;
    } else {
      brightness--;
    }

    //brightness(明るさ)がPWMの0から255の範囲内に収まるように調整
    brightness = constrain(brightness,0,255);

    //LED出力ピンにbrightnessの値でアナログ出力(PWM出力)する
    analogWrite(ledPin, brightness);

    //シリアルモニタ※デバッグ用
    //現在位置newPosition、前回位置oldPosition、明るさbrightness の値を表示する。
    Serial.print("newPosition:");
    Serial.println(newPosition);
    Serial.print("oldPosition:");
    Serial.println(oldPosition);
    Serial.print("brightness:");
    Serial.println(brightness);

    // 前回位置oldPosition を現在位置newPosition に更新する
    oldPosition = newPosition;
   }

  delay(10);
}

動作確認

ブレッドボードで組んで動作確認してみました。
ロータリーエンコーダを回すと、PWMでLEDの明るさを増減させることが出来ました。

また、シリアルモニタでPCにPWM値とロータリーエンコーダの数値を送って表示させることが出来ます。

上記のプログラムでは、右回りで明るさが減少、左回りで明るさが増加という動作になりました。
右回りで増加の方が直感的なので、A相とB相の接続を逆に変更しました。
(プログラムでピンを変更しても良かったかも)

ブレッドボードで試作した様子

上記の写真では、A相を3番ピンへ、B相を2番ピンへ接続しています。

確認用のシリアルモニタ出力が下記になります。
ロータリーエンコーダを回転させると、newPositionの数値が変化します。
その変化が前回値(oldPosition)より大きいと、明るさ(brightness)を+1、
小さい場合-1とするようなプログラムです。

シリアルモニタ:時計回り時

brightnessの範囲はPWM値の0~255で制限して、それ以上・以下にならない様にしています。
ちゃんと255でカンストしています。

シリアルモニタ:時計回り時、255でカンスト

反対に回すと、brightnessが減ってきます。

シリアルモニタ:反時計回り時

減らし続けた場合も、0以下にはなりません。

シリアルモニタ:反時計回り時、0でカンスト

255に到達するまでかなり回転させないといけないので、2か3づつ数値を増加させるようにしても良いですね。

まとめ

秋月電子で買ったロータリーエンコーダ(EC12E2420801)とアルデュイーノナノを使って、PWMでLEDの明るさを可変させることが出来ました。

普通の可変抵抗と違って無限にクルクル出来るので、電子ボリュームや操作関係のスイッチとしても利用できそうですね。

参考リンク

ロータリーエンコーダには、軸を垂直に押し込むことでスイッチになるタイプのものもあります。
下記はその例です。(Amazonで購入しました。)
基板実装されたモジュールになっており、プルアップ抵抗も実装されています。
このモジュールを使っても、同様に動作を確認できました。

Amazonで買ったスイッチ付きロータリーエンコーダ
Amazonで買ったスイッチ付きロータリーエンコーダ2

タイトルとURLをコピーしました