arduino 1 讀取電機編碼器值

#define BAUDRATE     115200
#define LEFT            0	//左輪
#define RIGHT           1	//右輪
#define FORWARDS true
#define BACKWARDS false

//如果一個變量所在的代碼段可能會意外地導致變量值改變那此變量應聲明爲volatile,
//比如並行多線程等。在arduino中,唯一可能發生這種現象的地方就是和中斷有關的代碼段,成爲中斷服務程序。
// 中斷函數中使用的變量需要定義爲 volatile 類型.
volatile long encoderLeft = 0L;
volatile long encoderRight = 0L;

//初始化編碼器
void initEncoders(){
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  //中斷函數(中斷源,中斷觸發函數,中斷觸發信號)
  //中斷源可選值爲0或1,一般分別對應2號和3號引腳
  //需要中斷的函數名
  //LOW(低電平觸發)、CHANGE(變化時觸發)、RISING(低電平變爲高電平觸發)、FALLING(高電平變爲低電平觸發)
  attachInterrupt(0, encoderLeftISR, CHANGE);  
  attachInterrupt(1, encoderRightISR, CHANGE);
}

//中斷觸發函數
void encoderLeftISR(){
    encoderLeft++;
}

//中斷觸發函數
void encoderRightISR(){
    encoderRight++;
}


//讀左輪或右輪編碼器
long readEncoder(int i) {
  long encVal = 0L;
  if (i == LEFT)  {
     noInterrupts(); //關中斷
    //detachInterrupt(0); //取消中斷;取消指定類型的中斷.
    encVal = encoderLeft;
    interrupts(); //開中斷
    //attachInterrupt(0, Code_left, FALLING);
  }
  else {
    noInterrupts();	//關中斷
    //detachInterrupt(1);
    encVal = encoderRight;
    interrupts();	//開中斷
    //attachInterrupt(1, Code_right, FALLING);
  }
  return encVal;
}

//指定左右輪編碼器復位,數值爲0
void resetEncoder(int i) {
  if (i == LEFT){
    noInterrupts();
    encoderLeft = 0L;
    interrupts();
  }else {
    noInterrupts();
    encoderRight = 0L;
     interrupts();
  }
}
//左右輪編碼器復位,數值都爲0
void resetEncoders() {
  resetEncoder(LEFT);
  resetEncoder(RIGHT);
}

//初始化
 void setup() {
  // 串口通信函數說明:
  // begin():打開串口,參數波特率;Serial.begin(BAUDRATE);
  // available():獲取串口上可讀取的數據的字節數,函數返回可讀取的字節數;Serial.available();
  //				該數據是指已經到達並存儲在接收緩存(共有64字節)中。available()繼承自Stream實用類。
  // read():讀串口數據,read()繼承自Stream實用類。Serial.read();
  //		返回值:串口上第一個可讀取的字節(如果沒有可讀取的數據則返回-1)- int型。
  // flush(): 刷新串口數據
  // print(): 往串口發數據,串口輸出數據函數。語法:1)Serial.print(val);2)Serial.print(val,format)
  // 參數: val: 打印的值,任意數據類型;format: 輸出的數據格式,包括整數類型和浮點型數據的小數點位數。
  // println(): 串口輸出數據函數。與Serial.print()不同的是輸出數據帶回車符。
  // write(): 寫二進制數據到串口,數據是一個字節一個字節地發送的,若以字符形式發送數字請使用print()代替。
  // peak(): 串口讀取函數。返回的是串口數據中下一字節的內容
  // serialEvent(): 當串口有數據到達時調用該函數(然後使用Serial.read()捕獲該數據)。
  Serial.begin(BAUDRATE);
  initEncoders();
  resetEncoders();
}

void loop() {
   long lval=readEncoder(0);
   long rval=readEncoder(1);
   Serial.print("left: ");
   Serial.print(lval);
   Serial.print("; right: ");
   Serial.println(rval);
   delay(30);
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章