Discusiones sobre Productos NI

cancelar
Mostrando los resultados de 
Buscar en lugar de 
Quiere decir: 

labview puerto serie serial port

¡Resuelto!
Ir a solución

Hola, he estado probando un programa similar al que has hecho, pero simplificado.

 

Problemas detectados:

 

  1. Una vez generado el evento que ocurre cuando el puerto serie envié caracteres o exista en el buffer, se leen los caracteres que existen en el buffer, pero eso no te garantiza que lea todo el mensaje que pretendes enviar. El evento saltará cuando recibas el primer carácter y leerá los que le de tiempo a enviar hasta que se ejecute la instrucción de bytes at port.
  2. Si el timeout de espera de eventos salta, ocurre un error en el programa.
  3. Todo lo que haya en el hilo o hebra esa se queda parado hasta que ocurra en evento.

Me he dado cuenta, y creo que puede ser la solución al problema de sincronismo en la recepción del mensaje, que tal vez sea mejor crear un evento "serial TermChar" en vez del evento "serial Character" y esperar a que ocurra el evento nuevo. Con ello se solucionan los dos primeros problemas. El tercero hay que cambiar de filosofía a la hora de hacer el programa o no con la gestión de errores y un timeout pequeño.

 

Saludos,

 

Emilio.

Mensaje 11 de 26
5.051 Vistas

Hola Emilio.

 

Gracias por tu ayuda, la configuración de puerto serie que me has enviado en el VI arduino funciona a la perfección en mi proyecto pero tengo un par de preguntas al respecto:

 

-El botón de stop de boolean pone a cero las iteraciones, ¿para que se hace esto?

 

-¿Porque cada vez que pongo el programa en marcha me rompe la conexión con el puerto serie? Esto es un problema porque si estas haciendo pruebas cuando le das a la flecha de run empieza a funcionar correctamente pero si le das al stop para por ejemplo cambiar algo y después vuelves a darle a run ya no funciona, la conexión esta rota. Tienes que salir de Labview y volver a entrar.

 

Te adjunto una imagen de como lo tengo montado. Gracias!!!

0 kudos
Mensaje 12 de 26
5.018 Vistas
Solución
Aceptado por el autor del tema gcapelo

Hola,  me alegro que te funcione aunque sea con el problema del puerto serie.

 

Respecto a la primera pregunta, el botón de Stop lo he puesto con el fin de parar o salirse del programa.

El indicador "iteraciones" lo puse para ver como cambia la velocidad de ejecución del bucle while al variar el timeout de "Visa Wait on Event". El indicador "lectura de datos" muestra los mensajes recibidos procedentes del arduino. El indicador "Code" muestra el código de error generado al agotarse el timeout del procedimiento "Visa Wait on Event", si todo va bien pues el código ese debe ser 0, en cambio si se agota el tiempo el código de error es el código -1073807339. Por cierto ¿cómo ejecutas el programa con el icono de la flecha o el icono de la doble flecha en bucle (run continuously)?. Si lo haces con el primero (run), al presionar stop se debe de salir.

 

En cuanto a la segunda cuestión, no sé respondertela con certeza, A mi me ocurrió lo mismo en un programa, creo que llegué a solucionarlo parcialmente, pero no sé como, tampoco sé porque ocurría. Puedes comprobar a ver si cierras el puerto serie correctamente, colócale un indicador de error en la línea de error al cerrar el puerto serie a ver que te muestra. También puede incluir otro indicador después de abrir el puerto serie (para ver que error es exactamente y buscarlo en el foro o ayuda de NI).

El programa que he colgado (arduino.vi) le he hecho perrerías y nada de nada, aunque lo aborte siempre lo ejecuto y no me da error abertura del puerto serie, pero pierdo la comunicación en la siguiente ejecución si presiono el botón de "abort execution", el problema se me corrige si cierro correctamente el programa (botón stop) y vuelvo a ejecutarlo (no me tengo que salir de labview ni cerrar el archivo o proyecto que estoy programando).

 

