O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.

Arduino序列通訊

2.233 visualizações

Publicada em

UART傳輸協定、RS232標準、Serial程式庫、使用Serial Monitor顯示狀態,序列傳輸命令控制LED

Publicada em: Tecnologia
  • Entre para ver os comentários

Arduino序列通訊

  1. 1. 電子工程系車用電子與資訊組 Arduino序列通訊 吳錫修 sswu@nkut.edu.tw Revised on July 6, 2018 UART傳輸協定、RS232標準、Serial程式庫、 使用Serial Monitor顯示狀態,序列傳輸命令控制LED
  2. 2. Makeeachdaycount  資料是1個bit接著1個bit傳送  每個資料封包 (package) 由起始位元、資料位元、檢查位元及結束位 元組成  在開始傳輸資料之前,Tx與Rx接腳都為⾼電位,要傳送資料時,先送出⼀ 個代表「要開始傳送的通知」的起始位元 (start bit,低電位)  每組資料位元 (data bits) ⻑度可以是5~8位元  資料位元之後可以送出⼀個檢查位元  無 (None) 不加檢查位元 非同步序列傳輸協定 1/3 2
  3. 3. Makeeachdaycount  奇同位 (Odd) 當資料位元有偶數個1時,則檢查位元為1,補成奇數;資料位元有奇數個1時, 則檢查位元為0,維持奇數  偶同位 (Even) 當資料位元有奇數個1時,則檢查位元為1,補成偶數;資料位元有偶數個1時, 則檢查位元為0,維持偶數  標記 (Mark) 檢查位元始終為1  空格 (Space) 檢查位元始終為0  封包最後是代表「傳送完畢」的停止位元 (stop bit),1~2位元 非同步序列傳輸協定 2/3 3
  4. 4. Makeeachdaycount  傳輸協定 (protocol) 代表通訊裝置雙方所遵循的規範和參數,通訊雙 方的設定必須⼀致,才能相互溝通  送收雙方須議定傳輸速率及封包格式  傳輸速率:每秒傳送的位元數 (bit per second,bps),也稱為鮑率 (baud rate)  取樣  通常是以鮑率的 16 倍頻⼯作,並在中⼼點附近取樣三次,三次結果⼀致 才視為正確 非同步序列傳輸協定 3/3 4
  5. 5. Makeeachdaycount  RS232C是最早廣泛使用之序列埠標準,傳輸距離約15m。  在USB普及之前,許多周邊裝置 (滑鼠、搖桿、條碼機、數據機…) 都 採用RS-232C介面  ⼀般使用DB-9端子,其中RXD、TXD及GND為最重要接腳  數據傳送 (Transmitter,Tx)  數據接收 (Receiver,Rx)  接地 (Ground,GND) RS232標準 1/2 5 DB-9公端子
  6. 6. Makeeachdaycount  RS232電氣訊號為負邏輯  3V~15V表示0 (Space)  -3V~-15V表示1 (Mark)  TTL電氣訊號為正邏輯  0.8V以下為0  2.0V以上為1  Arduino與RS232設備間需加裝訊號轉換元件 (如MAX232) RS232標準 2/2 6
  7. 7. Makeeachdaycount  序列埠監控視窗是⼀個透過序列埠和Arduino微控制器溝通的⼯具程式  選單命令Tools>Serial Monitor Serial Monitor 7 顥示接收到的訊息 傳輸速率 在此輸入要傳送之訊息 傳送
  8. 8. Makeeachdaycount  Arduino IDE內建處理序列傳輸的Serial程式庫  Serial.begin(speed) Serial.begin(speed, config)  設定序列傳輸速率,使用預設8n1傳輸格式  傳輸格式常數: SERIAL_5N1、SERIAL_6N1、SERIAL_7N1、SERIAL_8N1 (預設值)、SERIAL_5N2、 SERIAL_6N2、SERIAL_7N2、SERIAL_8N2、SERIAL_5E1、SERIAL_6E1、 SERIAL_7E1、SERIAL_8E1、SERIAL_5E2、SERIAL_6E2、SERIAL_7E2、 SERIAL_8E2、SERIAL_5O1、SERIAL_6O1、SERIAL_7O1、SERIAL_8O1、 SERIAL_5O2、SERIAL_6O2、SERIAL_7O2、SERIAL_8O2 Serial.begin(9600); //設定使用9600bps,8n1傳輸格式 使用Serial程式庫 1/8 8
  9. 9. Makeeachdaycount  Serial.end()  停用序列傳輸功能,允許RX和TX接腳做為通用輸入和輸出。調用 Serial.begin()可重新啟用序列傳輸  Serial.available()  傳回序列接收緩衝區 (64 bytes) 中已收到的位元組數  Serial.availableForWrite()  傳回還可寫入到序列緩衝區的位元組數  Serial.find (target_string)  從序列緩衝區讀取資料,直到找到指定字串。 如果找到指定字串,則傳回 true,如果逾時則傳回false Serial.find("ON"); 使用Serial程式庫 2/8 9
  10. 10. Makeeachdaycount  Serial.findUntil(target, terminal)  從序列緩衝區讀取資料,直到找到指定字串或終止字串 Serial.findUntil("ON","#");  Serial.flush()  等待序列緩衝區資料傳送完畢  Serial.parseFloat()  解析序列緩衝區資料並回傳第⼀個有效的浮點數值。非數字或減號的字元 會被略過,都找不到時回傳0.00  Serial.parseFloat()  解析序列緩衝區資料並回傳第⼀個有效的整數值。非數字或減號的字元會 被略過,都找不到時回傳0 使用Serial程式庫 3/8 10
  11. 11. Makeeachdaycount  Serial.peek()  讀取序列緩衝區的第⼀個字元,但並不將其從緩衝區中移除。若序列緩衝 區無資料則回傳-1  Serial.read()  取出序列緩衝區的第⼀個字元。若序列緩衝區無資料則回傳-1  Serial.readBytes (buffer, length)  從序列埠讀取資料儲存到緩衝區 (字元陣列),若已達指定資料⻑度或超時, 該函數終止  buffer用來儲存資料之緩衝區 (char[] or byte[]) char buffer[20]; int size = Serial.readBytes(buffer, 20); buffer[size]='0'; Serial.println(buffer); 使用Serial程式庫 4/8 11
  12. 12. Makeeachdaycount  Serial.readBytesUntil(character, buffer, length)  從序列埠讀取資料,直到檢測到終止字元或指定位元組數資料已被讀取或 逾時。終止字元並不會儲存到緩衝區 char buffer[20]; if (int size=Serial.readBytesUntil('#', buffer, 20)) { buffer[size]='0'; Serial.println(buffer); }  Serial.readString()  將序列緩衝區中的資料讀入字串 if (Serial.available()){ String buffer = Serial.readString(); Serial.println(buffer); } 使用Serial程式庫 5/8 12
  13. 13. Makeeachdaycount  Serial.readStringUntil(terminator)  將序列緩衝區中的資料讀入字串,直到終止字元或逾時 if (Serial.available()){ String cmd = Serial.readStringUntil('#'); Serial.println(cmd); }  Serial.setTimeout(milliseconds)  設定讀取序列資料逾時時間,預設為1000毫秒 使用Serial程式庫 6/8 13
  14. 14. Makeeachdaycount  Serial.print(val) Serial.print(val, format)  將數據作為方便閱讀的文字輸出到序列埠。整數資料可以指定格式,BIN 表示2進制,OCT表示8進制,DEC表示10進制,HEX表示16進制; 浮號 數資料可以指定小數點位數,預設為小數點後兩位 Serial.print(78); //輸出"78" Serial.print(1.23456); //輸出"1.23" Serial.print('N'); //輸出"N" Serial.print("Hello world."); //輸出"Hello world." Serial.print(78, BIN); //輸出"1001110" Serial.print(78, OCT); //輸出"116" Serial.print(78, HEX); //輸出"4E" Serial.print(1.23456, 0); //輸出"1" 使用Serial程式庫 7/8 14
  15. 15. Makeeachdaycount  Serial.println(val) Serial.println(val, format)  功能如Serial.print()函式,但會在資料後加上回車字元 (ASCII 13, or 'r') 及換行字元 (ASCII 10, or 'n')  Serial.write(val) Serial.write(str) Serial.write(buf, len)  將二進制數值寫入序列埠。 這些數據以位元組或⼀系列位元組形式發送 Serial.write(45); //輸出'-' Serial.write("Hello"); //輸出'H','e','l','l','o' 使用Serial程式庫 8/8 15
  16. 16. Makeeachdaycount  實驗目的  使用Serial Monitor監控開關狀態  當開關被壓放時,在序列埠監控視窗顯示訊息 Lab 序列埠監控視窗顯示開關狀態 1/3 16
  17. 17. Makeeachdaycount  參考程式 #define SW = 2 boolean lastState = HIGH; byte click = 0; void setup() { pinMode(SW, INPUT_PULLUP); Serial.begin(9600); Serial.println("start serial communication"); } Lab 序列埠監控視窗顯示開關狀態 2/3 17
  18. 18. Makeeachdaycount void loop() { boolean b1 = digitalRead(SW); //讀取開關目前狀態 if (b1 != lastState) { //開關狀態改變 delay(20); boolean b2 = digitalRead(SW); if (b1 == b2) { lastState = b1; click++; } } if (click == 2){ //已壓放⼀次開關 click = 0; Serial.println("SW was clicked"); } } Lab 序列埠監控視窗顯示開關狀態 3/3 18
  19. 19. Makeeachdaycount  實驗目的  使用序列埠字元命令控制LED  從Serial Monitor送出1時,點亮LED;送出0時,熄滅LED Lab 使用序列埠字元命令控制LED 1/3 19
  20. 20. Makeeachdaycount  參考程式 #define LED = 3 void setup() { pinMode(LED, OUTPUT); Serial.begin(9600); Serial.println("start serial communication"); } Lab 使用序列字元命令控制LED 2/3 20
  21. 21. Makeeachdaycount void loop() { if (Serial.available()){ byte cmd = Serial.read(); if (cmd == '1') { //從序列埠收到'1' digitalWrite(LED, HIGH); Serial.println("Turn LED on"); } if (cmd == '0') { //從序列埠收到'0' digitalWrite(LED, LOW); Serial.println("Turn LED off"); } } } Lab 使用序列字元命令控制LED 3/3 21
  22. 22. Makeeachdaycount  實驗目的  使用序列埠字元命令控制LED  從Serial Monitor送出"ON"時,點亮LED;送出"OFF"時,熄滅LED Lab 使用序列字串命令控制LED 1/3 22
  23. 23. Makeeachdaycount  參考程式 #define LED = 3 void setup() { pinMode(LED, OUTPUT); Serial.begin(9600); Serial.println("start serial communication"); } Lab 使用序列字串命令控制LED 2/3 23
  24. 24. Makeeachdaycount void loop() { if (Serial.available()){ String cmd = Serial.readString(); if (cmd == "ON") { //從序列埠收到"ON" digitalWrite(LED, HIGH); Serial.println("Turn LED on"); } if (cmd == "OFF") { //從序列埠收到"OFF" digitalWrite(LED, LOW); Serial.println("Turn LED off"); } } } Lab 使用序列字串命令控制LED 3/3 24

×