Problema Serial Arduino y Python!

Hola amigos, les comento que estoy desarrollando un proyecto en el que tengo que leer datos enviados por el arduino atravez de la comunicacion serial a un programa en python que tiene que tomar datos numericos y realizar operaciones matematicas...

Pero el problema en cuestion es el siguiente, tomo los datos que arduino envia atravez de la interfaz serial como "string" pero no los puedo convertir con ningun comando a una variable numerica del tipo "int" o "float" para asi poder realizar las operaciones...

Si alguien puede ayudarme a realizar esta conversion o directamente tomar los datos de forma numerica, le estaré muy agrecido, igual desde ya muchas gracias.

Aca dejo el codigo que estoy usando para leer los datos.

#Declaracion de librerias a utilizar
import serial
import win32api
import time
import math
#Clases para la ventana



#Inicializacion Serial
ser = serial.Serial(3)
ser.baudrate = 115200
ser.bytesize = 8
ser.parities = 0
ser.stopbits = 1
ser.xonxoff = 0
ser.rtscts = 0
ser.timeout = 1
print "Inicializando..."

loopVar = True
if (ser.isOpen()):
# Inicio del programa - void loop()
    cout=0
    while(loopVar):
        ser.write('x')
        ejeX = ser.readline()
        ser.write('y')
        ejeY = ser.readline()
        ser.write('z')
        ejeZ = ser.readline()

        while(cout!=1): #intento de transformar a int
            try:
                x = int(ejeX)
                y = int(ejeY)
                z = int(ejeZ)
                break
            except ValueError:
                x = 0
                y = 0
                z = 0
            cout = cout + 1


print " EjeX = %d EjeY = %d EjeZ = %d " % (x,y,z)

Salu2! ;)

No conozco mucho de python, pero se que es un lenguaje muy flexible. De todas maneras, estoy de acuerdo con Chiva en que parece que hay demasiados alergicos a google. Mira en esta direccion:
http://www.java2s.com/Code/Python/String/Convertinttoandfromstring.htm

Pues si Pofenas, ésta semana 4 personas preguntando por como leer cadenas por el puerto serie, cuando se ha explicado miles de veces y seguro que estará también en la referencia o playground y si no el que se acaba de comprar Arduino y quiere hacer una nave espacial… prefiero abstenerme de responder.

Bueno, vamos a lo que hemos venido a hablar, Pofenas en este caso ya está haciendo lo que dice en el link que le has pasado, por lo que es un poco más interesante, jejeje.

Emma, nos faltan bastante datos para saber que falla, ya que nos podrías poner el Traceback si aparece un error, o si entra en el except, que no deberías poner así ya que eliminas los datos y no sabes por que.
El int(ejeX), debería funcionar, si no es que podría recibir los datos con algún retorno de carro o algo similar que haga que no lo pueda convertir a entero (mira si en el Arduino haces Serial.println)

Otra cosa interesante sería que hagas un print en python con lo valores de x,y y z antes de convertirlos a int para ver que forma tienen.

Un saludo

Hola, muchas gracias por contestar, y Pofenas quedate tranquilo que si la solucion a mi problema estuviera en google, no estaria acá haciendoloes perder el tiempo, ya que soy de eso que no les gustan los re post…

Empezando por partes, el codigo cargado en el arduino es el siguiente…

//SDA (data line) is on analog input pin 4, and SCL (clock line) is on analog input pin 5

#include <Wire.h>

#define I2C_ADDRESS 0x4C
#define TILT_STATUS 0x03
#define SRST 0x04
#define SPCNT 0x05
#define INTSU 0x06
#define MODE 0x07
#define SR 0x08
#define PDET 0x09
#define PD 0x0A


#define POWER_UP_DELAY 10


#define X_OUT 0x00
#define Y_OUT 0x01
#define Z_OUT 0x02



void setup()
{
  Wire.begin();
  Serial.begin(115200);  // start serial for output
 // Serial.println("Setting up I2C protocol..."); 
 //Serial.println("Powering up SLAVE interface...");
  SLAVE_I2C_INIT(); 
  pinMode(13, OUTPUT);

}

void loop()
{

SLAVE_I2C_READ();

}
void SLAVE_I2C_INIT()
{
    SLAVE_I2C_SEND(0x07,0x00); // Setting up MODE to Stand by to set SR
    delay(2);
    
    SLAVE_I2C_SEND(0x08,0x00);  // Setting up SR register to 120 samples active and auto sleep mode
    delay(2); 
 
    SLAVE_I2C_SEND(0x07,0x01); //Setting up MODE Active to START measures 
}

void SLAVE_I2C_SEND(unsigned char REG_ADDRESS, unsigned  char DATA)  //SEND data to MMA7660
{
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.send(REG_ADDRESS);
  Wire.send(DATA);
  Wire.endTransmission();
}

