/*
RotaryEncoderInterrupt sketch
2017-01-19 test OK
*/
const int encoderPinA = 2;
const int encoderPinB = 3;
int Pos, oldPos;
volatile int encoderPos = 0; // variables changed within interrupts are volatile
void setup(){
pinMode(6, OUTPUT); digitalWrite(6, LOW); //encoder Gnd
pinMode(encoderPinA, INPUT_PULLUP);
pinMode(encoderPinB, INPUT_PULLUP);
Serial.begin(115200);
attachInterrupt(1, doEncoder, CHANGE); // encoder pin on interrupt 0 (pin 3)
// attachInterrupt(0, doEncoder, FALLING); // encoder pin on interrupt 0 (pin 2)
}
void loop(){
uint8_t oldSREG = SREG;
cli(); Pos = encoderPos; SREG = oldSREG; if(Pos != oldPos)
{
Serial.println(Pos,DEC); oldPos = Pos;
}
delay(10);
}
void doEncoder(){
if (digitalRead(encoderPinA) == digitalRead(encoderPinB))
encoderPos++; // count up if both encoder pins are the same
else
encoderPos--; //count down if pins are different
}
接著發現一個狀況~~
若需設定的值範圍很大時不就要轉很久 ...
利用轉動速度快慢(偵測脈波寬度)的方式來決定增量的值
/*
RotaryEncoderInterrupt sketch
2017-01-20 test OK
*/
const int encoderPinA = 2;
const int encoderPinB = 3;
int Pos, oldPos;
unsigned long duration;
volatile int encoderPos = 0; // variables changed within interrupts are volatile
void setup(){
pinMode(6, OUTPUT); digitalWrite(6, LOW); //encoder Gnd
pinMode(encoderPinA, INPUT_PULLUP);
pinMode(encoderPinB, INPUT_PULLUP);
Serial.begin(115200);
attachInterrupt(1, doEncoder, CHANGE); // encoder pin on interrupt 0 (pin 3)
// attachInterrupt(0, doEncoder, FALLING); // encoder pin on interrupt 0 (pin 2)
}
void loop(){
uint8_t oldSREG = SREG;
cli(); Pos = encoderPos; SREG = oldSREG; if(Pos != oldPos){
Serial.print(Pos,DEC);
Serial.print(", Pulse Width /nS :");
Serial.println(duration,DEC);
oldPos = Pos;
}
delay(10);
duration = pulseIn(encoderPinA, HIGH,100000);
}
void doEncoder(){
if (digitalRead(encoderPinA) == digitalRead(encoderPinB)){
if(duration == 0 || duration >= 35001)encoderPos++;
if(duration >= 1 && duration <= 35000)encoderPos += 20;
if(duration >= 1 && duration <= 10000)encoderPos += 80;
}
else{
if(duration == 0 || duration >= 35001)encoderPos--;
if(duration >= 1 && duration <= 35000)encoderPos -= 20;
if(duration >= 1 && duration <= 10000)encoderPos -= 80;
}
}
轉一格有 1個訊號
//2018-06-26 test OK
volatile long posCount = 0;
unsigned long t = 0;
void setup() {
Serial.begin(115200);
// 當狀態下降時,代表旋轉編碼器被轉動了
attachInterrupt(1, rotaryEncoderChanged, FALLING); //INT 1 -> pin 3
pinMode(3, INPUT_PULLUP); // 輸入模式並啟用內建上拉電阻
pinMode(4, INPUT_PULLUP);
pinMode(5, INPUT_PULLUP);
Serial.println("count reset to 0");
}
long position = -999;
word position1,newPos1;
void loop() {
//delay(500);
if (posCount != position) {
position = posCount;
Serial.println(position);
}
if(digitalRead(5) == LOW){ // 按下開關,歸零
posCount = 0;
delay(300);
}
}
void rotaryEncoderChanged(){ // when CLK_PIN is FALLING
// unsigned long temp = millis(); // 去彈跳
// if(temp - t < 20) // 去彈跳
// return; // 去彈跳
// t = temp; // 去彈跳
// DT_PIN的狀態代表正轉或逆轉
posCount += digitalRead(4) == HIGH ? 1 : -1;
// Serial.println(count);
}
可以不使用中斷的 Library -> https://github.com/PaulStoffregen/Encoder
轉一格有 4個訊號