題:
獲取新的串行命令時清除現有陣列
squeck
2014-07-04 02:20:10 UTC
view on stackexchange narkive permalink

我開始構建我的第一個Arduino項目,但是在串行通信方面遇到了一些問題。

我從控制台獲取串行數據並將其存儲在一個名為“數據”的char數組中

然後,當我向Arduino發送新的控制台消息時,我希望它清除現有的“數據”數組並僅將新數據存儲在該數組中。

I不完全了解我的代碼出了什麼問題:我相信那些嵌套的Serial.available()語句不起作用,但是我不知道如何解決該代碼。

  int count = 0; char data [30]; boolean dataComplete = false; void setup(){Serial.begin(9600); } void loop(){if(Serial.available()> 0){if(dataComplete == true){Serial.println(“已經有數據,正在清除...”);字符數據[30]; dataComplete = false; } if(dataComplete == false){Serial.println(“ New command,collection ...”); while(Serial.available()>0){char character = Serial.read();數據[計數] =字符;數++; } dataComplete = true; }。Serial.print(“收到的命令:”); Serial.println(數據); delay(1000);}  

謝謝!

五 答案:
JRobert
2014-07-04 23:59:38 UTC
view on stackexchange narkive permalink

要清除數組,請執行以下操作:

  for(int i = 0; i < sizeof(data); ++ i)data [i] =(char)0;  

  memset(data,0,sizeof(data));  

,其作用相同

但是,由於字符串(此處不指“字符串”對象)以零字節終止,因此僅第一個字節需要清零:

  data [0] =(char)0;  

將執行此操作。

Anonymous Penguin
2014-07-04 05:33:49 UTC
view on stackexchange narkive permalink

首先,這是空白很重要的優秀示例。您的代碼確實很難看清,因為略過它似乎像是第二個if語句不在第一個。

固定代碼:

  int count = 0; char data [30]; boolean dataComplete = false; void setup(){Serial.begin(9600);} void loop(){if(Serial.available()> 0){if(dataComplete == true){Serial.println(“已經有數據,正在清除...”);字符數據[30]; dataComplete = false; } if(dataComplete == false){Serial.println(“ New command,collection ...”);而(Serial.available()>0){char character = Serial.read();數據[計數] =字符;數++; } dataComplete = true; }。Serial.print(“收到的命令:”); Serial.println(數據); delay(1000);}  

此外,它似乎在每次迭代中都打印“ Command command:”(接收到的命令),而不管是否有新數據(儘管這可能是預期的功能)

就像提到的那樣,您不會清除變量,而只是創建一個新變量。您需要清除重置 count 來解決此問題。但是,如果第二個命令比以前的命令短,則僅重置計數將不起作用。

此外,為什麼還要使用 dataComplete 變量使代碼複雜化?我簡化了以下代碼:

  int count = 0; char data [30]; boolean dataComplete = false; void setup(){Serial.begin(9600);} void loop(){如果(Serial.available()){Serial.println(“新命令,正在收集...”);計數= 0; data [] =“”;而(Serial.available()){字符= Serial.read();數據[計數] =字符;數++; }。Serial.print(“收到的命令:”); Serial.println(數據); delay(1000);}  
Greg Hewgill
2014-07-04 02:41:55 UTC
view on stackexchange narkive permalink

這可能不符合您的預期目的:

  Serial.println(“已經有數據,正在清除...”); char數據[30];  

您的輸出顯示您正在清除 data 數組,但您沒有這樣做。實際上,您在聲明一個名為 data new 局部變量,該變量獨立於您已經在頂部聲明的全局 data 程序。局部變量僅存在於聲明它們的範圍內(在最接近的 {} 內)。

相反,您的 count 變量會跟踪您收到了多少數據。因此,也許可以執行以下操作:

  Serial.println(“已經有數據,正在清除...”); count = 0;  

這是並非唯一可能導致程序異常運行的東西,但它至少應該可以解決問題中指出的問題。

數據還需要一個空終止符:在dataComplete = true之後添加data [count] ='\ 0';
是的,的確如此,但是更大的問題是發送者除了暫停外沒有其他方法可以指示數據傳輸的結束。而且由於這是串行的,因此在傳輸的每個*字符之間將有足夠長的暫停時間。
多虧你們兩個。我的代碼有誤,將其更改為“ count = 0”有效。我還添加了一個定界符以指示輸入命令的結尾,並且它現在按預期工作。但是,清空“數據”數組的唯一方法是使用@JRobert:指示的for循環,這樣即使較早的新命令也可以使用新命令。
nu11
2015-05-06 08:47:36 UTC
view on stackexchange narkive permalink

要說出問題的重點以及作者試圖完成的工作。

實際上,這些代碼都無法正常工作。數據將被覆蓋,並保持連續循環……無論如何,這是原始代碼的有效示例。

我更喜歡清除數組的這種方法:

  for(int i = 0; i < sizeof(data); ++ i)data [i] =(char)0;  

這裡是工作示例。 (確保在串行監視器上選擇回車)

 字符消息[32]; uint8_t傳入字節= 0; uint8_t BufferPos = 0; int clearbyte = 0; void setup(){Serial.begin(9600); Serial.println(“ \ n字符串轉換測試”); } void loop(){if((BufferPos > = 32){Serial.print(“ Buffer Full \ n”); BufferPos = 00; entryByte = 0; }如果(Serial.available()){入站字節= Serial.read(); message [BufferPos ++] =來電字節; switch(incomingByte){case'\ n':case'':break;情況'\ r':Serial.println(message); for(int i = 0; i < sizeof(message); ++ i)message [i] =(char)0; BufferPos = 0; entranceByte = 0; }}}  
Ashif Riady
2019-01-17 10:54:12 UTC
view on stackexchange narkive permalink

我已閱讀了有關此問題的所有評論,但所有代碼共享得如此冗長。之後,我用簡單的功能創建了一個代碼,減少了代碼量。在這種情況下,我認為這段代碼可以正常工作

,如果您在115200以下設置波特率,則必須添加delay()才能將消息保存到char數組

  void循環( ){char data [255]; uint8_t k = 0;而(Serial.available()){data [k] = Serial.read(); k ++; } for(int i = 0; i < k; i ++){Serial.print(data [i]);數據[i] ='\ 0'; } // delay(50);}  
char data [] = {};`將為您提供零長度的數組。嘗試將數據放入其中不是一個好主意。
我同意@NickGammon的意見。測試代碼後,請編輯您的答案以將“我認為...會很好”替換為肯定的“是/否”。
@NickGammon感謝您的更正,我正在修改我的代碼


該問答將自動從英語翻譯而來。原始內容可在stackexchange上找到,我們感謝它分發的cc by-sa 3.0許可。
Loading...