2020年6月28日日曜日

RGB LED付きロータリエンコーダ習作

次の工作に使おうと考えているロータリエンコーダを試してみました。秋月で売られているフルカラーRGB LEDが付いていて、軸がプッシュスイッチになっているものです。取り合えずの習作なのでArduino UNOを引っ張り出してきて使っています。


動かしているときの様子です。



ロータリエンコーダのエンコード信号とLEDは独立しています。ただし各LEDのアノードとプッシュスイッチの一方は共通ピンです。

ロータリエンコーダのデコード方法は、ELMさんのロータリー・エンコーダの使い方 を参考にさせていただきました。感謝。回路・スケッチは無保証です。

//------------------------------------------------------------
//                                              2020.6.28 naka
//  ロータリエンコーダ習作
//
//------------------------------------------------------------
#include <FaBoLCDmini_AQM0802A.h>
FaBoLCDmini_AQM0802A lcd;

#define SDAPIN  A4
#define SCLPIN  A5
#define RT0     2
#define RT1     3
#define LED_R   4
#define LED_G   5
#define LED_B   6
#define SW      7

int Count;

void setup() {
  // i/oピン設定
  pinMode(RT0,INPUT_PULLUP);
  pinMode(RT1,INPUT_PULLUP);
  pinMode(LED_R,OUTPUT);
  pinMode(LED_G,OUTPUT);
  pinMode(LED_B,OUTPUT);
  pinMode(SW,INPUT);

  // モニタLCD設定
  SetupLCD();
  lcd.clear();
  lcd.print("Encoder ");
  
  // カウンタ
  Count  = 0;
}

void loop() {
  int  dir;
  char buff[10];
  
  while(1) {
    dir = sample_coder();    // エンコーダの回転方向

    if (dir!=0 || Count==0) {
      Count += dir;
      disp_count(Count);
      LED_LightsUp(Count);
    }

    if (digitalRead(SW)==1) {  // ロータリエンコーダの軸スイッチが押されたか?
      Count = 0;
      disp_count(Count);
      LED_LightsUp(Count);
      break;
    }
  }
  while(digitalRead(SW)==1);
    
  delay(100);
}

void SetupLCD() {
  lcd.begin();
  lcd.command(0x38);
  lcd.command(0x39);
  lcd.command(0x14);
  lcd.command(0x73);
  lcd.command(0x51);  // 5V
//  lcd.command(0x56);  // 3.3V
  delay(2);
  lcd.command(0x6c);
  delay(300);
  lcd.command(0x38);
  delay(1);
  lcd.command(0x01);
  delay(2);
  lcd.command(0x0c);
  delay(2);
}

void disp_count(int cnt) {
  char buff[9];
  sprintf(buff,"CNT=%3d",cnt);
  lcd.setCursor(0, 1); // Col,Raw
  lcd.print(buff);
}

void LED_LightsUp(int val) {
  if (val<0)        led_rgb(0,0,1); // Blue
  else if (val==0)  led_rgb(0,0,0); // off
  else if (val<10)  led_rgb(0,1,0); // green
  else if (val<20)  led_rgb(1,1,0); // yellow
  else if (val<30)  led_rgb(1,0,0); // red
  else if (val>=30) led_rgb(1,0,1); // purple
}

void led_rgb(int r,int g,int b) {
  r = (r ^ -1) & 1;        // 論理反転 
  digitalWrite(LED_R,r); 
  g = (g ^ -1) & 1; 
  digitalWrite(LED_G,g); 
  b = (b ^ -1) & 1; 
  digitalWrite(LED_B,b); 
}

int sample_coder()
{
  static int code = 0;
  int code_val,code_pin0,code_pin1;

  code_val = (PIND >> 2) & 3;
  code = ((code << 2) | code_val) & 15; //
  switch (code) {  // デテンド位置=3
    case 0xE:
      return(1);
    case 0xD:
      return(-1);
    default:
      return(0);
  }
}
//------------------------------------------------------------

0 件のコメント:

コメントを投稿