PROBLEMA CON EXTRACCION DE DATOS DE UNA CADENA

Saludos a todos.

Tengo una cadena alfanumérica que consta de un nombre seguido de varios números separados por comas:

Ejemplo: Altura,15,32,67,98,34,20

como puedo extraer la cadena Altura a una variable, el nº 15 a otra variable numérica (tipo int), el nº 32 a otra variable numérica (tipo int) y así con el resto.

Gracias de antemano.

El método para extraer todo varía según el tipo de dato de la cadena. Los utilizados en Arduino son:

"Array" de char

char texto[] = "Altura,15,32,67,98,34,20";

Objeto String

String texto = "Altura,15,32,67,98,34,20";

Antes de responderte necesito saber: de cuál de las dos formas está almacenado?

Pero antes corrige tu título

AYUDA CON

Esas palabras no estan permitidas. Te sugiero leas las normas del foro.

@Lucario448

Es como objeto String.

Gracias por la ayuda.

Para tu objetivo, puedes guiarte con este código:

String data = "Altura,15,32,67,98,34,20";                 // Cadena de caracteres de prueba

void setup() {
  Serial.begin(9600);                                     // Iniciar comunicación serial
  
  byte values[6];                                         // Una forma más "compacta" de crear seis variables.
  byte prevPos = data.indexOf(',');                       // Buscar la posición de la primera coma en la cadena
  String first = data.substring(0, prevPos);              // Extraer la primera cadena de caracteres (sin coma)
  prevPos++;                                              // Desplazar el índice de la primera coma. Sin esto, la próxima búsqueda resultará
                                                          // en la misma posición.
  byte currPos = data.indexOf(',', prevPos);              // La siguente subcadena ya no empezará desde el principio; por lo tanto, hay que
                                                          // almacenar dos posiciones.
  
  for (byte i = 0; i < 6; i++) {
    values[i] = data.substring(prevPos, currPos).toInt(); // Extrae la subcadena que contiene un número, luego se convierte en un valor
                                                          // númerico de variable.
    prevPos = currPos + 1;                                // Como ahora trabajamos con dos posiciones y necesitamos pasar a la siguiente
                                                          // subcadena, la "posición actual" ahora es la anterior. No olvidemos el
                                                          // desplazamiento de índice.
    currPos = data.indexOf(',', prevPos);                 // La "posición actual" ahora es la próxima ocurrencia del "caracter separador"
                                                          // (en este caso, una coma).
  }                                                       // Y todo esto se repite 5 veces más.

  Serial.println("Cadena: " + first);                     // Imprime, al monitor serie, la primera subcadena extraída.
  
  for (byte i = 0; i < 6; i++) {                          // Imprime el valor de las seis variables extraídas del texto de prueba.
    Serial.println("Valor " + String(i + 1) + ": " + String(values[i]));
  }
}

void loop() {
                                                          // Y se acabó. Luego no ocurre nada :P

}

NOTA: solo aplica específicamente para tu ejemplo. Si le piensas dar un uso más general, puede que haya que hacerle unas modificaciones.

Mirate el ultimo post de este topic está la solución a tu problema

cefere0:
Mirate el ultimo post de este topic está la solución a tu problema

Gracias cefere0, voy a mirar también lo que comentas.

Gracias Lucario448.

El codigo que posteas en principio está bien, pero al ponerlo en un Void aparte que va a ser llamado muchas veces me da un error de compilación: "ld.exe ha detectado un problema y debe cerrarse."

La cadena que pongo como ejemplo lleva 6 números, pero puede llegar a llevar hasta 32 según el caso (el valor de los números puede ser desde el 1 hasta el 1.000.000).

Necesito que los datos extraídos con "String(values*)" poder almacenarlos como numéricos "int32_t" en una matriz solo numérica para después ser llamados según la posición en la matriz.*
Muchas gracias por tu ayuda.

Mira el ejemplo de @cere0 porque el hace algo muy parecido a lo que necesitas.

TESLATRONICA:
El codigo que posteas en principio está bien, pero al ponerlo en un Void aparte que va a ser llamado muchas veces me da un error de compilación: "ld.exe ha detectado un problema y debe cerrarse."

Que el ejecutable se cuelgue no debería ser culpa del código a compilar :o

Si el código que yo postee lo encapsulas en una función, tal y como está; no me sorprende que tenga sus errores.

TESLATRONICA:
La cadena que pongo como ejemplo lleva 6 números, pero puede llegar a llevar hasta 32 según el caso (el valor de los números puede ser desde el 1 hasta el 1.000.000).