Tengo otra pregunta, ¿cómo paras el programa (con un botón, por ejemplo salir o con el botón rojo de la barra de herramientas (abort execution)?, puede que ahí tengas la solución si presionas el rojo (abort execution), pero solo es una suposición.

 

 

Si quieres pasarme el programa, pues puedo verlo y probar que lo hace todo correctamente. Otra opción es ir eliminando partes del programa y ver si te sigue ocurriendo eso. Por ejemplo la parte de interpretación de datos, la de representación, etc.

 

Importante, confírmame que tienes dos bucles while anidados: leer el puerto serie y el global de tu programa que no lo puedo ver. ¿Te sales correctamente o tienes que salir con "abort execution"?, si te sales de la segunda forma no cierras el puerto serie correctamente y ahí puede estar el problema.

 

Saludos,

 

Emilio.

Mensaje 13 de 26
5.005 Vistas

Hola,

 

     Algunos comentarios:

 

     - Te recomiendo usar un shift register en los ciclos while por donde pasa el VISA resource name.

 

    - La data es buena mandarla como string si te interesa que la puedas ver facilmente sin procesarla como por ejemplo desde el hyperterminal, pero si deseas aumentar la velocidad y precision lo mas adecuado es enviarla byte a byte en formato binario que no es legible a simple vista.

 

     - De los problemas con el puerto, asegurate como te dice emilio que si se este cerrando correctamente el puerto ya que tienes el close fuera del segundo while cuando deberia estar fuera del primer while pero dentro del mismo frame donde tienes el open (aunque creo que lo mejor seria que pongas el open fuera del while mas externo y abras y cierres el puerto una sola vez). Adicional a eso el puerto es un recurso de la computadora si lo estas usando el hyperterminal o en el monitor serial de arduino debes cerrarlo antes de poder usarlo con labview.

 

     - Es mas facil ayudarte a encontrar un error si subes tu codigo de LabVIEW o una version reducida de tu código de la parte de la comunicacion.

 

Saludos,

Luis A. Mata C.
Ing. Electrónico
Whatsapp: +58-414-1985579
BBM Pin: 2B83E99A
Thanks: Kudos
0 kudos
Mensaje 14 de 26
4.999 Vistas

Hola Emilio,

 

tu ayuda me ha venido muy bien, tenia bucles anidados que me estaban dando problemas pero ya esta solucionado el programa funciona bien excepto por algun problema con los botones de salir pero bueno es nada. Lo importante es que el programa funciona correctamente y puede estar horas funcionando sin que de error.

 

Tengo una ultima pregunta, te e subido el programa, para que le eches un vistazo y me digas que se puede mejorar, y veras que todos los VI estan sueltos en la carpeta, ¿como puedo hacer para que todo sea un mismo proyecto? El menu principal es el VI que tiene de nombre principal.

 

Gracias.

 

 

0 kudos
Mensaje 15 de 26
4.968 Vistas

Hola, 

 

En primer lugar me alegro por que te funciona y segundo lugar disculpame por no haberte respondido antes, he estado muy atareado y quería ver el programa antes de responderte pero no ha podido ser pues yo trabajo con Labview 2009  y esta versión es de un Labview posterior. No he podido convertirlo. Me podía haber descargado la demo pero ya me la he instalado(licencia expirada) y tengo que buscar otra computadora para volver a instalarlo. De todas forma a ver si este fin de semana saco un poco de tiempo y lo instalo en un ordenador viejo que tengo en casa de mis padres o genero una máquina virtual para convertirlo.

 

Al grano,

El problema de salir con tantos bucles yo lo solucionaría generando un botón o indicador booleano colocado en un lugar donde no se muestre del panel (llámalo por ejemplo saliendo). A partir de el generas una variable local (saliendo, true para salir por ejemplo) que se introduce en todos los bucles. El botón propiamente dicho de salir (exit) lo introduces en un bucle while paralelo a todo el programa que cuando presiones salga del while y ponga la variable saliendo en verdadero con ello garantizas si has introducido la variable local (saliendo) en todos los bucles se salga (espero que me hayas entendido). No olvides poner la variable local saliendo a falso al iniciar el programa pues sino se sale como si le hubieses dado a exit. A ver si tengo tiempo y hago un ejemplo (creo recordar que en alguno de los ejemplos que he colgado utilizo esta filosofía para salir del bucle).

 

Con respecto a unirlo en un proyecto todo, pues creo que es tan sencillo como crear el proyecto y arrastrar los archivos a la ventana que te sale y sino añadirlo. No se si eso es valido también para las variables globales, (no tengo experiencia en eso), pero si no creo que te generas un panel de variables globales y haces un copy-paste (de eso no me hagas mucho caso, pero creo recordar algo de eso ya que en alguna ocasión tuve que adaptar un programa que trabajaba con variables globales) .

 

Lo dicho a ver si encuentro un hueco para hacer esto y te puedo sacar algún error y mirar como incluirlo todo en un proyecto. 

 

Por ultimo, creo recordar que si intentas generar un ejecutable del programa te genera automáticamente un proyecto.

 

Saludos,

 

Emilio.

 

 

0 kudos
Mensaje 16 de 26
4.925 Vistas

Hola Emilio.

 

Estoi un poco desesperado porque cuando creia que ya lo tenia todo hecho y listo para entregar me sale un error que llevo dos dias intentando solucinar y nada.

 

Es un error de codigo C y ya lo tengo localizado pero no se ni porque pasa ni como solucinarlo, el codigo es este:

 

#include <SD.h>
#include <Time.h>
int analogPin0=0;
int analogPin1=1;
int analogPin2=2;
int t1;
int t2;
int luz;
int suma;
float luxes;
float pin0;
float pin1;
float pin2;
void setup()
{

// Abrir comunicaciones serie y dejar a la espera:
Serial.begin(9600);

Serial.print("Initializing SD card...");

// estar completamente seguro de que el pin esta seleccionado como
// salida, sino no funcionára:

pinMode(4, OUTPUT);

// Buscando la tarjeta SD:

if (!SD.begin(4)) {
Serial.println("Card failed, or not present");

// no hace nada más:

return;
}
Serial.println("card initialized.");
}


void loop()
{

pin0=(analogRead(0)*5.0*100.0)/1023.0;

pin1=((analogRead(1)-502)*5.0*100.0)/1023.0;

pin2= analogRead(2);

if( pin2 < 83 )
{
luxes=(pin2*4.6678)+2.1104;
}
else
if(pin2 > 83)
{
luxes=(pin2*28.283)-2062.6;
}

//como daba problemas en labview metemos el dato en esta variable
//para q se refresque cada 1s.

t1=pin0*100;
t2=pin1*100;
luz=luxes*100;
suma=t1+t2+luz;


// imprimir por puerto serie del PC:

Serial.print ("A");
Serial.print (t1,DEC);
Serial.print ("B");
Serial.print (t2,DEC);
Serial.print ("C");
Serial.print (luz,DEC);
Serial.print ("D");
Serial.println (suma,DEC);

delay(1000);

String dataString = "Posiciones sobre 1024 Bits: T1, ";

// Lectura de los tres sensores para su introduccion en el String:

for (int analogPin = 0; analogPin < 3; analogPin++) {
int sensor = analogRead(analogPin);
dataString += String(sensor);
if (analogPin <1) {

dataString += " ;T2, ";
}
else

if (analogPin <2) {
dataString += " ;LUZ, ";

}
}



// Abrir el archivo de texto, solo se puede abrir un archivo a la vez:

File dataFile = SD.open("datalog.txt", FILE_WRITE);

// si el archivo se ha abierto correctamente escribe lo siguiente:

if (dataFile) {
dataFile.print("Tiempo transcurrido desde el inicio de la medicion");
dataFile.print(hour());
dataFile.print(":");
dataFile.print(minute());
dataFile.print(":");
dataFile.print(second());
dataFile.println(" ");
dataFile.println(dataString);
dataFile.print ("T1");
dataFile.print (" ");
dataFile.print (pin0);
dataFile.print (" ");
dataFile.print ("Grados Celsius");

dataFile.println("");
dataFile.print ("T2");
dataFile.print (" ");
dataFile.print (pin1);
dataFile.print (" ");
dataFile.print ("Grados Celsius");

dataFile.println("");
dataFile.print (luxes);
dataFile.print (" ");
dataFile.print ("W/m^2");

dataFile.println("");
dataFile.println("");
dataFile.close();
}

// si el archivo no se ha abierto correctamente muestra el error:

else {
Serial.println("error opening datalog.txt");
}


//Dato para cambiar el tiempo de envio al puerto serie.

delay(30000);

}

 Sigue abajo.....

Spoiler
Spoiler
 

 

0 kudos
Mensaje 17 de 26
4.886 Vistas

El problema esta en la zona roja, todo lo demas lo hace bien. Te explico lo que pasa:

 

-Por el puerto serie pasa al ordenador una letra seguida del valor de cada sensor multiplicado por 100 y la suma de todos, y tambien guarda en la tarjeta de memoria los valores de los sensores.

 

-La variable luxes es la que utiliza para guardar ese valor en la tarjeta SD. La variable luz es esa varible pero multiplicada por 100 para enviar por puerto serie sin decimales. Aqui esta el fallo, cuando ese valor pasa de 300 y poco la variable luxes guarda en la tarjeta sd el valor correcto pero la variable luz se vuelve loca y pasa a ser negativa.

 

-Por lo que descarto que el sensor y la transformacion con la formula mediante el If esta mal por lo que el fallo solo puede estar en la zona roja.

 

-Recuerdo que al principio del proyecto me paso algo parecido con las temperaturas, que al pasar de 31 grados se hacian negativas, y lo solucione haciendo todas las operaciones de codigo en la misma linea, esto se puede ver de verde en el codigo, pero esta vez e cambiado de todo y sigue sin funcionar.

 

Haber si se te ocurre algo que me pueda ayudar ya que con lo del puerto serie me salvaste la vida. Te envio el proyecto de LabView que tengo ya finalizado, si no fuera por este error ya lo tendria todo acabado y montado.:womansad:

0 kudos
Mensaje 18 de 26
4.885 Vistas

Perdon pero lo que he dicho que estaba en verde son la primeras lineas de lo rojo. Gracias por tu ayuda!!

0 kudos
Mensaje 19 de 26
4.884 Vistas

Hola,

He detectado que la variable luz es int (en arduino eso significa entero de 16bits, cuyo rango de representación es −32,768 a 32,767,( from −(215) to 215 − 1)) si multiplicas 100 *300 estas en el límite, luego tienes un overflow, en cambio luxes es float (32bits). Te recomiendo que los cambios de tipos (casting) lo hagas con mucho cuidado, y los veas como un sospechoso a tener en cuenta en los errores que se comenten, concretamente ese es el error que estas cometiendo. Solución cambiar el tipo de dato de luz por long. Y para curarte en salud de otros overflow, hacerlo lo mismo con suma, t1 y t2.

 

Te lo voy a decir, sin rodeos, la forma que tienes para calcular el checksum es poco ortodoxa pero si te funciona pues ni modo. (suma).

 

Te recomiendo que hagas todas las operaciones en float ya que trabajas con ellos (y es como lo estas haciendo) y al finalizar los pases a long. Los casting de datos simples se pueden realizar así: formatoConvertido= (formato a convertir)formato original; por ejemplo: int b=43; long a; a =(long)b; 

 

Ejemplo solución:

 

// cambia las variables t1,t2,luz, suma de int a long.

pin0=((float)analogRead(0)*5.0*100.0)/1023.0;

pin1=(((float)analogRead(1)-502)*5.0*100.0)/1023.0;

pin2= (float)analogRead(2);
//Ojo ¿que pasa si es pin2==83.0?
if( pin2 < 83.0 )

luxes=(pin2*4.6678)+2.1104;
}
else
if(pin2 > 83.0)
{
luxes=(pin2*28.283)-2062.6;
}

