Pergunta

Qual é a melhor maneira de acessar uma porta serial da VBA?

Tenho necessidade de alguns de nossos representantes de vendas poderem enviar uma string simples pela porta serial a partir de um botão de ação no PowerPoint. Eu geralmente não uso o VBA, especialmente para algo assim. Normalmente, eu o transformava em uma aplicação de algum tipo, mas na verdade não acho que a ideia seja tão ruim assim. Será uma ferramenta útil para eles demonstrarem este dispositivo com um projetor e conversando com outros vendedores e pessoas não técnicas. Além disso, esse vendedor não terá nenhum problema em fazer pequenas modificações na apresentação do VBA ou do PowerPoint, mas não se sairia tão bem ao recompilar um aplicativo .NET.

Eu sei que poderíamos fazer isso através de um arquivo em lote executado da apresentação sobre a ação, mas isso não me deixa muito feliz. Eu acho que provavelmente poderíamos acessar um objeto COM e correr a partir daí, mas novamente não sou real nas melhores e mais recentes bibliotecas a serem usadas no VBA, e também seria bom obter um pequeno primer rápido em como abrir facilmente, Envie e feche a conexão.

Como isso precisará ser executado em computadores de várias pessoas, seria bom se fosse facilmente transportável para outras máquinas. Devo ser capaz de dizer que tem que ser executado no Office 2007 e no Windows XP. A compatibilidade com qualquer outra coisa seria um bom bônus.

Como devo lidar com isso? Alguma boa dica ou truques? Recomendações da biblioteca?

Foi útil?

Solução

A API Win32 lida com a porta serial como um arquivo. Você pode acessar as portas seriais diretamente chamando essas funções da API de dentro do VBA. Eu tive que fazer isso para um aplicativo .NET antigo, mas o VBA não é diferente.

Em vez de sair para você neste site, aqui está uma referência em que me apeguei ao longo dos anos. Como realizar comunicações portuárias em série em VBA

Outras dicas

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

Isso funciona para mim. Não tenho certeza se o Open realmente configura a taxa de transmissão, como usei o Teraterm pela primeira vez. Minha porta COM é uma conexão USB com um kit de prototipagem Basys3. Está vomitando caracteres em 9600, registros de 36 caracteres terminando com CR. Eu posso enviar aleatoriamente comandos de 9 caracteres. No código acima, eu gero essas seqüências de comando toda vez que recebi uma nova linha. A maneira como escolhi qual personagem enviar é um pouco desajeitado: talvez uma maneira melhor seja ter um ponteiro de personagem e vários caracteres, e quando esses são iguais para definir os dois a zero.

Here is a brief module of VBA code that can send and receive messages on a PC serial port. This is not very elegant, but it is simple and should work on modern versions of Excel and Windows.

You are left on your own to expand the functionality and store or parse the messages. This just shows the low-level stuff to deal with the serial port.

The first 5 lines declare the millisecond "Sleep" library function (based on Excel version).

The SerialPort() subroutine outlines the steps to open the port, transmit some data, receive some data, try again to receive some data (to show that it really does not run afoul of the "end of file" error), and close the port.


#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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top