Yo antes había dicho que para uso general, el código debería modifcarse. Yo solo me limité a hacerlo con base en el ejemplo.

Si dices que el rango de posibles valores es de 1 a 1 millón, entonces las variables pueden ser unsigned long.
Si dices que hasta 32 números a la vez pueden haber en un String... entonces ese String podría ocupar incluso hasta 1 KB de RAM (la mitad en un ATmega328P). Un array de 32 long requiere de 128 bytes; algo que también debes considerar dependiendo de tu programa.

TESLATRONICA:
Necesito que los datos extraídos con "String(values*)" poder almacenarlos como numéricos "int32_t" en una matriz solo numérica para después ser llamados según la posición en la matriz.[/quote]*
Piénsalo bien. Si son 32 de esos por fila, serían 128 bytes por fila.
Un Arduino Uno/Nano solo dispone de 2 KB de RAM, así que cuidado si eventualmente se te cuelga el programa.

Gracias de nuevo a Todos.

He conseguido quitar los errores y ya lo tengo funcionando como deseo, a falta de una limitación, que es la siguiente:

He metido nuevos valores al ejemplo (ver código), todo funciona correctamente salvo cuando los valores numéricos sobrepasan al valor máximo de "int" (32767), entonces devuelve un valor que no corresponde con el original del "String data", creo que el problema está en la siguiente línea values = data.substring(prevPos, currPos).toInt(); que al convertir a int sobrepasa su capacidad, no se si sabéis como solucionar esto.
```
*unsigned long matriz_general[30];                        //matriz de almacenamiento hasta 30 números enteros positivos
int final_matriz;                                        //nº total real de números a almacenar
String data = "Altura,15,32,67,98,34,20000,225000";      // Cadena de 7 caracteres numéricos de prueba (30 max)

void setup() {
 
  Serial.begin(9600);                                    // Iniciar comunicación serial

}

void loop() {
    conversion_cadena();                                  //llama el procedimiento                       
    delay (100000);

//resto de comandos

}

void conversion_cadena() {                                //procedimiento que convierte las cadenas y almacena en la matriz numérica
 
  unsigned long values[30];                              // Una forma más "compacta" de crear 30 variables.
  byte prevPos = data.indexOf(',');                      // Buscar la posición de la primera coma en la cadena
  String first = data.substring(0, prevPos);              // Extraer la primera cadena de caracteres (sin coma)
  prevPos++;                                              // Desplazar el índice de la primera coma. Sin esto, la próxima búsqueda resultará
                                                          // en la misma posición.
  byte currPos = data.indexOf(',', prevPos);              // La siguente subcadena ya no empezará desde el principio; por lo tanto, hay que
                                                          // almacenar dos posiciones.
 
  for (byte i = 0; i < 30; i++) {
    values[i] = data.substring(prevPos, currPos).toInt(); // Extrae la subcadena que contiene un número, luego se convierte en un valor
                                                          // númerico de variable.
    prevPos = currPos + 1;                                // Como ahora trabajamos con dos posiciones y necesitamos pasar a la siguiente
                                                          // subcadena, la "posición actual" ahora es la anterior. No olvidemos el
                                                          // desplazamiento de índice.
    currPos = data.indexOf(',', prevPos);                // La "posición actual" ahora es la próxima ocurrencia del "caracter separador"
                                                          // (en este caso, una coma).
  }                                                      // Y todo esto se repite 5 veces más.

Serial.println("Cadena: " + first);                    // Imprime, al monitor serie, la primera subcadena extraída.
 
  for (byte i = 0; i < 30; i++) {                        // Imprime el valor de las seis variables extraídas del texto de prueba.
   
    Serial.println("Valor " + String(i + 1) + ": " + String(values[i]));

char a_[33];                                          //define variable char
    unsigned long b_;                                    //define variable numeros enteros positivos long
    String(values[i]).toCharArray(a_, 32);                //convierte strig a char
    b_  = atoi(a_);                                      //convierte char a int
    //Serial.println( b_);

matriz_general[i]=b_;                                //almacena los valores numéricos en la matriz
    //Serial.println( matriz_general[i]);

//el bucle de hasta 30 termina cuando ya no detecta mas números
                                                          //y en Serial.println... imprime el nº 0
   
    if (b_==0){                                          //si detecta valor 0 pone el contador i a 30 y fuerza la salida del for
      final_matriz=i;                                    //al salir de for queda almacenado el nº total
                                                          //de números válidos (max 30 según String data)
     
      //Serial.println( final_matriz );
      i=30;                                              //al asignar el valor 30 fuerza la salida del bucle for
    }

}

}*
```

