Datos erroneos al convertir string en entero

Hola estoy realizando un programa en Python en el cual realizo el envió de datos por medio de serial a un Arduino UNO.

Tengo lo siguiente en Python:

class CONFIGURACION_SERIAL():
    def __init__(self, PUERTO_COM='COM7',BAUDIOS=115200):
        self.PUERTO_COM =PUERTO_COM
        self.BAUDIOS=BAUDIOS

        self.CONEXION_SERIAL = Serial(PUERTO_COM,BAUDIOS, timeout=.1)# CONFIGURAMOS EL PUERTO COM PARA COMUNICACIÓN
        time.sleep(2)# TIEMPO DE ESPERA PARA CONEXIÓN CON EL MICRO
    
    def MANDAR_DATOS (self,AVANCE): 

        AVANCE_STR = str(AVANCE) + "\n" # AQUÍ CONVIERTO EL VALOR FLOTANTE EN STRING Y LE AGREGO UN SALTO DE LÍNEA
        AVANCE_BYTES = AVANCE_STR.encode()# AQUÍ CONVIERTO LA CADENA A BYTES PARA ENVIARLO POR SERIAL
        self.CONEXION_SERIAL.write(AVANCE_BYTES) # AQUÍ SE MANDAN LOS DATOS POR SERIAL AL MICRO

        return AVANCE_BYTES

    def RECIBIR_DATOS (self):
        RESPUESTA_SERIAL = self.CONEXION_SERIAL.readline() # AQUÍ SE LEEN LOS DATOS QUE ENVÍA EL MICRO

        return RESPUESTA_SERIAL
    
    def CERRAR_CONEXION (self):
       self.CONEXION_SERIAL.close()

En Arduino tengo lo siguiente:

#define LEDPWM1 5
String datos;
int LED;
void setup()
{
    Serial.begin(115200);	
    Serial.setTimeout(.1);  
    pinMode (LEDPWM1, OUTPUT);
}

void loop()
{   
    while (Serial.available() > 0) 
    {
      datos = Serial.readString(); 
      delay(1);  
      LED = datos.toInt();
      analogWrite(LEDPWM1,LED);
      Serial.print(LED);
      }

}

Como pueden ver es un programa realmente sencillo, el problema está que al momento de realizar la conversión a entero obtengo datos erróneos en la conversión:

Enviando valor: b'94\n'
Distancia dedos 118 Proporción distancia avanzada 93.903 MICRO : b'93'
Enviando valor: b'93\n'
Distancia dedos 119 Proporción distancia avanzada 94.252 MICRO : b'94'
Enviando valor: b'94\n'
Distancia dedos 120 Proporción distancia avanzada 95.806 MICRO : b'95'
Enviando valor: b'95\n'
Distancia dedos 121 Proporción distancia avanzada 96.433 MICRO : b'96'
Enviando valor: b'96\n'
Distancia dedos 121 Proporción distancia avanzada 96.565 MICRO : b'96'
Enviando valor: b'96\n'
Distancia dedos 120 Proporción distancia avanzada 95.487 MICRO : b'95'
Enviando valor: b'95\n'
Distancia dedos 123 Proporción distancia avanzada 98.016 MICRO : b'98'
Enviando valor: b'98\n'
Distancia dedos 124 Proporción distancia avanzada 99.278 MICRO : b'99'
Enviando valor: b'99\n'
Distancia dedos 125 Proporción distancia avanzada 100.873 MICRO : b'10'
Enviando valor: b'100\n'
Distancia dedos 125 Proporción distancia avanzada 100.96 MICRO : b'10'
Enviando valor: b'100\n'
Distancia dedos 127 Proporción distancia avanzada 102.487 MICRO : b'12'
Enviando valor: b'102\n'
Distancia dedos 129 Proporción distancia avanzada 104.692 MICRO : b'14'
Enviando valor: b'104\n'
Distancia dedos 129 Proporción distancia avanzada 104.035 MICRO : b'14'
Enviando valor: b'104\n'
Distancia dedos 135 Proporción distancia avanzada 110.059 MICRO : b'110'
Enviando valor: b'110\n'
Distancia dedos 133 Proporción distancia avanzada 108.765 MICRO : b'18'
Enviando valor: b'108\n'
Distancia dedos 131 Proporción distancia avanzada 106.552 MICRO : b'16'
Enviando valor: b'106\n'
Distancia dedos 134 Proporción distancia avanzada 109.406 MICRO : b'19'
Enviando valor: b'109\n'
Distancia dedos 134 Proporción distancia avanzada 109.715 MICRO : b'19'
Enviando valor: b'109\n'
Distancia dedos 132 Proporción distancia avanzada 107.853 MICRO : b'17'
Enviando valor: b'107\n'
Distancia dedos 130 Proporción distancia avanzada 105.943 MICRO : b'15'
Enviando valor: b'105\n'
Distancia dedos 131 Proporción distancia avanzada 106.898 MICRO : b'16'
Enviando valor: b'106\n'
Distancia dedos 132 Proporción distancia avanzada 107.197 MICRO : b'17'
Enviando valor: b'107\n'
Distancia dedos 127 Proporción distancia avanzada 102.781 MICRO : b'12'
Enviando valor: b'102\n'
Distancia dedos 135 Proporción distancia avanzada 110.093 MICRO : b'110'
Enviando valor: b'110\n'
Distancia dedos 194 Proporción distancia avanzada 169.879 MICRO : b'169'
Enviando valor: b'169\n'
Distancia dedos 194 Proporción distancia avanzada 169.795 MICRO : b'169'
Enviando valor: b'169\n'
Distancia dedos 203 Proporción distancia avanzada 178.325 MICRO : b'178'
Enviando valor: b'178\n'
Distancia dedos 244 Proporción distancia avanzada 219.311 MICRO : b'219'
Enviando valor: b'219\n'
Distancia dedos 240 Proporción distancia avanzada 215.033 MICRO : b'215'
Enviando valor: b'215\n'
Distancia dedos 239 Proporción distancia avanzada 214.24 MICRO : b'214'
Enviando valor: b'214\n'
Distancia dedos 226 Proporción distancia avanzada 201.524 MICRO : b'21'
Enviando valor: b'201\n'
Distancia dedos 229 Proporción distancia avanzada 204.787 MICRO : b'24'
Enviando valor: b'204\n'
Distancia dedos 226 Proporción distancia avanzada 201.636 MICRO : b'21'
Enviando valor: b'201\n'
Distancia dedos 230 Proporción distancia avanzada 205.313 MICRO : b'25'
Enviando valor: b'205\n'
Distancia dedos 230 Proporción distancia avanzada 205.846 MICRO : b'25'
Enviando valor: b'205\n'
Distancia dedos 229 Proporción distancia avanzada 204.924 MICRO : b'24'
Enviando valor: b'204\n'
Distancia dedos 230 Proporción distancia avanzada 205.263 MICRO : b'25'
Enviando valor: b'205\n'
Distancia dedos 217 Proporción distancia avanzada 192.61 MICRO : b'192'
Enviando valor: b'192\n'

