ESTE BLOG COMENZÓ A PUBLICARSE EN 2008, POR LO TANTO MUCHOS DE LOS TEMAS HAN QUEDADO DESACTUALIZADOS U OBSOLETOS. LOS LECTORES QUE DESEEN UTILIZAR ALGUNO DE LOS ELEMENTOS AQUI DESCRITOS DEBERÏAN ASEGURARSE DE BUSCAR LAS REFERENCIAS MAS MODERNAS DE LOS TEMAS DE SU INTERÉS. EL BUSCADOR INCLUIDO SERÄ UNA AYUDA PARA ESA BÚSQUEDA

sábado, 28 de enero de 2012

Un poco de software (y II)


En el artículo anterior, decía que puede hacerse un programa para manejar desvíos (y otros artículos electromagnéticos tales como desenganchadores señales de brazo y relés), de una forma muy sencilla, de modo que con un programa así, construyendo una o más placas DEMU02 de mi sistema de control, y comprando una placa Velleman K8055 es posible tener un sistema de control por ordenador para los aparatos de vía que sustituye con ventaja a un cuadro esquemático realizado de forma artesanal.

Esbocé un poco la forma de hacerlo, pero una vez publicado el artículo, pensé que realmente sería muy sencillo hacerlo, tan sencillo, que podría terminarlo, poco menos que en un rato.

Así que me puse manos a la obra, y el resultado es positivo. La imagen de cabecera muestra la pantalla de ordenador con el esquema de vías que he hecho para la prueba. Como se ve, en cada desvío, hay un botón que, al presionarlo actúa sobre el desvío correspondiente y al mismo tiempo cambia de color, con lo que se convierte en una excelente señalización de la posición del desvío. He llamado CzLite a este programa.

En este pequeño vídeo se ve el programa funcionando. Como se puede apreciar no hay más que el ordenador con el programa funcionando, y una conexión por USB a la placa Velleman. Siento no haber tenido disponibles algunas placas DEMU y algunos desvíos para verlos moverse en correspondencia con las pulsaciones del ratón en los botones del programa, pero lo que si se ve muy bien son los leds indicadores de las salidas de la placa, encendiéndose y apagándose. Esto es lo esencial del tema, lo demás está ya super comprobado.




Bueno, pues tal como anticipaba, el programa que hace esto es sencillísimo. De hecho son apenas cincuenta líneas de programa en Visual Basic.

Como es habitual, he puesto en la página de descargas de este blog un enlace a una página de mi web desde la cual es posible descargarse el programa, tanto en modo ejecutable como en modo fuente. Las personas que tengan conocimientos de programación pueden basarse en el programa fuente suministrado para modificarlo y perfeccionarlo de acuerdo con sus necesidades, pero con el programa que se incluye en la descarga es posible ya manejar siete desvíos y es posible modificarlo para manejar una gran cantidad de desvíos (124 exactamente). En esa página de descargas hay instrucciones de como cargar el programa y de como modificarlo para incluir el esquema de vías necesario y situar todos los controles que se necesiten para manejarlo, así que no voy a repetir aquí esas instrucciones.

Lo que si voy a explicar es la forma de conseguir que las órdenes generadas por el programa actúen sobre la placa Velleman.

Como ya comenté recientemente Velleman suministra con su placa una librería DLL. También comenté que es mejor descargarla de la página de Velleman para garantizar que tenemos la última versión. Esta DLL hay que copiarla al directorio Windows/System del ordenador. Esta Dll suministra una serie de funciones, que hay que declarar en el programa. Por eso el programa lleva un módulo de nombre Welleman.bas con la declaración de variables:

Option Explicit

