Problema con Serial.Read() [Solucionado]

Hola, estoy teniendo problemas al leer datos enviados desde una raspberry a un arduino UNO vía Serial. La idea general es enviar un caracter desde el arduino a la raspberry y que luego la raspberry devuelva otro valor al arduino y el arduino ejecute algo. El código que tengo es el siguiente:

En el arduino

int estado = 0;

typedef struct
  {
    byte mov;
    byte luz;
  } sensores;
  
  sensores sensor[4];

void setup() {
  
  pinMode(3, INPUT);
  pinMode(13, OUTPUT);
  pinMode(4, INPUT);
  pinMode(11, OUTPUT);
  pinMode(6, INPUT);
  pinMode(12, OUTPUT);  
  
  Serial.begin(9600);
  
  //Sector #1//
  sensor[0].mov = 3;
  sensor[0].luz = 13;
  
  //Sector #2//
  sensor[1].mov = 6;
  sensor[1].luz = 12;

  
  //Sector #3//
  sensor[2].mov = 5;
  sensor[2].luz = 11;
  
}

void loop() {

  estado = digitalRead(sensor[0].mov);
    if (estado == HIGH && Serial.available()==0){
     Serial.println('A');
   delay(2000);  
  }
    estado = digitalRead(sensor[1].mov);
  if (estado == HIGH && Serial.available()==0){
     Serial.println('B');
     delay(2000);
  }
  estado = digitalRead(sensor[2].mov);
  if (estado == HIGH && Serial.available()==0){
    Serial.println('C');
    delay(2000);
  }
  
  byte data = Serial.read();

  if(data == 0){
  digitalWrite(sensor[0].luz, HIGH);
  delay(1000);
  }
  else if(data == 1){
  digitalWrite(sensor[1].luz, HIGH);
  delay(1000);
}
  else if(data == 2){
  digitalWrite(sensor[1].luz, HIGH);
  delay(1000);
  }
  else{
  delay(1000);
  }
}

Lo que hago es enviar A, B o C dependiendo del sensor que se activó y luego la raspberry recibe eso, Hasta ahi no tengo problemas ya que la probe con un código en python y recibe A, B, o C sin problemas, el error que tengo es que cuando quiero enviar de vuelta otro comando al arduino no pasa nada. Aquí dejo el código en python que tengo por ahora:

#!/usr/bin/python

import serial
import time

se = serial.Serial('/dev/ttyACM0', 9600)

