Pregunta:
Borre la matriz existente al obtener un nuevo comando en serie
squeck
2014-07-04 02:20:10 UTC
view on stackexchange narkive permalink

Estoy empezando 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 la matriz de "datos" existente y almacene solo los datos nuevos en esa matriz.

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

Los datos están almacenados correctamente por el Arduino pero concatena la cadena más nueva con la anterior.

  int count = 0; char data [30]; boolean dataComplete = false; void setup () {Serial.begin (9600); } bucle vacío () {if (Serial.available () > 0) {if (dataComplete == true) {Serial.println ("Ya hay datos, borrando ..."); datos de char [30]; dataComplete = falso; } if (dataComplete == false) {Serial.println ("Nuevo comando, recopilando ..."); while (Serial.available () >0) {carácter char = Serial.read (); datos [cuenta] = carácter; contar ++; } dataComplete = true; }} Serial.print ("Comando recibido:"); Serial.println (datos); delay (1000);}  

¡Gracias de antemano!

Cinco respuestas:
#1
+15
JRobert
2014-07-04 23:59:38 UTC
view on stackexchange narkive permalink

Para borrar una matriz, haría lo siguiente:

  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 caracteres (que no se refieren a los objetos 'String' aquí) terminan con un byte cero, solo el primer byte debe ponerse a cero:

  data [0] = (char) 0;  

lo hará.

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

En primer lugar, este es un ejemplo excelente de por qué son importantes los espacios en blanco. Su código es realmente difícil de leer tal como está, ya que al hojearlo, 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 ("Ya hay datos, borrando ..."); datos de char [30]; dataComplete = falso; } if (dataComplete == false) {Serial.println ("Nuevo comando, recopilando ..."); while (Serial.available () >0) {carácter char = Serial.read (); datos [cuenta] = carácter; contar ++; } dataComplete = true; }} Serial.print ("Comando recibido:"); Serial.println (datos); 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ó anteriormente, no borra la variable, simplemente crea una nueva. Deberá borrar y restablecer count para solucionar este problema. Sin embargo, simplemente restablecer el recuento no funcionará si el segundo comando es más corto que el anterior.

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

  int count = 0; char data [30]; boolean dataComplete = false; void setup () {Serial.begin (9600);} void loop () { if (Serial.available ()) {Serial.println ("Nuevo comando, recopilando ..."); cuenta = 0; datos [] = ""; while (Serial.available ()) {carácter char = Serial.read (); datos [cuenta] = carácter; contar ++; }} Serial.print ("Comando recibido:"); Serial.println (datos); retraso (1000);}  
#3
+1
Greg Hewgill
2014-07-04 02:41:55 UTC
view on stackexchange narkive permalink

Esto probablemente no haga lo que pretendes hacer:

  Serial.println ("Ya hay datos, borrando ..."); char data [30];  

Su salida dice que está limpiando la matriz data , pero no está haciendo tal cosa. De hecho, está declarando una nueva variable local llamada datos , que es independiente de los datos globales que ya ha declarado en la parte superior de su programa. Las variables locales solo existen dentro del ámbito en el que se declaran (dentro del {} 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 ("Ya hay datos, borrando ..."); count = 0;  

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

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 mayor es que no hay forma de que el remitente indique el final de una transmisión de datos que no sea una pausa. Y dado que esto es serial, habrá una pausa lo suficientemente larga entre * cada * carácter transmitido.
Gracias a ambos, chicos. Mi código estaba mal 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 de "datos" fue usando un bucle for como lo indica @JRobert: de esta manera los comandos más nuevos funcionan incluso si son más cortos que los más antiguos.
#4
  0
nu11
2015-05-06 08:47:36 UTC
view on stackexchange narkive permalink

Para hablar sobre el tema de la pregunta y lo que el autor intentaba lograr.

Ninguno de este código funciona en su totalidad. 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;  

Aquí hay un ejemplo de trabajo. (Asegúrese de seleccionar Carriage Return en el monitor serial)

  char message [32]; uint8_t entranteByte = 0; uint8_t BufferPos = 0; int clearbyte = 0; configuración vacía () {Serial.begin (9600); Serial.println ("\ n Prueba de conversión de cadenas"); } bucle vacío () {if (BufferPos > = 32) {Serial.print ("Buffer completo \ n"); BufferPos = 00; entranteByte = 0; } if (Serial.available ()) {entranteByte = Serial.read (); mensaje [BufferPos ++] = entranteByte; switch (entranteByte) {caso '\ n': caso '': romper; case '\ r': Serial.println (mensaje); for (int i = 0; i < sizeof (mensaje); ++ i) mensaje [i] = (char) 0; BufferPos = 0; entranteByte = 0; }}}  
#5
  0
Ashif Riady
2019-01-17 10:54:12 UTC
view on stackexchange narkive permalink

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 ( ) {datos de caracteres [255]; uint8_t k = 0; while (Serial.available ()) {datos [k] = Serial.read (); k ++; } para (int i = 0; i < k; i ++) {Serial.print (datos [i]); datos [i] = '\ 0'; } // retraso (50);}  
`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


Esta pregunta y respuesta fue traducida automáticamente del idioma inglés.El contenido original está disponible en stackexchange, a quien agradecemos la licencia cc by-sa 3.0 bajo la que se distribuye.
Loading...