implementação do projeto mpeu com ms-visual studiomodbus a cliente_1 mosquitto cliente_2 publica...
TRANSCRIPT
Implementação do projeto MPEU com MS-Visual Studio
MODBUS
PU
BLI
CA
CLIENTE_1
MOSQUITTO CLIENTE_2
PUBLICA
ASSINA
projeto MPEU
PROGRAMANDO EM VISUAL BASIC NO MS-VISUAL STUDIO
•Baseada em elementos gráficos (controles) e, atualmente, com recursos para programação orientada por objetos
•Possibilita o desenvolvimento de aplicativos para Windows com baixo custo e tempo
•Teve início com um IDE (Integrated Development Environment) dedicado: VB 3.0; VB 4.4; VB5.0 e VB6.0
•Em 2001, com o lançamento da plataforma .NET Framework , a Microsof lançou o Visual Studio com sendo o novo IDE para programação em VB, C++, C# e outros.
•A partir de 2010 a Microsoft lançou um versão gratuita do Visual Studio e foi denominada com Visual Studio Express e atualmente é conhecida como Community e já está na versão 2019.
INICIANDO UM PROJETO EM VISUAL BASIC. .NET Versão Community 2017
A versão atual do Visual Basic possibilita, além de aplicativos baseados em formulários, a criação de versões do tipo console, biblioteca de classes e as WPF (Microsoft Windows Presentation Foundation )
Selecione a opção “Aplicativo do Windows Forms” Crie uma pasta específica para armazenar o projeto. Dê um nome para o mesmo e acione o botão “OK” . Evite manter o nome genérico para o projeto, tal como “windowsApp1”.
Um formulário funciona como um pano de fundo para inserção dos controles que serão visíveis em tempo de execução.
Após acionar o botão “OK” aparece (automaticamente) um formulário vazio; o “Gerenciado de Soluções” ; a “caixa de ferramentas” ; a”lista de propriedades”;...
Leiaute do IDE para aplicativos do tipo Windows Forms
Mude o nome do formulário de Form1 para , por exemplo, MAQUINAS.
Para adicionar um controle ao formulário Arraste-o e solte-o no local desejado ou execute um “duplo click” sobre ele.
Alterando propriedades do formulário principal e incluindo controles
A parte seguinte desta apostila foi retirada da apostila anterior (programando em Visual Basic 2010) disponível em :
http://www.labusig.ufpr.br/cnc/apst_VB_2010_express.pdf ou
http://www.labusig.ufpr.br/cnc/apst_VB_2010_express.pptx
A apostila 2010 aborda o seguinte :
•Montagem do leiaute com controles de texto e rótulos para entrada e saída de dados
•Tipos e declarações de variáveis
•Operadores
•Atribuição de valores
•Manipulação de strings
•Iterações
•Condicionais
•Arquivos (leitura e gravação)
•Controles para leitura e gravação de dados em arquivos
•Funções e sub-rotinas
Além dos slides da apostila anterior, foram acrescentados os seguintes
tópicos: • Inclusão de pacotes • Inclusão de Referências • Inclusão de classes • Criação do aplicativo “MAQUINAS” para publicação de mensagens no Broker Mosquitto • Criação do aplicativo “NUVEM” para assinatura e recebimento de mensagens enviadas pelo aplicativo “MAQUINAS” por meio do Broker Mosquitto • Interfaceamento do aplicativo “MAQUINAS” com a rede Fieldbus do Laboratório de Usiangem * Monitoramento do torno CNC e sua publicação em nuvem
Inclusão de pacotes do NuGet em projetos MS-Visual Basic
Pacotes contêm classes que podem ser utilizadas em outros aplicativos
Inclusão do pacote M2Mqtt desenvolvido por Paulo Patierno para establecer as conexões para publicação e assinatura no
broker Mosquitto
Após a inclusão do pacote M2Mqtt acerte o leiaute do formulário principal, tal como sugerido abaixo
Group box
TextBox
label Button
Controle Nome
Texbox1 TbTpcPub
Texbox2 TbMsgPub
Button1 BtPub
Button2 BtFim
Renomeie os seguintes controles :
Altere a propriedade text dos labels
Mude cores e fontes de acordo com o seu interesse
Dê um “duplo click” na área interna do formulário principal e inclua as classes utilizando o comando “imports”
'classes do pacote M2Mqtt Imports uPLibrary.Networking.M2Mqtt Imports uPLibrary.Networking.M2Mqtt.Messages 'classe para tratamento de texto: Imports System.Text
Estas classes devem ser incluídas antes do formulário principal (classe MAQUINAS)
Dê um “duplo click” na área interna do formulário principal para abrir e editar o evento “Load”. Declare as
variáveis “client” e “clientId” antes do evento “Load”
Dim client As MqttClient Dim clientId As String
Inclua o código para estabelecer a conexão com o broker no evento “Load”
Private Sub MAQUINAS_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'CÓDIGO PARA CONEXÃO COM O BROKER MOSQUITTO - DESENVOLVIDO POR PAULO PATIERNO 'Dim BrokerAddress As String = "85.119.83.194" 'ENDEREÇO ALTERNATIVO Dim BrokerAddress As String = "test.mosquitto.org" client = New MqttClient(BrokerAddress) ' // GERA UM IDENTIFICADOR ÚNICO PARA CLIENTE A CADA INÍCIO DO APLICATIVO MAQUINAS clientId = Guid.NewGuid().ToString() client.Connect(clientId) End Sub
Dê um “duplo click” no botão “PUBLICA” para abrir e editar o evento “click”. Inclua o código para publicação das mensagens
nos tópicos que serão digitados em tempo de execução nos controles de texto
If (TbTpcPub.Text <> "") Then '' // whole topic Dim Topic As String = "/ElektorMyJourneyIoT/" + TbTpcPub.Text + "/test" '' // publish a message with QoS 2 client.Publish(Topic, Encoding.UTF8.GetBytes(TbMsgPub.Text), MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE, True) Else MessageBox.Show("Vc tem que informar o tópico a ser publicado!") End If
Dê um “duplo click” no botão “ENCERRA” para abrir e editar o evento “click”. Inclua o código para desconexão
com o broker e encerramento do aplicativo
'desconecta do broker client.Disconnect() 'fecha aplicativo End
Esses dois últimos eventos devem ficar assim....
Compile o projeto para verificar inconsistências “aperte a tecla F5”
A tela final deve ficar assim....
Click no botão “ENCERRA” e feche o aplicativo. Ele será testado mais tarde
Repita os passos anteriores para iniciar o novo aplicativo. Se quiser, dê o nome de sua preferência para ele e o formulário
principal e monte os controle conforme o leiaute sugerido abaixo
Controle Nome
Texbox1 TbTpcAsnd
Texbox2 TbMsgRcb
Button1 BtAsnd
Button2 BtFim
Renomeie os seguintes controles :
Altere a propriedade text dos labels
Mude cores e fontes de acordo com o seu interesse
Inclua o pacote M2Mqtt e importe as suas classes para dentro do aplicativo, conforme mostrado nos
slides anteriores
O evento “Load” deverá ser programado conforme abaixo:
Private Sub Nuvem_Load(sender As Object, e As EventArgs) Handles MyBase.Load 'PROGRAMA DESENVOLVIDO POR PAULO PATIERNO 'Dim BrokerAddress As String = "85.119.83.194"'ENDEREÇO AUXILIAR Dim BrokerAddress As String = "test.mosquitto.org" client = New MqttClient(BrokerAddress) 'cria uma gerenciamento do HANDLER ... PARA RECEBER AS MENSAGENS DISPARADAS 'UM EVENTO DO BROKER SERÁ PROCESSADO AUTOMATICAMENTE 'VEJA DEFINIÇÃO EM: https://docs.microsoft.com/pt-br/dotnet/visual-basic/language-reference/statements/addhandler-statement AddHandler client.MqttMsgPublishReceived, AddressOf client_MqttMsgPublishReceived Application.DoEvents() ' // usa um identificador único toda vez que iniciar este aplicativo clientId = Guid.NewGuid().ToString() client.Connect(clientId) End Sub
Crie uma rotina nova (Sub) abaixo do evento “Load” nomeando-a por “client_MqttMsgPublishReceived” e insira o
código abaixo:
Sub client_MqttMsgPublishReceived(sender As Object, e As MqttMsgPublishEventArgs) Dim ReceivedMessage As String = Encoding.UTF8.GetString(e.Message) 'tem que testar se existem linhas( trheads) separadas 'vide exemplo em: https://dotnetbrowser.support.teamdev.com/support/solutions/articles/9000119178--cross-thread-operation-not-valid-control-accessed-from-a-thread-other-than-the-thread-it-was-create If Me.TbMsgRcb.InvokeRequired Then BeginInvoke(Sub() Me.TbMsgRcb.Text = ReceivedMessage End Sub) Else Me.TbMsgRcb.Text = ReceivedMessage End If End Sub
Programe o evento “Click” do botão “ASSINA TÓPICO” conforme código abaixo
If (TbTpcAsnd.Text <> "") Then '// todo o tópico:::??? Dim Topic(0) As String Topic(0) = "/ElektorMyJourneyIoT/" + TbTpcAsnd.Text + "/test" Dim Qs(0) As Byte Qs(0) = 2 ' // assina o tópico com QoS 2 client.Subscribe(Topic, Qs) Me.TbMsgRcb.Text = "" Else MessageBox.Show("Vc deve entrar o nome do tópico para assinar!") End If
Programe o evento “Click” do botão “ENCERRA” conforme código abaixo
Dim Topic(0) As String Topic(0) = "/ElektorMyJourneyIoT/" + Me.TbTpcAsnd.Text + "/test" client.Unsubscribe(Topic) client.Disconnect() End
Compile o projeto para verificar inconsistências “aperte a tecla F5”
A tela final deve ficar assim....
Abra o projeto anterior “MAQUINAS” e faça um teste para verificar se a comunicação com o broker Mosquitto está funcionando
De volta ao primeiro projeto “MAQUINAS” ....
Abra o projeto com o Visual Studio e insira o
pacote “KONECT-V19.dll” como uma
referência
Baixe o pacote “KONECT-V19.dll” no link: E armazene-o na pasta do projeto “MAQUINAS”
Após selecionado, o pacote “KONECT-V19” Deverá aparecer na lista de Referencias do GERENCIADOR DE SOLUÇÕES
Inserindo referências em projetos do Visual Basic
Pressione “OK” para confirmar a inserção da Referência
Algumas informações sobre a classe KONECT...
Medidor
Konect CRC
SerialPort ConstKron
EltPar
Notação UML
Algumas informações sobre a classe KONECT...
Medidor
EndMed: Byte ArqSd: String SrPort: SerialPort StatusMd: Byte Grnd(): Eltpar() TmpInc: Float LstGrv: String ConstProj: ConstKron ReadGrnd(): Boolean Readstatus(): As Byte SetGrndZ()
Algumas informações sobre a classe KONECT...
Konect
Lfunc: Byte Crcerro: Byte RegIni: Integer QtReg: FrameRiR: RcbDados:
ReadGrnd(): Boolean Readstatus(): Byte SetGrndZ() MntFrame() Leitura(): Boolean
Índices das grandezas medidas conforme definido no método SetGrndZ
ÍNDICE NOME UNIDADE DIMENSIONAL
0 Tensão trifásica W
1 Tensão linha 1 V
2 Tensão linha 2 V
3 Tensão linha 3 V
4 Tensão fase/fase (A-B) V
5 Tensão fase/fase (B-C) V
6 Tensão fase/fase (C-A) V
7 Corrente trifásica A
8 Corrente de neutro A
9 Corrente de linha 1 A
10 Corrente de linha 2 A
11 Corrente de linha 3 A
12 Frequência linha 1 Hz
13 Frequência linha 2 Hz
14 Frequência linha 3 Hz
15 Frequência Hz
16 Potência ativa trifásica W
17 Potência ativa linha 1 W
18 Potência ativa linha 2 W
19 Potência ativa linha 3 W
20 Potência reativa trifásica VAr
21 Potência reativa linha 1 VAr
22 Potência reativa linha 2 VAr
23 Potência reativa linha 3 VAr
24 Potência aparente trifásica VA
25 Potência aparente linha 1 VA
26 Potência aparente linha 2 VA
27 Potência aparente linha 3 VA
28 Fator de potência trifásico
29 Fator de potência linha 1
30 Fator de potência linha 2
31 Fator de potência linha 3
Índice Nome Unidade
dimensional
32 ENERGIA ATIVA POSITIVA kWh
33 ENERGIA REATIVA POSITIVA kVAr
34 ENERGIA ATIVA NEGATIVA KWh
35 ENERGIA REATIVA NEGATIVA kVAr
BLOCO I
BLOCO II
De volta ao projeto “Maquinas” – cliente 1
Selecione o controle “GroupBox1” referente ao “PUBLICADOR-PROVISÓRIO” e mude as propriedades ENABLE e VISIBLE para FALSE isto irá desabilitar e esconder, em tempo de execução, todos os controles agrupados por ele.
De volta ao projeto “Maquinas” – cliente 1
Modifique o leiaute do formulário principal incluindo os controles montados acima
De volta ao projeto “Maquinas” – cliente 1 ajuste as propriedades dos controles como indicado na tabela abaixo
CONTROLE TEXTO/FUNÇÃO NAME ENABLED
ComboBox Lista de portas
seriais
Cb1
TRUE
GroupBox
Instrumentos
disponíveis na
rede
Gb1
Monitora usinagem Gb2
NumericUpDown Endereços dos
medidores
NupD1
TextBox
Máquina Tb3
Situação Tb4
Duração Tdm
Tópico Tb2
Button
Encerra BtFim
Monitora BtLab FALSE
OBS.: LABELS NÃO PRECISAM SER ALTERADOS
Dê um “duplo click” na área interna do formulário principal e atualize as classes utilizando o comando “imports”
Estas classes devem ser incluídas antes do formulário principal (classe MAQUINAS)
'classes do pacote M2Mqtt
Imports uPLibrary.Networking.M2Mqtt
Imports uPLibrary.Networking.M2Mqtt.Messages
'classe para tratamento de texto:
Imports System.Text
'porta serial RS232
Imports System.IO.Ports
'Controle da formatação de números:
Imports System.Threading
Imports System.Globalization
Dim client As MqttClient 'CLASSE DO PACOTE M2MQTT
Dim clientId As String 'IDENTIFICADOR TIPO "ADRESS" DO CLIENTE
Public RS232 As New SerialPort 'CLASSE REFERENTE À PORTA SERIAL TIPO RS232
Public InstrMt As New KONECT_V19.KONECT ' DEFINE OBJETO DA CLASSE KONECT
Public EndInstr As Byte = 2 'endereço do instrumento (medidor) conforme cadastro na rede Fieldbus - 2 É VALOR DEFAULT DO TORNO CNC
Public FlgPar As Boolean = False 'flag que habilita execução automática de alguns eventos
Continue com o código do formulário principal aberto e atualize a declaração de variáveis da classe principal
(formulário)
Estas variáveis devem ser incluídas antes do evento LOAD do formulário principal (classe MAQUINAS)
No menu principal, selecione “Projeto” e depois “Adicionar módulo”
renomeie-o para “TestFieldbus” e pressione o botão “OK”
Dentro do editor do módulo (vide figura abaixo) inclua o código para teste do “status” dos instrumentos, tal como disponível no link:
http://www.labusig.ufpr.br/Mnf_INT/func-readStatus.txt
Dê um “duplo click” no controle NumericUpDown (NupD1) e inclua o seguinte código entre “Private Sub NupD1_ValueChanged(sender As Object, e As EventArgs) Handles
NupD1.ValueChanged” e “End Sub”
EndInstr = NupD1.Value
Select Case EndInstr
'segue cadastro já realizado na rede Fieldbus do Lab. Usinagem
Case 1 'menor valor
'medidor MKM
Tb3.Text = "TORNO CONVENCIONAL"
Case 2
'medidor KONECT
Tb3.Text = "TORNO MAZAK"
Case 3
'medidor KONECT
Tb3.Text = "CENTRO DE USINAGEM DISCOVERY"
Case Else
'medidor NÃO EXISTE AINDA
Tb3.Text = "MEDIDOR NÃO CADASTRADO NA REDE"
Tb4.Text = "INSTRUMENTO DESLIGADO"
BtLab.Enabled = False 'DESABILITA BOTÃO DA LEITURA
Exit Sub 'PUXA TOMADA!!!
End Select
If FlgPar Then ' todos os parâmentos do instrumentos já foram carregados
If Ligado(EndInstr, InstrMt) Then
Tb4.Text = "INSTRUMENTO LIGADO"
BtLab.Enabled = True 'HABILITA BOTÃO PARA INÍCIO DA LEITURA
Else
Tb4.Text = "INSTRUMENTO DESLIGADO"
BtLab.Enabled = False 'DESABILITA BOTÃO DA LEITURA
End If
End If
Dê um “duplo click” no controle Button (BtLab) e inclua o seguinte código entre “Private Sub BtLab_Click(sender As Object, e As EventArgs) Handles BtLab.Click” e “End Sub”
'DISPARA EVENTO PARA LER, PELA PORTA SERIAL RS232, OS VALORES ENVIADOS PELO MEDIDOR SELECIONADO
Dim msgBPS As String = "" 'TROCA MENSAGENS COM USUÁRIO
Dim TmpL As Single = CSng(Tdm.Text) 'duração do monitoramento em segundos, conforme valor digitado pelo usuário
'Define valores necessários para a configuração do instrumento
'Isto poderia ficar em um arquivo de texto do tipo "Config", mas vamos deixá-lo aqui
'por facilidade
Const Ng As Short = 35 '36 grandezas no KONECT, contando desde ZERO
ReDim InstrMt.Grnd(Ng)
'3:DEFINE ENDEREÇO DO MEDIDOR; PORTA SERIAL PARA COMUNICAÇÃO E PREFIXO PARA GRAVAÇÃO
InstrMt.EndMd = EndInstr 'esse endereço será definido pelo usuário em tempo de execução
'MAS É POSSIVEL MODIFICAR ESSA ROTINA PARA LEITURA EM TODA A REDE FIELDBUS
' DEFINE ENDEREÇO DOS REGISTROS DAS GRANDEZAS A SEREM LIDAS; OPÇÃO DE GRAVAÇÃO E OPÇÃO DE VISUALIZAÇÃO
Dim id As Short = 0 'eneumerador
' os endereços das grandezas estão ordenados sequencialmente, contando de dois em dois
' e divididos em dois blocos. Maiores detalhes vide protocolo MODBUS-KONECT Rev. 1.2 de Dezembro/2015
'BLOCO 1:
For id = 0 To 31
'inicializa objeto
InstrMt.Grnd(id) = New KONECT_V19.EltPar
'acerta endereços
InstrMt.Grnd(id).EndReg = 30003 + 2 * id
'redimensiona array da leitura
ReDim InstrMt.Grnd(id).Regs(3)
'cancela opção para gravação
InstrMt.Grnd(id).FlagGrv = False
Next
'BLOCO 2:
For id = 32 To 35
'inicializa objeto
InstrMt.Grnd(id) = New KONECT_V19.EltPar
'acerta endereços - incia com '30.201
InstrMt.Grnd(id).EndReg = 30199 + 2 * id
'redimensiona array da leitura
ReDim InstrMt.Grnd(id).Regs(3)
'cancela opção para gravação
InstrMt.Grnd(id).FlagGrv = False
Next
'################################
'ENTRA EM LOOP PARA LEITURA ENVIO DE DADAOS PARA O MOSQUITTO (28/09/19)
'TESTA SE DURAÇÃO PARA MONITORAMENTO É VÁLIDA::
InstrMt.TmpInc = Date.Now.TimeOfDay.TotalSeconds 'AJUSTA RELÓGIO...
Dim AtlTime As Double = Date.Now.TimeOfDay.TotalSeconds 'TEMPO ATUAL
Dim Topic As String = "/ElektorMyJourneyIoT/" + Tb2.Text + "/test"
' Dim Qs(1) As Byte
Do While (AtlTime - InstrMt.TmpInc) <= TmpL
If InstrMt.ReadGrnd() Then
'###EM TESTE - PUBLICA APENAS O VALOR DA POTÊNCIA
msgBPS = Tb3.Text & "//" & InstrMt.Grnd(16).VlrDec
'' // PUBLICA UMA MENSAGEM COM QoS 2
client.Publish(Topic, Encoding.UTF8.GetBytes(msgBPS), MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE, True)
End If
AtlTime = Date.Now.TimeOfDay.TotalSeconds
Loop
'FIM DAS LEITURAS:::
client.Publish(Topic, Encoding.UTF8.GetBytes("FIM DAS LEITURAS"), MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE, True)
Dê um “duplo click” no formulário principal e atualize o código do evento “LOAD”
Dê um “duplo click” no formulário principal e inclua a sub-rotina “LoadSpar” referente à configuração da porta serial
Sub LoadSpar() Dim msgBPS As String = "" 'acertando separador decimal... Dim sep As New System.Globalization.NumberFormatInfo If NumberFormatInfo.CurrentInfo.NumberDecimalSeparator = "," Then 'troca para ponto Thread.CurrentThread.CurrentCulture = New CultureInfo("en-us") NumberFormatInfo.CurrentInfo.NumberDecimalSeparator = "." End If 'define parametros comunicação serial Dim LstPort() As String = System.IO.Ports.SerialPort.GetPortNames If LstPort.Length > 0 Then 'LISTA PORTAS SERIAIS TIPO RS-232 DISPONÍVIEIS NO MICRO 'ISTO SERÁ APENAS PARA VISUALIZAÇÃO, POIS A POSSIBILIDADE DE ALTERAR A PORTA NÃO SERÁ 'IMPLEMENTADA AGORA Cb1.Items.AddRange(LstPort) 'INCLUI LISTA NO CONTROLE TIPO "COMBOBOX" Cb1.Sorted = True 'ARRANJA EM ORDEM ALFABÉTICA Cb1.SelectedIndex = 0 'apresenta primeira porta como alternativa 'verifica EXISTE UMA PORTA aberta/fechada If Not RS232.IsOpen Then 'porta fechada, então abre RS232.PortName = "COM1" 'SERÁ MANTIDA COMO CONSTANTE, POIS SÓ EXISTE 'UM CONVERSOR DO TIPO RS232//RS485. E ELE ESTÁMONTADO NA PORTA 1 RS232.Open() Else 'porta aberta (pouco provável, mas pode acontecer) msgBPS = "A PORTA SERIAL " & RS232.PortName & " ESTÁ OCUPADA. CONTINUA MESMO ASSIM?!!" If MsgBox(msgBPS, vbYesNo, "MPEU") = MsgBoxResult.No Then 'ENCERRA.. End End If End If ElseIf (MsgBox("ESTE COMPUTADOR NÃO POSSUI PORTA SERIAL! CONTINUA?", vbYesNo, "MPEU") = MsgBoxResult.No) Then 'ENCERRA... End Else '... End If 'SE CHEGOU AQUI: ACERTA CONFIGURAÇÃO DA PORTA '1: opções para configuração da porta serial 'EXISTE A POSSIBILIDADE DE DEIXAR OS PARÂMETROS DA PORTA SERIAL COMO VARIÁVIES 'O QUE POSSIBILITA AO USUÁRIO FINAL MODIFICÁ-LOS PARA FINS DE TESTES 'ENTRETANTO, AGORA ELES SERÁ FIXADOS EM TEMPO DE PROJETO RS232.DataBits = 8 'TAMANHO DO BYTE DE DADOS RS232.Parity = Parity.None 'SEM CONTROLE DE PARIDADE RS232.StopBits = 2 'SEGUE O FORMATO 8N2 RS232.BaudRate = 57600 '- DEVE SER ESTA TAXA PARA EFETUAR A TRANSFERÊNCIA "EM MASSA" DOS REGISTROS RS232.Handshake = Handshake.None 'ISTO INTERFERE DEVE SER "NONE" (OBRIGATORIAMENTE) InstrMt.SrPort = RS232 'TRANSFERE PARÂMETROS DA PORTA SERIAL End Sub
Compile o código criado – tecle F5 e verifique possíveis erros. Mude o endereço do instrumento para 2 e veja o que acontece...
A tela de abertura será semelhante à imagem abaixo. O TESTE FINAL SERÁ FEITO NO LABORATÓRIO DE USINAGEM