새 직렬 명령을받을 때 기존 배열 지우기

첫 번째 Arduino 프로젝트를 빌드하기 시작했지만 직렬 통신에 문제가 발생했습니다.

콘솔에서 직렬 데이터를 가져와 “data”라는 문자 배열에 저장합니다.

그런 다음 Arduino에 새 콘솔 메시지를 보낼 때 기존 “데이터”배열을 사용하고 해당 배열에 새 데이터 만 저장합니다.

내 코드에 무엇이 잘못되었는지 정확히 이해하지 못합니다. 중첩 된 Serial.available () 문이 작동하지 않는다고 생각합니다. 하지만 코드를 수정하는 방법에 대한 아이디어가 없습니다.

데이터는 Arduino에 의해 올바르게 저장되지만 최신 문자열을 이전 문자열에 연결합니다.

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("There is data already, clearing..."); char data[30]; dataComplete = false; } if (dataComplete == false){ Serial.println("New command, collecting..."); while (Serial.available()>0){ char character = Serial.read(); data[count] = character; count++; } dataComplete = true; } } Serial.print("Command received: "); Serial.println(data); delay(1000); } 

미리 감사합니다!

답변

배열을 지우려면 다음을 수행하십시오.

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

또는

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

, 라이브러리 함수를 사용하여 동일한 작업을 수행합니다.

그러나 문자열이 문자 수 (여기서 “문자열”개체를 참조하지 않음)는 0 바이트로 종료되며 첫 번째 바이트 만 0으로 설정되어야합니다.

data[0] = (char)0; 

이 작업을 수행합니다. .

답변

우선 공백이 중요한 훌륭한 예입니다. 코드를 훑어 보면 두 번째 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("There is data already, clearing..."); char data[30]; dataComplete = false; } if (dataComplete == false){ Serial.println("New command, collecting..."); while (Serial.available()>0){ char character = Serial.read(); data[count] = character; count++; } dataComplete = true; } } Serial.print("Command received: "); Serial.println(data); delay(1000); } 

또한 새 데이터가 있는지 여부에 관계없이 매 반복마다”Command received : “를 인쇄하는 것처럼 보입니다 (이는 의도 된 기능 일 수 있음).

언급했듯이 변수를 지우지 않고 새 변수를 만듭니다. 이 문제를 해결하려면 지우고 count를 재설정해야합니다. 그러나 두 번째 명령이 명령보다 짧으면 카운트 재설정이 작동하지 않습니다.

또한 dataComplete 변수로 코드를 복잡하게 만드는 이유는 무엇입니까? 아래 코드를 단순화했습니다.

int count = 0; char data[30]; boolean dataComplete = false; void setup() { Serial.begin(9600); } void loop() { if (Serial.available()){ Serial.println("New command, collecting..."); count = 0; data[] = ""; while (Serial.available()){ char character = Serial.read(); data[count] = character; count++; } } Serial.print("Command received: "); Serial.println(data); delay(1000); } 

Answer

아마도 하려는 작업을 수행하십시오.

Serial.println("There is data already, clearing..."); char data[30]; 

출력에 data 배열을 지우고 있지만 “그런 일은하지 않는다. 실제로 data라는 지역 변수를 선언합니다.이 변수는 전역 data 사용자와 독립적입니다. 이미 프로그램 상단에 선언했습니다. 지역 변수는 선언 된 범위 내에서만 존재합니다 (가장 가까운 { } 내부).

대신 count 변수는 수신 한 데이터의 양을 추적합니다. 따라서 다음을 수행 할 수 있습니다.

Serial.println("There is data already, clearing..."); count = 0; 

이것은 프로그램이 예기치 않게 작동하게 할 수있는 유일한 원인은 아니지만 최소한 다음에 명시된 문제를 해결해야합니다. 귀하의 질문입니다.

댓글

  • 또한 데이터에 null 종결자가 필요합니다. data[count]='\0'; 뒤에 data[count]='\0'; 추가 div id = “64b99aaa0d”>
  • 예, ' 사실이지만 더 큰 문제는 발신자가 다음을 수행 할 방법이 없다는 것입니다. 일시 정지 이외의 데이터 전송 종료를 나타냅니다. 그리고 이것은 연재물이기 때문에 전송되는 모든 캐릭터 사이에 충분히 긴 멈춤이있을 것입니다.
  • 두 분 모두 감사합니다. 내 코드가 잘못되어 " count = 0 "로 변경되었습니다. 또한 입력 명령의 끝을 나타내는 구분 기호를 추가했으며 현재 의도 한대로 작동합니다. 그러나 " data " 배열을 비우는 유일한 방법은 @JRobert가 표시하는 for 루프를 사용하는 것입니다. 명령은 이전 명령보다 짧더라도 작동합니다.
  • 답변

    질문의 요점을 말하려면 , 그리고 저자가 수행하려고 시도한 것.

    이 코드는 실제로 전체적으로 작동하지 않습니다. 데이터가 덮어 써지고 계속 반복됩니다 … 어쨌든 여기에 원래 코드의 작동 예제가 있습니다.

    이 방법은 배열을 지우는 것을 선호합니다.

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

    다음은 실제 작동하는 예입니다. (직렬 모니터에서 캐리지 리턴을 선택해야합니다.)

     char message[32]; uint8_t incomingByte = 0; uint8_t BufferPos = 0; int clearbyte = 0; void setup() { Serial.begin(9600); Serial.println("\n String conversion testing"); } void loop() { if (BufferPos >= 32) { Serial.print("Buffer Full\n"); BufferPos = 00; incomingByte = 0; } if (Serial.available()) { incomingByte = Serial.read(); message[BufferPos++]= incomingByte; switch(incomingByte) { case "\n": case " ": break; case "\r": Serial.println(message); for( int i = 0; i < sizeof(message); ++i ) message[i] = (char)0; BufferPos= 0; incomingByte= 0; } } } 

    Answer

    이 질문에 대한 모든 의견을 읽었지만 모든 코드가 너무 말 그대로 공유되었습니다. 그 후, 간단한 기능과 적은 줄로 코드를 만듭니다. 이 경우에는이 코드가 잘 작동한다고 생각합니다.

    전송 속도를 115200 미만으로 설정하면 char 배열에 메시지를 저장하기 위해 delay ()를 추가해야합니다.

    void loop() { char data[255]; uint8_t k = 0; while (Serial.available()) { data[k] = Serial.read(); k++; } for (int i = 0; i < k; i++) { Serial.print(data[i]); data [i] = "\0"; } //delay(50); } 

    댓글

    • char data[] = {};는 길이가 0 인 배열을 제공합니다. 데이터를 넣는 것은 나쁜 생각입니다.
    • @NickGammon에 동의합니다.답변을 수정하여 " 제 생각에 … 잘 작동 할 것 같습니다 "를 테스트 한 후 확실한 예 / 아니오로 코드.
    • @NickGammon 수정 해 주셔서 감사합니다. 코드를 수정했습니다.

    답글 남기기

    이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다