Pregunta

¿Cuál es la mejor manera de acceder a un puerto serie desde VBA?

Necesito que algunos de nuestros representantes de ventas puedan enviar una cadena simple a través del puerto serie desde un botón de acción en PowerPoint. Comúnmente no uso VBA, especialmente para algo como esto. Normalmente lo convertiría en una aplicación de algún tipo, pero en realidad no creo que la idea sea tan mala. Será una herramienta útil para ellos demo este dispositivo mientras está en un proyector y hablando con otros vendedores y personas no técnicas. Además, este vendedor no tendrá problemas para hacer pequeñas modificaciones a la presentación de VBA o PowerPoint, pero no funcionaría tan bien con la recompensa de una aplicación .NET.

Sé que podríamos hacerlo a través de un archivo por lotes que se ejecuta desde la presentación en la acción, pero eso no me hace muy feliz. Supongo que probablemente podríamos acceder a un objeto COM y correr desde allí, pero nuevamente no soy real en las últimas y mejores bibliotecas para usar en VBA, y también sería bueno obtener una pequeña introducción rápida sobre cómo abrir fácilmente, Enviar y cerrar la conexión.

Dado que esto deberá ejecutarse en las computadoras de varias personas, sería bueno si fuera fácilmente transportable a otras máquinas. Debería poder decir que tiene que ejecutarse en Office 2007 y Windows XP. Sin embargo, la compatibilidad con cualquier otra cosa sería una buena ventaja.

¿Cómo debo manejar esto? ¿Algún buen consejo o truco? ¿Recomendaciones de la biblioteca?

¿Fue útil?

Solución

La API WIN32 maneja el puerto serie como un archivo. Puede acceder a los puertos serie directamente llamando a estas funciones API desde VBA. Tuve que hacer esto para una vieja aplicación .NET, pero VBA no es diferente.

En lugar de desanimarse para usted en este sitio, aquí hay una referencia a la que he colgado a lo largo de los años. Cómo realizar comunicaciones de puertos en serie en VBA

Otros consejos

Sub Stinky()
Dim COM_Byte As Byte
Dim Received_Lines As Long
Dim Input_Buffer As String
Dim Output_Buffer As String
Dim Chars2Send As Long
Dim CharsRemaining As Long
Dim lfsr As Long
    Open "COM7:9600,N,8,1" For Random As #1 Len = 1
    Input_Buffer = ""
    CharsRemaining = 0
    Do
    Get #1, , COM_Byte
    If COM_Byte Then
        If COM_Byte = 13 Then           ' look for CR line termination
            Debug.Print Input_Buffer, Now   ' print it
            Input_Buffer = ""               ' and clear input buffer
        '   generate some output (9 characters)
            lfsr = &H3FFFFFFF - 2 ^ (Received_Lines And 15)
            Output_Buffer = "?@@@@@@@@"
            Chars2Send = 9
            CharsRemaining = 9
            For j = 0 To 2
                Mid(Output_Buffer, 2 + j, 1) = Chr(Asc(Mid(Output_Buffer, 2 + j, 1)) + (31 And Int(lfsr / 32 ^ (2 - j))))
            Next j
            Debug.Print Output_Buffer
        '   show what I generated
            Received_Lines = Received_Lines + 1 ' keep track of received line count
        Else
            Input_Buffer = Input_Buffer & Chr(COM_Byte) ' assemble output buffer
        '   process any characters to send
            If CharsRemaining Then
                CharsRemaining = CharsRemaining - 1
                COM_Byte = Asc(Mid(Output_Buffer, Chars2Send - CharsRemaining, 1))
                Put #1, , COM_Byte
            End If
        End If
    End If
    DoEvents
    Loop
    Close
End Sub

Esto funciona para mí. No estoy seguro de si el Abierto realmente establece la tasa de baudios, ya que usé Teraterm. Mi puerto COM es una conexión USB con un kit de prototipos BASYS3. Está arrojando personajes a 9600, registros de 36 caracteres que terminan con CR. Puedo enviar aleatoriamente comandos de 9 caracteres. En el código anterior, genero estas cadenas de comando cada vez que recibo una nueva línea. La forma en que elegí qué personaje enviar es un poco torpe: tal vez una mejor manera es tener un puntero de personajes y varios personajes, y cuando los igualan para establecerlos a ambos en cero.

Aquí hay un breve módulo de código VBA que puede enviar y recibir mensajes en un puerto serie de PC. Esto no es muy elegante, pero es simple y debería funcionar en versiones modernas de Excel y Windows.

Te queda solo para expandir la funcionalidad y almacenar o analizar los mensajes. Esto solo muestra las cosas de bajo nivel para lidiar con el puerto serie.

Las primeras 5 líneas declaran la función de la biblioteca "Sleep" MilliseCond (basada en la versión de Excel).

La subrutina Serialport () describe los pasos para abrir el puerto, transmitir algunos datos, recibir algunos datos, intentar nuevamente recibir algunos datos (para demostrar que realmente no se encuentra en conflicto con el error de "final del archivo") y cierre el Puerto.


#If VBA7 Then ' Excel 2010 or later
    Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal Milliseconds As LongPtr)
#Else ' Excel 2007 or earlier
    Public Declare Sub Sleep Lib "kernel32" (ByVal Milliseconds As Long)
#End If

Public Sub SerialPort()
    ' open a COM port, transmit a message, gather results, close the port.

    ' open the COM port as file #1
    Debug.Print "Open COM port 4"
    Open "COM4:115200,N,8,1" For Binary Access Read Write As #1

    transmit$ = Chr(2) + "Hello, World." + Chr(13)
    receiveDummy$ = "~~~"

    ' transmit a message
    Put #1, , transmit$
    Debug.Print "Message sent."

    ' wait a bit for a response
    Sleep 100

    ' check for received message
    Debug.Print "Look for incoming message."
    On Error Resume Next
    Do While True
        receive$ = receiveDummy$  'dummy value
        Input #1, receive$
        If receive$ = receiveDummy$ Then Exit Do  'the string didn't change, so move on
        Debug.Print receive$
    Loop
    On Error GoTo 0

    ' do it again to show that the empty input queue doesn't stop the flow
    Debug.Print "Look again for incoming message (should not stop on error)."
    On Error Resume Next
    Do While True
        receive$ = receiveDummy$  'dummy value
        Input #1, receive$
        If receive$ = receiveDummy$ Then Exit Do  'the string didn't change, so move on
        Debug.Print receive$
    Loop
    On Error GoTo 0

    ' close the serial port
    Debug.Print "Close COM port."
    Close #1

    Debug.Print "Done."
End Sub
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top