Acceso al puerto paralelo LPT – Algo Más que encender un LED o Imprimir un DOC

Durante más de medio año y sobre todo desde LatinoAmerica estoy recibiendo cantidad de solicitudes de ayuda para manejar el puerto paralelo del Ordenador y poder así activar relés que ponen en marcha cualquier tipo de artilugio eléctrico o electrónico. He sido reticente a escribir nada al respecto, pues consideraba que existen mil y una soluciones actuales tanto en HardWare como en SoftWare que permiten controlar motores, luces o cualquier tipo de mecatronica pero de forma profesional  con tecnología y medios actuales. Pensar el soluciones del tiempo de MS-DOS, me parece como menos equivocado siempre y cuando la finalidad no sea como ejercicio docente o como una forma de aprender y experimentar. Una vez entendida la declaración me complace compartir la siguiente explicación para contextualizar que encender un ‘led’ utilizando el puerto paralelo no es ningún logro, aunque sin despreciar la experiencia pueda ser divertido, teniendo en cuenta que la interacción con el sistema operativo es la que marcan los cánones a pesar de que de vez en cuando podamos hacerle un giño.  A demás no debemos olvidar que a día de hoy no todos los ordenadores incorporan la antigua especificación para el puerto paralelo.

Una de las características de la arquitectura x86 es el direccionamiento de dispositivos periféricos a través de un bus de entradas/salidas. Si nos remontamos en el tiempo, para la mayoría de los que utilizaron “Macro Assembler” o “C” en los tiempos de sistemas operativos como CP/M o MS/DOS, recordaran como nos hacíamos con el control de los dispositivos desviando los vectores de interrupción a nuestras rutinas y por supuesto comunicándonos directamente con los dispositivos a través de sus puertos mapeados en tal bus de E/S. Estamos hablando de dispositivos como el Teclado, Puerto Serie, Paralelo, Memoria, Timer, etc … ciertamente todos los dispositivos que componían la estructura básica de nuestro sistema. Por supuesto estábamos más que familiarizados con la utilización de las instrucción ‘in’ y ‘out’, ellas nos permitían enviar o recibir un byte utilizando un puerto (Mapa E/S) que conectaba directamente y permitía el intercambio de información con un periférico en concreto.

En esos tiempos los sistemas operativos estaban orientados a la ejecución mono-Usuario, Mono tarea, sin entorno grafico y con la única posibilidad de interaccionar a través de un ‘prompt’  por parte del usuario.

Con la llegada y evolución de los sistemas gráficos, multitarea, multiusuario para plataformas Intel, tuvieron que adaptarse a una arquitectura adecuada para tal cometido. Dicha arquitectura dicta las normas en las deben efectuarse las llamadas a  procedimientos, manejar las interrupciones y como no las excepciones, por citar algunas.

Dicho esquema, familiar para cualquier estudiante de informática como mecanismo de protección reconoce en forma de aros, en concreto cuatro aros concéntricos que representan cuatro niveles de privilegio del 0 al 3, la principal razón para usar ese esquema se vasa en mejorar la fiabilidad del propio sistema operativo.

Privilegios

El primer aro en el centro es utilizado por módulos de código que contienen partes vitales y criticas del sistema, por lo tanto disponen del nivel de privilegios más alto. El resto de módulos con menor nivel de privilegio solo pueden acceder al nivel superior a través de un estricto controlador llamado “puerta” o “gate”, intentar acceder a un segmento privilegiado de un nivel superior directamente o si utilizar la protección “gate” sin los suficientes permisos causara una excepción de protección general.

En nuestro entorno Intel/Windows, tuvimos la posibilidad de utilizar las instrucciones de ‘in’ ‘out’ tanto desde lenguajes como Asm, C y Basic y los sistemas operativos DOS, 95 y 98. Sin embargo con la tecnología NT, el uso de estas instrucciones por programas con privilegios de usuarios generaba la consecuente excepción en el sistema.

Cabe dejar claro que es del todo irreconciliable la mentalidad de acceder al puerto paralelo enviando un byte a la dirección de su puerto en un entorno como el nuestro. Difícilmente podemos justificar una programación orientada a controlar los dispositivos… ese tiempo ya paso y precisamente una de las tareas más eficientes que nuestro sistema operativo es capaz de llevar a cabo es ese control. No debemos perder la perspectiva que si necesitamos programar partes especificas que justifican ese nivel de privilegios, debemos utilizar las herramientas que nos facilita el fabricante del SO, tales como SDK, DDK..etc.  Es evidente que necesitamos una serie de conocimientos avanzados, para encajar nuestra pieza en todo este puzle, pero sin duda solo siguiendo esos patrones seremos capaces de construir soluciones profesionales aptas para superar las pruebas a nivel de los mercados a los que van dirigidos.

