Como convertir variable uint8_t en int?? (SOLUCIONADO)

Buenas noches!!!

Tengo un inconveniente. Estaria muy agradecido si me ayudan a solucionarlo…

necesito convertir unos datos que llegan a una variable uint8_t en datos enteros.

Llegan en bytes y los necesito en int…

void dataReceived(uint16_t addr, uint8_t *data, uint16_t dataSize) {
 
  


  Serial.print('\n');
  for(int i=0;i<dataSize;i++) {
    Serial.write(data[i]);
   

    String str = (char*)data;
    new_str = str.substring(8, 15);
    Serial.print(new_str);
    
  }
 

  
}

La pregunta y el código son algo confusas.

Por un lado preguntas como convertir un uint8_t en un int. Eso se hace con un “cast”, que consiste en indicar al compilador que trate una variable de un tipo como si fuera de otro:

uint8_t a;
int b;

b = (int)a;

El código anterior hace una cast (int)a, haciendo que a que es del tipo uint8_t se trate como un int.

Por otro lado, en tu codigo tienes un array de uint8_t. Parece que quisieras transformar un array de caracteres en el valor númerico que representa. Por ejemplo, recibes la cadena “123” y quieres convertirla en el valor 123. Ya que estas usando el objeto String, puede usar la función toInt() para convertirlo en entero.

String str = (char*)data;
new_str = str.substring(8, 15);
int valor = new_str.toInt();

Con una aclaración mejor de lo que es, podremos orientarte mejor.

Saludos victorjam.

Es correcta la idea que captaste de lo que pregunte. Y me aydudo mucho a aclarar dudas sobre los datos que estaba recibiendo…

Mi modelo consta de 3 nodos que sensan C02. estos nodos envían los datos mediante Xbee a un nodo coordinador. las Xbee transmite en bytes y es allí donde surge mi inconveniente.

El siguiente código es el que se encarga de la recepción de los datos en el nodo coordinador. Allí se devuelve un arreglo de “enteros”. la variable llamada “dataSize” es la que determina el tamaño del arreglo recibido lo procesa de manera acorde.