//como daba problemas en labview metemos el dato en esta variable 
//para q se refresque cada 1s.

// puedes incrementar el timeout del evento de lectura de puerto serie en labview por encima de 30 segundos (por ejemplo 45000ms)


t1=(long)(pin0*100.0); 
t2=(long)(pin1*100.0); 
luz=(long)(luxes*100.0);


suma=t1+t2+luz; //ojo cuando hagas la suma en labview hazla con el mismo tipo de dato (long equivale a I32 en labview)

 

 

Creo que esto te puede solucionar el problema.

 

De todas formas, si quieres convierteme el programa a Labview 2009 el de labview y lo veo.

 

Comentame si se soluciona el problema, según los síntomas, creo que tienes un overflow. Te recomiendo que paso a paso para depurarlo imprimas todos los valores en el puerto serie cuando te ocurra algo de ello. Parece que deben dar lo mismo no sea así por culpa de los tipos de datos. Ejemplo:

int a; 

a=(35*1000)/5; //falla, trabaja con int

Serial.println(a,DEC);

a=(int)(35.0*1000.0)/5.0; // no falla, trabaja con float

Serial.println(a,DEC);

a=35*(1000/5);//trabaja con int pero no hay overflow, correcto, pero hay que asegurarse que no existe overflow. Con las divisiones no exactas ocurre tres cuartos de lo mismo.

Serial.println(a,DEC);

a=10*(3/5); // esto es cero,  3/5 = 0

Serial.println(a,DEC);

a=(10*3)/5;// 30/5 =6;

Serial.println(a,DEC);

 

 

Te recomiendo que lo pruebes y que visites la página http://arduino.cc/es/Reference/HomePage para ver los limites de los tipos de datos en arduino y pinches sobre el tipo de dato que desee ver (int, long, float,...).

 

 

Por último, conviérteme los archivos a labview 2009 ver le programa y sacarle alguna pequilla. No te juegues la vida con la informática y la electrónica o terminaran matándote en una de estas.

 

 

Saludos,

 

Emilio.

 

Mensaje 20 de 26
4.876 Vistas