Borre la matriz existente cuando obtenga un nuevo comando en serie

Estoy comenzando a construir mi primer proyecto Arduino pero tengo algunos problemas con la comunicación en serie.

Obtengo datos en serie de la consola y los guardo en una matriz de caracteres llamada «datos».

Luego, cuando envío un nuevo mensaje de consola al Arduino, quiero que borre el matriz de «datos» existente y almacenar solo los datos nuevos en esa matriz.

No entiendo exactamente qué es lo que está mal en mi código: creo que esas declaraciones Serial.available () anidadas no funcionan pero no tengo ideas sobre cómo arreglar el código.

El Arduino almacena correctamente los datos, pero concatena la cadena más nueva con la anterior.

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); } 

¡Gracias de antemano!

Responder

Para borrar una matriz, haría:

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

o

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

, que hace lo mismo usando una función de biblioteca.

Sin embargo, debido a que las cadenas de los caracteres (sin hacer referencia a los objetos «String» aquí) terminan con un byte cero, solo el primer byte debe ponerse a cero:

data[0] = (char)0; 

lo hará .

Respuesta

En primer lugar, este es un excelente ejemplo de por qué los espacios en blanco son importantes. Su código es realmente difícil de leer tal como está, ya que si lo hojea, parece que la segunda instrucción if está fuera de la primera.

Código fijo:

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); } 

Además, parece que imprime» Comando recibido: «en cada iteración, independientemente de si hay nuevos datos o no (aunque, esta podría ser la función deseada).

Como se mencionó, no borra la variable, simplemente crea una nueva. Deberá borrar y restablecer count para solucionar este problema. Sin embargo, restablecer el conteo no funcionará si el segundo comando es más corto que el antes.

Además, ¿por qué complica el código con la variable dataComplete? Simplifiqué el código siguiente:

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); } 

Respuesta

Esto probablemente no «t haz lo que pretendes que haga:

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

Tu resultado dice que estás limpiando la matriz data, pero «No estás haciendo tal cosa. De hecho, está declarando una nueva variable local llamada data, que es independiente de la data global que ya han declarado en la parte superior de su programa. Las variables locales solo existen dentro del ámbito en el que se declaran (dentro de su { } que las encierra más cercano).

En cambio, su variable count realiza un seguimiento de la cantidad de datos que ha recibido. Así que quizás haga lo siguiente:

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

Esto no es lo único que puede hacer que su programa funcione inesperadamente, pero al menos debería solucionar el problema indicado en su pregunta.

Comentarios

  • También se necesita un terminador nulo para los datos: agregue data[count]='\0'; después de dataComplete = true;
  • Sí, eso ‘ es cierto, pero el problema más grande es que el remitente no puede indicar el final de una transmisión de datos que no sea pausar. Y como esto es serial, habrá una pausa lo suficientemente larga entre cada carácter transmitido.
  • Gracias a los dos. Mi código era incorrecto y cambiarlo a » count = 0 » funcionó. También agregué un delimitador para indicar el final de un comando de entrada y ahora funciona según lo previsto. Sin embargo, la única forma que funcionó para vaciar la matriz » data » fue usando un bucle for como lo indica @JRobert: de esta manera más reciente Los comandos funcionan incluso si son más cortos que los más antiguos.

Responder

Para hablar sobre el punto de la pregunta , y lo que el autor estaba intentando lograr.

Ninguno de este código realmente funciona como un todo. Los datos se sobrescriben y simplemente se repiten continuamente … de todos modos, aquí hay un ejemplo funcional del código original.

Este método prefiero borrar una matriz:

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

Este es un ejemplo de trabajo. (Asegúrese de seleccionar Carriage Return en el monitor de serie)

 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

Me leyeron todos los comentarios sobre esta pregunta, pero todos los códigos se compartieron de manera tan detallada. Después de eso, creo un código con funciones simples y menos de línea. en este caso, creo que este código funcionará bien

Si configura la velocidad en baudios por debajo de 115200, debe agregar delay () para guardar el mensaje en la 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); } 

Comentarios

  • char data[] = {}; le dará una matriz de longitud cero. Intentar poner datos en él es una mala idea.
  • Estoy de acuerdo con @NickGammon.Edite su respuesta para reemplazar » Creo que … funcionará bien » con un sí / no definitivo, una vez que haya probado el código.
  • @NickGammon gracias por la corrección, estaba revisando mi código

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *