Hola muchachos, he estado intentando comunicar arduino con python pues me dispongo a establecer comunicación con raspberry en el futuro, sin embargo me estoy topando con un problema en la comunicación serial, y es que cuando envío mis datos de arduino a python y viceversa después de cierto tiempo la comunicación simplemente se corta y no estoy seguro de por qué ocurre esto, ya he hecho varias pruebas y pude concluir que, en lo que respecta a una comunicación sostenida, el problema es cuando no solo leo datos desde python, sino que además le envío al arduino datos, cuando eso ocurre, aparentemente la comunicación está bien, los datos del arduino los sigue leyendo bien python, pero como dije luego de cierto tiempo ya se corta la comunicación.
Para expandir este problema he hecho un video corto e ilustrativo del problema para que lo puedan ver y entender bien en la parte de abajo de esta publicación, adicionalmente dejaré los códigos abajo, de arduino son 2 y de python uno solo.
Dos últimas cosas, la primera, hay variables y funciones que creé meramente experimental para medir tiempos de ejecución y simular una salida de datos de sensores, y la segunda es que, pueden ver el video, y pueden entender mucho mejor las pruebas simples que planteo.
Codigo 1 arduino
int contador=1;
void setup() {
Serial.begin(9600);
}
void loop() {
contador+=1;
Serial.println(String(contador));
}
Codigo 2 arduino
double ax=2000.345,ay=314.23,az=12.34,wx=1543,wy=2390,wz=3426,vel=44.02,sp1=0.0,sp2=0.0,sp3=0.0;
bool sd=0,flag=0;
unsigned int currentime,currentime2,currentime3,previoustime=0,previoustime2=0,previoustime3=0,tiemporecibe=0,tiempoenviar=0,data_in[3];
String dataout="0,0,0,0,0,0,0",datain="0,0,0";
byte vmot=0,vled=0;
String cad,cad1,cad2,cad3,borrar;
int contador=0,contador2=0;
void setup() {
Serial.begin(9600);
Serial.setTimeout(10);
delay(30);
}
void loop() {
contador+=1;
currentime=millis();//Conteo de tiempo para enviar
if(currentime-previoustime>100){
previoustime=currentime;
ax-=20.34;
ay+=15.23;
az+=30.2;
vel-=0.5;
wx-=15.2;
wy-=34.5;
wz+=15.2;
sd=!sd;
}
dataout=MPU_data(contador,tiemporecibe,tiempoenviar,az,wx,wy,wz)+medRPM(vel)+save_data(sd);
currentime2=millis();
if(Serial.available()){
//contador2+=1;
cad = Serial.readString() ; //Recibimos varios datos separados por una coma, cada uno es una variable diferente, hay que separarlos
}//StringUntil('\n')
//
tiemporecibe=currentime2-previoustime2;//Tiempo de recepcion de dato
previoustime2=currentime2;
currentime3=millis();
borrar=String(10000);
Serial.println(dataout);
//String(int(currentime/1000))
tiempoenviar=currentime3-previoustime3;//Tiempo de envio de dato
previoustime3=currentime3;
cad1=data_in[1];
cad2=data_in[2];
cad3=data_in[3];
vled=cad1.toInt();
vmot=cad2.toInt();
}
String MPU_data(int num0,double num1,double num2,double num3,double num4,double num5,double num6){
String aux1=String(num0)+","+String((int)num1)+","+String((int)num2)+","+String((int)num3)+","+String((int)num4)+","+String((int)num5)+","+String((int)num6);
return aux1;
}
String medRPM(double num1){
String aux1=","+String((int)num1);
return aux1;
}
String save_data(bool baux){
String aux1=","+String(baux*4000);
return aux1;
}
void decoding(String aux1,int iaux){
byte pos = aux1.indexOf(',');
byte pos2 = aux1.indexOf(',',pos+1);
data_in[1]=aux1.substring(0,pos).toInt();
data_in[2]=aux1.substring(pos+1,pos2).toInt();
data_in[3]=aux1.substring(pos2+1).toInt();
}
Codigo 1 python
import serial,time,threading,random
arduino=serial.Serial('COM3',9600)
time.sleep(2)
t_inicio,tfin,tanterior=0,0,0
dato="0,1,2,3,4,5,6"
division=dato.split(',')
def Timer_Interrupt_emition():
global division,tanterior,dato,tinicio,tfin
tinicio=time.time()
#print("Tiempo de llamado del timer:"+str(tinicio-tfin))
tfin=tinicio
num1=str(random.randint(0,1))+","+str(random.randint(0,1))+","+str(random.randint(0,1))
##
arduino.write(num1.encode('utf-8').strip())
#print("Envio: "+num1 )
dato_anterior=dato
dato=arduino.readline().decode('utf-8').strip()
print("Recibido: "+dato)
if dato_anterior!=dato:
print("Actualizacion de lectura tarda:"+str(tinicio-tanterior))
tanterior=tinicio
tfin=time.time()
#print("Tiempo de ejecucion del codigo:"+str(tfin-tinicio))
print(" ")
print("En ejecucion")
threading.Timer(0.5,Timer_Interrupt_emition).start()#Este tiempo en realidad se limita a la velocidad de conexion entre arduino y python, no va a ser tan bajo
threading.Timer(0.5,Timer_Interrupt_emition).start()