Mostrando entradas con la etiqueta miniproyecto. Mostrar todas las entradas
Mostrando entradas con la etiqueta miniproyecto. Mostrar todas las entradas

11 de febrero de 2011

SimSeny no se lleva bien con el tratamiento de errores..

Un alumno me envía un problema que tiene al intentar activar una salida. Parece que la tarjeta de inicializa bien, pero al hacer clic en el botón "Activar calefactor" se muestra el siguiente error:


La solución es sencilla, debes ir a la función que genera el error (en este caso "proceso_escribir_calefactor()" y comentar la línea correspondiente a la llamada de la función "proceso_error" (resaltada en color rojo en la imagen de abajo):


Una vez hecho, al activar la salida, podrás ver en el simulador como cambian los niveles y así comprobar que lo estás haciendo bien (que se activa sólo una salida y no todo el puerto por ejemplo):

Con el simulador abierto puedes ir haciendo clic en los botones activar/desactivar calefactor/válvula de tu programa y comprobar si cambian los niveles en las salidas (H/L). Es una manera magnífica de ver si lo estás haciendo bien.

Recuerda que estamos en un entorno de simulación que nos permite trabajar sin tener el "HW". En situaciones reales, deberás tener muy presente el tratamiento de errores para poder determinar, en caso de error, donde puede estar el fallo.
..
..

Diferencias entre el modo manual y el automático

Hay que tener clara la diferencia entre el modo manual y el automático.

En el modo manual, será el usuario el que pueda encender o apagar la válvula, calefactor o cualquier otra salida disponible. En la figura la esfera representa el sistema y las piezas blancas el usuario. Dos salidas, en color azul, están controladas por el usuario en modo manual. Las otras dos salidas siguen estando supervisadas por el sistema (según estrategias y diseño, el modo manual puede no permitir tener el control de todas las salidas).


En el modo manual, no es necesario un temporizador y deberá estar desactivado.
Para ello puedes escribir la siguiente instrucción en tu programa:
"Form1->Timer1->Enabled=false;"

En el modo automático, el temporizador del sistema será el "encargado" de comprobar las entradas y ajustar automáticamente las salidas, a una frecuencia dada. En la figura, la esfera representa el sistema y las cajas los dispositivos a controlar. El color indica que todos los dispositivos están supervisados.


En el modo automático, el usuario pasa a un segundo plano. El temporizador deberá estar encendido.
Para ello puedes escribir la siguiente instrucción en tu programa:
"Form1->Timer1->Enabled=false;"

Al iniciar el programa..los temporizadores deberían estar apagados

En los proyectos se debe incluir uno o varios temporizadores para controlar la frecuencia de refresco de las entradas/salidas. Un alumno me envía un correo comentando los errores que se muestran al iniciar el programa:


Son dos mensajes, uno en el fondo con el título "SimSenyII" y otro delante "ssDAQmxReadAnalogScalarF64()..". Esta claro que el primero es del simulador, que intenta arrancar (cuando se llama a alguna función de la tarjeta) y el segundo corresponde a una función de la tarjeta de adquisición..Estos errores aparecen sin intervención del usuario, nada más arrancar, ésto sugiere que es debido a un temporizador que debería estar parado.

Lo que sucede aquí es bastante frecuente, arrancar la aplicación con los temporizadores ENCENDIDOS. Como el timer se dispara antes de poder inicializar el simulador y la tarjeta, todo salta por los aires, no se puede empezar a usar una función de la tarjeta si antes no se ha inicializado..

Solución: Busca el temporizador en el formulario y desactívalo cambiando su propiedad "Enabled=false", de este modo, al arrancar el programa, el timer estará apagado:


De esta manera el sistema estará inicializado pero detenido hasta que el usuario determine los valores deseados y el modo (manual o automático) .

Si se usa el modo automático, habrá que activar el temporizador:
"Form1->Timer1->Enabled=1" (el timer es el "encargado" de controlar el sistema)

Si se usa el modo manual, habrá que detener el temporizador:
"Form1->Timer1->Enabled=0" (el usuario controla las salidas, el timer no hace falta)

Por último, yo añadiría un botón nuevo con el que puedas inicializar la tarjeta, añade uno al formulario, cámbiale el nombre y haz doble clic en para escribir el código que deberá ejecutarse al pulsarlo:
"proceso_inicializar_proceso();" (inicia la tarjeta y el simulador)

De este modo, cuando arranques la aplicación, pulsa primero en el botón y tendrás las tarjeta lista para usar. A partir de este momento ya puedes llamar a las funciones que quieras.

Esto es una parte de la solución.
Ahora el programa permite inicializar la tarjeta y elegir el modo de funcionamiento, sin errores.
..

8 de diciembre de 2010

Duda con una función del módulo de proceso

Un alumno envía una función del módulo de proceso:

int Proceso_leer_rebose(void) {
int32 errdaq;
uInt32 data;
errdaq = DAQmxStartTask(en_dig); //
errdaq = DAQmxReadDigitalScalarU32(en_dig,0.0,&data,NULL);
errdaq = DAQmxStopTask(entradas_digitales);
if ((data & 0x00000001) == 0){
return(REBOSE_HAY);}
else{
return(REBOSE_NO_HAY);
}

Esta función "Proceso_leer_rebose" lee físicamente los pines de la tarjeta para detectar niveles de tensión, usa para ello tres funciones de la tarjeta NI USB-6008 (aparecen resaltadas). Este valor es almacenado en la variable "data".

Como esta variable tiene el valor del puerto completo y queremos mirar sólo un bit, aplicamos una máscara (línea resaltada en verde) para quedarnos con el bit de interés.

De este modo podemos detectar el estado del bit y almacenarlo en el módulo de datos, para que esté a disposición de otras funciones, por lo tanto yo modificaría esta última parte de la función:

if ((data & 0x00000001) == 0){
Datos_escribir_rebose(0);
else
{
Datos_escribir_rebose(1);
}

Por lo tanto la función no devuelve nada, sólo almacena el valor que lee del sensor en el módulo de datos. Esta función "Proceso_leer_rebose" está haciendo uso de la función "Datos_escrbir_rebose" del módulo de datos para guardar esta información. El último cambio que habría que hacer sería redefinir la cabecera de la función para que devuelva "void":

void Proceso_leer_rebose(void) {

Se indica "void" porque la función no devuelve ningún valor. Lo hace a través de las funciones del módulo de datos.