Declare Function OpenDevice Lib "k8055d.dll" (ByVal CardAddress As Long) As Long
' Declare Sub CloseDevice Lib "k8055d.dll" ()
' Declare Function ReadAnalogChannel Lib "k8055d.dll" (ByVal Channel As Long) As Long
' Declare Sub ReadAllAnalog Lib "k8055d.dll" (Data1 As Long, Data2 As Long)
' Declare Sub OutputAnalogChannel Lib "k8055d.dll" (ByVal Channel As Long, ByVal Data As Long)
' Declare Sub OutputAllAnalog Lib "k8055d.dll" (ByVal Data1 As Long, ByVal Data2 As Long)
' Declare Sub ClearAnalogChannel Lib "k8055d.dll" (ByVal Channel As Long)
' Declare Sub SetAllAnalog Lib "k8055d.dll" ()
' Declare Sub ClearAllAnalog Lib "k8055d.dll" ()
' Declare Sub SetAnalogChannel Lib "k8055d.dll" (ByVal Channel As Long)
Declare Sub WriteAllDigital Lib "k8055d.dll" (ByVal Data As Long)
' Declare Sub ClearDigitalChannel Lib "k8055d.dll" (ByVal Channel As Long)
Declare Sub ClearAllDigital Lib "k8055d.dll" ()
' Declare Sub SetDigitalChannel Lib "k8055d.dll" (ByVal Channel As Long)
' Declare Sub SetAllDigital Lib "k8055d.dll" ()
' Declare Function ReadDigitalChannel Lib "k8055d.dll" (ByVal Channel As Long) As Boolean
' Declare Function ReadAllDigital Lib "k8055d.dll" () As Long
' Declare Function ReadCounter Lib "k8055d.dll" (ByVal CounterNr As Long) As Long
' Declare Sub ResetCounter Lib "k8055d.dll" (ByVal CounterNr As Long)
' Declare Sub SetCounterDebounceTime Lib "k8055d.dll" (ByVal CounterNr As Long, ByVal DebounceTime As Long)

Este bloque está copiado directamente del programa ejemplo suministrado por Velleman. Como se puede ver, he dejado sólo tres funciones activas, que son las que se usan en este programa. El resto las he dejado comentadas.

Como decía el programa consta de un módulo denominado Welleman.bas y un único formulario, denominado Form1.frm. Al arrancar el programa se activa el formulario, así que lo primero que se ejecuta es el procedimiento Load del formulario Form1. Este procedimiento contiene las siguientes instrucciones:

Private Sub Form_Load()

Dim AnchoPixel As Integer
Dim AltoPixel As Integer

AnchoPixel = 1024 ' Resolucion de pantalla. Pixels ancho
AltoPixel = 600 ' Resolución de pantalla. Pixels alto


Me.Move 0, 0, AnchoPixel * Screen.TwipsPerPixelX, AltoPixel * Screen.TwipsPerPixelY
Me.Show


If Not AbreCanal(1) Then End ' Intenta abrir el canal de comunicación. Si no lo consigue termina

End Sub

Lo primero que hace este procedimiento es dar valor a dos variables que definen el tamaño que se desea dar a la ventana del programa. Aquí se le ha dado 1024 pixels de ancho por 600 de alto. La instrucción Move ajusta ese tamaño y la instrucción Show lo visualiza.

A continuación hace una llamada a la función AbreCanal. Esta función la veremos a continuación y lo que hace es "encender" la placa de comunicaciones. Como puede haber hasta cuatro placas de comunicaciones se incluye el parámetro 1 indicando que se debe abrir la primera placa. Esta función devuelve un valor True o False en función de si la placa ha respondido a la orden de apertura. Si la respuesta es False el programa termina, puesto que hay algo que no funciona.

Esta es la función AbreCanal:

Function AbreCanal(Canal As Integer) As Boolean


Dim CardAddress As Long 'Variables long para la función
Dim h As Long


CardAddress = Canal - 1 ' Puede abrir los canales 1 2 3 0 4 las direcciones de tarjeta son 0 1 2 y 3
h = OpenDevice(CardAddress) ' llama a la función y devuelve un valor h


Select Case h
     Case 0, 1, 2, 3 ' Si devuelve en h la dirección de tarjeta es correcto
           MsgBox "Canal " & Canal & " abierto", vbInformation + vbOKOnly
          AbreCanal = True
     Case -1 ' Si devuelve -1 no ha funcionado
          MsgBox "El canal " & Canal & " no funciona", vbCritical + vbOKOnly
          AbreCanal = False
End Select


End Function

