LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Programacion en LabWindows

Solved!
Go to solution

Muy buenas Roberto:

 

Tengo un problema porque quiero unir dos programas que tengo, que los he conseguido de NI. Uno es para escribir a traves de una targeta, que en mi caso es USB-6009, una codificacion para activar un motor, y el otro programa es el que tu me ayudaste para conseguir que las imagenes fuesen pasando cuando yo pulsase start, pero por si acaso te mando los dos programas. Entonces lo que quiero conseguir es que al pulsar estar las imagenes sigan pasando y que me activase la cinta. Echale un vistazo y me comentas lo que sea. Muchas gracias.

0 Kudos
Message 1 of 8
(4,769 Views)

hola,

 

para hacer esto, lo que tienes que hacer es lanzar las dos tareas dentro de dos callbacks de tu programa, o crearte un pool de theads de ejecución y colocar cada función en un hilo diferente. La opción más encilla es la de las callbacks, ya que CVI pone de manera automática cada una de las ejecuciones de las callbacks en hilos diferentes de ejecución, de manera que los dos códigos pasan a ejecutarse en paralelo.

 

En estos tres enlaces puedes encontrar toda la información que necesitas para implementar esta ejecución en paralelo:

 

http://zone.ni.com/devzone/cda/tut/p/id/3663

 

http://digital.ni.com/public.nsf/allkb/6ECCBAA87476EB22862568950071CCD6?OpenDocument

 

http://zone.ni.com/devzone/cda/tut/p/id/3066

0 Kudos
Message 2 of 8
(4,739 Views)

Muy buenas:

 

La duda que tengo ahora es como puedo asignar 2 CVICALLBACK a un mismo boton, porque este boton activa todo inicialmente, esto es se pone una cinta transportadora en marcha siempre que el primer sensor detecte una caja. Pero luego a una cierta distancia tengo otro sensor y lo que quiero es que este segundo sensor al detectar la caja pare la cinta durante un tiempo determinado, entonces lo que yo he hecho es asignar a un mismo boton 2 CVICALLBACK pero el programa me da un error, que es:   111, 1   Redefinition of 'StartCallback' previously defined at Barcode.c:33.


Y yo entiendo que no puedo asignar a un mismo boton 2 CVICALLBACK iguales.

 

Muchas gracias y añado el  proyecto.

Download All
0 Kudos
Message 3 of 8
(4,714 Views)

Creo que en absoluto sendia se refería a asignar dos callbacks al mismo botón, que no se puede hacer y creo que nunca se podrá. Posiblemente su idea era que con dos botones en tu panel se lanzaran las dos tareas.

Ahora, viendo como planteas el problema, parece que simplemente podrías desarrollar el códigode esta manera:

 

- Con el botón Start se ejecuta una routina que en un loop lee continuamente los ingresos digitales

- Cuándo detecta la caja pone en marcha la cinta, sale del loop y

- Ingresa en otro loop que sigue leyendo el segundo sensor

- Cuando detecta el segundo sensor para la cinta

 

Este esquema puede bloquear la pc si no tienes posibilidad de detectar otros eventos del sistema. Para evitar esto el código puede desarrollarse dentro de un timer con una variable que indique en qué fase está el programa. Además esto permite detectar los eventos del usuario (por ej. un botón de paro de emergencia...). Si la routina está bien desarrollada (esto es, es *breve*) puedes asignarla a un timer con un interval corto (por ej. 30-50 milisegundos) que posiblemente es suficiente para detectar el paso de la caja delante de los sensores. La callback del timer podría ser (pseudo código):

 

// Detectar botones de start / stop

if (stop) {

    - Parar la cinta

    - Terminar el programa ??

    return 0;

}

if (!fase && start) {

    Deshabilitar el start (para evitar problemas)

    fase = 1;

    return 0;

}


switch (fase) {

    case 1:         // Detectando el primer sensor

      - Leer el sensor

      - Si hay la caja:

          poner en marcha la cinta

          fase = 2

          break;

    case 2:

      - Leer el sensor

      - Si hay caja:

          Parar la cinta

          fase = 0;

          Habilitar el start

          break;

}

 