// Procesa los datos recibidos
void dataReceived(uint16_t addr, uint8_t *data, uint16_t dataSize) {
  

  Serial.print('\n');
  
  for(int i=0;i<dataSize;i++) {
      Serial.write(data[i]);
      Serial.print(".............................");
      Serial.println(data[i]);
  }

Cuando imprimo con:

Serial.write(data[i]);

Imprime por serial:
0.13

Cuando imprimo con:
[code]Serial.println(data[i]);[/code]
imprime

48
46
49
51
13
10

Converti estos numeros de ascci a caracteres y efectivamente corresponde a 0.13 el 13 y 10 son espacios.

Ahora quiero convertir esos numeros ascii a valores normales numericos. y guardarlos en una variable uno por uno.

Espero me puedas colaborar…

Quedo muy atento!!!

Entonces lo que recibes en realidad es una cadena ASCII con un valor float que termina en "retorno de carro" y "cambio de linea", CR y LF, 13 y 10.

Puedes intentar dos cosas:

La díficil. Recorrer el array y buscar el '.' (punto decimal), dividir la cadena en dos a partir del punto. Así tendrás dos cadenas con números: una con la parte entera y otra con la parte decimal. Usar toInt() o la función atoi() para convertirlos en enteros.

La fácil. Usa la función toFloat() del objeto string que te convertirá la salida en un número float.

String str = (char*)data;
float valor = str.toFloat();

Moderador
Recuerda no incluir palabras como Ayuda por favor en tus títulos presente y futuros. Ya edité este pero no lo haré en el futuro.

Saludos!!

El código que me compartiste para convertir a float me termino arrojando un numero en float pero muy diferente al que necesitaba. Al parecer llegaba un arreglo de muchos Ascci debido a la trasmisión vía Zigbee que es de donde provienen los datos que necesito en entero. Aun asi me ayudo a aclarar muchas dudas sobre lo que estaba recibiendo y como debía tratarlo. Muchas gracias… Lo tendré en cuenta para futuros proyectos ya que es muy útil tener claro como manejar o convertir las variables.

Sin embargo ya encontré solución a mi problema. A continuación comparto el código.

String vec1;
String vec2;
String vec3;
String vec4;

void loop() {

//Tener en cuenta que el siguiente handler aplica solo a mi código. Como tal el for si es muy general y fácil de adaptar

void dataReceived(uint16_t addr, uint8_t *data, uint16_t dataSize) {

   for(int i=0; i<=6; i++)
    {
      
      vec1=(data[0])-48;
      vec2=(data[1])-46;
      vec3=(data[2])-48;
      vec4=(data[3])-48;
  
    }

   
    dato=vec1+"."+vec3+vec4;

    Serial.println(dato);

}

Divido el arreglo que recibo en variables independientes. Posterior a ello los convierto los Ascii a int restando 48 por ultimo lo rearmo concatenando las variables en un nuevo String y remplazando la variable que corresponde al punto eliminándola e insertando un punto en el String concatenado.

Espero me entiendan.

ahora solo necesito dividir esa variable en tres variables mediante un identificador o algo así. Eso lo preguntare en un nuevo hilo para no hacer confusa esta solución que puede servirle a alguien mas.

Saludos!!

Tengo 5 variables y necesito reemplazar el valor detro de una de ellas cuando esta llegue con determinado numero. A continuación adjunto el código para ser mas claro.

String vec1;
String vec2;
String vec3;
String vec4;
String vec5;
int vec6;
String vec7;
String dato;
String separador;
String Sensor1;
String Sensor2;
String Sensor3;
Separador s;
int t=98;
int t2=97;

void dataReceived(uint16_t addr, uint8_t *data, uint16_t dataSize) {
   for(int i=0; i<=6; i++)
    {
      
      Serial.write(data[i]);
      vec=(data[i])-48;
      vec1=(data[0])-48;
      vec2=(data[1])-46;
      vec3=(data[2])-48;
      vec4=(data[3])-48;
      vec6=(data[6]);
       
       if(data[6]==t2){
      vec6=="a";
      }
      if (data[6]==t){
      vec6=="b";
      
      }
       

      
     
      Serial.print(".....................");
      Serial.println(vec);
      
      
    }

   
    dato=vec1+"."+vec3+vec4+vec6;

    Serial.println(dato);

Necesito que cuando Vec6 = 97 reemplazar ese 97 por una a. y si es Vec6=98 reemplazar el 98 por una b. Para posterior a ello poder separar el arreglo de string mediante este identificador de letra. Espero me entiendan.

Quedo atento a alguna sugerencia y de antemano gracias.

Saludos!

Tengo un lió. al momento de separar las variables que obtengo de un for…
Quiero que el resultado de cada ciclo se guarde en un campo de un arreglo. Pero no sucede. lo que obtengo es que el resultado del for, llena los 4 campos y el arreglo se me vacía al momento de realizarse el nuevo ciclo del for.

Siendo mas especifico recibo los datos de 2 sensores. En el for los proceso y obtengo una variable final llamada dato. Quiero que cada vez que el for haga su ciclo se guarde ese resultado en un campo del arreglo. Y así sucesivamente.

A continuación esta el código para que me entiendan mejor y ojala me puedan ayudar con comentarios o sugerencias. Los últimos post me han sido de gran ayuda.
Estoy trabajando con Arduino uno y transmitiendo con protocolo Zigbee A través de unas Xbee s1pro.

#include <Separador.h>
#include <teubico_XBeeSeries1.h>
#include <teubico_utils.h>

XBeeSeries1 * myXBee;

// Variable para el pseudo-timer
long lastMessage = 0;

int vec;
//variables para separar arreglo de datos recibido. 
String vec1;
String vec2;
String vec3;
String vec4;
String dato;
//variables para separar datos 
String separador;
String sensor1;
String sensor2;
String sensor3;
//Arreglo para guardar datos que se obtienen del ciclo for
String ojala[2];

Separador s;
int t=98;
int t2=97;
void setup() {
   
  Serial.begin(9600);
  // Indicamos que debera de pegarse al Serial
  // Con la direccion 0x0002
  myXBee = new XBeeSeries1(Serial, 0x0002);
  myXBee->onDataReceived16(dataReceived);
  myXBee->init();
}

void loop() {
  // Escuchar por nuevos datos
  myXBee->listen();
  
  // Enviar un mensaje cada segundo aproximadamente
  if(checkTimeout(lastMessage,1000)) {
   
    lastMessage = millis();     
  }
}
// Procesa los datos recibidos

//Funcion que recibe datos Bytes de los 3 nodos sensores. Tener en cuenta que el arreglo que arroja
//esta en Ascii hay que convertir
void dataReceived(uint16_t addr, uint8_t *data, uint16_t dataSize) {
  
   
   for(int i=0; i<=6; i++)
    {
      vec=(data[i])-48;
      vec1=(data[0])-48;
      vec2=(data[1])-46;
      vec3=(data[2])-48;
      vec4=(data[3])-48;

      //concateno datos convertidos agregando punto decimal y coma al final para utilizar
      //libreria separar
       dato=vec1+"."+vec3+vec4+",";   
    } 
    Serial.println(dato);
    for(int i=0; i<=2; i++){
      //Arreglo String para guardar resultado del for. Llegan 3 datos los guardo en 3 campos
      ojala[i]=dato;    
     }
    
  //Separo arreglo para aplicar funcion que separa cuando encuentra comas ","

  //NO ESTA SEPARANDO. ESTA GUARDANDO EL MISMO DATO EN TODOS LOS CAMPOS DEL ARREGLO
  //COMO SI EL ARREGLO SE EJECUTARA 3 VECES EN CADA CICLO
    String separar = ojala[0]+ojala[1]+ojala[2];
    sensor1=s.separa(separar,',',0);
    sensor2=s.separa(separar,',',1);
    sensor3=s.separa(separar,',',2); 
   
    Serial.println("El elemento 1 es:"+sensor1);
    Serial.println("El elemento 2 es:"+sensor2);
    Serial.println("El elemento 3 es:"+sensor3);

     delay(3000);   
}

not sure I understand the Xbee interface. The Received Data section of this page suggests that the arguments to the callback function, dataReceived() contain "dataSize" bytes of data in "data"

the following code you posted has some issues

  • why only 6 and not dataSize?
  • why is data indexed by "i" in the first line, but fixed values, 0, 1, 2, 3, in the following 4
  • it looks like 48 or '0' is subtracted from each data value. is this an attempt to convert them to integers?
  • if vec, vec1, vec2, ... are Strings, why copy one byte (or char) into each String and not copying the entire data to a String (not sure this is the correct way
       vec=(data[i])-48;
        vec1=(data[0])-48;
        vec2=(data[1])-46;
        vec3=(data[2])-48;
        vec4=(data[3])-48;

Saludos gcjr!!!

Es correcta la forma que interpretas mi código. y Efectivamente tienes razon con lo que dices…

  • why only 6 and not dataSize?

Es porque estaba haciendo pruebas para determinar la forma mas viable para separar los datos. Intente enviando una letra desde los nodos por lo que la recibía en ascii y serviría como identificador para cada nodo. El método consistía en convertir el Ascii que correspondía al campo 5 del arreglo recibido, a letra mediante un if. El if consistía en que cuando encontrar un 98 en vec5 remplazara el valor de vec5 por "a"pero no me funciono. El if no hacia su función y no entendí el porque. . Encontré una librería que separa los datos definiendo un carácter. Es por ello que al final de dato la variable donde concateno las variables coloco una coma “,”.

dato=vec1+"."+vec3+vec4+",";
  • why is data indexed by “i” in the first line, but fixed values, 0, 1, 2, 3, in the following 4

Porque si coloco como limite datasize me llegan muchos bytes. y en realidad los datos que necesito solo corresponden a los 4 primer bytes. Por lo que si dejo el contador en 3 igual funcionaria. Al no guardar los demás campos del arreglo en variables simplemente se están perdiendo. Igual voy a modificar para no desperdiciar memoria. “vec=(data*)-48;” lo tenia para hacerle Println(vec); y saber ue estaba llegando en el arreglo como tal. A partir de allí pude concluir que en realidad los datos que necesitaba correspondían a los [4] primeros campos del arreglo. Se puede eliminar del codigo. En realidad solo fue para pruebas.*
```
* for(int i=0; i<=3; i++)
   {
     
     vec1=(data[0])-48;
     vec2=(data[1])-46;//Este campo corresponde al punto decimal. Se puede ignorar.
     vec3=(data[2])-48;
     vec4=(data[3])-48;

//concateno datos convertidos agregando punto decimal y coma al final para utilizar
     //libreria separar
      dato=vec1+"."+vec3+vec4+",";   //Inserto punto decimal y “,” que permitirá separar los datos
   }*
* *- parece que 48 o '0' se resta de cada valor de datos []. ¿Es este un intento de convertirlos en enteros?* *Es correcto. Convierto los Ascii a enteros restando un 48. El "vec 2" o "data[1]" se pueden ignorar ya que corresponden a un punto decimal.* *
*for(int i=0; i<=3; i++)
   {
     
     vec1=(data[0])-48;
     vec3=(data[2])-48;
     vec4=(data[3])-48;

//concateno datos convertidos agregando punto decimal y coma al final para utilizar
     //libreria separar
      dato=vec1+"."+vec3+vec4+",";  
   }*
```
if vec, vec1, vec2, … are Strings, why copy one byte (or char) into each String and not copying the entire data[] to a String (not sure this is the correct way
Porque el objetivo de separar es poder hacer la conversión de solo los primeros 4 campos del arreglo que llega. Si concateno todo lo que llega sin dividir es mas complicado hacer la conversión. Por ejemplo. como convierto el 46 Ascii a un punto decimal. ’

if data contains a decimal value as an ASCII string, you can use sscanf() or atoi()

int val = atoi(data);

Moderado:
Por favor @muchocode, no repitas lo que se lee arriba y presta atención al lenguaje que usas cuando posteas en sitios en español (como estas ahora) o en inglés como inicialmente usaste porque tu hilo fue movido por un modeador a este lugar.

Si escribes en español usa este foro en Español.

Que tal asi, defines a

String vec[6];

y luego en tu procedimiento usas

data = "";
  for (int i=0; i<=6; i++) {
        vec[i]=(data[i])-48;
        data += vec[i];           // concateno datos convertidos agregando punto decimal y coma al final para utilizar
                                        // librería separar
  }

Para separar usa .indexOf(‘caracter’) sumado a .subSting la combinación detecta donde esta el caracter delimitador y subString toma la cadena desde hasta.

Moderador
Doble posteo. Mismo código diferente post.
Quedas advertido y de seguir posteando leves diferencias respecto a tu código tendré que darte un descanso (entiéndase suspención o baneo).
Las normas son claras y estar con diferencias sutiles del mismo código solo nos hace perder el tiempo a quienes te respondemos.

surbyte:
Que tal asi, defines a

String vec[6];

y luego en tu procedimiento usas

data = "";

for (int i=0; i<=6; i++) {
        vec[i]=(data[i])-48;
        data += vec[i];          // concateno datos convertidos agregando punto decimal y coma al final para utilizar
                                        // librería separar
  }




Para separar usa .indexOf('caracter') sumado a .subSting la combinación detecta donde esta el caracter delimitador y subString toma la cadena desde hasta.

translating a decimal value represented in an ascii string by subtracting ‘0’ from the ascii values will not result in a correct decimal value a hex value of 0x100 represents 256 not 100.

you should use “atoi()” or “sscanf()”