![]() |
Se propone a continuación la secuenciación y la distribución temporal de un conjunto de contenidos y actividades de aula-taller destinadas a introducir a los alumnos en el control programado, basadas en los contenidos expuestos en los distintos apartados de este tema. Se trata de una programación para alumnos de 4º curso de la E.S.O., a desarrollar durante la 2ª evaluación del curso (aproximadamente en 24 sesiones, 3 sesiones/semana). Esta planificación ha sido llevada al aula durante el presente curso con los alumnos de Tecnología del mencionado nivel en el I.E.S. Zorrilla e Valladolid.
Se presupone que el profesor cuenta en el aula-taller de Tecnología con, al menos, un ordenador por equipo de trabajo de alumnos (normalmente, 5 o 6), o bien, que cuenta con horas suficientes de uso del aula de Informática del Centro. Recordemos por lo expuesto en Una forma de realizar control programado con el PC, que se pueden aprovechar ordenadores que hoy se considerarían como obsoletos en las aulas de informática, con un sistema operativo Windows 95 en su versión mínima o, incluso, simplemente con el sistema operativo DOS.
Puesto que los contenidos proporcionados en las distintas partes de este trabajo son considerablemente más amplios que lo indispensable para el nivel de destino mencionado, queda al criterio del profesor la selección específica de los mismos. Por otra parte, y siempre que sea posible, se aportarán al alumno como parte introductoria de una actividad práctica y no en sesiones teóricas independientes.
Contenidos |
Actividades y recursos |
Duración |
|
1 | Introducción. Procesos
para la mejora y el control de la producción. El PC como sistema de control. |
Apertura de un PC. Reconocimiento de los diferentes interfases y puertos de comunicación con los periféricos. | 1 |
2 | ¿Qué es un programa?.
Programación imperativa. |
Realizar el ordinograma de un proceso que muestre la lista de los n primeros números naturales y sus cuadrados. | 1 |
3 | El lenguaje QBasic: fundamentos | Utilizar el entorno integrado de programación de QBasic para escribir el código fuente de un programa elemental: mensaje de bienvenida | 2 |
4 | Entrada/salida de
datos:
teclado y pantalla. Uso básico de: PRINT
e INPUT ¿Qué son las variables?. Identificadores y tipos (sólo lo más básico). |
Escribir el código y ejecutar diferentes programas de ejemplo. Ejemplos de entrada/salida de caracteres: ej. 1, ej. 2, ej. 3, ej. 4, ej. 5, ej. 6, ej. 7, ej. 8. Ejemplos de uso de variables: ej. 1, ej.2. |
3 |
5 | ¿Qué es el puerto paralelo del
PC y para qué se utiliza?.
Líneas de datos, estado y control. Direcciones de E/S para acceder a las líneas (no tratar la detección automática de los puertos y de sus direcciones, pues excede el nivel). |
Utilizar la aplicación LPTPanel para que el alumno se familiarice con la identificación, distribución y uso de las líneas del puerto. |
1 |
6 | Control independiente de una entrada y una salida digital. | ![]() Insistir en aspectos como la correcta soldadura en los pines del conector. Utilizar LPTPanel para comprobar el correcto funcionamiento. Activar/desactivar la salida y detectar los cambios en la entrada utilizando un programa similar a CTRL.BAS . |
2 |
7 | Interacción con el entorno:
actuar en la salida dependiendo del estado de la entrada. Modificación del flujo del programa: la sentencia if .
|
Con el mismo montaje anterior, modificar el código de CTRL.BAS
utilizando la sentencia if
para controlar el flujo de programa en función del valor de la entrada.
Por ejemplo, encender el LED cuando se cierre el interruptor y apagarlo
cuando se abra. |
2 |
8 | Control de una entrada y una salida digital
utilizando el modo bidireccional. |
![]() Utilizar un programa como CTRL_0.BAS
para activar/desactivar la salida, detectar los cambios en la entrada e
interaccionar entre la entrada y la salida; todo ello utilizando líneas
de datos tanto para la entrada como para la salida.Dar a entender a los alumnos que los interfases de control cuentan en muchas ocasiones con líneas que son, simultáneamente, de entrada y salida, y no de uno solo de ambos modos. |
1 |
9 | Introducción al código binario. Ejecución repetida de sentencias en un programa: los bucles
|
![]() ![]() Realizar el montaje de la figura de la izquierda. Conectar un display de 7 segmentos, como el representado a la derecha, a las 8 líneas de datos del puerto. Calcular el número entero que, enviado al puerto, ilumina cada segmento y el punto decimal. Calcular el número entero que enviado al puerto, ilumina los dígitos 0, 1, ...., 9. Realizar una cuenta adelante entre 0 y 9 segundos, y una cuenta atrás. |
3 |
10 | Programación estructurada: utilización básica de subprogramas y funciones. | Escribir el código y ejecutar los programas de ejemplo
de utilización de funciones sin/con argumentos y con/sin retorno de
valores.
|
3 |
11 | Control de actuadores: motores de c.c. | ![]() Hacer comprender al alumno la necesidad del uso de alimentación externa para actuadores cuya potencia no sea tan ínfima como la de los LED. Utilizar una versión simplificada del programa MOTOR_CC.BAS para comprobar el funcionamiento del circuito. Explicar al alumno que esta interfase no funciona debido a que las líneas del puerto no proporcionan corriente suficiente para la conmutación del relé. Realizar el montaje de la figura. Utilizar una versión simplificada del programa MOTOR_CC.BAS para producir el giro del motor en ambos sentidos y su parada. |
2 |
12 | Aplicación a proyectos ya construidos. | Tomar proyectos ya construidos en el presente curso o en anteriores (vehículos, ascensores, etc.) y sustituir la forma de mando actual de los actuadores (motores y lámparas, por ejemplo) por el control programado. | 3 |
Contenidos |
Actividades y recursos |
Duración |
|
1 | Introducción. Procesos
para la mejora y el control de la producción. El PC como sistema de control. |
Apertura de un PC. Reconocimiento de los diferentes interfases y puertos de comunicación con los periféricos. | 1 |
2 | ¿Qué es un programa?.
Programación imperativa. |
Realizar el ordinograma de un proceso que muestre la lista de los n primeros números naturales y sus cuadrados. | 1 |
3 | El lenguaje C: estructura de un programa. Códigos fuente, objeto y ejecutable. | Utilizar el entorno integrado de programación de Turbo C para escribir el código fuente de dos programas elementales: main() vacío e impresión de un mensaje de bienvenida. Compilado, enlazado y ejecución.. | 2 |
4 | Entrada/salida de caracteres:
teclado y pantalla. Uso básico de: putchar
y getchar , printf
y scanf .¿Qué son las variables?. Identificadores y tipos (sólo lo más básico). |
Escribir el código y ejecutar diferentes programas de ejemplo. Ejemplos de entrada/salida de caracteres: ej. 1, ej. 2, ej. 3, ej. 4, ej. 5, ej. 6, ej. 7, ej. 8. Ejemplos de uso de variables: ej. 1, ej.2. |
3 |
5 | ¿Qué es el puerto paralelo del
PC y para qué se utiliza?.
Líneas de datos, estado y control. Direcciones de E/S para acceder a las líneas (no tratar la detección automática de los puertos y de sus direcciones, pues excede el nivel). |
Utilizar la aplicación LPTPanel para que el alumno se familiarice con la identificación, distribución y uso de las líneas del puerto |
1 |
6 | Control independiente de una entrada
y una salida digital.
Programación de la E/S: instrucciones |
![]() Insistir en aspectos como la correcta soldadura en los pines del conector. Utilizar LPTPanel para comprobar el correcto funcionamiento. Activar/desactivar la salida y detectar los cambios en la entrada utilizando un programa similar a CTRL.C . |
2 |
7 | Interacción con el entorno:
actuar en la salida dependiendo del estado de la entrada. Modificación del flujo del programa: la sentencia if .
|
Con el mismo montaje anterior, modificar el código de CTRL.C
utilizando la sentencia if
para controlar el flujo de programa en función del valor de la entrada.
Por ejemplo, encender el LED cuando se cierre el interruptor y apagarlo
cuando se abra. |
2 |
8 | Control de una entrada y una salida digital
utilizando el modo bidireccional. |
![]() Utilizar un programa como CTRL_0.C
para activar/desactivar la salida, detectar los cambios en la entrada e
interaccionar entre la entrada y la salida; todo ello utilizando líneas
de datos tanto para la entrada como para la salida.Dar a entender a los alumnos que los interfases de control cuentan en muchas ocasiones con líneas que son, simultáneamente, de entrada y salida, y no de uno solo de ambos modos. |
1 |
9 | Introducción al código binario.
Ejecución repetida de sentencias en un programa: los bucles Realización de temporizaciones: instrucción delay. |
![]() ![]() Realizar el montaje de la figura de la izquierda. Conectar un display de 7 segmentos, como el representado a la derecha, a las 8 líneas de datos del puerto. Calcular el número entero que, enviado al puerto, ilumina cada segmento y el punto decimal. Calcular el número entero que enviado al puerto, ilumina los dígitos 0, 1, ...., 9. Realizar una cuenta adelante entre 0 y 9 segundos, y una cuenta atrás. |
4 |
10 | Programación estructurada: utilización básica de subprogramas y funciones. | Escribir el código y ejecutar los programas de ejemplo
de utilización de funciones sin/con argumentos y con/sin retorno de
valores.
|
3 |
11 | Control de actuadores: motores de c.c. | ![]() Hacer comprender al alumno la necesidad del uso de alimentación externa para actuadores cuya potencia no sea tan ínfima como la de los LED. Utilizar una versión simplificada del programa MOTOR_CC.C para comprobar el funcionamiento del circuito. Explicar al alumno que esta interfase no funciona debido a que las líneas del puerto no proporcionan corriente suficiente para la conmutación del relé. Realizar el montaje de la figura. Utilizar una versión simplificada del programa MOTOR_CC.C para producir el giro del motor en ambos sentidos y su parada. |
3 |
12 | Control de actuadores: motores paso a paso (si se dispone de ellos). | ![]() Realizar el montaje de la figura. Escribir una versión simplificada de MOTOR_PP.C
para realizar el giro en ambos sentidos según una secuencia de paso
completo doble de un motor paso a paso unipolar. |
2 |
13 | Control de sensores: entradas analógicas. | Realizar el montaje
de la figura. Facilitar al alumno el programa
de control para que compruebe el cambio del valor mostrado en
pantalla cuando se gira el vástago del potenciómetro.
|
2 |
14 | Aplicación a proyectos ya construidos. | Tomar proyectos ya construidos en el presente curso o en anteriores (vehículos, ascensores, etc.) y sustituir la forma de mando actual de los actuadores (motores y lámparas, por ejemplo) por el control programado. | 3 |
A continuación se exponen algunos aspectos de un proyecto de control realizado con alumnos de 4º de E.S.O., consistente en la maqueta de un puente levadizo accionado neumáticamente y manejado mediante control programado en lenguaje C. Se trata de un proyecto relativamente complejo, desarrollado de forma cooperativa y con participación activa de los profesores en la realización del circuito de control y en la elaboración del programa.
La maqueta consta de un puente de dos hojas atravesado por una calzada cuyo cruce se halla regulado por dos semáforos. Las hojas se elevan gracias a dos cilindros neumáticos de doble efecto cuyas carreras se activan mediante electroválvula 5/2 y se ajustan mediante válvulas unidireccionales reguladoras de caudal. Cuenta con un zumbador que actúa como sirena cuando el puente se halla elevado. El control de la activación del ciclo de los semáforos, de la sirena, y de la elevación y recogida de las hojas del puente se programa utilizando las líneas del puerto paralelo.
La elevación del puente se puede llevar a cabo manualmente, mediante la pulsación de las teclas +/- en el teclado o mediante la pulsación de dos pulsadores rojo/negro situados en la propia maqueta. Asimismo, se puede realizar mediante la activación de una puerta óptica (elaborada con un diodo emisor/receptor de infrarrojos propio de los sistemas de mando a distancia de TV) situada en el vano del puente cuando ésta es atravesada por un barco.
El estado por defecto del puente consiste en un ciclo repetitivo verde-ámbar-rojo que es interrumpido cuando el sensor óptico o el control manual (pulsadores y/o teclado) se activan, para producir la elevación del puente. Ésta termina cuando el barco deja de detectarse en la puerta óptica o cuando lo decide el control manual.
La conexión de actuadores y sensores a las líneas del puerto paralelo se resume en la tabla que figura a continuación. Los detalles concretos del control se pueden seguir a través de los comentarios insertados en el código fuente del programa utilizado.
Líneas del puerto |
|||
Actuadores digitales |
Sirena | 2 | bit 1 de Datos (D0) |
Semáforos LED rojo-verde | 3 | bit 2 de Datos (D2 | |
Semáforos LED verde-rojo | 4 | bit 3 de Datos (D3) | |
Semáforos LED ámbar-ámbar | 5 | bit 4 de Datos (D3) | |
Electroválvula: subir (ELV1) | 6 | bit 5 de Datos (D4) | |
Electroválvula: bajar (ELV2) | 7 | bit 6 de Datos (D5) | |
Sensores digitales |
Detector de IR | 10 | bit 6 de Estado (S6) |
Pulsador rojo (subir) | 11 | bit 7 de Estado (S7) | |
Pulsador negro (bajar) | 12 | bit 5 de Estado (S5) | |
Otros (*) | Alimentación de pulsadores | 9 | bit 7 de Datos (D0) |
(*) Se pone la línea 9 en nivel alto por programa para alimentar a +5V el circuito de los pulsadores rojo y negro.
El esquema del circuito de control es el siguiente:
y el esquema neumático:
El listado del código fuente del programa utilizado es:
/* PUENTE.C Control de un puente levadizo accionado neumáticamente, mediante puerto paralelo 2002 Víctor R. González - Angelberto Mieres */ #include <stdio.h> #include <dos.h> #include "paralelo.h" #define APAGADO 0x00 /* D0-D7, pin 2-9, desactivados */ #define SIRENA 0x01 /* D0, pin 2, zumbador */ #define ROJO 0x02 /* D1, pin 3, LED */ #define VERDE 0x04 /* D2, pin 4, LED */ #define AMBAR 0x08 /* D3, pin 5, LED */ #define PUENTE_SUBE 0x10 /* D4, pin 6, electroválvula */ #define PUENTE_BAJA 0x20 /* D5, pin 7, electroválvula */ #define PULSA_ALIM 0x80 /* D7, pin 9, alimentación pulsadores */ #define BARCO_VIENE 0x0 /* S6, pin 10 alto, detector IR */ #define PULSA_SUBIR 0x0 /* S7#,pin 11 bajo, pulsador n/c de subida */ #define PULSA_BAJAR 0x0 /* S5, pin 12 bajo, pulsador n/a de bajada */ /* El estado normal de los sensores (desactivados) es: S7#=1, S6=1, S5=1 */ #define T_ROJO 5 /* duración (en segundos) de la luz roja */ #define T_VERDE 5 /* duración (en segundos) de la luz verde */ #define T_AMBAR 2 /* duración (en segundos) de la luz ambar */ #define T_PARPADEO 400 /* duración (en milisegundos) del parpadeo de la luz ambar */ #define T_SUBIDA 3 /* duración (en segundos) de la elevación del puente */ #define T_BAJADA 3 /* duración (en segundos) de la bajada del puente */ #define T_ESPERA 10 /* período (en milisegundos) de atención al teclado */ /* Activa las señales adecuadas del puerto */ #define Activa(valor) if (en_marcha) {outportb (DATOS, valor | PULSA_ALIM); printf("Enviado: 0x%X\n", valor);} #define SensorSubir() (inportb (ESTADO) & 0x80) /* Toma sólo bit 7 de ESTADO */ #define SensorBarco() (inportb (ESTADO) & 0x40) /* Toma sólo bit 6 de ESTADO */ #define SensorBajar() (inportb (ESTADO) & 0x20) /* Toma sólo bit 5 de ESTADO */ #define Apaga() outportb (DATOS, APAGADO) /* Desactiva las salidas */ int ParaleloIni (void);/* Detecta el puerto paralelo */ void Espera (float); /* Espera con atención al teclado y a las entradas digitales */ char en_marcha; /* Indica el funcionamiento o el fin del proceso */ void main (void) { /* Realiza el control si se detecta el puerto paralelo */ if ( ParaleloIni() != LPT_NINGUNO ) { Activa (PULSA_ALIM); /* Activa alimentación circuito pulsadores */ en_marcha = TRUE; /* Secuencia periódica de los semáforos esperando suceso de teclado o entrada digital */ do { Activa (VERDE); Espera (T_VERDE); Activa (AMBAR); Espera (T_AMBAR); Activa (ROJO); Espera (T_ROJO); } while( en_marcha ); Apaga(); /* Apaga las señales del puerto */ } else { printf ("No se encuentra ningún puerto paralelo\n"); exit(1); } } /* Realiza una espera activa de <t> segundos. Atiende al teclado y a las entradas digitales cada 10 ms */ void Espera (float t) { int t_max = 1000*t; /* tiempo a esperar (en ms) */ int crono = 0; /* tiempo transcurrido (en ms) */ int periodo= T_ESPERA; int tecla, sens_barco, barco = FALSE; char puente_arriba = FALSE; /* Espera hasta que se agota el crono */ while (en_marcha && crono < t_max) { if ( kbhit() ) tecla = getch(); /* Comprueba teclado */ sens_barco = SensorBarco(); /* Comprueba presencia del barco */ if (tecla == '+' || SensorSubir() == PULSA_SUBIR || (!barco && sens_barco == BARCO_VIENE)) { if (sens_barco == BARCO_VIENE) barco = TRUE; /* Eleva las hojas del puente */ for (crono=0; crono< 1000*T_SUBIDA; crono += 2*T_PARPADEO) { Activa (SIRENA + PUENTE_SUBE + AMBAR); delay (T_PARPADEO); Activa (SIRENA + PUENTE_SUBE); delay (T_PARPADEO); } Activa (SIRENA); puente_arriba = TRUE; tecla = 0; crono = 0; } else if( tecla == '-' || (!barco && SensorBajar() == PULSA_BAJAR) || (barco && sens_barco != BARCO_VIENE)) { barco = FALSE; /* Baja las hojas del puente */ for (crono=0; crono< 1000*T_BAJADA; crono += 2*T_PARPADEO) { Activa (SIRENA + PUENTE_BAJA + AMBAR); delay (T_PARPADEO); Activa (SIRENA + PUENTE_BAJA); delay (T_PARPADEO); } Apaga(); puente_arriba = FALSE; tecla = 0; crono = t_max; /* Sale del modo espera */ } else if( tecla == 'f' ) { /* Finaliza; si el puente está elevado, lo baja */ if (puente_arriba) { Activa (PUENTE_BAJA); delay (1000*T_BAJADA); } en_marcha = FALSE; } else if (puente_arriba) { /* Si el puente sigue elevado, la sirena suena y las luces ambar parpadean */ Activa (SIRENA + AMBAR); delay (T_PARPADEO); Activa (SIRENA); delay (T_PARPADEO); } else { /* Espera hasta nueva comprobación de teclado y pulsadores */ delay (periodo); crono += periodo; } } } /* Identifica los puertos paralelos instalados en el PC Devuelve (ver paralelo.h): LPT_NINGUNO: si no hay puertos instalados LPT_OTROS : si el primer puerto es de tipo desconocido LPT_SPP : si el primer puerto es SPP LPT_BIDIR : si el primer puerto es bidireccional LPT_EPP : si el primer puerto es EPP LPT_ECP : si el primer puerto es ECP */ int ParaleloIni (void) { unsigned int PuertoNum, Puerto, NumPuertos; unsigned int Byte, tmp; char PuertoEPP; int PuertoTipo; char *PuertoNombre[]={"", "Estandar (SPP)", "Bidireccional", "EPP", "ECP"}; /* Busca la dirección de E/S de los puertos instalados */ NumPuertos = 0; PuertoTipo = LPT_NINGUNO; for (PuertoNum=1; PuertoNum<=3; PuertoNum++) { _lpt_dir[PuertoNum] = peek(0x0040,0x0008 + (PuertoNum-1)*2); if (_lpt_dir[PuertoNum] == 0) printf ("No se encuentra puerto asignado a LPT%d \n", PuertoNum); else { printf ("La dirección asignada a LPT%d es 0x%X\n", PuertoNum, _lpt_dir[PuertoNum]); NumPuertos++; } } if (NumPuertos > 0 ) { /* Detecta el tipo de puerto del primero hallado */ printf ("\nPuerto seleccionado: LPT%d en 0x%X. ", LPT_NUM, LPT_BASE); /* Prueba puerto ECP */ Byte = inportb (CONTROL_EXT) & 0x03; /* toma bits 0 y 1 de CONTROL_EXT */ if (Byte == 1) { Byte = inportb (CONTROL); tmp = Byte; outportb (CONTROL, Byte ^ 0x03); /* pone a 0 los bits 0 y 1 de CONTROL */ Byte = inportb(CONTROL_EXT) & 0x03; if (Byte == 1) PuertoTipo = LPT_ECP; outportb (CONTROL, tmp); /* restaura CONTROL */ } /* Prueba puerto EPP */ if (!PuertoTipo) { PuertoEPP = FALSE; if (LPT_BASE != 0x03BC) { Byte = inportb (ESTADO); tmp = Byte; outportb (ESTADO, Byte & (~0x01) ); /* Pone a 0 el bit 0 de ESTADO */ for (Puerto=REG_EPP_PRI; Puerto<=REG_EPP_ULT; Puerto++) { outportb (Puerto, 0x55); Byte = inportb (Puerto); if (Byte == 0x55) { outportb (Puerto, 0xAA); Byte = inportb (Puerto); PuertoEPP = (Byte == 0xAA); if (!PuertoEPP) break; } } outportb (ESTADO, tmp); /* restaura bit 1 de ESTADO */ } if (PuertoEPP) PuertoTipo = LPT_EPP; } /* Prueba puerto SPP */ if (!PuertoTipo) { Byte = inportb (CONTROL); tmp = Byte; outportb (CONTROL, Byte | 0x20 ); /* Pone a 1 el bit 5 de CONTROL (entrada de DATOS) */ outportb (DATOS, 0x55); Byte = inportb (DATOS); if (Byte == 0x55) { outportb (CONTROL, Byte | 0x20 ); /* Pone a 1 el bit 5 de CONTROL (entrada de DATOS) */ outportb (DATOS, 0xAA); Byte = inportb (DATOS); if (Byte == 0xAA) PuertoTipo = LPT_SPP; } outportb (CONTROL, tmp); /* Restaura el bit 5 de CONTROL */ } /* Prueba puerto bidireccional */ if (!PuertoTipo) { Byte = inportb (CONTROL); tmp = Byte; outportb (CONTROL, Byte | 0x20 ); /* Pone a el 1 bit 5 de CONTROL (entrada de DATOS)*/ outportb (DATOS, 0x55); Byte = inportb (DATOS); if (Byte != 0x55) { outportb (CONTROL, Byte | 0x20 ); /* Pone a el 1 bit 5 de CONTROL (entrada de DATOS) */ outportb (DATOS, 0xAA); Byte = inportb (DATOS); if (Byte != 0xAA) PuertoTipo = LPT_BIDIR; } outportb (CONTROL, tmp); /* Restaura el bit 5 de CONTROL */ } if (PuertoTipo) { printf("Puerto tipo: %s (%i)\n", PuertoNombre[PuertoTipo], PuertoTipo); /* Pone DATOS en modo salida */ DATOS_out(); /* Pone las salidas en bajo */ outportb (DATOS, 0x00); /* reg. de DATOS */ outportb (CONTROL, inportb (CONTROL) & 0xFB); /* nibble bajo del reg. de CONTROL */ } else { PuertoTipo= LPT_OTROS; /* Puerto de tipo desconocido */ printf("Puerto de tipo desconocido\n"); } } /* NumPuertos > 0 */ return( LPT_TIPO = PuertoTipo ); } |