첫 번째 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;
이것은 프로그램이 예기치 않게 작동하게 할 수있는 유일한 원인은 아니지만 최소한 다음에 명시된 문제를 해결해야합니다. 귀하의 질문입니다.
댓글
답변
질문의 요점을 말하려면 , 그리고 저자가 수행하려고 시도한 것.
이 코드는 실제로 전체적으로 작동하지 않습니다. 데이터가 덮어 써지고 계속 반복됩니다 … 어쨌든 여기에 원래 코드의 작동 예제가 있습니다.
이 방법은 배열을 지우는 것을 선호합니다.
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 수정 해 주셔서 감사합니다. 코드를 수정했습니다.
data[count]='\0';
뒤에data[count]='\0';
추가 div id = “64b99aaa0d”>