Aquí hay por primera vez una llamada a una función de las incluidas en la DLL suministrada por Velleman. Se trata de la función OpenDevice que se invoca con la dirección de la tarjeta y devuelve en la variable h el mismo valor, si la apertura fue correcta, o el valor -1 si fué incorrecta. En ambos casos se emite un mensaje y cuando el usuario acepta el mensaje termina la función.

El otro objeto que tiene definido el programa es una matriz de "Command Buttons" de nombre Command1(). En la versión que se puede descargar desde mi página tiene definidos 8 elementos, numerados del 0 al 7. El primero de ellos Command1(0) tiene la propiedad Visible a False para que no se visualice en tiempo de ejecución. Se utiliza en tiempo de diseño para generar copias de si mismo y poder así hacer tantos elementos de la matriz de botones como sean necesarios. El resto son los botones que se activan al pulsarlos con el ratón y pasan de rojo a verde y viceversa, y emiten la orden de cambio.

Cuando presionamos cualquiera de estos botones se ejecuta el evento Command1.Click y la variable Index toma el valor del ídice del elemento pulsado. El código de este evento es el siguiente:

Private Sub Command1_Click(Index As Integer)



Dim Direccion As Integer
Dim Milisegundos As Single

Direccion = 2 * Index 'se asignan diecciones a cada botón segun su indice. De dos en dos
Milisegundos = 200 ' Tiempo de activación de los desvíos


If Command1(Index).BackColor = &HFF00& Then Command1(Index).BackColor = &HFF& Else Command1(Index).BackColor = &HFF00&


If Command1(Index).BackColor = &HFF00& Then ' botón verde
     SendData Direccion, Milisegundos ' Envía el dato para posición desvío en recto
End If


If Command1(Index).BackColor = &HFF& Then ' botón rojo
    SendData Direccion + 1, Milisegundos ' Envía el dato para posición desvío en curva
End If


End Sub

Aquí vemos que al ejecutarse este procedimiento, se calcula un dato denominado Direccion que es el dato que hay que enviar a la placa. Para hacerlo sencillo he hecho que la dirección se calcule a parttir del indice de cada botón, o sea de la variable Index. Asi para el primer botón Index vale 1 y Dirección se calcula igual a 2. Pra el segundo botón, la Dirección sale 4. Para el tercer botón la Dirección sale 6, y así sucesivamente hasta el botón numero 7 cuya Dirección es 14

La otra variable importante es Milisegundos Define el tiempo que va a durar el impulso que enviamos a cada desvío. Aquí está puesto fijo a 200 que representan 200 milisegundos.

La siguiente instrucción cambia el color de fondo del botón (variable BackColor del elemento de la matriz de botones) Si era verde lo pone rojo y si era rojo lo pone verde.

Y por último sea el color resultante verde o rojo se llama a la función SendData, que es la que efectivamente va a hacer la transmisión del dato. Obsérvese que en el caso de que el botón sea verde, o sea que queremos que el desvío se ponga recto, enviamos el dato Dirección, mientras que si el botón está rojo, queremos que el desvío se ponga en curva, y entonces enviamos el dato Direccion +1

O sea que, por ejemplo si presionamos el botón 4, y lo ponemos verde, llamamos a la función SendData con los parámetros 8 y 200 mientras que si lo ponemos rojo llamamos a la función con los parámetros 9 y 200.  Se ve claro, el porqué asignamos la Dirección con valores de dos en dos.

Y por último, aquí está la función SendData:




Sub SendData(Dato As Integer, Tiempo As Single)



Dim segundos As Single
Dim t As Long
Dim N As Long


If Dato = 0 Then Exit Sub
segundos = Tiempo / 1000


N = Dato


WriteAllDigital N


t = Timer: Do While t + segundos > Timer: DoEvents: Loop


ClearAllDigital


End Sub


Como se ve, sencillamente convierte la variable de dirección (que aquí llama Dato) a entero largo con el nombre N También convierte el tiempo de transmisión que venía en milisegundos a segundos.

Entonces llama a la función de Velleman WriteAllDigital con el parámetro N. Es decir ordena que la salida de la placa muestre el valor N