Como se puede observar Proporción distancia avanzada es el flotante que quiero enviar a arduino, sin envargo Enviando valor es lo que envió a arduino (datos con el formato), y lo que recibo como una respuesta desde arduino es MICRO.

el problema está que cuando llega a 100<valores<110 y 200<valores<210 la respuesta de Arduino es erronea ya que en el caso que se observa mando un 204 pero arduino me manda un 24.

cambié el código para ver si los datos que recibía en Arduino eran incorrectos:

void loop()
{   
    while (Serial.available() > 0) 
    {
      datos = Serial.readString(); 
      delay(1);  
      LED = datos.toInt();
      analogWrite(LEDPWM1,LED);
      Serial.print(datos);
      }

}

Sin embargo al correr el programa en Python lo que recibe Arduino es lo que le envio:

Distancia dedos 125 Proporción distancia avanzada 100.575 MICRO : b'100\n'
Enviando valor: b'100\n'
Distancia dedos 125 Proporción distancia avanzada 100.674 MICRO : b'100\n'
Enviando valor: b'100\n'
Distancia dedos 124 Proporción distancia avanzada 99.788 MICRO : b'99\n'
Enviando valor: b'99\n'
Distancia dedos 128 Proporción distancia avanzada 103.876 MICRO : b'103\n'
Enviando valor: b'103\n'
Distancia dedos 126 Proporción distancia avanzada 101.89 MICRO : b'101\n'
Enviando valor: b'101\n'
Distancia dedos 122 Proporción distancia avanzada 97.053 MICRO : b'97\n'
Enviando valor: b'97\n'
Distancia dedos 123 Proporción distancia avanzada 98.911 MICRO : b'98\n'
Enviando valor: b'98\n'

Por lo que intuyo que el problema está en la conversión a entero con toInt, sin embargo no tengo idea de que es lo que pudiera estar afectando la conversión.

Agradecería mucho si alguien tiene alguna solución, o se a encontrado con algo similirar.

Has probado usar "toFloat" en vez de "toInt"?

Se recomienda utilizar atoi en vez de toint, puedes probar con el siguiente codigo

char myData[10]; // tamaño del arreglo para almacenar los valores numeros de 0 a 255
// [10] permite almacenar una palabra de 10 caracteres
void setup() 
{
  Serial.begin(9600);
}

void loop() 
{
  byte n = Serial.available();
  if( n!=0)
  {
    byte m = Serial.readBytesUntil('\n', myData, 10); 
    myData[m] = '\0';  //inserta caracter nulo 
    int x = atoi(myData); // se utiliza para convertir el string a int
    Serial.println(x);  // imprime el numero recibido
  }
}

