Estou começando a construir meu primeiro projeto Arduino, mas estou tendo alguns problemas com a comunicação serial.
Eu obtenho dados seriais do console e os armazeno em uma matriz de char chamada “dados”.
Então, quando eu enviar uma nova mensagem de console para o Arduino, quero limpar o array “data” existente e armazena apenas os novos dados nesse array.
Não entendo exatamente o que há de errado com meu código: acredito que as instruções aninhadas Serial.available () não funcionam mas não tenho ideias sobre como consertar o código.
Os dados são armazenados corretamente pelo Arduino, mas ele concatena a string mais recente com a antiga.
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); }
Agradecemos antecipadamente!
Resposta
Para limpar uma matriz, você faria:
for( int i = 0; i < sizeof(data); ++i ) data[i] = (char)0;
ou
memset(data, 0, sizeof(data));
, que faz a mesma coisa usando uma função de biblioteca.
No entanto, porque strings de caracteres (não se referindo a objetos “String” aqui) são encerrados por um byte zero, apenas o primeiro byte precisa ser zerado:
data[0] = (char)0;
fará isso .
Resposta
Em primeiro lugar, este é um excelente exemplo de por que o espaço em branco é importante. Seu código é realmente difícil de ler do jeito que está, visto que o examinando rapidamente, parece que a segunda instrução if está fora da primeira.
Código corrigido:
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); }
Além disso, parece que imprime” Comando recebido: “a cada iteração, independentemente de haver novos dados ou não (embora este possa ser o recurso pretendido).
Como mencionado, você não limpa a variável, apenas cria uma nova. Você precisará limpar e redefinir count
para corrigir esse problema. No entanto, apenas redefinir a contagem não funcionará se o segundo comando for mais curto que o antes.
Além disso, por que você complica o código com a variável dataComplete
? Simplifiquei o código abaixo:
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); }
Resposta
Isso provavelmente não faça o que pretende fazer:
Serial.println("There is data already, clearing..."); char data[30];
Sua saída diz que você está limpando a matriz data
, mas você “não está fazendo tal coisa. Na verdade, você está declarando uma nova variável local chamada data
, que é independente do data
global que você já declarou no topo do seu programa. Variáveis locais existem apenas dentro do escopo em que são declaradas (dentro de seu invólucro mais próximo { }
).
Em vez disso, sua count
variável mantém registro de quantos dados você recebeu. Então, talvez faça o seguinte:
Serial.println("There is data already, clearing..."); count = 0;
Isso não é a única coisa que pode fazer com que seu programa opere inesperadamente, mas deve pelo menos corrigir o problema declarado em sua pergunta.
Comentários
Resposta
Para falar direto ao ponto da pergunta , e o que o autor estava tentando realizar.
Nenhum desses códigos realmente funciona como um todo. Os dados seriam sobrescritos e continuariam em loop continuamente … de qualquer maneira, aqui está um exemplo funcional do código original.
Este método eu prefiro limpar um array:
for( int i = 0; i < sizeof(data); ++i ) data[i] = (char)0;
Aqui está um exemplo prático. (Certifique-se de selecionar Retorno de carro no monitor serial)
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; } } }
Resposta
Todos os comentários sobre esta questão foram lidos, mas todos os códigos foram compartilhados de forma verbosa. Depois disso, crio um código com funções simples e menos de linha. neste caso, acho que este código funcionará bem
se você definir a taxa de transmissão abaixo de 115200, deve ser adicionado delay () para salvar a mensagem na matriz de caracteres
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); }
Comentários
-
char data[] = {};
fornecerá uma matriz de comprimento zero. Tentar colocar dados nele é uma má ideia. - Eu concordo com @NickGammon.Edite sua resposta para substituir ” Eu acho … funcionará bem ” por um sim / não definitivo, depois de testar o código.
- @NickGammon obrigado pela correção, fui revisar meu código
data[count]='\0';
depois dedataComplete = true;