Despues hace un loop para esperar el tiempo definido, que en nuestro caso serán 200 milisegundos, y entonces llama a la función de Velleman ClearAllDigital, que borra la salida de la placa.

Y eso es todo!.  En este artículo he reproducido el código fuente del programa CzLite completo, tal como puede descargarse desde la página de descargas.

Como ya advertí en un artículo anterior, la parte de comunicaciones que a priori parece lo más difícil, es realmente mucho más sencilla de lo que cualquiera puede esperar, mientras que la parte gráfica, sobre todo cuando hacemos gráficos animados es mucho más dificil de hacer de lo que la mayoría espera. En este programa CzLite, la parte gráfica se ha reducido al mínimo, y por eso el programa ha resultado extraordinariamente simple. Por el contrario la parte de comunicaciones, no ha sido simplificada y de hecho, las funciones empleadas; AbreCanal, y SendData proceden del código del programa "grande" ControlZ.

Como vemos en el vídeo, hay unos Leds que se encienden en la placa Velleman cuando pulsamos los botones del programa. Supongo que muchos de mis lectores lo saben, pero aclaro que esos Leds están mostrando el nivel de tensión (0 voltios o 5 voltios) de los ocho bits de salida de la placa, bits que se activan para formar la expresión hexadecimal del dato que hemos enviado a la salida. Asumiendo que los leds encendidos representan los "unos" y los apagados los "ceros", los datos que enviamos se visualizan así:

0     00000000
1     00000001
2     00000010  --> Desvio 1 recto
3     00000011  --> Desvio 1 curva
4     00000100  --> Desvio 2 recto
5     00000101  --> Desvio 2 curva
6     00000110  --> Desvio 3 recto
7     00000111  --> Desvio 3 curva
8     00001000  --> Desvio 4 recto
------------------------------------------ etc

Las dos primeras direcciones no se usan porque la correspondiente a la posición recta es la 00000000 que en realidad es la posición de reposo, que adopta la salida cuando no hay ninguna orden

Nótese que esta tabla puede continuarse hasta el el valor 255, lo que da el enorme valor de 127 desvíos que sería posible manejar con este programa.

Y para el que no lo tenga claro, lo que hace el conjunto de placas  DEMU1 DEMU2 y DEMU3 de mi sistema es activar con 12 voltios cada una de las 255 salidas que puede llegar a tener, en respuesta a las 255 posibles situaciones de la salida de la placa Velleman. Esta salida de 12 voltios se mantiene durante el tiempo que dura la activación de la salida, en definitiva durante 200 milisegundos en este caso.En definitiva hemos mandado un impulso de 12 voltios y 200 milisegundos de duracuón por esa salida. Si en esa salida está conectado el cable de un desvío éste se moverá en consecuencia.

miércoles, 25 de enero de 2012

Un poco de software (I)


Pantalla del programa ControlZ en un ordenador de 1280 x 1024 pixels de resolución de pantalla.
Como saben mis lectores, en este blog voy publicando todos los avances que realizo en la construcción de mi maqueta. También voy explicando en los distintos artículos cómo y porqué voy haciendo cada cosa, y publico fotografías planos y esquemas de trazados de vía, esquemas eléctricos, etc. No sólo eso, sino que en las páginas de Descargas, a las que se accede desde el menú de la cabecera, publico esquemas eléctricos, plantillas de PCB, listas de material, y en definitiva todo cuanto se necesita para que si alguien quiere seguir mis pasos, pueda hacerlo.

Debo dejar claro, sin embargo que éste es un sistema absolutamente original, y distinto del sistema que se ha impuesto de forma absolutamente global. Me refiero, claro está al sistema digital, asi que el que quiera meterse por mi camino sabe que no va a encontrar prácticamente ningún producto comercial que venga en su ayuda, de forma que, como yo, tendrá que hacerse todo el hardware de forma artesanal.

Pero seguramente, con ser eso un problema, no es el mayor, porque realmente los elementos de hardware son bastante sencillos, y para el sistema de comunicaciones he podido utilizar una placa de comunicaciones comercial.

