Robofun 機器人論壇

 找回密碼
 申請會員
搜索
熱搜: 活動 交友 discuz
查看: 5742|回復: 5
打印 上一主題 下一主題

SerialEvent問題.

[複製鏈接]
跳轉到指定樓層
1#
發表於 2013-4-19 16:14:40 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
本帖最後由 pizg 於 2013-4-19 16:15 編輯

這個網頁 http://arduino.cc/en/Tutorial/SerialEvent
依照下面的範例做, 在Serial Monitor內隨意輸入一些文字, 為什麼沒有任何顯示?
  1. String inputString = "";         // a string to hold incoming data
  2. boolean stringComplete = false;  // whether the string is complete

  3. void setup() {
  4.   // initialize serial:
  5.   Serial.begin(9600);
  6.   // reserve 200 bytes for the inputString:
  7.   inputString.reserve(200);
  8. }

  9. void loop() {
  10.   // print the string when a newline arrives:
  11.   if (stringComplete) {
  12.     Serial.println(inputString);
  13.     // clear the string:
  14.     inputString = "";
  15.     stringComplete = false;
  16.   }
  17. }

  18. /*
  19.   SerialEvent occurs whenever a new data comes in the
  20. hardware serial RX.  This routine is run between each
  21. time loop() runs, so using delay inside loop can delay
  22. response.  Multiple bytes of data may be available.
  23. */
  24. void serialEvent() {
  25.   while (Serial.available()) {
  26.     // get the new byte:
  27.     char inChar = (char)Serial.read();
  28.     // add it to the inputString:
  29.     inputString += inChar;
  30.     // if the incoming character is a newline, set a flag
  31.     // so the main loop can do something about it:
  32.     if (inChar == '\n') {
  33.       stringComplete = true;
  34.     }
  35.   }
  36. }
複製代碼
2#
發表於 2013-4-19 20:59:06 | 只看該作者
因為 Arduino 等不到換行字元,所以....

3#
發表於 2013-4-19 21:01:42 | 只看該作者
  1. String inputString = "";         // a string to hold incoming data
  2. boolean stringComplete = false;  // whether the string is complete

  3. void setup() {
  4.   // initialize serial:
  5.   Serial.begin(9600);
  6.   // reserve 200 bytes for the inputString:
  7.   inputString.reserve(200);
  8. }

  9. void loop() {
  10.   serialEvent();

  11.   // print the string when a newline arrives:
  12.   if (stringComplete) {
  13.     Serial.println(inputString);
  14.     // clear the string:
  15.     inputString = "";
  16.     stringComplete = false;
  17.   }
  18. }

  19. /*
  20.   SerialEvent occurs whenever a new data comes in the
  21. hardware serial RX.  This routine is run between each
  22. time loop() runs, so using delay inside loop can delay
  23. response.  Multiple bytes of data may be available.
  24. */
  25. void serialEvent() {
  26.   while (Serial.available()) {

  27.     // get the new byte:
  28.     char inChar = Serial.read();
  29.     // add it to the inputString:
  30.     inputString += inChar;
  31.     // if the incoming character is a newline, set a flag
  32.     // so the main loop can do something about it:
  33.      stringComplete = true;
  34.   }
  35.         
  36.   delay(300);
  37. }
複製代碼
4#
 樓主| 發表於 2013-4-19 23:58:55 | 只看該作者
本帖最後由 pizg 於 2013-4-20 01:10 編輯

首先, 感謝cooper和babyfish0226兩位老師的釋疑.

我個人的看法如下:
1.原始範例程式碼有點問題, 誠如cooper老師所說的它會等不到換行字元'\n', 所以不會印出任何東西.
我的作法跟cooper老師有點不同, 我是去修改程式碼, 去除'\n'的判斷式, 只留下
stringComplete = true;
這一行, 此部分做法跟babyfish0226老師的做法一樣.

2.serialEvent();這部分我跟babyfish0226老師的做法不一樣.
在參考文獻中指出 serialEvent() 這個函數會在每一次執行loop()時先被執行,
所以serialEvent()函數無須加在loop()裏面.

我的結論是:
這個範例的確是serialEvent()在讀取資料時, 還來不及讀完就被loop()所影響(註A),
因此, 只需要在loop()的最後一行加入適當的delay()即可,
如果Serial要讀的資料量很大, 那麼delay的時間就要相對地增多.程式碼如下:
  1. //延遲0.1秒時間,讓SerialEvent有足夠的時間去讀取COM PORT資料。

  2. String inputString = "";         // a string to hold incoming data
  3. boolean stringComplete = false;  // whether the string is complete

  4. void setup() {
  5.   // initialize serial:
  6.   Serial.begin(9600);

  7.   // reserve 200 bytes for the inputString:
  8.   //inputString.reserve(250);
  9. }

  10. void loop() {
  11.   // print the string when a newline arrives:
  12.   if (stringComplete) {
  13.     Serial.println(inputString);   
  14.   }
  15.   // clear the string:
  16.   inputString = "";
  17.   stringComplete = false;
  18.   delay(100);
  19. }

  20. /*
  21.   SerialEvent occurs whenever a new data comes in the
  22. hardware serial RX.  This routine is run between each
  23. time loop() runs, so using delay inside loop can delay
  24. response.  Multiple bytes of data may be available.
  25. */
  26. void serialEvent() {
  27.    while (Serial.available()) {
  28.     // get the new byte:
  29.     char inChar = (char)Serial.read();
  30.     // add it to the inputString:
  31.     inputString += inChar;   
  32.     // if the incoming character is a newline, set a flag
  33.     // so the main loop can do something about it:
  34.     stringComplete = true;   
  35.   }
  36. }
複製代碼


以上純屬個人意見, 如有錯誤還請各位先進不吝指正.
註A: loop()不會理會SerialEvent()是否已執行完畢。
5#
發表於 2013-4-20 11:27:20 | 只看該作者
我Arduino很久沒碰了,最近才又開始玩,serialEvent(); 原來是內建的function,另外更改NewLine就能偵測到\n字元,嗯嗯,我也學到了,果然大家一起切磋比較能求進步
6#
 樓主| 發表於 2013-4-21 17:09:27 | 只看該作者
呵~~我最近正在玩手機控制Arduino,
才會重新注意到Arduino的Serial相關問題,
個人覺得利用手機作為Arduino的UI是不錯的做法.
您需要登錄後才可以回帖 登錄 | 申請會員

本版積分規則

小黑屋|手機版|Archiver|機器人論壇 from 2005.07

GMT+8, 2025-1-31 18:36 , Processed in 0.195971 second(s), 9 queries , Apc On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回復 返回頂部 返回列表