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要高一些。