Go Down

Topic: ayuda con cadenas de datos (Read 1 time) previous topic - next topic

chechucv

Hola, a todos. Tengo un problema para separar un char*. que recibo por Serial, se trata de una cadena tipo A,250,125,112
Estoy intentanto simplemente separar cada dato en una variable. ejemplo: valor1 = 250  , valor2 = 125, valor3 = 112 empieza de nuevo desde que lea la 'A'. He llegado asta aquí pero se me atasca,,creo que hay algo escrito por aquí pero no lo encuentro, me podéis ayudar por favor?.
if (Serial.available()>0)           
{
   delay(12);                         
   
   serAva = Serial.available(); 
   for (i=0; i<serAva;i++ )       
   inputBytes = Serial.read();
   inputBytes =  '\0';             
   atoi(inputBytesPtr);   
   }
   else
   return ;                           //ya recibimos el string.


  datos = inputBytesPtr;
 
  for ( i=0;i<1;i++){
  resultados = datos;
  //Serial.println(inputBytes);
  Serial.println(datos);
  delay (200);
  }

SrDonGato

Has mirado en el playground ?

es una pregunta además que sale muchas veces, esta por el foro infinidad de veces.

en playground
Calcular Int a partir de String o cadena de caracteres

http://arduino.cc/forum/index.php/topic,69309.0.html

un saludo

Sergegsx

Arduino 1.0 incluye un par de funciones nuevas para hacer estas cosas,si no recuerdo mal

curro92

Hola,
¿cómo tienes declarado inputBytes?

chechucv

Hola, curro92 la tengo como char.
SrDonGato, muchisimas gracias lo ví en su dia pero no lo encontraba, perdona.
Es alucinante lo sencillo que es, pero no entiendo como puedo hacer para coger los primero 3 numeros y meterlos en un int, luego los tre siguientes en otro int y luego los otros tres en otro int. Dado que la cadena es de 12 numeros y tengo que separarlos de tres en tres. El envío que hago desde el XBEE transmisor lo puedo separa por signos ("," o ";" o lo que sea), en el "receptor" XBEE lo recibo igual que lo envío sin problemas, pero mi problema es que como lo que transmito es el resultado de 4 entradas analógicas, debo separar esas cuatro entradas. Se que la forma mas tosca sería por multiplicaciones y divisiones pero me gustaría aprender como hacerlo mas limpio y sencillo y se me está atascando :smiley-eek:, un saludo.

SrDonGato

primero almacena la linea completa, vas metiendo los caracteres en un array hasta que llegue un retorno de carro ( en decimal 13)
luego analizas la linea, calculas que posiciones son las que quieres para calcular el numero, esto es, despues de cada coma y el primer número
si tu trama es A123,243,231,34

las posiciones que te interesan son la 2 siempre y posiciondecoma+1

desconozco si en la version 1 del IDE ya hay funciones para esto, no he tenido tiempo de mirarmelo

un saludo

chechucv

No entiendo bien como hacerlo en el array, peri si he realizado esto con tu libreria pero me devuelve 0:
char cadena[12];
int numeroobtenido =0;

#include "CharToInt.h"

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  if (Serial.available()>0)           // Check to see if there are any serial input
{
   delay(12);
   cadena[12] = Serial.read();
 
   Serial.print("Numero en la posicion 8 ");
   numeroobtenido=calculadesdeASCII(cadena,8);
   Serial.println(numeroobtenido,DEC);
}
}

SrDonGato

tienes un error de concepto ...

la linea  cadena[12] = Serial.read();

en la posicion 12 del array cadena te va a meter siempre lo mismo.


SrDonGato

en el ejemplo que pongo en la funcion puedes ver que funciona

lo que no sabes es como crear el array con lo que te llega del puerto serie, una vez tengas el array le puedes aplicar la funcion

en este reciente post http://arduino.cc/forum/index.php/topic,80816.0.html explica como hacerlo, aunque el rray sea para otro fin

Code: [Select]
char* nombrearchivo;
int inByte;
int indice=0;

void setup(){
Serial.begin(9600);
pinMode(10,OUTPUT);
}