Advertencia y Aclaración.
Está claro que os facilito este articulo por vuestra insistencia, aunque debo advertiros que el mal uso del soldador con el conector de 25 al intentar realizar experimentos o utilizar inadecuadamente el puerto paralelo conectando aparatos o dispositivos inadecuados o incompatibles, puede causar averías en el equipo o en el peor de los casos daños personales, debo rechazar categóricamente cualquier responsabilidad por el uso de la información contenida, cualquier aplicación o uso derivada de la información de este artículo y su alcance es estrictamente responsabilidad del lector aunque estaré encantado de recibir vuestros comentarios.

En el caso que nos ocupa, para poder enviar o recibir un byte de puerto, necesitaremos estar dentro del anillo de ‘driver’ que nos proporcione los derechos de privilegio suficiente para realizar dicha operación. La mayoría de nosotros carecemos de los conocimientos suficientes para desarrollar un adaptador que nos permita fabricarnos nuestro propio ‘driver’ aunque podemos encontrar multitud de ejemplos en la red, existe una conocida librería llamada ‘inpout32.dll’ que viene a implementar ese ‘kernel model driver’. Podemos descargarnos esa librería desde un montón de ubicaciones, solo es necesario buscar ‘inpout32.dll DownLoad’ en la red y una vez dispongamos de ella copiarla en “\windows\system32”.

Luego solo nos restara crear un nuevo proyecto en Visual Studio e incluir nuestras referencias como sigue:

‘Declaraciones para leer/ecribir un puerto E/S utilizando inpout32.dll

Public Declare Function leer Lib «inpout32.dll» Alias «Inp32» _

       (ByVal puerto As Short) As Short

Public Declare Sub escribir Lib «inpout32.dll» Alias «Out32» _

       (ByVal puerto As Short, ByVal Valor As Short)

 

Finalmente en el evento clic del botón por ejemplo:

    ‘ Para la prueba de los led’s

    ‘ Conectar los led’s a traves de una resistencia.

    ‘ La resistencia debe soldarse a la masa en las

    ‘ patillas del conector de (25pins) correspondientes

    ‘ a los pines 19,20,21,22,23,24,25 (son todos masa).

    ‘ El otro extremo de la resistencia lo soldaremos al

    ‘ negativo del led, y el positivo del mismo a las

    ‘ patillas 2,3,4,5,6,7,8,9 que corresponden a la salida

    ‘ del registro de datos del puerto serie.

 

    Private Sub Button1_Click() Handles Button1.Click

        Static OnOff As Boolean = False

        ‘el puerto &h378 corresponde a la direccion

        ‘del registro ‘data’ del LPT1:

        If OnOff Then

            ‘Apagar todos los led’s

            escribir(&H378, &H0)

        Else

            ‘Encender todos los led’s

            escribir(&H378, &HFF)

        End If

        OnOff = Not OnOff

    End Sub

 

Luego para leer el estado de las líneas del registro de datos:

    Private Sub Button2_Click() Handles Button2.Click

        MessageBox.Show(leer(&H378))

    End Sub

 Saludos,
Pep Lluis,

Firmware : La dichosa inteligencia del silicio.

Podriamos pensar en el Cerebro humano como el soporte físico a nuestra inteligencia así mismo y según creo entender el Firmware de una electrónica es la “inteligencia del silicio”. En mis tiempos, muchos chips (incluso algunas CPU’s) implementaban su funcionalidad configurando diversas y complejas conexiones entre cientos o incluso miles de transistores. Cada patilla, cada asignación tenía su propio y único cometido… pero los tiempos vuelan y aunque también hace mucho tiempo los ingenieros electrónicos entendieron que la versatilidad de sus desarrollos pasaba por dotarlos de un mínimo de flexibilidad para que dichos diseños tuvieran mayor usabilidad pudiéndose adaptar a diferentes escenarios, se trataba de separar la electrónica y su funcionalidad o sea el famoso “Hardware” y “Software”, todo ello vino a convertirse lo que se conoce como firmware. Inicialmente acostumbraba a ser una serie de Micro interruptores que hacían posible esa customización, posteriormente y con la generalización de los procesadores una ROM y con los tiempos las EPROM’s las E2PROM y un etc. hasta llegar a las FLASH. Hoy en día estamos rodeados de ‘firmware’ por todas partes incluso el pequeño ‘ratón’ que utilizas en tu PC tiene implementado su propio ‘firmware’.

Llegados a este punto os estaréis preguntando a que viene la explicación y donde quiero llegar. Pues bien os relatare en tono de humor mi última experiencia con la supuesta inteligencia del silicio.