while True:
    rec = se.readline()
    print rec
    '''
    if rec == (str('A')):
        se.write(str('1'))
        time.sleep(1)
    elif rec == (str('B')):
        se.write(str('2'))
        time.sleep(1)
    elif rec == (str('C')):
         se.write(str('3'))
         time.sleep(1)
    else:
        time.sleep(1)
se.close()

Muchas gracias :slight_smile:

Saludos

Colocar parte del codigo no ayuda a nada.
Por ejemplo yo no entiendo
digitalRead(sensor[0].mov)

Perdón, edité y dejé completo el código de Arduino.

Gracias :slight_smile:

No veo el posible problema, pero sí que por ejemplo, activas los pines:

  pinMode(3, INPUT);
  pinMode(13, OUTPUT);
  pinMode(4, INPUT);
  pinMode(11, OUTPUT);
  pinMode(6, INPUT);
  pinMode(12, OUTPUT);

Pero no coinciden con los que usas en los sensores:

 //Sector #1//
  sensor[0].mov = 3;
  sensor[0].luz = 13;
 
  //Sector #2//
  sensor[1].mov = 6;
  sensor[1].luz = 12;

 
  //Sector #3//
  sensor[2].mov = 5;
  sensor[2].luz = 11;

Pero bueno, eso es que tienes que cambiar el 4 por un 5 :slight_smile:

¿Te recibe sin problemas? A mi cuando interactuo con MATLAB, no me lee o escribe si no le doy permisos cada vez que conecto un dispositivo. Es decir, escribir en la consola:

sudo chmod a+rw /dev/ttyUSB0

Pero si te lee correctamente en python no creo que sea eso

Ahora si.

Cual es el problema que te presenta? no te envia datos?

Prueba cambiando

 if (estado == HIGH && Serial.available()==0)

por

 if (estado && !Serial.available())

Esto tambien podria ser un problema:

byte data = Serial.read();

Ya que podrias estar guardando el valor ascii del caracter que recibes y no el caracter en si ,para comprobarlo haz un serial.print (data) al final del loop .si es asi ,la solucion es substituir el tipo byte de data por char ,poner los digitos a comparar entre comillas simples:

char data = Serial.read();
if (data == '0'){

Si solo vas a recibir numeros ,tambien puedes definir data como int y usar la funcion parseInt:

Y dejar las comparaciones sin comillas como las tienes ahora.

arriazu:
No veo el posible problema, pero sí que por ejemplo, activas los pines:

  pinMode(3, INPUT);

pinMode(13, OUTPUT);
  pinMode(4, INPUT);
  pinMode(11, OUTPUT);
  pinMode(6, INPUT);
  pinMode(12, OUTPUT);




Pero no coinciden con los que usas en los sensores:



//Sector #1//
  sensor[0].mov = 3;
  sensor[0].luz = 13;

//Sector #2//
  sensor[1].mov = 6;
  sensor[1].luz = 12;

//Sector #3//
  sensor[2].mov = 5;
  sensor[2].luz = 11;




Pero bueno, eso es que tienes que cambiar el 4 por un 5 :)

¿Te recibe sin problemas? A mi cuando interactuo con MATLAB, no me lee o escribe si no le doy permisos cada vez que conecto un dispositivo. Es decir, escribir en la consola:


sudo chmod a+rw /dev/ttyUSB0




Pero si te lee correctamente en python no creo que sea eso

Gracias por el detalle de los sensores, como tu dices python me lee perfecto lo que envío, el gran problema es que no envía de vuelta, de todas manera muchas gracias.

max_saeta:
Ahora si.

Cual es el problema que te presenta? no te envia datos?

Prueba cambiando

 if (estado == HIGH && Serial.available()==0)

por

 if (estado && !Serial.available())

Si logro enviar datos desde el arduino a la raspberry, lo que no puedo hacer es el viceversa, es decir que la raspberry envíe datos al arduino. Probe con lo que me dijiste y me pasa lo mismo, estoy casi seguro que hay algún problema de conversión de algun tipo de dato en conflicto.... de todos modos muchas gracias por responder.

jose:
Esto tambien podria ser un problema:

byte data = Serial.read();

Ya que podrias estar guardando el valor ascii del caracter que recibes y no el caracter en si ,para comprobarlo haz un serial.print (data) al final del loop .si es asi ,la solucion es substituir el tipo byte de data por char ,poner los digitos a comparar entre comillas simples:

char data = Serial.read();

if (data == '0'){



Si solo vas a recibir numeros ,tambien puedes definir data como int y usar la funcion parseInt:

https://www.arduino.cc/en/Serial/ParseInt
Y dejar las comparaciones sin comillas como las tienes ahora.

Creo que el asunto va por ahí, ya que al imprimir el 'data' me salian puras "y" con dos puntitos arriba y al tratar de definir 'data' como int y luego usar la función Serial.parseInt(data) me daba este error error:

"long int stream::parseInt(char) is protected"

La verdad es que algo no me calza en las conversiones o los tipos de datos...de todas maneras muchas gracias por las respuestas!

La observacion que te ha hecho maxsaeta es correcta,puesto que serial.read devuelve el numero de bytes disponibles o -1 en el caso contrario,serial.read() == 0 nunca se va cumplir ,o es mayor que 0 o -1 ,pero nunca 0...

El error es por usar mal parseInt.seria:

if( Serial.available()){
  int data = Serial.parseInt();
}

Ok, según entiendo el Arduino trabaja bien, el problema es del RapsBerry, no?

Si es así, diré como dice Surbyte, eso me supera. Tengo un RespBerry pero aun no lo que comenzado a usar.

La verdad es que no se si será problema de la raspi, ya que la raspi lee bien los datos que le mando y cuando uso el .write desde la raspi envia bien también, quizás se debe al tipo de dato que envio y luego el que recibo, es probable que no haga nada el arduino si al hacer la comparación no coinciden.. al parecer tengo un mal concepto de lo que hace el Serial.read()....

Edit: Creo que encontré el problema y se debía netamente a un tema de conversión de datos, ya que cambié el código para que enviara solo letras y devolviera solo letras y al leer los datos de vuelta de la raspi los guarde en una variable char de esta forma:

char dato = Serial.read()

y luego comparé

if (dato == 'Letra'){
//prenda la luz
}

El problema persiste con el envío de numeros de vuelta de parte de la raspi, pero ese asunto lo consultaré en el foro que corresponda. Muchas gracias por la ayuda brindada, doy el tema por cerrado.

Saludos