Sin embargo, apenas he comentado nada acerca del software que he desarrollado para mi proyecto, y que se materializa en el programa que he denominado "ControlZ".  En mi último artículo me referí de nuevo a él, comentando que había podido ponerlo en marcha en un nuevo ordenador (más bien un mini ordenador) y en un nuevo sistema operativo (Windows 7). Así que ahora que estoy de nuevo metido en harina con el software, es una buena oportunidad para hablar de este tema.

Lo primero que hay que decir, es que el programa está incompleto, tan incompleto como el resto del proyecto, porque todo va avanzando en paralelo.

Sin embargo, en algunas ocasiones, se han dirigido a mi algunos lectores pidiéndome que les explique cómo, o les ayude a realizar un programa similar para sus maquetas. En todos los casos he contestado a esas demandas con explicaciones o incluso aportando piezas de software, pero tengo la sensación de que a ninguno de esos demandantes les han servido de mucho mis respuestas.

Y es que parece que estos comunicantes esperaban algún procedimiento maravilloso para dibujar un desvío en la pantalla, desvío que cambia de posición al pulsar con el ratón sobre él, o para dibujar un semáforo cuyas luces cambian de verde a rojo, o un desenganchador que parece que se levanta al pulsar sobre el mismo y no digamos ya, si de lo que se trata es de dibujar un velócímetro, cuya aguja se mueve por la escala indicando la velocidad en cada momento de la locomotora, o de dibujar una rotonda cuyo puente hacemos girar con el ratón  y que como consecuencia hace que la rotoda de la maqueta se mueva.(ver: Rotondas digitales). Todo ello, como decía aquél, es "more transpìration than inspiration". Quiero decir que conseguir eso, es complicado, y requiere bastante experiencia en programación, y concretamente en programación de gráficos.  Se da la circunstancia de que la programación ha sido mi actividad profesional durante muchos años, así que estaba dentro de mi alcance el abordar este tipo de software, pero precisamente en esa actividad profesional he podido comprobar como muchos programadores expertos patinan clamorosamente, cuando se enfrentan a ese tipo de programación.

Tomemos como ejemplo  el conseguir que la aguja del velocímetro se mueva por la escala. Para ello hay que aplicar unos cuantos conceptos de trigonometría. Si se tienen, es fácil dibujar esa aguja móvil, pero si no se tienen, por mucha experiencia de programación que se tenga, no se será capaz de hacerlo.

Concretamente: las siguientes siete instrucciones de Visual Basic dibujan la aguja del velocímetro que vemos dentro de cada una de las ventanas de control de locomotora.

     Picture1.DrawWidth = 4
     Picture1.ForeColor = &HFFFFFF
     Picture1.FillColor = &HFFFFFF

     Picture1.Circle (0, 0), 6


     Grados = (VeloActual / VeloFondo) * 270
     Angulo = (225 - Grados) * 1.74532925199433E-02 'radianes
     Picture1.Line (-20 * Cos(Angulo), -20 * Sin(Angulo))-(51 * Cos(Angulo), 51 * Sin(Angulo))

Las tres primeras lineas establecen cómo se va a dibujar: Con trazo de grosor 4, con color blanco, y con color de relleno blanco.

La cuarta instrucción dibuja el circulito blanco que se sitúa en el punto de giro de la aguja.
En la quinta instrucción calculamos la proporción entre la velocidad actual, la que debe indicar la aguja, respecto de la velocidad de fondo de escala. Esta proporción aplicada al total de grados que abarca la escala, 270, nos da el número de grados que debe moverse la aguja.

En la siguiente instrucción cambiamos esa cifra de grados a radianes obteniendo el valor "Angulo"

Y en la última linea dibujamos la línea que representa la aguja trazando una línea entre dos puntos cuyas coordenaedas son: x=-20 * Cos(Angulo),    y= -20 * Sin(Angulo)    y    x=51 * Cos(Angulo),    y=51 * Sin(Angulo).

Observese que se está dibujando en el objeto "Picture1" que en una fase anterior se ha definido como un control de tipo picture con un sistema de coordenadas con el origen en el centro y 200 unidades de ancho y alto

