1. 程式人生 > >arduino學習系列——串列埠通訊

arduino學習系列——串列埠通訊

今天學習了串列埠通訊的相關內容,其實就是Serial的一系列函式:

Serial.begin(); //開啟串列埠
Serial.end();    //關閉串列埠
Serial.available();//判斷串列埠緩衝器是否有資料裝入
Serial.read();    //讀取串列埠資料
Serial.flush();    //清空串列埠快取
Serial.print();    //寫入字串資料到串列埠
Serial.println();   //寫入字串資料+換行到串列埠
Serial.write();     //寫入二進位制資料到串列埠
Serial.SerialEvent();//read時觸發的事件函式
Serial.readBytes(buffer,length);//讀取固定長度的二進位制流

我想實現一個通過串列埠控制arduino板子上LED等點亮和熄滅的程式,具體程式碼如下:

String str = "Hello world!";
int val =20;
float iVal=2.29;
void setup(){
  Serial.begin(9600);//
  pinMode(13,OUTPUT);
}

void loop(){ 
//    while (Serial.available()>0){
//       val = Serial.read();
//        Serial.println(char(val));
//        val = int(val);
//         Serial.println(val);
//         if(val == 82){
//            Serial.println(str);//
//            Serial.println(val);
//            digitalWrite(13,HIGH);
//            delay(2000);
//       }else{
//         digitalWrite(13,LOW);
//       }
//    }
    str = parseString();
    //Serial.println(str);
    if(str=="open"){
      val = 101;
    }else if(str=="close"){
      val = 10;
    }
    
    switch(val){
    case 101:
      digitalWrite(13,HIGH);
      Serial.println(56,BIN);
       Serial.println(56,OCT);
        Serial.println(56,DEC);
         Serial.println(56,HEX);
          Serial.println(1.2343,0);
          Serial.println(1.2343,1);
          Serial.println(1.2343,2);
          Serial.println(1.2343,3);
//      Serial.write(iVal);
      val = 0;
      delay(2000);
      break;
    case 10:
      digitalWrite(13,LOW);
      val = 0;
      break;
    default:
      break;
    }

}

String parseString(){
  String str ;
  while(Serial.available()>0){
    str +=char(Serial.read());
    delay(1);
  }
  return str;
}

這個程式碼是在完成基本功能的情況下又做了一些測試工作。首先我想將命令字元變成一個字串,測試一些在串列埠上傳輸一個字串的接受方法,寫在parseString這個函式裡面。另外對printLn和write函式的功能區別進行了探究。有一下幾點內容需要注意:
一、關於arduino程式設計環境的理解
在這個環境中有兩個最基本的函式,一個是setup()主要負責初始化工作,比如引腳的定義,串列埠波特率的定義等等。另一個是loop()函式,這個函式就相當於是微控制器的作業系統,當程式注入到晶片後,完成相關初始化工作,這個程式就會反覆執行。注意是一遍一遍的反覆執行,在執行過程中,根據程式碼的指令要求做相關的事項,比如從串列埠讀取資料等。由於她會反覆執行,所以寫這個函式的程式碼時要注意程式碼邏輯(這裡面有迴圈)!
二、關於時延的問題
在從串列埠read資料時,如果讀取的是一個位元組序列,那麼讀完一個位元組,要加入一個delay,如果不加入的話就無法正常讀取位元組序列,這個可能是因為串列埠通訊的同步問題造成的。這也是硬體開發與軟體開發的一個區別,可能還有點類似與軟體開發過程中的非同步問題,但這裡沒有多執行緒,所以只能等待,這也就可能導致資料傳輸的速率不可能太快。
三、關於read()函式
該函式每次只能從緩衝區中讀取一個位元組,並把該位元組解析為一個ASCII碼,如果你想把他轉化為其他型別,可以對其進行強制型別轉化,可以使用Serial.available()>0判斷緩衝區中是否還有資料,這兩個函式配合就能實現輸入資料的讀取。並且read函式執行之後,就會把已經讀取的資料自動從緩衝區中刪除,這樣就不會重複讀取資料的情況。
四、關於print和write兩個函式的區別
在輸出字串方面這兩個函式的效果是一致的,例如Serial.write(“jfdslajfdslk\n”);
Serial.println(“jfdslajfdslk”);
這兩個函式輸出後在控制檯接受到的內容是完全一樣的。(\n是換行的意思。等同於print後面的ln)但是如果是如下
Serial.println(56);
Serial.write(56);
這兩個的輸入結果就是不一樣的,
這裡寫圖片描述


print輸出的是數字56,而write輸出的是56所代表的ASCII碼。也就是說在函式print中你可以輸出任何東西,你輸出的東西他都會將其轉換為字元進行傳輸,所以當我們print(56)時,其傳輸的並不是數字56,而是將其轉換為字串,然後傳輸,所以你得到的56其實是一個字串,而並不是一個整數。而write函式的輸入引數如果是整數,他會把這個整數轉換成一個位元組的ASCII碼然後傳輸,所以得到的是56所代表的ASCII碼。另外,write函式的輸入引數只能是字串或者整數。而且正如程式碼中看到的print的還有第二引數,可以規定第一個輸入引數的型別,如果是浮點型,還可以規定精度。可見print要比write要靈活的多。
但是有一點是確定的,在這個通訊的過程中傳輸的都是一個位元組的ASCII或者是ASCII的序列,只不過print函式在接受到後對資料進行了處理。也許這會導致在傳輸較大數量的資料時write的效率要比print要高一些。