Hola, la realidad es que no lo probé ya que lo que enviaba desde Python ya estaba convertido de flotante a entero y de entero a string, pero lo voy a calar.

ya lo he probado pero no obtengo los datos correctos

esto es lo que modifiqué según lo que me comentas:

#define LEDPWM1 5
char datos[10]; // tamaño del arreglo para almacenar los valores numeros de 0 a 255
// [10] permite almacenar una palabra de 10 caracteres
//String datos;
int LED;
void setup()
{
    Serial.begin(9600);	
    Serial.setTimeout(.05);  
    pinMode (LEDPWM1, OUTPUT);
}

void loop()
{   
   byte n = Serial.available();
   if( n!=0)
  //while (Serial.available() > 0) 
    {
      byte m = Serial.readBytesUntil('\n', datos, 10); 
      //datos = Serial.readString(); 
      delay(1);  
      datos[m] = '\0';  //inserta caracter nulo 
      //LED = datos.toFloat();
      LED = atoi(datos); // se utiliza para convertir el string a int
      analogWrite(LEDPWM1,LED);
      Serial.println(LED);
      }

y esto es lo que obtengo:
Distancia dedos 27 Proporción distancia avanzada 2.313 MICRO : b'0\r\n'
Enviando valor: b'2\n'
Distancia dedos 23 Proporción distancia avanzada 0.0 MICRO : b'9\r\n'
Enviando valor: b'0\n'
Distancia dedos 24 Proporción distancia avanzada 0.0 MICRO : b'0\r\n'
Enviando valor: b'0\n'
Distancia dedos 106 Proporción distancia avanzada 81.888 MICRO : b'7\r\n'
Enviando valor: b'81\n'
Distancia dedos 89 Proporción distancia avanzada 64.067 MICRO : b'5\r\n'
Enviando valor: b'64\n'

Ya logré resolverlo en Python quedó así:

from serial import Serial# LIBRERÍA PARA LA COMUNICACIÓN SERIAL
import time# IMPORTAMOS LIBRERÍAS DE TIEMPO

class CONFIGURACION_SERIAL():
    def __init__(self, PUERTO_COM='COM7',BAUDIOS=9600):
        self.PUERTO_COM =PUERTO_COM
        self.BAUDIOS=BAUDIOS

        self.CONEXION_SERIAL = Serial(PUERTO_COM,BAUDIOS, timeout=.05)# CONFIGURAMOS EL PUERTO COM PARA COMUNICACIÓN
        time.sleep(2)# TIEMPO DE ESPERA PARA CONEXIÓN CON EL MICRO
    
    def MANDAR_DATOS (self,AVANCE): 

        AVANCE_BYTES = str(AVANCE).encode()# AQUÍ CONVIERTO LA CADENA A BYTES PARA ENVIARLO POR SERIAL
        self.CONEXION_SERIAL.write(AVANCE_BYTES) # AQUÍ SE MANDAN LOS DATOS POR SERIAL AL MICRO

        return AVANCE_BYTES

    def RECIBIR_DATOS (self):
        RESPUESTA_SERIAL = self.CONEXION_SERIAL.readline() # AQUÍ SE LEEN LOS DATOS QUE ENVÍA EL MICRO

        return RESPUESTA_SERIAL
    
    def CERRAR_CONEXION (self):
       self.CONEXION_SERIAL.close()

y en Arduino así:

#define LEDPWM1 5
String datos;
int LED=0;
void setup()
{
    Serial.begin(9600);	
    Serial.setTimeout(.05);  
    pinMode (LEDPWM1, OUTPUT);
}

void loop()
{   
  while (Serial.available() > 0) 
    {
      LED = Serial.parseInt();
      delay(.5);  
      analogWrite(LEDPWM1,LED);
      Serial.print(LED);
      }

}

gracias a los que se tomaron su tiempo en responder.

No entiendo como un "float" puedes recibirlo en un "int"...

En Python hago la conversión y después mando a llamar el método para el envío de datos:

  AVANCE_BYTES = CONEXION_SERIAL.MANDAR_DATOS(int(AVANCE)) # AQUÍ SE MANDAN LOS DATOS POR SERIAL AL MICRO

No lo tomes a mal pero es mala práctica usar mayúsculas para expresar variables.
Y ahora que miro todo tu código en Python usa muchas variables en mayúsculas.
Funciona igual, pero...

No acepta decimales, deben ser enteros en milisegundos. Te lo esta tomando como 0.

delay(.5);

delay() tampoco acepta decimales.


"Parámetros
ms: el número de milisegundos para hacer una pausa.
Tipos de datos permitidos: unsigned long."

Fuente:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.