El resultado se puede apreciar en el vídeo adjunto



Como se ve, intervienen las funciones trigonométricas seno y coseno, así que hay que tener claro su significado. Como antes decía, no hay nada mágico. Hay que calcularse el ángulo que debe tener la aguja, las coordenadas de los puntos extremos y dibujar una linea entre esos dos puntos extremos con un determinado color, y un determinado espesor. Realmente en programación, para dibujar, sólo hay dos instrucciones Line y Circle. Las dos las he usado aquí, y no hay ninguna más, asi que cada dibujo que queramos ver hay que componerlo a base de estas dos instrucciones.

Realmente estas dos instucciones corresponden a una regla y a un compás, y como sabemos, esos son los dos únicos instrumentos imprescindibles para dibujar.

Y para que la aguja realmente se mueva, el truco es el mismo que el del cine o la televisión: La aguja se está dibujando continuamente, cada vez en la situación que corresponde a la velocidad en cada momento. Esto también es poco habitual en programación: Realmente el programa está permanentemente metido en un bucle que redibuja continuamente los elementos gráficos que cambian. Por ejemplo en la esquina superior derecha de la pantalla de la cabecera vemos un cronómetro que va calculando los minutos y segundos que lleva funcionando el programa. Los números van cambiando porque el programa redibuja continuamente las cifras.

Si nos fijamos, en el caso de la aguja del velocímetro, hay una variable, de nombre VeloActual que determina la posición en que debe aparecer la aguja. Cada vez que se ejecutan esas instrucciones se dibuja la aguja de acuerdo a este valor. Se trata de una variable analogica, porque realmente su valor corresponde a la velocidad teórica de la locomotora en Kilómetros/hora, que varía de forma continua entre cero y el valor máximo.

En otros casos la variable es de tipo digital, por ejemplo un semáforo de dos luces, puede lucir en rojo o en verde.por lo que la variable que dice como se debe dibujar, solo puede tener dos valores. Bueno en realidad tiene cuatro posibilidades: encendido el rojo, encendido el verde, encendidos ambos y apagados ambos. Pero en todo caso, se trata de una variable entera que solo admite unos pocos valores. En este caso 0, 1 o 2 (el caso de los dos apagados no se contempla) Tratándose de semáforos, el nombre de esta variable es "Aspecto".  Si algún lector se pregunta cuando se muestran encendidos simultáneamente el rojo y el verde la respuesta es que se muestran así en el modo de diseño, es decir cuando el usuario está definiendo que en una determinada posición, va un semáforo.

Bueno pues la rutina que dibuja un semáforo es la siguiente:

Case 1 'semaforos dos aspectos


    Destino.DrawWidth = Grueso
    Destino.Line (x - 3 * a, y)-(x + m, y), Negro 'palo
    Destino.Line (x - 3 * a, y + n)-(x - 3 * a, y - n), Negro 'base


    Destino.DrawWidth = Grueso * 4
    Destino.Line (x - m, y)-(x + m, y), Negro ' cabeza

    Destino.DrawWidth = Grueso


    Select Case Aspecto
        Case 1
            Destino.Circle (x + m, y), Grueso / 1.6, Rojo
        Case 2
            Destino.Circle (x - m, y), Grueso / 1.6, Verde
        Case Else
            Destino.Circle (x + m, y), Grueso / 1.6, Rojo
            Destino.Circle (x - m, y), Grueso / 1.6, Verde
    End Select



Ya sé que para la mayoría de los lectores, el presentar aquí estos segmentos de código puede resultar aburrido, pero, insisto, lo hago para aquellas personas que tengan conocimientos de programación, y que tengan curiosidad por saber cómo se pueden hacer este tipo de programas con gráficos móviles. Vemos como aquí la variable "Aspecto" hace que ejecuten unas u otras instrucciones del último bloque, y que en definitiva están dibujando un circulo de color rojo o verde.