void SLAVE_I2C_READ() //READ MMA7660 data
{
  unsigned char REG_ADDRESS[3];
  int i=0;
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.send(0x00);  // register to read
  Wire.endTransmission();
  Wire.requestFrom(I2C_ADDRESS, 3); // read a byte
  
  for(i=0; i<3; i++){
   if(Wire.available())REG_ADDRESS[i]=Wire.receive();
  }
  /*
  for(i=0; i<3; i++){
  
    
    Serial.print("  || 0x0");
    Serial.print(i);
    Serial.print(":");
    Serial.print(REG_ADDRESS[i], DEC);
    Serial.print("  ||");
  */
  int x = REG_ADDRESS[0];
  int y = REG_ADDRESS[1];
  int z = REG_ADDRESS[2];
  
  
  if (Serial.available() > 0) {
      // read the incoming byte:
      unsigned char eje = Serial.read(); 
      //Serial.print(a);
      
      switch(eje){
          case 'x':
            Serial.println(x, DEC);
            break;
          case 'y':
            Serial.println(y, DEC);
            break;
          case 'z':
            Serial.println(z, DEC);
            break;
          default: 
          Serial.println("ERROR");
      }
          
          
          
      }  
  
 // }

  delay(5);
}

Que lo uso para leer los datos de un acelerometro i²c MMA7660, basicamente lo que hace es que cuando yo le envio un comando desde python, lee el eje que quiero y me tira un valor que es el qeu se encuentra almacenado en el registro del eje…

El codigo en python es el siguiente (sin los except)

#Declaracion de librerias a utilizar
import serial
import win32api
import time
import math
#Clases para la ventana



#Inicializacion Serial
ser = serial.Serial(3)
ser.baudrate = 115200
ser.bytesize = 8
ser.parities = 0
ser.stopbits = 1
ser.xonxoff = 0
ser.rtscts = 0
ser.timeout = 1
print "Inicializando..."

loopVar = True
if (ser.isOpen()):
# Inicio del programa - void loop()
    cout=0
    while(loopVar):
        ser.write('x')
        ejeX = ser.readline()
        ser.write('y')
        ejeY = ser.readline()
        ser.write('z')
        ejeZ = ser.readline()
        
        x = int(ejeX)
        y = int(ejeY)
        z = int(ejeZ)
      
        #Llamada a ventana        

        print " EjeX = %d EjeY = %d EjeZ = %d " % (x,y,z)
        
        #win32api.SetCursorPos((ejeX,ejeY))
        
        

  

        #time.sleep(.1)

ser.stop()

El traceback de error de eso es lo siguiente

Traceback (most recent call last):
  File "C:\Python\Lib\SITE-P~1\PYTHON~1\pywin\framework\scriptutils.py", line 325, in RunScript
    exec codeObject in __main__.__dict__
  File "C:\Users\Emma\Desktop\Acelerometro\Python\emma.py", line 33, in <module>
    x = int(ejeX)
ValueError: invalid literal for int() with base 10: ' '

Que no se si a lo que se refiere es que no puedo transformar un “NULL” a int …

Les dejo un screenshot de los datos obtenidos con el siguiente codigo (sin la transformacion a int)

#Declaracion de librerias a utilizar
import serial
import win32api
import time
import math
#Clases para la ventana



#Inicializacion Serial
ser = serial.Serial(3)
ser.baudrate = 115200
ser.bytesize = 8
ser.parities = 0
ser.stopbits = 1
ser.xonxoff = 0
ser.rtscts = 0
ser.timeout = 1
print "Inicializando..."

loopVar = True
if (ser.isOpen()):
# Inicio del programa - void loop()
    cout=0
    while(loopVar):
        ser.write('x')
        ejeX = ser.readline()
        ser.write('y')
        ejeY = ser.readline()
        ser.write('z')
        ejeZ = ser.readline()
        
        #x = int(ejeX)
        #y = int(ejeY)
        #z = int(ejeZ)
      
        #Llamada a ventana        

        print " EjeX = %s EjeY = %s EjeZ = %s " % (ejeX,ejeY,ejeZ) #Pongo %s porque los datos son strings
        
        #win32api.SetCursorPos((ejeX,ejeY))
        
        

  

        #time.sleep(.1)

ser.stop()

Muchas Gracias

Salu2 :wink:

Otra cosa interesante sería que hagas un print en python con lo valores de x,y y z antes de convertirlos a int para ver que forma tienen.

La clave del problema está ahí, si nos puedes poner una de las líneas de salida, no estaría de más.

Listo, problema resuelto, era cuestion de pensarlo un poco mas, analice mejor el traceback y puse una condicion de que si el valor que tomaba era un NULL o ’ ’ me envie un 0 y listo problema resuelto, aca les dejo el codigo por las dudas que alguien tenga el mismo problema…

        x=0
        y=0
        z=0
        
        if ejeX != '':
            x = int(ejeX)
        if ejeY != '':
            y = int(ejeY)
        if ejeZ != '':
            z = int(ejeZ)

Gracias de todas formas…

Salu2 :wink: