[SOLUCIONADO] Problema con bucles entre Python y Arduino

Hola a todos!

Estoy iniciandome en el mundo de Arduino todavía, así que estoy empezando por "recrear", modificar y adaptar a mi gusto proyectos ya hechos por otra gente y liberados, para intentar comprenderlos y aprender todo lo que pueda.

Hace poco encontré un par de proyectos que me llamaron la atención, así que decidí llevarlos a cabo. O intentarlo, al menos.

Hoy os voy a hablar de uno de ellos. GMAIL Notifier

Primero, se prepara la placa Arduino con el siguiente codigo:

int outPin = 13;
int mail = LOW;
int val;
 

void setup()
{
  pinMode(outPin, OUTPUT);
  Serial.begin(9600);
  Serial.flush();
}
 
void loop()
{
  if (Serial.available())
  {
    val = Serial.read();
    Serial.println(val);
    if (val == 'M') mail = HIGH;
    else if (val == 'N') mail = LOW;
  }
 
  digitalWrite(outPin, mail);
}

Y este es el codigo del programa en Python

import serial, feedparser, time
 
# store your serial port address
SERIALPORT = 0
 
#open serial port
ser = serial.Serial(SERIALPORT, 9600)
 
loop = 1
prevCheck = 0
 
while loop > 0:
	#set variable to hold parsed xml data
	d = feedparser.parse('https://nombredegmail:passdegmail@mail.google.com/mail/feed/atom')
 
	#statement just to get title
	print d.feed.title
 
	newMail = len(d['entries'])
 
	#delay x seconds
	time.sleep(10)
 
	if newMail > 0:
    		#write to the serial port
       		ser.write('M')
       		print " Tienes correo por leer"
	else: ser.write('N')

(Necesitais descargar feedparser y la libreria de comunicacion serial para python)

Bueno, hasta aqui bien, y cambiando los campos de "nombredegmail:passdegmail" por los que corresponden, consigo la comunicación y la conexion.

Os explico el codigo y lo que hace (y despues, lo que no hace)

Por un lado, tenemos la placa Arduino preparada para que, en caso de recibir por comunicacion serial el valor M, la variable "mail" pasa a ser HIGH (y en caso de recibir N, "mail" pasa a ser LOW), y posteriormente a esta comprobacion, se hace un digitalWrite al pin del LED con el valor la variable "mail" (es decir, si hay correo seria HIGH, por lo que se encendera el led; y si no hay correo, sera LOW, con lo que no se encenderá).

Por el otro lado, tenemos el codigo en Python, que lo que hace es, primero, cargar los modulos necesarios (estan correctamente instalados) y almacenar el puerto (en mi caso, 0).
Después, inicia el bucle y conecta con la el feed xml de mi cuenta de GMail, e imprime el titulo (Es "GMail Inbox for "direcciondegmail" "), y en caso de que haya correo sin leer, envia mediante el puerto serial el valor M, y muestra en la consola del script "Tienes correo sin leer" (y en caso de que no, no muestra nada y envia por el puerto serial el valor N). Y repite la comprobacion cada 10 segundos.

El codigo funciona correctamente, pero tiene un fallo que me gustaria que, si alguien sabe y puede (estoy convencido de que si), me ayudara a solucionar.

El problema es que parece que Arduino se "queda" solo con el primer valor que le llega. Me explico

Si tengo un correo sin leer y conecto el Arduino e inicio el script, el LED se enciende, hasta ahí correcto. Pero si lo leo, en la consola donde estoy ejecutando el script en Python, me muestra correctamente que no hay correo nuevo (es decir, al cabo de 10 segundos simplemente me vuelve a aparecer el titulo de "GMail Inbox for "direcciondegmail", sin aparecerme el "Tienes correo sin leer"), por tanto, debe estar enviando tambien el valor N por el puerto serial... Pero no se desactiva el LED.
Y a la inversa tampoco, es decir, si inicio el script en Python sin tener correo sin leer, me muestra correctamente el titulo cada 10 segundos, y al llegarme un correo, me muestra el mensaje "Tienes correo sin leer", pero el LED no se enciende...

Ademas, mientras se ejecuta el script, no puedo acceder al Monitor Serial de Arduino para ver que valor esta recibiendo, ya que ya esta en uso el puero por otro programa

Por eso pido ayuda, por si alguien sabe por que puede ser que el Arduino se "quede" solo con el primer valor, y no varíe...

Gracias por adelantado!

Tras varios dias sin recibir respuesta (ojo, no lo digo quejándome! Al contrario, eso me ha impulsado a investigar todavía más árduamente), he descubierto el fallo...

El fallo residía en la llamada a Serial.flush(), el cual dejó de funcionar a partir de 1.0, y eso corrompía las siguientes lecturas de Serial recibidas por el programa en Python...

Dejo los códigos de nuevo, pero actualizados, por si alguien quiere repetir el proyecto!
(yo de momento lo usaré como base para el siguiente proyecto que quiero, un avisador remoto)

Codigo Arduino:

//Avisador GMail
//Original por Zunayed Ali
//Retocado por arduleo

int outPin = 13; //Ponemos el pin 13 como salida
int mail = LOW; //Creamos una variable int llamada "mail" con el valor inicial LOW, ya que no queremos falsos positivos
int val;


void setup()
{
  pinMode(outPin, OUTPUT); //Seleccionamos el pin13 (outPin) como salida
  Serial.begin(9600); //Iniciamos la comunicacion serial
}
 
void loop()
{
  if (Serial.available()) //En caso de que exista comunicacion Serial
  {
    val = Serial.read(); //La variable val tomará el valor de la lectura recibida por Serial
    Serial.println(val); //Imprimirá en consola (enviará al Arduino) el valor de val
    if (val == 'M') mail = HIGH; //Si el valor recibido (val) es 'M', la variable mail sera HIGH
    else if (val == 'N') mail = LOW; //Si el valor recibido (val) es 'N', la variable mail sera LOW
  }
 
  digitalWrite(outPin, mail); //Escribimos la informacion de mail (HIGH en caso de que haya, LOW en caso de que no) en el pin 13

  
}

Y aqui el codigo de Python (necesarias las librerias pySerial y feedparser)

#Codigo original creado por Zunayed Ali
#deyanuz.com
#Gmail notifier

 
#feedparser module download it from http://www.feedparser.org/
# pySerial module also needed
import serial, feedparser, time
 
#Seleccionamos nuestro puerto Serial (CAMBIAR VALOR DE SERIALPORT AL QUE CORRESPONDA)
SERIALPORT = 0
 
#Abrimos la comunicacion serial
ser = serial.Serial(SERIALPORT, 9600)
 
loop = 1
prevCheck = 0
 
while loop > 0:
	#Seleccionamos el xml que tomaremos como base (REEMPLAZAR LAS MAYUSCULAS POR LOS DATOS CORRESPONDIENTES)
	d = feedparser.parse('https://TUDIRECCIONDEGMAIL:TUPASSDEGMAIL@mail.google.com/mail/feed/atom')
 
	#Obtenemos el titulo del xml (Nuestra bandeja de entrada de GMail)
	print d.feed.title
 
	newMail = len(d['entries']) #Creamos la variable newMail
 
	#Asignamos un delay, para que compruebe cada X segundos la bandeja de entrada
	time.sleep(10) 
 
        #Si hay nuevos correos
	if newMail > 0:
    		#Enviamos por comunicacion serial el valor 'M' e imprimimos en la consola de Python "Tienes correo nuevo"
       		ser.write('M')
       		print "Tienes correo nuevo"
        #Si no hay correos nuevos
	else:
                        #Mandamos el valor 'N' por comunicacion serial e imprimimos en la consola de Python "No tienes correo nuevo"
			ser.write('N')
			print "No tienes correo nuevo"

Adjunto un zip con ambos archivos y las librerias de python necesarias:
http://arduleo90.site50.net/ARCHIVOS%20PARA%20DESCARGA%20PUBLICA/GMail_notifier.zip

Espero que a alguien le pueda resultar útil!

Se agradece que después de tanto tiempo, postees la solución.

P.D: Karma para ti! :smiley: