Neste artigo vamos mostrar como usar controle MSComm da Microsoft e como detectar as portas COM disponíveis.
Cada computador possui portas seriais denominadas sucessivamente : COM1 , COM2 , etc. Geralmente o mouse usa a porta COM1 o modem a porta COM2 o scanner a COM3 e assim por diante. Assim as portas seriais possibilitam um canal de transmissão de dados a partir destes dispositivos.
Se você tentar verificar a disponibilidade das portas COM de sua máquina provavelmente você irá obter o erro 8002 - Número de porta Inválida . Entretanto você pode fazer o feitiço virar contra o feiticeiro usando este erro para detectar quais portas estão disponíveis e exibir somente as portas realmente disponíveis.
Vamos então mostrar um projeto que pode ser usado para detectar as portas COM disponíveis ( deve funcionar bem no Win95/98 e NT)
1- Inicie um novo projeto no Visual Basic e no formulário padrão - form1 - insira um botão de comando - command1 , uma label - Portas COM disponíveis , e um controle ComboBox conforme abaixo:
2- Inclua um módulo no seu projeto e a seguir insira o seguinte código no módulo:
Type DCB DCBlength As Long BaudRate As Long fBitFields As Long wReserved As Integer XonLim As Integer XoffLim As Integer ByteSize As Byte Parity As Byte StopBits As Byte XonChar As Byte XoffChar As Byte ErrorChar As Byte EofChar As Byte EvtChar As Byte wReserved1 As Integer End Type Type COMMCONFIG dwSize As Long wVersion As Integer wReserved As Integer dcbx As DCB dwProviderSubType As Long dwProviderOffset As Long dwProviderSize As Long wcProviderData As Byte End Type ' Declare Function GetDefaultCommConfig Lib "kernel32" _ Alias "GetDefaultCommConfigA" (ByVal lpszName As String, _ lpCC As COMMCONFIG, lpdwSize As Long) As Long |
3- Ainda no módulo insira o seguinte código para a função DetectaPortaCOM :
Public Function DetectaPortaCOM(port As Integer) As Long 'retorna zero se a porta com não existir Dim cc As COMMCONFIG, ccsize As Long ccsize = LenB(cc) DetectaPortaCOM = GetDefaultCommConfig("COM" + Trim(Str(port)) + Chr(0), cc, ccsize) End Function |
4- Inclua o código abaixo no evento click do botão de comando - command1 :
Private Sub Command1_Click() Dim i As Integer Combo1.Clear For i = 1 To 16 If DetectaPortaCOM(i) <> 0 Then Combo1.AddItem "COM" & i End If Next Combo1.ListIndex = 0 End Sub |
Ao executar o projeto e clicar no botão para detectar as portas a combobox irá exibir as portas disponíveis. Ver figura acima.
Usando o Controle MSComm - Propriedades
A primeira coisa a
fazer para usar o controle MSComm em seu projeto e
incluir o componente no seu formulário. Clique em Project |
Components e
selecione : Microsoft Comm Control 6.0 Obs: Este controle somente esta disponível na versão Professional do VB. |
O controle MSComm fornece a interface para um conjunto de comandos de comunicação padrão : conectar com uma porta serial , conectar com outro dispositivo de comunicação , trocar dados , monitar e responder a vários eventos durante uma comunicação serial. Podemos usar o controle para realizar as seguintes tarefas:
Ao lado temos o controle MSComm sendo incluido no formulário e as propriedades que podemos configurar. |
Uma das primeiras propriedades que podemos configurar é a propriedade Settings. Esta propriedades permite configurar :
O formato da propriedade
Settings é : "BBBB,P,D,S"
Onde :
Os valores padrão para esta
propriedade é : "9600,N,8,1"
Se a propriedade for configurada com valores inválidos , ao tentar abrir uma porta COM iremos obter o erro : 380 - Invalid Property value
Para usar o controle MSComm e estabelecer uma comunicação com uma porta serial usamos as seguintes propriedades:
Propriedade | Descrição |
CommPort | Define e retorna o número a porta de comunicação |
Settings | Define e retorna : baud rate, parity, data bits, e stop bits como uma string |
PortOpen | Define e retorna o estado da porta de comunicação. Também abre e fecha a porta. |
Vejamos um exemplo de código para realizar esta tarefa:
'Abre a porta serial
MSComm1.CommPort = 2 MSComm1.Settings = "9600,N,8,1" MSComm1.PortOpen = True
Como funciona:
Podemos configura estas propriedades em tempo de projeto clicando em Custom na janela de propriedades do controle e definindo os valores na janela Property Pages . |
Usando um Modem
Podemos usar o controle MSComm com um modem através dos comandos compatíveis com o padrão Hayes; tanto para discar um número de telefone como para efetuar uma conexão com outro modem.
Apos definir as propriedades CommPort, Settings e PortOpen para estabelecer a conexão , usamos a propriedade Output para ativar e interagir com o modem. Exemplo:
MSComm1.Output = "ATDT 235-4545" & vbCr
Onde :
Nota: Os comandos Hayes são padronizados e permitem que o programa de comunicação controle as funções do modem. Porém, nem todos os modems compatíveis com o padrão Hayes (hoje, maioria absoluta) aceitam todos os comandos, e alguns possuem comandos especiais. O manual do modem deve conter essas informações e também os valores default (pré-configurados na fábrica).
Os comandos são dados a partir do programa de comunicação, em modo terminal, ou já estão embutidos no próprio soft de comunicação. Normalmente, começam com os caracteres AT, que fazem o modem prestar atenção ao que é comandado a seguir, podem ter (conforme o modem) de 40 a 255 caracteres na linha de comando e terminam, como qualquer comando em computador, com o sinal <CR> (Carriage Return - sinal obtido quando se pressiona a tecla [Enter] ou [Return] - em código <CR> equivale a usar CHR$(13) ou vbcr)
Lista de comandos Hayes
Os comandos Hayes são enviados na forma AT[primeiro comando] [segundo comando] [terceiro comando etc.] [Enter/Return].
AT é o código de atenção, usado no início de cada linha de comando, tenha ela um ou mais comandos Hayes. Apenas o comando [A/] não usa o código de atenção, e serve para repetir o último comando executado. A seguir uma lista dos principais comandos Hayes :
Comando Hayes | Descrição |
A | conecta em modo de resposta |
Dx | Discar (Dial) ; onde x pode assumir P(Pulso) , T(Tom) , R (modo de resposta) , W (espera por tom de discar) |
Ex | Ecoa ou não os caracteres para o micro em modo local , onde o x pode assumir : 0 ( retira o eco) ou 1 (inclui o eco) |
Hx | Controla a conexão do modem. O x pode assumir: 0 (desconecta) ou 1 (conecta) |
Vx | Formato de resposta, onde x pode ser : 0 (formato numérico) ou 1 (formato texto) |
Z | Reseta o modem. |
Ex: ATZ - reseta o modem , ATA - coloca o modem em estado de resposta , ATH0 - Desconecta o modem.
Alocação do Buffer de Memória
Quando uma porta é aberta , são criados buffers para transmitir e receber dados. Para gerenciar estes buffers podemos usar a janela de Property Pages clicando em Custom na janela de propriedades do controle. |
As propriedades InBufferSize e OutBufferSize definem quanto de memória é alocado para receber e transmitir buffers. ( armazenam os dados de chegada e de saida). Quanto maior o valor usado , menor a memória disponível para sua aplicação. Se o valor for muito pequeno você corre o risco de um transbordamento de buffer a menos que você use Handshaking. Atualmente , devido a quantidade de memória dos computadores , podemos usar valores maiores para alocar memória.
As propriedades RThreshold e SThreshold
As propriedades RThreshold e SThreshold ajustam ou retornam o número de caracteres que são recebidos nos buffers de transmissão e recepção antes que o evento OnComm seja disparado.
O evento OnComm é usado para monitorar e responder ás mudanças no estado da comunicação. Se cada propriedade for definida com o valor 0 ( este é o padrão ) evita que o evento OnComm seja disparado. Qualquer outro valor diferente de zero fará com que o evento OnComm seja disparado sempre que um caractere for recebido no buffer.
As propriedades InputLen e EOFEnable
Definir a propriedade InputLen com o valor 0 faz com que o controle leia todo o conteúdo do buffer de recepção quando usamos a propriedade Input . Ao ler dados de uma máquina cuja saída esta formatada para blocos de dados de tamanho de comprimento fixo podemos ajustar o valor desta propriedade de forma correta.
A propriedade EOFEnable é usada para indicar quando um caracter de fim de arquivo ( End of File) for encontrado duranta uma entrada de dados. Definir esta propriedade como True faz com que a entrada de dados pare e o evento OnComm seja disparado para informar a condição acabou de ocorrer.
Gerenciando os buffers de transmissão e recepção
Quando uma porta é aberta os buffers de transmissão e recepção de dados são criados . Eles são usados para receber os dados que chegam e transmitir os dados que saem. O controle MSComm permite gerenciar estes buffers através de propriedades que permitem receber e transmitir dados , determinar o tamanho de cada buffer e manipular dados do tipo teto e dados do tipo binário.
O buffer de recepção
A propriedade Input é usada para armazenar e retornar dados de um buffer de recepção. Assim se você que receber dados de um buffer de recepção e exibí-los em uma caixa de texto ( text1.text ) pode usar o seguinte código:
Text1.text = MSComm1.Input
Se quiser receber e exibir todo o conteúdo do buffer deve definir a propriedade InputLen com valor 0 .
Para receber dados no formato Texto ou Binario você deve definir a propriedade InputMode para um dos seguintes valores : comInputModeText (dados no formato ANSI) ou comInputModeBinary(dados que contenham caracteres de controles , Nulls ,etc..)
Cada byte de dados recebido é movido para o buffer de recepção e a propriedade InBufferCount é incrementada de um ; assim podemos usar a propriedade InBufferCount para retornar o numero total de bytes no buffer de recepção. Para limpar o buffer de recepção definimos o valor desta propriedade para o valor igual a 0.
O buffer de transmissão
A propriedade Output é usada para enviar comandos e dados para o buffer de transmissão.
Da mesma forma que a propriedade Input , os dados podem ser enviados no formato Texto ou Binário. Podemos enviar comandos , tetos , ou uma matriz de dados : Veja o código exemplo a seguir:
Dim Out as byte
' Envia um comando AT
MSComm1.Output = "ATDT 555-5555"
' Envia uma string
MsComm1.Output = "Estou enviando uma string"
' Enviando uma matriz de dados
MSComm1.Output = Out
Ao final de uma linha de dados devemos usar o caracter de retorno - vbCr .
Para monitorar o buffer de transmissão usamos a propriedade OutBufferCount. Definindo o valor desta propriedade como igual a zero limparemos o buffer de transmissão.
Agora um exemplo prático
Vamos aplicar toda a teoria vista acima em um exemplo prático. Vamos criar um projeto para discar um número telefônico usando um modem.
1- Inicie um novo projeto no VB e no formulário padrão insira uma caixa de texto - text1.text
2- Faça uma referência ao componente MSComm - MSComm1 - no seu projeto - Microsoft Comm Control 6.0 ( MSCOMM32.ocx)
3- Inicialmente vamos configurar as seguintes propriedades do controle MSComm1 :
Propriedade | Valor |
RThreshold | 1 |
SThreshold | 1 |
InputLen | 0 |
ComPort | A porta do seu modem |
- AT diz ao modem que um comando esta chegando
- DT informa para discar o número usando a discagem de tom. Veja abaixo o código:
Private Sub Command1_Click() MSComm1.PortOpen = True MSComm1.Output = "ATDT" & text1.Text & Chr$(13) End Sub |
Obs: precisamos incluir o codigo de controle CHR$(13) depois do comando. O número a ser discado deverá ser informado na caixa de texto - text1.text.
Como vamos ter certeza de que a discagem ocorreu com sucesso ??? Para isto vamos usar o evento OnComm.
Usamos o evento OnComm para verificar se os dados estão sendo recebidos. Para receber os dados checamos a propriedade Input , ocorre que os dados ficam por pouco segundos na propriedade Input. Aí é que entra o evento OnComm .
Para disparar o evento configuramos as propriedades RThreshold e SThreshold com valor igual a 1. Para obter o resultado de um comando enviado para o modem vamos usar o seguinte código no evento OnComm:
Private Sub MSComm1_OnComm() Select Case MSComm1.CommEvent 'mensagens dos eventos Case comEvReceive Text1.Text = Text1.Text & StrConv(MSComm1.Input, vbUnicode) End Select End Sub |
Este código verifica qual evento ocorreu e se o for o evento Receive o conteúdo da propriedade Input é adicionada ao final da caixa de texto:
Podemos usar o evento OnComm também para monitorar erros durante a comunicação. Vejamos a seguir uma tabela com as constantes que podem ocorrer quando o evento OnComm ocorre.
Constante | Valor | Descrição |
comEvSend | 1 | Numeros de caracteres no buffer de transmissão menor que RThreshold. |
comEvReceive | 2 | Recebendo RThreshold número de caracteres. |
comEvCTS | 3 | Alteraçao em Clear To Send line. |
comEvDSR | 4 | Alteração na linha Data Set Ready. |
comEvCD | 5 | Alteração em Carrier Detect line. |
comEvRing | 6 | Chamado detectado. Alguns UARTs (universal asynchronous receiver-transmitters) podem não suportar este evento. |
comEvEOF | 7 | Fim de arquivo (ASCII character 26) |
Para encerrar o artigo vamos mostrar um projeto onde usamos as propriedades e eventos do controle MSComm discutidas.
1-) inicie um novo projeto no VB e no formulário padrão insira os controles conforme o layout abaixo:
Private Sub Form_Load() Dim i As Integer Dim sSettings As String sSettings = MSComm1.Settings cboBaubRate.Text = Left$(sSettings, 4) cboParity.Text = Mid$(sSettings, 6, 1) cboDataBits.Text = Mid$(sSettings, 8, 1) cboStopBits.Text = Mid$(sSettings, 10, 1) cboCommand.ListIndex = 0 '// obtem porta com Show DoEvents ListaPortasCom End Sub |
Como podemos ver na carga do formulário , no evento Load , obtemos os valores da propriedade Settings e preenchemos as caixas de combinação extraindo os valores pertinentes a cada propriedade.
A seguir usamos a função ListaPortasCom para detectar e listar as portas COM disponíveis. A função é exibida a seguir:
Private Sub ListaPortasCom() Dim i As Integer cboComm.Clear SetStatus "Verificando as portas disponíveis...", True For i = 1 To 16 If DetectaPortaCOM(i) Then cboComm.AddItem i SetStatus "COM" & i & " encontrada", False End If Next cboComm.ListIndex = 0 End Sub |
Abaixo a tela de exibição do projeto:
A função DetectaPortaCOM foi discutida no inicio do artigo. O resto do código é trivial. Para fazer o download do projeto clique aqui : Exemplo de utilização do MSComm - Mscom.zip
José Carlos Macoratti