2016年9月24日 星期六

Rotary Encoder的程式動作原理以及Arduino程式的實現

#Arduino
#Rotary Encoder
#編碼器
#旋轉編碼器
Rotary Encoder 在一般的儀器或者家電產品常常看到他的蹤影在此特別的說明一下他的原理與程式的實現。






Rotary Encoder 外觀


這一張圖是ENCODER的工作原理【橘色】的部分是接地片或這是電源片,A,B兩點是信號它是利用角度的時間差來判斷正傳或者是反轉的,我個人覺得他的圖畫的很好再次引用說明。
圖片來源:http://howtomechatronics.com/tutorials/arduino/rotary-encoder-works-use-arduino/
【圖片版權屬該網站作者所有】


分別處於兩個角度當旋轉是ON、OFF就會輸出AB相位信號。
根據這個信號圖撰寫程式,程式如附檔這個程式有實測過是OK的
寫ENCODER程式會有幾個環節必須注意
  1. 外部中斷的設定方式:
Arduino 建議的語法如下:
attachInterrupt(digitalPinToInterrupt(18), interrupt1,RISING); //CHANGE);
必須使用這個語法才能動作,官方網站建議接腳的定義要寫這個【digitalPinToInterrupt(18)】,不能寫IO PORT
一般網路的寫法如下:
 attachInterrupt(0, doEncoder, CHANGE);  // encoder pin on interrupt 0 - pin 2
我在Arduino MEGA2560測試一直無法成功啓動外部中斷我不知道爲什麼,因爲無法看到compiler之後的組合語言所以無法得知爲什麼。
還有TOUCH功能和VR功能還沒有實現,繼續努力。

Arduino 範例:
void ENCODER_SUB(void)
{
if ((f_cw_start ==0)||(f_ccw_start==0))
{
// if(digitalRead(outputB)==1)
if (bit_is_set(P_ENC,BP_ENCB))
{
f_cw_start = 1;
attachInterrupt(digitalPinToInterrupt(outputA), ENCODER_SUB,RISING);  //CHANGE);
} else{
attachInterrupt(digitalPinToInterrupt(outputA), ENCODER_SUB,RISING);  //CHANGE);
f_ccw_start = 1;
}
}

if ((f_cw_start ==1)||(f_ccw_start==1))
{
// if(digitalRead(outputB)==0)
if (bit_is_clear(P_ENC,BP_ENCB))
{
attachInterrupt(digitalPinToInterrupt(outputA), ENCODER_SUB,FALLING);  if(encoder_counter <13 div="">
{
encoder_counter++;
}else{ 
encoder_counter = 0;
}
f_cw_start = 0;
}else{
attachInterrupt(digitalPinToInterrupt(outputA), ENCODER_SUB,FALLING); 
if (encoder_counter >0)
{
encoder_counter--;
}else{
encoder_counter = 13;
}
f_ccw_start = 0;
}


}
 Serial.print("Interrupt-->");
 Serial.println(encoder_counter);
}


這個程式經過測試是OK的沒有漏格現象,但是由於我的Encoder他的AB相位只差1.3ms~3ms所以當你旋轉速度過快程式會反應不及,因爲Arduino的IO函數有延遲,使用我將digitalRead()改爲bit_is_set or bit_is_clear 兩個巨集指令。



沒有留言:

如何使用終端機軟體收集來自於Arduino的資料

  將治具使用Micro USB cable 連上電腦 開啟終端機軟體 選擇 Serial🡪按下OK File🡪Log…  設定log file要存放位置,建議檔案名稱直接取名為*.CSV 例如:20231224.csv 按下治具Reset按鍵開始收集資料