Esta rutina es polivalente, ya que se usa para dibujar semáforos en más de una situación de programa. Por eso se usa la variable Destino que indica dónde hay que dibujar en cada caso. Las variables x e y especifican las coordenadas donde debe hacerse el dibujo, a es la altura del poste y m es la altura de la cabeza del semáforo. La variable "Grueso" indica el espesor de las líneas de dibujo, y las variables "Rojo", "Verde" y "Negro" contienen la definición binaria de esos colores.

Y naturalmente, el caso de los desvíos es análogo. Una variable, que por cierto también se llama "Aspecto" dibuja las lineas correspondientes a la posición del desvío. Hay desvíos con dos aspectos, y otros con tres, caso de los desvíos triples.

De hecho cualquier segmento de vía se dibuja igual que un desvío ya que puede corresponder a un trazo vertical, horizontal, inclinado a derecha, inclinado a izquierdas, y todas las combinaciones de esquinas que permiten cerrar los dibujos. Sin embargo, los tramos simples no tienen aspectos, por lo que se dibujan siempre igual, a diferencia de los desvíos.

Seguramente algún lector que tenga experiencia en programación se habrá visto sorprendido por el hecho de que el programa dibuja CADA VEZ cada elemento utilizando las instrucciones Line y Circle para dibujar las imagenes. Cuando se hacen cosas parecidas a esta, muchos programadores realizan previamente una gran cantidad de imágenes, utilizando un programa de dibujo (Paint o PhotoShop, por ejemplo), almacenan todas estas imágenes, y luego durante la ejecución presentan unas u otras imágenes en el lugar oportuno. Mi experiencia es que ese tipo de sistemas resultan más lentos, y mucho más difíciles de mantener, pero sobre todo, el dibujar los elementos cada vez durante la ejecución tiene la enorme ventaja de que puede dibujarse a cualquier escala sin más que dar un nuevo valor a las coordenadas. De esta forma se consigue muy sencillamente que se pueda hacer zoom sobre cualquier zona del dibujo y a cualquier grado de ampliación. También es posible utilizar colores variables con significados apropiados porque en definitiva para la rutina de dibujo los colores son variables cuyo valor le viene dado.

También es facilisimo adaptarse a las distintas resoluciones de pantalla. En la imagen de cabecera de este artículo vemos la imagen del programa en un ordenador de sobremesa con pantalla de 1280 x 1024 pixels, pero como contaba en mi anterior artículo, no he tenido la menor dificultad eh hacerlo funcionar en un pequeño ordenador con bastante menos resolución, incluso con proporciones distintas, ya que tiene una pantalla apaisada, tal como vemos en la fotografía de cabecera de mi anterior artículo (Un hito).

Si algun lector, que estaba considerando la posibilidad de hacer un programa para controlar su maqueta, se ha asustado al leer todo lo anterior, le hago la advertencia de que hacer un programa de la forma en que yo lo he hecho, es realmente un lujo, ya que el programa está hecho como si fuera a venderse, es decir que permite definir cualquier trazado de vías y colocar los desvios, señales, y demás elementos que sean necesarios. Esto está muy bien, porque permite hacer modificaciones con toda facilidad, y tiene las ventajas que he comentado en cuanto a la posibilidad de zoom y la adapatación a distintas resoluciones de pantalla, pero realmente se puede hacer un programa mucho más sencillo, si nos conformamos con que sea hecho específicamente para una determinada maqueta, y para una determinada resolución de pantalla. En un próximo artículo trataré más extensamente este tema.

Claro que aquí viene la segunda parte: ¿Como hacemos para que esas "ordenes" que el programa envía salgan del ordenador y lleguen a mover un desvío en la maqueta? Aunque parezca raro, esto es muchísimo más sencillo que lo que hemos explicado hasta ahora, pero de eso trataremos en el artículo siguiente.


lunes, 16 de enero de 2012

Un hito


Supongo que algunos lectores de este blog, habrán pensado más de una vez, "pero este tío, ¿cuándo va a poner en marcha la maqueta de una vez? Y es que en efecto, desde hace aproximadamente un año, se han ido sucediendo una serie de problemas, el principal de los cuales ha sido el traslado de domicilio, y las consiguientes obras de adaptación de la maqueta a su nueva ubicación.