Después que has desarrollado el código con un timer estándard, puedes utilizar un timer asíncrono asignándole la misma callback del timer estandard (que tedrás que deshabilitar en este momento): los timer asíncronos se ejecutan en un thread independiente por lo que ganas en eficiencia en el programa. Sin embargo, en este momento deberás preocuparte del intercambio de datos entre los dos threads del programa, por lo que los documentos que te ligó sendia van a serte muy útiles.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 4 of 8
(4,705 Views)
Solution
Accepted by topic author mikelmoyano

Muy buenas Roberto:

 

Ya tengo mas o menos solucionado todo pero tengo un pequeño problema y no se porque es. El problema que tengo es que si activo el proceso paso por paso lo hace perfectamente pero si lo hago todo de seguido no me activa nada. No se si tu podras ayudarme pero si no muchisimas gracias, por si acaso te envio el programa que tengo hasta ahora. Gracias.

Download All
0 Kudos
Message 5 of 8
(4,665 Views)

Normalmente esto pasa por no tener pequeños intervalos entre los comandos u por no dejar un tiempo adeciato para detectar los fenómenos. Por ejemplo, la primera detección de la caja está echa inmediatamente: si la caja no está delante del sensor no será detectada (el timeout en la DAQmxReadDigitalU32 en absoluto indica esperar por un tiempo antes que leer). Ejecutando el código paso a paso se introducen algunos instantes entre instrucción y instrucción que pueden hacer que el fenómeno sea correcto.

 

Como te dije anteriormente, puedes desarrollar el código de manera que se espere un tiempo para que la caja pase delante del sensor, algo así:

 

        GetCtrlVal(panel,PANEL_CHANNEL2,chan);

        /*********************************************/
        // DAQmx Configure Code
        /*********************************************/
        SetWaitCursor(1);
        DAQmxErrChk (DAQmxCreateTask("",&taskHandle));
        DAQmxErrChk (DAQmxCreateDIChan(taskHandle,chan,"",DAQmx_Val_ChanForAllLines)) ;

        /*********************************************/
        // DAQmx Start Code
        /*********************************************/
        DAQmxErrChk (DAQmxStartTask(taskHandle));

 

        /*********************************************/
        // DAQmx Read Code

        // Espera sin límite

       /*********************************************/
        while (TRUE) {
            DAQmxErrChk (DAQmxReadDigitalU32(taskHandle,1,10.0,DAQmx_Val_GroupByChannel,&lectura,1,&read,NULL));
            if (lectura == 2) break;
        }
         DAQmxClearTask (taskHandle);

 

u mejor:

 

        /*********************************************/
        // DAQmx Read Code

        // Espera por un tiempo

       /*********************************************/

       tini = TImer ();
        while (Timer () - tini < 2.0) {
            DAQmxErrChk (DAQmxReadDigitalU32(taskHandle,1,10.0,DAQmx_Val_GroupByChannel,&lectura,1,&read,NULL));
            if (lectura == 2) break;
        }
         DAQmxClearTask (taskHandle);

 

Sin embargo, este modo de proceder no es apto para ser ejecutado en una callback de un control, puesto que no vas detectando los otros eventos del sistema y el programa está bloqueado en la detección del sensor; un procedimiento largo no debería estar dentro de una callback de un botín. Mejor es que pases a un timer contro y una máquina de estados como te sugerí anteriormente.

 

 

La otra posibilidad es dividir el código en más que un thread como te sugerió sendia: esto es notablemente más complejo y debe ser estudiado muy bien antes de desarrollar el código para definir las tareas de los diferentes threads y el intercambio de los datos entre ellos.

Message Edited by Roberto Bozzolo on 03-30-2009 03:59 PM


Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 6 of 8
(4,648 Views)

Muy buenas Roberto:

 

No se si habras probado el programa pero lo siguiente que he hecho es añadir un if (lectura != 2&3) para ver si entra donde tiene que entrar y cada vez que lo ejecuto, incluyendo la primera recomendacion que me has dado, siempre llega hasta este if, y sino le pongo ninguna caja llega hasta el if (lectura == 3), pero de todas todas se salta el if (lectura == 2), que donde deberia entrar. Gracias. Te adjunto el programa.

Download All
0 Kudos
Message 7 of 8
(4,642 Views)
¿Has probado usando la condición if (lectura & 2)? Esto permite testear el valor del ingreso 1 solamente, sin que el estado de los otros ingresos importe nada.


Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 8 of 8
(4,629 Views)