Como tecnólogo, me vi en la obligación escoger un dispositivo portátil dotado de un procesador VIA una pantalla de 8.9” que ahora están de súper moda. La diferencia entre los dos candidatos era que uno tenía soporte para WSVGA y el otro para WXGA, resumiendo uno alcanzaba una resolución de 1024 * 600 y el otro 1280 * 768 ¡Brutal! Para visualizar todo un escritorio del Vista en tan solo 8.9”, aunque sin dudarlo dispuesto en asumir el tormento de forzar la vista o incluso ponerme gafas.

La otra historia viene cuando aprovechando una salida para un segundo monitor alguien piensa que sería fantástico poder utilizar uno de esos de 20” para cuando llegamos de nuestras incursiones fuera de la oficina poder disfrutar del gran tamaño y de la gran resolución que nos proporciona WXGA.

Siendo fiel a la idea, adquirimos un monitor 16:9 de 20” que nos permitiera sacar esos 1280 * 768 y la gran sorpresa con mucha angustia fue ver como las ilusiones se iban hacia arriba y hacia abajo al ritmo de un desesperante tembleque de la gran pantalla. La primera conclusión fue pensar que el pequeño portátil no estaba dando la frecuencia requerida por el flamante monitor y al desespero de no poder hacerlo trabajar correctamente con resoluciones superiores a  1024 * 768 fue pensar que los temblores de la imagen tuvieran su origen en un defecto de fabricación.

PUES NO!!
El inteligente firmware del silicio de la pantalla, entre las más de cien y una opciones parametrizables y ajustables a ciento y un escenarios, disponía en su menú 15 de una opción que algún avispado ingeniero había decido deshabilitar, pensando en que la mayoría de los mortales usuarios de su producto utilizaría por defecto el gran monitor de 1280 * 768 a resoluciones inferiores a 1024 * 600 … quien va a comprar un monitor y va a usar la máxima resolución? Está claro que nadie!

Bien pues, en algún abandonado rincón del menú dentro de retorcidos literales complicados de interpretar y después de 4 horas dándole vueltas apareció majestuosa la opción :

MODO WXGA : off … el firmware de mi Cerebro automáticamente resolvió a … ¡Esto debería ser ‘on’! y efectivamente después de cambiar esa configuración y para regocijo de todos el monitor empezó a mostrar firme, sin titubeos ni tembleques una a una la resolución de 1280 * 768 líneas!!!, aunque estoy convencido y a favor del ingeniero que tomo la decisión de incluir la configuración de MODO fue intentando resolver una casuística concreta, debo matizar que no las contemplo todas, pues el MANUAL de usuario donde se describen resoluciones y frecuencias, debería haber incluido una columna anunciando el MODO.

Sabéis que acostumbro a escribiros cortos con la intención de poner un tono de humor a nuestro día a día, aunque en ocasiones como esta  creo que lo importante no es el hecho aislado y la ironía, si no la reflexión final a todo esto.

No me preocupan las cuatro horas en sí, ni tan siquiera la dudosa puesta en escena de los valores de fábrica que maneja el ‘firmware’.  Me preocupan los cientos de personas que desconociendo las terminologías (tales como WSVGA, WXGA) que no saben distinguir entre pulgadas o resoluciones, de altas definiciones, caen a manos de productos que por prestaciones tienen un coste superior y finalmente por ese desconocimiento dejan de darles su mejor uso o prestaciones. En el caso de esta historia no tiene importancia pues después de dedicarle el tiempo necesario conseguimos el objetivo… pero me pregunto cuantas personas y en cuantas situaciones similares terminan mal, aborreciendo, dando mal uso y lo peor frustrando ilusiones.

Como desarrolladores no solo tenemos la responsabilidad de saber aportar técnicamente soluciones sino que además deben ser soluciones que sepan conectar o acoplar esa tecnología con la gente en general, que al fin y al cabo son los destinarios de todo esto. De nada sirve proyectar y conseguir grandes logros a nivel tecnológico si no somos capaces de hacerlos llegar de una forma asequible y agradable a personas no expertas, que para expertos representa que ya estamos nosotros.

… y ahora vuestros comentarios J

Serial Port – Enumeración & Disponibilidad

 

         Saber sobre la disponibilidad de nuestros puertos serie antes de su selección en un combobox.

  How to know about availability of our computer serial ports before select one from a combo box.

A menudo las aplicaciones que requieren seleccionar un dispositivo antes de efectuar algún tipo de comunicacion, no ofrecen ninguna información adicional sobre el estado del dispositivo. Sobre todo si hablamos del puerto serie, normalmente nos ofrecen una simple enumeración de los COM. Esto último es el causante de que la aplicación nos permita seleccionar un puerto que en ocasiones no existe o está siendo usado por otro programa.