Pero no ha sido éste el único problema: He tenido problemas con los dos ordenadores que manejo. El que utilizo habitualmente, que es un sobremesa, tuvo una serie de problemas de software que casi me hacen perder un montón de cosas. Afortunadamente tenía copias de seguridad, pero siempre falta algo.

El principal problema fue con el ordenador portátil que había ya asignado a controlar la maqueta. Este sencillamente se averió, sin reparación posible.

Sopesé varias opciones, pero al final decidí comprar un nuevo portátil, de los más sencillos y de pequeño tamaño, con la intención de usarlo primordialmente para manejar la maqueta, aunque si quería, para evitar problemas de compatibilidad, que tuviera sistema operativo Windows. Al final compré un Dell Inspiron mini, que podemos ver en la foto de cabecera.

Me vino con Windows 7, lo cual no me gustó demasiado, porque en el otro ordenador conservaba  (y conservo) mi Windows XP de siempre.

Y esto me llevó a una cuestión: El desarrollo de mi programa de control de trenes está hecho en Windows XP. ¿Funcionará en Windows 7? La duda es bastante lógica, porque este programa, como mis lectores saben se mete en muchas interioridades, como son los gráficos animados, las comunicaciones por USB, etc.

La verdad es que el temor a lo que pudiera encontrarme ha sido otro de los motivos de que no me decidiera a probar a hacer el montaje en el nuevo ordenador, pero este fin de semana  decidí que ya estaba bien de marear la perdiz, y me puse con el tema.

En primer lugar se trataba de volver a poner en marcha el entorno de desarrollo en Visual Basic del ordenador grande, cosa que no había probado desde la recuperación de las copias de seguridad. Tal como sospechaba faltaba algún módulo, pero afortunadamente pude recargar el Visual Basic y dejar todo operativo de nuevo. Así que me volvió a funcionar mi programa, y pude hacer una compilación del mismo sin problemas, que funcionó perfectamente con las placas Welleman.

El siguiente paso fue crear un paquete de instalación y cargarlo en el ordenador pequeño como quien instala un producto comercial. Aquí me esperaba problemas, pero para mi sorpresa el Windows siete se dejó instalar el programa sin problemas. Esto puede parecer elemental, pero la instalación es compleja y lleva un montón de librerías dll's varios módulos ejecutables, archivos de datos, etc. creados para un entorno de Windows XP antes de que existiese Windows 7. Mi enhorabuena a Microsoft.

Ya estaba yo aplaudiendo con las orejas, cuando al probar el programa, veo que todo funciona....excepto que la placa Welleman conectada al puerto USB no reacciona. Naturalmente si esto no se resuelve, todo el montaje no sirve para nada.

Bueno, ¡que no panda el cúnico! La placa Welleman viene con una dll que hay que instalar en el ordenador, y seguramente es la que no funciona. ¡vaya por Dios! la única que no es de Microsoft ni mía.

Rápidamente me metí en la web de Welleman a ver si tenían una nueva versión de esta dll...... Y... ¡ SI ahí estaba! Descarga, copia, instalación, prueba... ¡Y funcionando!


Asi que por fin, tengo el programa de control instalado y completamente operativo en el ordenador portátil. Al menos esta gente de Welleman son serios y cuando han comprobado que su sistema no funciona en Windows 7, han corregido el problema y lo han puesto a disposición de los usuarios. Me gustaría saber que me hubiera pasado si hubiese tenido este problema con la placa de Micropick que utilicé inicialmente.

El peligro de hacer estos desarrollos propios, es precisamente éste. Al paso que avanza la tecnología informática, puede uno encontrarse fácilmente con que con alguno de estos cambios algo deja de funcionar y el arreglo, suponiendo que se sepa localizar cual es el problema, lleva un tiempo prohibitivo para una sola persona. Las grandes empresas de Software pueden ir actualizando sus productos para mantener la compatibilidad con los nuevos sistemas, pero hacer esto para un programa que es ejemplar único y desarrollado por una única persona, resulta prohibitivo.

Afortunadamente, por esta vez he salvado el problema, y bueno, Windows 7 es un standard bastante actual, así que puedo estar tranquilo por un tiempo.