no uses int, usa unsigned int y seran valores SIN SIGNO de 0 a 65535= 2^16 - 1

Ohhhhh. Es que tu entendes por "matriz" a cualquier conjunto "contiguo" de variables. Yo por "matriz" entendía que era un arreglo bidimensional (2D); no unidimensional (como lo estas haciendo ahora).

char a_[33];                                          //define variable char
    unsigned long b_;                                     //define variable numeros enteros positivos long
    String(values[i]).toCharArray(a_, 32);                //convierte strig a char
    b_  = atoi(a_);                                       //convierte char a int
    //Serial.println( b_);

    matriz_general[i]=b_;                                 //almacena los valores numéricos en la matriz
    //Serial.println( matriz_general[i]);

                                                          //el bucle de hasta 30 termina cuando ya no detecta mas números
                                                          //y en Serial.println... imprime el nº 0
    
    if (b_==0){                                           //si detecta valor 0 pone el contador i a 30 y fuerza la salida del for
      final_matriz=i;                                     //al salir de for queda almacenado el nº total 
                                                          //de números válidos (max 30 según String data)
      
      //Serial.println( final_matriz );
      i=30;                                               //al asignar el valor 30 fuerza la salida del bucle for

Para qué hacer todo esto si ya tienes los datos extraídos?
Además, atoi devuelve un int (con signo).

ESTAS CONVIRTIENDO UN unsigned long A int? Una variable de 4 bytes a otra de 2 bytes?
Eso es, estás eliminando información; por eso es que te arroja valores incorrectos.

surbyte he cambiado a "unsigned int" y voy a probar.

Lucario448 tienes razón, repetí en el código la conversión porque cuando quise almacenar los valores numéricos en la matriz numérica me dio error de tipo de variables, he corregido el código y ahora no me da error:

unsigned long matriz_general[30];                         //matriz de almacenamiento de numeros enteros positivos
int final_matriz;                                         //nº total real de números a almacenar
String data = "Altura,15,32,67,98,34,20000,225000";       // Cadena de 7 caracteres numéricos de prueba (30 max)

 
void setup() {
  
  Serial.begin(9600);                                     // Iniciar comunicación serial
    
 
}


void loop() {
    conversion_cadena();                                  //llama el procedimiento                        
    delay (100000);

                                                          //resto de comandos

    
}


void conversion_cadena() {                                //procedimiento que convierte las cadenas y almacena en la matriz numérica
   
  unsigned int values[30];                               
  byte prevPos = data.indexOf(',');                       // Buscar la posición de la primera coma en la cadena
  String first = data.substring(0, prevPos);              // Extraer la primera cadena de caracteres (sin coma)
  prevPos++;                                              // Desplazar el índice de la primera coma. Sin esto, la próxima búsqueda resultará
                                                          // en la misma posición.
  byte currPos = data.indexOf(',', prevPos);              // La siguente subcadena ya no empezará desde el principio; por lo tanto, hay que
                                                          // almacenar dos posiciones.
  
  for (byte i = 0; i < 30; i++) {
    values[i] = data.substring(prevPos, currPos).toInt(); // Extrae la subcadena que contiene un número, luego se convierte en un valor
                                                          // númerico de variable.
   
    matriz_general[i]= values[i];   //almacena los valores numéricos en la matriz

    if (matriz_general[i]==0){ 
      final_matriz=i;   
      i=30; 
    }


    
    prevPos = currPos + 1;                                // Como ahora trabajamos con dos posiciones y necesitamos pasar a la siguiente
                                                          // subcadena, la "posición actual" ahora es la anterior. No olvidemos el
                                                          // desplazamiento de índice.
    currPos = data.indexOf(',', prevPos);                 // La "posición actual" ahora es la próxima ocurrencia del "caracter separador"
                                                          // (en este caso, una coma).
  }                                                       // Y todo esto se repite 5 veces más.

  Serial.println("Cadena: " + first);                     // Imprime, al monitor serie, la primera subcadena extraída.
  
  for (byte i = 0; i < 30; i++) {                         // Imprime el valor de las seis variables extraídas del texto de prueba.
    
    Serial.println("Valor " + String(i + 1) + ": " + String(values[i]));

    //Serial.println( matriz_general[i]);

   }

}

A falta de probarlo creo que seguiré con la limitación de no poder llegar a números hasta el millón, voy a estar sin conexión varios días por lo que no podré contestar, luego seguiré con el tema.

Saludos a todos y gracias por vuestro interés.

Por qué no llegarías al millón?
toInt en realidad devuelve un long; lo que quiere decir que el rango de posibles valores es de -2147483648 a 2147483647.