Os propongo una idea con la intención de mejorar y facilitar la selección de este tipo de dispositivos en nuestras aplicaciones.

Básicamente se trata de enumerar en un ‘ComboBox’ personalizado los puertos existentes en nuestro equipo, utilizando el mandato :

My.Computer.Ports.SerialPortNames.ToArray

En el momento de la inicialización del ‘combobox’ asignaremos el evento de ‘DrawItem’ a la función que enriquecerá el aspecto, añadiendo al nombre un rectángulo coloreado y el texto correspondiente a la disponibilidad del puerto.

AddHandler ComboBox1.DrawItem, AddressOf cmbo_SerialPorts_Status

No dudéis en contactar conmigo si necesitáis aclarar o necesitáis entender alguna parte del código.

Para poder darle mayor difusión los comentarios del código están en inglés, aunque si os parece oportuno y necesario puedo posteároslo también en español.

Sometimes our communications applications are required to select any type of external device, and normally these applications are not giving any extra information about their availability. This is the case when talk around serial ports, normally when select the port only have a simple enumeration of COM’s, this may be confusing at time leaving at users selecting inexistent ports or ports that simply are already in use.

With this sample, you can improve and make easy these device selections in our applications.

The main think is enumerate serial port inside our customized ‘ComboBox’, using :

My.Computer.Ports.SerialPortNames.ToArray

After when initialize our combo only need assign ‘DrawItem’ event to function with our personalized combo draw,

AddHandler ComboBox1.DrawItem, AddressOf cmbo_SerialPorts_Status

This function are adding red rectangle and “busy” text when no have availability, and green rectangle and “available” text when the port is free.

Please no doubt in contact with me if you need any other explanation or opinion about this.

 

 SerialEnum_Es

SerialEnum_en 

 

Public Class Form1
    ‘Enumerate Serial Ports on Machine
    ‘Get Serial Port availability

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ‘Just drag & drop combobox from toolbox to form designer
        Me.ComboBox1.DrawMode = DrawMode.OwnerDrawVariable                     ‘select my own drag mode
        Me.ComboBox1.DropDownStyle = ComboBoxStyle.DropDownList                ‘aspect when drop down
        Me.ComboBox1.DataSource = My.Computer.Ports.SerialPortNames.ToArray    ‘enumerate serialports
        Me.ComboBox1.TabIndex = 0                                              ‘select first tabindex
        AddHandler ComboBox1.DrawItem, AddressOf cmbo_SerialPorts_Status       ‘draw my personal cmbo
    End Sub
   
    ‘ Draw our custom combo
    Private Sub cmbo_SerialPorts_Status( _
        ByVal sender As Object, _
        ByVal CmboItem As System.Windows.Forms.DrawItemEventArgs)

        ‘ Draw the background of the item.
        CmboItem.DrawBackground()
       
        ‘Default Values if port is available
        Dim status As String = «Available»
        Dim brush As New SolidBrush(Color.Green)
        Dim font As System.Drawing.Font = Me.Font
        Dim fontbrush As Brush = Brushes.Black
        Dim rectangle As Rectangle = New  _
            Rectangle(2, CmboItem.Bounds.Top + 2, _
                         CmboItem.Bounds.Height, _
                         CmboItem.Bounds.Height – 4)
       
        ‘Check for port availability
        Try
            ‘ If port open & close with no exception
            ‘ draw the item with default font and green rectangle
            Dim PortTest As New System.IO.Ports.SerialPort
            PortTest = My.Computer.Ports.OpenSerialPort(My.Computer.Ports.SerialPortNames(CmboItem.Index))
            PortTest.Close()
        Catch ex As Exception
            ‘ If port is not available
            ‘ draw the item with italic & strikeout font and red rectangle
            brush = New SolidBrush(Color.Red)
            status = «In Use»
            font = New Font(FontFamily.GenericSansSerif, Me.Font.Size, FontStyle.Italic Xor FontStyle.Strikeout)
            fontbrush = Brushes.DimGray
        End Try

        ‘fill combo item rectangle
        CmboItem.Graphics.FillRectangle(brush, rectangle)
        ‘write text with actual port status for this item
        CmboItem.Graphics.DrawString( _
            My.Computer.Ports.SerialPortNames(CmboItem.Index) + » – « + status, _
            font, _
            fontbrush, _
            New  _
                    RectangleF(CmboItem.Bounds.X + rectangle.Width, _
                               CmboItem.Bounds.Y, _
                               CmboItem.Bounds.Width, _
                               CmboItem.Bounds.Height) _
        )
        ‘ Draw focus rectangle when mouse are over an item.
        CmboItem.DrawFocusRectangle()
    End Sub
End
Class