void loop(){
  if (Serial.available()>0){ // si hay un caracter en el buffer
     inByte = Serial.read();     // metes el primer byte
     if (inByte!=13){  // si el byte es distinto del retorno de carro
     nombrearchivo[indice] = char(inByte);     //va poniendo los caracteres uno por uno en en nombre de archivo
     indice++; // incremento el indice para el proximo caracter
     }
     else {  // si llega un retorno de carro
      nombrearchivo[indice+1] = 0;  //indico el final de string con caracter nulo
      indice=0; // reseteo indice
     }
  }
myFile = SD.open(nombrearchivo, FILE_WRITE);
}


adecúalo a los fines que pretendes.

un saludo

chechucv

Hola de nuevo, no dudo de que funcione y además doy fé que funciona perféctamente bien y descarto que sea tu programa.
Tengo ya solucionado el prolema de la entrada por serial que tengo la cadena que mencionabamos antes 256210210200 por ejemplo, pero con tu programa no me compila  y creo que es por el char. No hay una forma como en visual o AWl o cualquier otro lenguaje en el que se pueda convertir directamente?. quiero decir que con tu programa funciona si le pongo una cadena de caracteres específica en el char de inicio pero si se lo envío desde serial ya convertido a char no me devuelve nada. No se que estoy haciendo mal, me estoy volviendo... :smiley-eek-blue:
Un saludo.

chechucv

En el  codigo que tengo hasta ahora,  he conseguido guardar la trama que recibo en un char. Puedo convertir esoso datos a long de alguna manera?.

curro92

#11
Dec 06, 2011, 05:37 pm Last Edit: Dec 06, 2011, 05:40 pm by curro92 Reason: 1
Hola, chechucv
No me has aclarado, como "char" se pueden definir por lo menos 3 cosas:
Code: [Select]

 char inputBytes;      // un único carácter
char inputBytes[22];  // una cadena con espacio para 21 caracteres
char *inputBytes;     // un puntero a cadena de caracteres, pero sin lugar para almacenarla

¿Cuál es tu caso?

chechucv

Hola curro92, char es  inputbytes, para que se añadan cada byte al char. curoo92 esto está superado, lo que no tengo claro es como hacer que ya teniendo el numero entero en forma de char ej. 256235456123, separarlos de 3 en 3 numeros y asignarlos a un int cada uno. Lo tengo ya hecho con sumas, multiplicaciones y divisiones pero no creo que sea la manera má ortodocxa. Creo que debe existir una forma de hacerlo mas limpia ¿no?.
Un saludo y gracias por tu repuesta.

SrDonGato

ese código que te he puesto  hace parte de lo que quieres, guarda los caracteres que vienen por serie en una cadena de char.

a esta cadena de char debes aplicar la funcion que te he dicho.

despues de que llegue un retorno de carro, analizas el array completo.

El array que muestras no tiene delimitaciones entre número y otro, como sabes donde empieza uno ?
tienes que enviarlos separados por comas al menos

no te funciona la funcion porque si aplicas la funcion que te he dado tienes el máximo dado por INT.
lo dicho, separa los datos por comas, lo metes en un array,
te quedara algo como 123,32,54,345

aplicas la funcion que te explico. donde ? en la posicion 1 siempre, y luego buscas la posicion de la coma y aplcas la funcion en posicioncoma+1, o posicioncoma+2 si es que es negativo


chechucv

Perdoname SrDonGato, estoy espeso pero no te entiendo. Yo ya envio la trama como me cometas desde el transmisor 256,235,563,121 o como tu quieras no importa. Cuando recibo esa trama lo hago exactamente igual que la que envío.
Ya la tengo en char,  ok. Ahora necesito convertir dicha trama en int separados, he llegado a:


char* datos;
long int  dato1=0;
unsigned long  dato2=0;
unsigned long  dato3=0;

void setup() {
  Serial.begin(9600);
}

void loop() {


int i,serAva;     
char entranBytes [7];               
char * entranBytesPtr = &entranBytes[0]; 
     
if (Serial.available()>0)         
{
   delay(15);                                                         
   serAva = Serial.available();
   for (i=0; i<serAva;i++ )       
   entranBytes = Serial.read();
   entranBytes =  '\0';             
   atoi(entranBytesPtr); 
   }
   else
   return ;                         
  datos = entranBytes;
   
  long int dato1= atol( datos);   

Pero en dato1 ya está convertido a long... (es para hacerlo con sumas y restas). pero como diferencio los 3 primeros numeros la coma los otros 3 numeros, etc.?

Go Up