Upload
others
View
26
Download
0
Embed Size (px)
Citation preview
PLC CONNECT : UMA PLATAFORMA DE AQUISICAO DE DADOS PARA
IDENTIFICACAO DE SISTEMAS A EVENTOS DISCRETOS
Creison Maique Nunes
Projeto de Graduacao apresentado ao curso de
Engenharia de Controle e Automacao da Escola
Politecnica, Universidade Federal do Rio de
Janeiro, como parte dos requisitos necessarios
a obtencao do tıtulo de Engenheiro.
Orientador: Gustavo da Silva Viana
Rio de Janeiro
Marco de 2020
PLC CONNECT : UMA PLATAFORMA DE AQUISICAO DE DADOS PARA
IDENTIFICACAO DE SISTEMAS A EVENTOS DISCRETOS
Creison Maique Nunes
PROJETO DE GRADUACAO SUBMETIDO AO CORPO DOCENTE DO
CURSO DE ENGENHARIA DE CONTROLE E AUTOMACAO DA ESCOLA
POLITECNICA DA UNIVERSIDADE FEDERAL DO RIO DE JANEIRO COMO
PARTE DOS REQUISITOS NECESSARIOS PARA A OBTENCAO DO GRAU
DE ENGENHEIRO DE CONTROLE E AUTOMACAO.
Examinada por:
Prof. Gustavo da Silva Viana, D.Sc.
Prof. Joao Carlos dos Santos Basılio, Ph.D
Prof. Marcos Vicente de Brito Moreira, D.Sc.
RIO DE JANEIRO, RJ – BRASIL
MARCO DE 2020
Maique Nunes, Creison
PLC Connect : Uma plataforma de aquisicao de dados
para identificacao de sistemas a eventos discretos/Creison
Maique Nunes. – Rio de Janeiro: UFRJ/Escola
Politecnica, 2020.
XIV, 109 p.: il.; 29, 7cm.
Orientador: Gustavo da Silva Viana
Projeto de Graduacao - UFRJ/Escola Politecnica/Curso
de Engenharia de Controle e Automacao, 2020.
Referencias Bibliograficas: p. 58 – 59.
1. Redes de Petri. 2. Controladores Logicos
Programaveis. 3. Python. 4. Factory I/O. I. da
Silva Viana, Gustavo. II. Universidade Federal do Rio
de Janeiro, Escola Politecnica, Curso de Engenharia de
Controle e Automacao. III. Tıtulo.
iii
Dedico este trabalho a minha
famılia por sua simplicidade e
esforco em me ensinar o
caminho da integridade e
honestidade, pelo encorajamento
e dedicacao em cada sonho
almejado tornando possıvel a
realizacao dessa etapa tao
importante em minha vida
iv
Agradecimentos
Agradeco, primeiramente, a Deus, que ate aqui me sustentou e conduziu meus
passos para a conclusao deste trabalho. Ele se manteve presente em momentos de
alegria e tambem de angustia fazendo-me enxergar seu amor e sua graca.
Agradeco aos meus pais Maria Helena e Raimundo pelo amor, cuidado, abs-
tencoes e por sempre priorizarem minha educacao.
Aos meus familiares pelo incentivo e apoio em momentos difıceis.
A minha noiva que ilumina os meus dias e me transforma com o seu sor-
riso.
Ao meu orientador Gustavo Viana que me auxiliou com suas ponderacoes
evidenciando assim sua gentileza e paciencia.
Ao corpo docente da Universidade Federal do Rio de Janeiro por cada ex-
periencia e conhecimentos transmitidos ao longo do curso.
A todas as outras pessoas que direta ou indiretamente colaboraram para a
elaboracao deste trabalho.
v
Resumo da Projeto de Graduacao apresentada a Escola Politecnica/UFRJ como
parte dos requisitos necessarios para a obtencao do grau de Engenheiro de Controle
e Automacao.
PLC CONNECT : UMA PLATAFORMA DE AQUISICAO DE DADOS PARA
IDENTIFICACAO DE SISTEMAS A EVENTOS DISCRETOS
Creison Maique Nunes
Marco/2020
Orientador: Gustavo da Silva Viana
Curso: Engenharia de Controle e Automacao
Neste trabalho, foi desenvolvido um programa em Python chamado PLC Con-
nect, com o objetivo de fazer a aquisicao de sinais provenientes de controladores
logicos programaveis (CLPs) da Siemens de uma forma “plug-and-play”, isto e, sem
a necessidade de acesso a interface de projeto do controlador. Para isso, o PLC
Connect conta com uma interface simples e intuitiva, permitindo ao usuario gra-
var os dados adquiridos em um arquivo pronto para ser usado em um modelo de
identificacao. No decorrer deste trabalho, as etapas de elaboracao do PLC Connect
sao apresentadas, bem como todos os seus recursos. Para mostrar a eficacia do pro-
grama, dois exemplos de projetos de manufatura sao apresentados: a aquisicao de
dados de uma planta virtual e a aquisicao de dados de uma planta real.
vi
Abstract of Dissertation presented to Polytechnic School/UFRJ as a partial
fulfillment of the requirements for the degree of Control and Automation
Engineering.
PLC CONNECT: A PLATFORM FOR DATA ACQUISITION TO
IDENTIFICATION OF DISCRETE EVENT SYSTEMS
Creison Maique Nunes
March/2020
Advisor: Gustavo da Silva Viana
Course: Control and Automation Engineering
In this work, a python software called PLC Connect was developed. Its goal
is to obtain signals from Siemens programmable logic controllers (PLCs), being a
“plug-and-play” device to data acquitision, that is, there is no need to access the
interface of controller design. In order to do so, PLC Connect has an intuitive user
interface, allowing the user to save acquired data in files ready to be inputs in an
identification model. Throught the text, an user guide is presented as well as all
PLC Connect’s resources. To show effective results of the software, two examples
are presented: the data acquisition from virtual and real plant.
vii
Sumario
Lista de Figuras xi
Lista de Tabelas xiv
1 Introducao 1
2 Sistemas a Eventos Discretos 3
2.1 Definicao de Sistemas a Eventos Discretos . . . . . . . . . . . . . . . 3
2.2 Fundamentos Basicos das Redes de Petri . . . . . . . . . . . . . . . . 4
2.2.1 Estrutura de uma Rede de Petri . . . . . . . . . . . . . . . . . 4
2.2.2 Rede de Petri Marcada . . . . . . . . . . . . . . . . . . . . . . 5
2.2.3 Transicao Habilitada . . . . . . . . . . . . . . . . . . . . . . . 5
2.2.4 Rede de Petri Estendida . . . . . . . . . . . . . . . . . . . . . 6
2.2.5 Rede de Petri Segura . . . . . . . . . . . . . . . . . . . . . . . 7
2.2.6 Rede de Petri Rotulada . . . . . . . . . . . . . . . . . . . . . 7
2.2.7 Rede de Petri Temporizada . . . . . . . . . . . . . . . . . . . 7
2.3 Rede de Petri Interpretada para Controle . . . . . . . . . . . . . . . . 8
3 Controlador Logico Programavel e Identificacao de SEDs 11
3.1 Definicao do Controlador Logico Programavel . . . . . . . . . . . . . 11
3.2 Linguagens de Programacao . . . . . . . . . . . . . . . . . . . . . . . 14
3.3 A Linguagem Ladder . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.3.1 Contatos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.3.2 Bobinas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.3.3 Temporizador TON . . . . . . . . . . . . . . . . . . . . . . . . 19
3.3.4 Estrutura de Funcionamento . . . . . . . . . . . . . . . . . . . 19
3.4 Conversao de RPICs para Ladder . . . . . . . . . . . . . . . . . . . . 20
3.4.1 Modulo de Eventos . . . . . . . . . . . . . . . . . . . . . . . . 20
3.4.2 Modulo de Condicoes para o Disparo . . . . . . . . . . . . . . 21
3.4.3 Modulo da Dinamica . . . . . . . . . . . . . . . . . . . . . . . 21
3.4.4 Modulo de Inicializacao . . . . . . . . . . . . . . . . . . . . . . 22
3.4.5 Modulo de Acoes . . . . . . . . . . . . . . . . . . . . . . . . . 23
viii
3.5 Identificacao de Sistemas a Eventos Discretos . . . . . . . . . . . . . 24
4 PLC Connect 26
4.1 Visao Geral . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
4.2 Guia do Usuario e Apresentacao da Interface . . . . . . . . . . . . . . 27
4.2.1 Instalacao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
4.2.2 Configuracoes Necessarias . . . . . . . . . . . . . . . . . . . . 30
4.2.3 Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
5 Projeto do Controlador e Aquisicao de Dados de uma Planta Vir-
tual e de um Sistema de Manufatura Real 36
5.1 Projeto da Planta Virtual . . . . . . . . . . . . . . . . . . . . . . . . 36
5.1.1 Sensor Retrorreflexivo e Refletor . . . . . . . . . . . . . . . . . 37
5.1.2 Transportadores de Carga Pesada . . . . . . . . . . . . . . . . 37
5.1.3 Transportadores de Carga Leve . . . . . . . . . . . . . . . . . 38
5.1.4 Itens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
5.1.5 Estacoes de Trabalho . . . . . . . . . . . . . . . . . . . . . . . 39
5.1.6 Operadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
5.1.7 Emissor e Removedor . . . . . . . . . . . . . . . . . . . . . . . 41
5.1.8 Driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
5.1.9 Simulacao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
5.2 Sistema Didatico de Manufatura . . . . . . . . . . . . . . . . . . . . . 49
5.2.1 Pecas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
5.2.2 Sensores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
5.2.3 Atuadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
5.2.4 A Planta de Manufatura Didatica . . . . . . . . . . . . . . . . 52
6 Conclusoes 57
Referencias Bibliograficas 58
A Rede de Petri Interpretada para Controle 60
B Arquivos em Ladder 62
B.1 Arquivos Planta Virtual . . . . . . . . . . . . . . . . . . . . . . . . . 62
B.1.1 Modulo de Condicoes para o Disparo . . . . . . . . . . . . . . 62
B.1.2 Modulo da Inicializacao . . . . . . . . . . . . . . . . . . . . . 64
B.1.3 Modulo da Dinamica . . . . . . . . . . . . . . . . . . . . . . . 65
B.1.4 Modulo de Acoes . . . . . . . . . . . . . . . . . . . . . . . . . 69
B.2 Arquivos Planta Real . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
B.2.1 Modulo de Condicoes para o Disparo . . . . . . . . . . . . . . 71
ix
B.2.2 Modulo da Inicializacao . . . . . . . . . . . . . . . . . . . . . 73
B.2.3 Modulo da Dinamica . . . . . . . . . . . . . . . . . . . . . . . 74
B.2.4 Modulo de Acoes . . . . . . . . . . . . . . . . . . . . . . . . . 78
C Como Exportar Tags Utilizando o TIA PORTAL 14 80
D Implementacao em Python 83
D.1 Back-End . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
D.1.1 Bibliotecas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
D.1.2 Importando Dados . . . . . . . . . . . . . . . . . . . . . . . . 84
D.1.3 PLC Controller . . . . . . . . . . . . . . . . . . . . . . . . . . 85
D.1.4 Generator File . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
D.1.5 Thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
D.1.6 Communication Classes . . . . . . . . . . . . . . . . . . . . . 91
D.2 Front-End . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
D.2.1 Bibliotecas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
D.2.2 Janela Principal UI . . . . . . . . . . . . . . . . . . . . . . . . 93
D.2.3 Janela Principal . . . . . . . . . . . . . . . . . . . . . . . . . . 103
x
Lista de Figuras
2.1 Exemplo de grafo de uma rede de Petri . . . . . . . . . . . . . . . . . 5
2.2 Exemplo de uma rede de Petri com marcacao . . . . . . . . . . . . . 5
2.3 Exemplo de uma rede de Petri pos disparo . . . . . . . . . . . . . . . 6
2.4 Exemplo de uma rede de Petri com arco inibidor . . . . . . . . . . . . 7
2.5 Exemplo de uma rede de Petri temporizada . . . . . . . . . . . . . . 8
2.6 Exemplo de um cruzamento . . . . . . . . . . . . . . . . . . . . . . . 9
2.7 Exemplo de uma rede de Petri interpretada para controle . . . . . . . 10
3.1 Esquema que ilustra a relacao entre o CLP e os componentes . . . . . 12
3.2 Ciclo de varredura do CLP . . . . . . . . . . . . . . . . . . . . . . . . 14
3.3 Contato normalmente aberto . . . . . . . . . . . . . . . . . . . . . . . 16
3.4 Contato normalmente fechado . . . . . . . . . . . . . . . . . . . . . . 16
3.5 Contato tipo P . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.6 Contato tipo N . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.7 Bobina simples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.8 Bobina SET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.9 Bobina RESET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.10 Temporizador TON . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.11 Controle de partida / parada do motor com travamento . . . . . . . . 20
3.12 Modulo de condicoes para o disparo . . . . . . . . . . . . . . . . . . . 21
3.13 Modulo da dinamica . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.14 Modulo de inicializacao . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.15 Modulo de acoes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.16 Comunicacao entre os componentes em um SED em malha fechada. . 24
4.1 Escolha do idioma do instalador . . . . . . . . . . . . . . . . . . . . . 27
4.2 Escolha do destino para instalacao . . . . . . . . . . . . . . . . . . . 28
4.3 Criar atalhos no menu iniciar . . . . . . . . . . . . . . . . . . . . . . 28
4.4 Criar atalhos na area de trabalho . . . . . . . . . . . . . . . . . . . . 29
4.5 Confirmacao de instalacao . . . . . . . . . . . . . . . . . . . . . . . . 29
4.6 Concluir instalacao . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
xi
4.7 Atalho do PLC Connect . . . . . . . . . . . . . . . . . . . . . . . . . 30
4.8 Propriedades do projeto no TIA Portal . . . . . . . . . . . . . . . . . 31
4.9 Propriedades do banco de dados no TIA Portal . . . . . . . . . . . . 31
4.10 PLC Connect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
4.11 Conexao bem-sucedida com o CLP . . . . . . . . . . . . . . . . . . . 33
4.12 Erro na tentativa de conexao com o CLP . . . . . . . . . . . . . . . . 33
4.13 Inserir variaveis do projeto . . . . . . . . . . . . . . . . . . . . . . . . 34
4.14 Criando o arquivo *.csv . . . . . . . . . . . . . . . . . . . . . . . . . 34
4.15 Gravar arquivo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
4.16 Aquisicao de dados do exemplo 2.3.1 . . . . . . . . . . . . . . . . . . 35
5.1 Sensor retrorreflexivo e refletor. Extraıdo de [1] . . . . . . . . . . . . 37
5.2 Esteira transportadora. Extraıdo de [1] . . . . . . . . . . . . . . . . . 38
5.3 Correia transportadora. Extraıdo de [1] . . . . . . . . . . . . . . . . . 38
5.4 Itens. Extraıdo de [1] . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
5.5 Caixa media. Extraıdo de [1] . . . . . . . . . . . . . . . . . . . . . . . 39
5.6 Palete. Extraıdo de [1] . . . . . . . . . . . . . . . . . . . . . . . . . . 39
5.7 Manipulador robotico. Extraıdo de [1] . . . . . . . . . . . . . . . . . 40
5.8 Botoes. Extraıdo de [1] . . . . . . . . . . . . . . . . . . . . . . . . . . 40
5.9 Emissor. Extraıdo de [1] . . . . . . . . . . . . . . . . . . . . . . . . . 41
5.10 Removedor. Extraıdo de [1] . . . . . . . . . . . . . . . . . . . . . . . 41
5.11 I/O drivers. Extraıdo de [1] . . . . . . . . . . . . . . . . . . . . . . . 42
5.12 Janelas dos drivers. Extraıdo de [1] . . . . . . . . . . . . . . . . . . . 42
5.13 Janelas das configuracoes. Extraıdo de [1] . . . . . . . . . . . . . . . 43
5.14 Planta virtual, numerada da seguinte forma: de 1 ate 6 sao as saıdas
(outputs) e de 7 a 15 sao as entradas (inputs). . . . . . . . . . . . . . 44
5.15 Caixa parada no sensor i1 e palete no sensor i2 . . . . . . . . . . . . . 45
5.16 Posicionamento da primeira caixa . . . . . . . . . . . . . . . . . . . . 45
5.17 Manipulador robotico pegando a segunda caixa . . . . . . . . . . . . 46
5.18 Posicionamento da segunda caixa . . . . . . . . . . . . . . . . . . . . 46
5.19 Acionamento da segunda esteira . . . . . . . . . . . . . . . . . . . . 47
5.20 Eliminacao dos itens . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
5.21 Aquisicao dos outputs da planta virtual . . . . . . . . . . . . . . . . . 48
5.22 Aquisicao dos inputs da planta virtual . . . . . . . . . . . . . . . . . 48
5.23 PLC Connect durante aquisicao dos dados da planta virtual . . . . . 49
5.24 Metades do cubo. Extraıdo de [2]. . . . . . . . . . . . . . . . . . . . . 49
5.25 Conjunto de sensores. Editado de [2]. . . . . . . . . . . . . . . . . . . 50
5.26 Conjunto de empurradores. Editado de [2]. . . . . . . . . . . . . . . . 51
5.27 Armazenador. Editado de [2]. . . . . . . . . . . . . . . . . . . . . . . 51
xii
5.28 Correia transportadora. Editado de [2]. . . . . . . . . . . . . . . . . . 52
5.29 Planta de manufatura, numerada da seguinte forma: de 1 ate 8 sao
as saıdas (outputs) e de 9 a 26 sao as entradas (inputs). . . . . . . . . 54
5.30 Planta de manufatura com metades do cubo posicionados . . . . . . . 55
5.31 Aquisicao dos outputs da planta real . . . . . . . . . . . . . . . . . . 56
5.32 Aquisicao dos inputs da planta real . . . . . . . . . . . . . . . . . . . 56
A.1 Rede de Petri da planta virtual . . . . . . . . . . . . . . . . . . . . . 60
A.2 Rede de Petri da planta real . . . . . . . . . . . . . . . . . . . . . . . 61
C.1 Tabela de tags do projeto . . . . . . . . . . . . . . . . . . . . . . . . 80
C.2 Escolhendo caminho para salvar o arquivo . . . . . . . . . . . . . . . 81
C.3 Nome do arquivo que sera gerado . . . . . . . . . . . . . . . . . . . . 81
C.4 Confirmacao da exportacao . . . . . . . . . . . . . . . . . . . . . . . 82
xiii
Lista de Tabelas
3.1 Identificador das posicoes de memoria de um CLP . . . . . . . . . . . 12
3.2 Tipo das posicoes de memoria de um CLP . . . . . . . . . . . . . . . 13
4.1 Padrao de rack e slot de alguns dispositivos . . . . . . . . . . . . . . 32
xiv
Capıtulo 1
Introducao
No decorrer das ultimas decadas, houve um grande avanco no setor industrial, de-
vido a utilizacao de maquinas eletromecanicas, softwares e equipamentos especıficos
para automatizar sistemas cada vez mais complexos. Com isso, houve uma melhora
na eficiencia dos processos, maximizando a producao com menor consumo de ener-
gia, menor emissao de resıduos e melhores condicoes de seguranca, seja material,
humana ou das informacoes. Entre os dispositivos eletroeletronicos que fizeram com
que ocorresse esse grande avanco, estao os computadores e outros dispositivos capa-
zes de efetuar operacoes logicas, como controladores logicos programaveis (CLPs),
microcontroladores, SDCDs ou CNCs.
Em um sistema tıpico, toda a informacao dos sensores e geralmente concentrada
em um controlador programavel, sendo que o estado dos atuadores e definido de
acordo com uma logica implementada em sua memoria. Alguns exemplos desses sis-
temas sao: a automacao de industrias automobilısticas, semaforos, elevadores, entre
outros. Sistemas desse tipo sao regidos, em geral por eventos. Eventos sao alteracoes
do sistema ou do ambiente externo que podem causar uma mudanca no estado do
sistema. Essas alteracoes podem ser intencionais, de ocorrencia espontanea, con-
trolada ou com a verificacao de uma condicao, e geralmente produzem mudancas
de estado em intervalos de tempo aleatorios. Sistemas com essas caracterısticas sao
conhecidos como sistemas a eventos discretos (SEDs) [3].
Entre os inumeros temas de pesquisa dentro da area de SEDs, pode-se destacar a
identificacao de sistemas a eventos discretos com o objetivo de diagnostico de falhas
[4–7]. A ideia e obter um modelo para o sistema sem precisar de conhecimento previo
do mesmo. Para isso, e necessario fazer a aquisicao dos sinais trocados entre a planta
e o controlador, com o sistema funcionando livre de falhas. Uma vez obtido o modelo
do comportamento livre de falhas do sistema, pode-se entao utilizar metodos para
identificacao e isolamento da falha [5, 7].
A maioria dos trabalhos na literatura tem focado no desenvolvimento de modelos
mais eficientes e mais fieis ao comportamento livre de falhas do sistema [6–9]; e
1
tambem nas estrategias para deteccao de falhas que possam ocorrer no sistema
[5, 10]. Entretanto, e necessario tambem voltar as atencoes para uma das partes mais
importantes na obtencao de um bom modelo identificado: o processo de aquisicao
de dados dos sinais entre a planta e o controlador.
Em [4, 7], projetos praticos envolvendo identificacao de uma planta mecatronica
montadora de cubos foram desenvolvidos. Em ambos, os sinais de sensores e atu-
adores foram obtidos da seguinte forma: apos a implementacao de um controlador
feito na plataforma de desenvolvimento da Siemens TIA PORTAL, algumas funcoes
foram adicionadas dentro da propria plataforma para que os dados pudessem ser
registrados. Esse metodo tem as seguintes desvantagens: a necessidade de acesso
e edicao do projeto, conhecimento das funcoes necessarias para gravacao e a falta
de confiabilidade na gravacao dos dados. Dentro desse contexto, surgiu a ideia da
elaboracao de um programa que fosse capaz de obter os sinais de qualquer CLP da
Siemens, sem a necessidade de acesso ao codigo fonte do projeto.
Neste trabalho, foi desenvolvido um programa em Python chamado PLC Con-
nect, com o objetivo de fazer a aquisicao de sinais provenientes dos CLPs da Siemens
de uma forma “plug-and-play”, isto e, sem a necessidade de acesso a interface de
projeto do controlador. Para isso, o PLC Connect conta com uma interface sim-
ples e intuitiva, permitindo ao usuario gravar os dados adquiridos em um arquivo
pronto para ser usado em um modelo de identificacao. Sendo assim, apresentamos
no decorrer do trabalho as etapas de elaboracao do PLC Connect, bem como todos
os seus recursos. Para mostrar a eficacia do programa, dois exemplos de projetos de
manufatura sao apresentados: uma planta virtual e uma planta real.
O trabalho esta estruturado da seguinte forma. No capıtulo 2, serao apresen-
tados os principais conceitos de sistemas a eventos discretos. No capıtulo 3, serao
apresentados conceitos envolvendo controladores logicos programaveis, tendo como
destaque o metodo de conversao de rede de Petri interpretada para controle para
linguagem Ladder. No capıtulo 4 e apresentado o software desenvolvido nesse traba-
lho: o PLC Connect. No capıtulo 5, dois projetos de manufatura sao desenvolvidos
para apresentar o funcionamento do PLC Connect. Por fim, no capıtulo 6, sao
apresentadas as conclusoes deste trabalho e sugestoes para trabalhos futuros.
2
Capıtulo 2
Sistemas a Eventos Discretos
Neste capıtulo sao apresentados conceitos basicos de sistemas a eventos discretos,
necessarios para a compreensao e elaboracao deste trabalho.
Para tanto, este capıtulo esta estruturado da seguinte forma. Na secao 2.1, o
conceito de sistemas a eventos discretos e introduzido. Na secao 2.2, e apresentada
a descricao de rede de Petri e algumas de suas propriedades. Finalmente, na secao
2.3, o conceito de redes de Petri interpretada para controle e introduzido, bem como
a importancia do seu uso.
2.1 Definicao de Sistemas a Eventos Discretos
De um modo geral, um sistema e um conjunto de elementos, concretos ou abs-
tratos, intelectualmente organizados, realizando funcoes que nao seriam possıveis
individualmente. Os sistemas considerados nesse trabalho sao denominados siste-
mas a eventos discretos, isto e, sistemas de estados discretos dirigidos pela ocorrencia
assıncrona de eventos [3]. Eventos sao basicamente a ocorrencia de acoes, sejam elas
acoes especificas (como o acionamento de uma botoeira), acoes inerentes do processo
(como a perda de calor para o ambiente) ou resultado de uma condicao do sistema ser
satisfeita (como um lıquido em um recipiente alcancar um nıvel predeterminado),
entre tanto outros. Dessa forma, o sistema evolui conforme a ocorrencia desses
eventos, mudando de estados de modo que novos estados podem ser alcancados. O
conjunto de eventos que ocorrem em um sistema pode ser considerado o alfabeto
do sistema, em que as sequencias possıveis de eventos de comprimento finito sao
consideradas palavras e o conjunto de todas as sequencias sao consideradas lingua-
gem. As linguagens sao responsaveis por determinar a evolucao de estados em um
SED baseada na ocorrencia de eventos, possuindo uma funcao similar as equacoes
diferenciais para descrever sistemas dinamicos contınuos no tempo [3].
Apesar das linguagens serem suficientes para representar uma SED, na maioria dos
casos praticos, sua representacao se torna extremamente complexa. Para solucionar
3
esse problema, normalmente se usa estruturas em grafos, tais como o automato e
a rede de Petri. Para o desenvolvimento desse trabalho foram utilizadas redes de
Petri, sendo apresentada um breve descricao do seu funcionamento a seguir.
2.2 Fundamentos Basicos das Redes de Petri
Uma rede de Petri e um grafo direcionado, com peso e bipartido, sendo utilizada
como ferramenta matematica para modelar sistemas a eventos discretos [3]. A seguir
sera apresentada uma breve revisao da teoria de redes de Petri.
2.2.1 Estrutura de uma Rede de Petri
O grafo de uma rede de Petri e composto por lugares, transicoes e arcos ponderados.
Os lugares sao representados graficamente por cırculos, fornecendo informacoes sobre
o estado e condicoes do sistema. As transicoes sao representadas por barras e os
arcos sao representados por setas orientadas, cuja funcao e estabelecer as relacoes
entre transicoes e os lugares.
Definicao 2.2.1. (Grafo de uma rede de Petri) O grafo de uma rede de Petri e uma
quadrupla
N = (P, T, Pre, Post)
em que:
• P = {p1, p2, ..., pn} e o conjunto finito de lugares;
• T = {t1, t2, ..., pm} e o conjunto finito de transicoes;
• Pre : P x T → N e a funcao que atribui um peso a cada arco orientado de um
lugar para uma transicao;
• Post : T x P → N e a funcao que atribui um peso a cada arco orientado de
uma transicao para um lugar.
A figura 2.1 mostra um exemplo basico de um grafo de rede de Petri, cujos
componentes sao:
• P = {p1, p2};
• T = {t1};
• Pre(p1, t1) = 1;
• Post(t1, p2) = 2.
4
Figura 2.1: Exemplo de grafo de uma rede de Petri
2.2.2 Rede de Petri Marcada
Somente a estrutura de uma rede de Petri nao e suficiente para modelar o comporta-
mento dinamico de um sistema, pensando nisso e adicionada um marcacao na rede
de Petri que indicara o estado do sistema e quais transicoes estao habilitadas. Para
marcar a rede de Petri e atribuıda fichas aos lugares, que e representada como um
ponto no respectivo lugar.
Definicao 2.2.2. (Estado de uma rede de Petri) Uma rede de Petri com marcacao
e uma quıntupla
N = (P, T, Pre, Post, xo)
em que:
• (P, T, Pre, Post) e o grafo da rede de Petri;
• xo : P → N e o vetor de marcacao.
A figura 2.2 mostra o mesmo exemplo da figura 2.1, porem foi adicionada uma
marcacao, onde xo =
[1
0
]
Figura 2.2: Exemplo de uma rede de Petri com marcacao
2.2.3 Transicao Habilitada
Uma transicao tj e dita habilitada, se o numero de fichas em um lugar e maior que
o peso do arco orientado desse lugar. Quando uma transicao se encontra habilitada,
a seguinte condicao deve ser satisfeita:
x(pi) ≥ Pre(pi, tj), ∀i = 1, ..., n
Com a transicao habilitada, pode ocorrer o que usualmente e chamado de disparo.
Quando uma transicao dispara, uma nova marcacao e alcancada, tal que:
x′(pi) = x(pi) + Post(tj, pi)− Pre(pi, tj), ∀i = 1, ..., n
5
O disparo pode ser entendido como a transferencia de n = Post(tj, pi) fichas para
o lugar subsequente, ocorrendo uma perda de m = Pre(pi, tj) fichas. Mostrando o
mesmo exemplo da figura 2.2, a figura 2.3 mostra a ocorrencia no lugar anterior do
disparo, onde p1 perde m = Pre(p1, t1) = 1 ficha e p2 recebe n = Post(tj, pi) = 2
fichas.
Figura 2.3: Exemplo de uma rede de Petri pos disparo
2.2.4 Rede de Petri Estendida
Uma extensao a rede de Petri pode ser adicionada, acrescentando um novo tipo de
arco: o arco inibidor. Os arcos inibidores sao representados por um cırculo em sua
extremidade.
Um arco inibidor de peso y, ligado um lugar pi a uma transicao tj, habilita tj
quando o numero de fichas em pi < y, quando tj disparar o numero de fichas em pi
permanecera inalterado [11].
Definicao 2.2.3. (Rede de Petri Estendida) Uma rede de Petri estendida e uma
sextupla:
N = (P, T, Pre, Post, ln, xo)
em que:
• (P, T, Pre, Post) e o grafo da rede de Petri;
• xo : P → N e o vetor de marcacao;
• ln : P x T→ N e a funcao dos arcos inibidores que ligam lugares a transicoes.
A figura 2.4 para que t1 esteja habilitada, p1 deve ter pelo menos uma ficha e p3
deve ter um numero de fichas menor do que 2. Portanto, nesse exemplo a transicao
t1 esta desabilitada.
6
Figura 2.4: Exemplo de uma rede de Petri com arco inibidor
2.2.5 Rede de Petri Segura
Definicao 2.2.4. (Rede de Petri Segura) Uma rede de Petri e considerada segura,
se a partir de uma marcacao inicial xo todas as marcacoes alcancaveis na rede de
Petri possuırem no maximo uma ficha em qualquer instante, ou seja, o numero de
fichas em cada lugar deve ser menor ou igual a 1.
Todas as redes de Petri desenvolvidas nesse trabalho sao seguras, com excecao as
usadas como exemplos. O porque disso sera explicado na Secao 2.3.
2.2.6 Rede de Petri Rotulada
A rede de Petri rotulada e definida como uma octupla:
N = (P, T, Pre, Post, E, l, xo, Xm)
em que:
• (P, T, Pre, Post) e o grafo da rede de Petri;
• E: e o conjunto de eventos para rotulagem;
• l: T → E e a funcao de rotulacao das transicoes;
• xo e o vetor de marcacao inicial;
• Xm e o conjunto de estados marcados.
Observacao 2.2.1. Uma observacao importante e que existe a possibilidade de ha-
ver mais de uma transicao rotulada pelo mesmo evento.
2.2.7 Rede de Petri Temporizada
Com o que foi introduzido ate o momento, e possıvel descrever apenas a estrutura
logica de sistemas utilizando redes de Petri. Isto porque a formulacao original de
redes de Petri considera que eventos sao instantaneos, o que impede o tratamento
7
de tempo atraves dela. Para contornar esse problema surgiu o conceito de rede de
Petri temporizada.
Na figura 2.5 temos um exemplo de uma rede de Petri temporizada, onde T
e o numero de segundos que corresponde ao tempo de atraso de disparo de uma
transicao. Assim que a transicao e habilitada, inicia-se uma contagem de tempo.
Assim que o tempo predeterminado e alcancado, a transicao dispara.
Figura 2.5: Exemplo de uma rede de Petri temporizada
2.3 Rede de Petri Interpretada para Controle
As redes de Petri apresentadas nas secoes anteriores sao utilizadas para modelagem
de sistemas dinamicos a eventos discretos. Contudo essas redes de Petri possuem
limitacoes ao modelar um controlador de um sistema. Pensando nisso certas estru-
turas sao adicionadas para lidar com sensores e atuadores, sendo entao nomeadas
redes de Petri interpretadas para controle(RPIC).
Utilizando RPICs, e possıvel associar o disparo de uma transicao, ou a existencia
de fichas em um lugar, a condicoes que ocorreram na planta ou a variaveis de
memoria. Quando associada a um lugar, as acoes podem ser impulsionais ou
contınuas:
• As acoes impulsionais sao realizadas durante um intervalo de tempo predeter-
minado, a partir de quando a etapa se tornar ativa.
• As acoes contınuas sao realizadas durante todo o perıodo em que houver uma
ficha no respectivo lugar. Isto e, assim que uma transicao subsequente for
disparada a acao cessara.
Definicao 2.3.1. (Rede de Petri Interpretada para Controle) Uma rede de Petri
interpretada para controle (RPIC), e uma decupla dada por:
N = (P, T, Pre, Post, ln, xo, C, E, l,D, lD, AI , AN , lA)
em que:
• (P, T, Pre, Post, ln, xo) e a rede de Petri estendida segura;
• C e E sao os conjuntos de condicoes e eventos externos associados as transicoes
nao temporizadas pertencentes a To;
8
• l : To → E x C e a funcao que associa a cada transicao nao temporizada um
evento e uma condicao para o disparo da transicao;
• D e o conjunto de atrasos de disparo associados as transicoes temporizadas
TD;
• lD : TD → D e a funcao que associa a cada transicao de TD um atraso do
conjunto D;
• AI denota o conjunto de acoes impulsionais e de operacoes;
• AN Denota o conjunto de acoes de nıvel;
• lA : P → AI ∪ AN e a funcao que associa aos lugares da rede uma acao
pertencente a AI ∪ AN .
Observacao 2.3.1. Na definicao 2.3.1, tem-se que cada transicao tj ∈ To esta
associada a uma condicao e um evento.
Observacao 2.3.2. Quando foi introduzido o conceito de rede de Petri segura,
afirmou-se que todas as redes de Petri desenvolvidas seriam seguras. Isso se deve
ao fato que e necessario apenas uma ficha em um lugar para a acao associada ser
executada. Portanto e desnecessario haver mais de uma ficha no mesmo lugar.
Exemplo 2.3.1. Considerando que no cruzamento da figura 2.6, nao sao permitidas
mudancas na direcao de deslocamento. Deseja-se implementar o comportamento de
quatro semaforos de modo a evitar conflitos entre os carros.
Figura 2.6: Exemplo de um cruzamento
Como nao sao permitidas mudancas na direcao de deslocamento, a melhor ma-
neira para resolver esse problema, e implementar os semaforos, de modo que, os
presentes na mesma direcao, mas em pista distinta, apresente o mesmo compor-
tamento. Com isso, somente e necessario modelar dois semaforos, um para cada
rodovia.
9
A figura 2.7 mostra a RPIC desse exemplo. As acoes executadas nesse sistemas
sao booleanas e as lampadas so permanecerao ligadas enquanto houver fichas no
respectivo lugar. Algumas das transicoes sao temporizadas, tal que o atraso corres-
ponde ao tempo que cada lampada fica acesa.
Os dois semaforos estao inicialmente em vermelho. Apos a transicao t1 disparar,
p1 e p7 sao desmarcados, apagando a luz vermelha do semaforo 01, e marcando p2,
acendendo a luz verde desse semaforo. Sendo assim, a transicao t2 e habilitada, per-
manecendo por T0 segundos ate o seu disparo, quando a ficha sai de p2, desligando
a luz verde desse semaforo, adicionando uma ficha em p3, acendendo a luz amarela
por T3 segundos. Apos o disparo de t3, p1 e p8 recebem uma ficha e p3 perde uma.
Nesse momento a transicao t4 esta ativada, pois as fichas estao em p4 e p8, apos
seu disparo a luz verde do semaforo 02 sera ativada, realizando o mesmo ciclo que
o semaforo 01, mas usando transicoes e lugares diferentes. Quando a transicao T1
disparar volta-se a condicao inicial do sistema.
Figura 2.7: Exemplo de uma rede de Petri interpretada para controle
10
Capıtulo 3
Controlador Logico Programavel e
Identificacao de SEDs
Neste capıtulo sao apresentados algumas caracterısticas e metodos de operacao dos
controladores logicos programaveis, usualmente chamados CLPs ou PLCs (program-
mable logic controller). Alem disso, sao apresentadas as informacoes que precisam
ser aquisitadas dos controladores, para criacao de modelos para identificacao de
SEDs.
A estrutura do capıtulo e a seguinte. Na secao 3.1, serao apresentados os con-
ceitos basicos de CLPs. Na secao 3.2, serao abordadas as diversas linguagens de
programacao para os CLPs. Na secao 3.3 e apresentada a linguagem Ladder de
forma mais aprofundada. Por fim, na secao 3.4 e apresentada um metodo de con-
versao de RPIC para a linguagem Ladder.
3.1 Definicao do Controlador Logico Programavel
Um controlador logico programavel (CLP) e um equipamento eletronico digital pro-
jetado para aplicacoes industriais. Ele e capaz de armazenar instrucoes em tempo
discreto e e capaz de comandar diferentes sistemas atraves de entradas e saıdas di-
gitais ou analogicas [12]. O CLP interage com uma planta industrial atraves de
sensores e atuadores, em que:
• Sensores: sao dispositivos que servem para informar um circuito eletronico
sobre a ocorrencia de eventos, a partir da qual deve-se executar uma determi-
nada acao. Um exemplo e um sensor de nıvel que fornece sinal logico 1, quando
determinado nıvel e alcancado e fornece sinal 0, caso contrario. Dessa forma,
o sensor converte a condicao fısica para sinal eletrico, que e interpretado pelo
controlador como um nıvel logico.
• Atuadores: sao dispositivos que alteram uma variavel controlada. O atuador
11
recebe um sinal proveniente do controlador e assim atua sobre o sistema a
ser controlado. Um exemplo e uma esteira que recebe o sinal do controlador
(on/off) e entao executa a acao de acordo com o nıvel logico correspondente.
Um sistema de controle e mostrado na figura 3.1. Ele ilustra a interacao entre
usuario e o sistema atraves de sensores e atuadores.
Figura 3.1: Esquema que ilustra a relacao entre o CLP e os componentes
Em um sistema, as informacoes dos sensores sao obtidas pelo CLP, que de acordo
com as instrucoes gravadas em sua memoria, altera o estado de determinado atua-
dor. As entradas, as saıdas e a memoria interna sao os elementos mais importantes
de um CLP. Com suas entradas conectadas aos sensores e possıvel o recebimento
de informacoes do mundo externo, assim como, com suas saıdas conectadas aos
atuadores e possıvel controlar algum dispositivo.
Para acessar as variaveis responsaveis por cada area existem algumas especi-
ficacoes: a primeira letra identifica se a variavel esta relacionada a entrada, saıda
ou posicao de memoria, conforme a tabela 3.1.
Tabela 3.1: Identificador das posicoes de memoria de um CLP
Identificador Significado
I Entradas
Q Saıdas
M Memoria
A segunda letra identifica o tipo da variavel, conforme a tabela 3.2
12
Tabela 3.2: Tipo das posicoes de memoria de um CLP
Tipo Significado
Bool
B Byte
W Word
D Dword
D Real
D Time
Variaveis do tipo Bool sao compostas por um bit; variaveis do tipo Byte, Word,
Dword sao sequencias de 8, 16 e 32 bits respectivamente; variaveis do tipo Real
representam numeros que podem ser utilizados em operacoes matematicas e uma
variavel do tipo Time e utilizada para especificar valores de tempo em temporiza-
dores. Para definir uma variavel deve ser fornecido um nome simbolico, fornecer um
identificador, o tipo de variavel desejada e um endereco. Para variaveis booleanas
ainda e necessario fornecer um valor numerico. Temos como exemplo, uma variavel
booleana %Q0.0 e uma variavel real %QD0. Uma vez configuradas as variaveis,
resta desenvolver o programa utilizando algumas das linguagens de programacao
disponıveis para o CLP.
De forma geral, o CLP funciona realizando ciclos de varreduras. Um ciclo de
varredura e composto de 3 etapas
1. Leitura dos registro de entrada;
2. Execucao do codigo de controle programado;
3. Atualizacao do registro de saıda.
A figura 3.2 ilustra graficamente o ciclo de varredura realizado em um CLP. Apos
a inicializacao, o CLP faz a leitura e armazena os valores logicos das variaveis de
entrada obtidas pelos sensores, e em seguida, o codigo de controle e executado. Uti-
lizando os valores de entrada armazenados, sao determinados os valores das variaveis
de saıda. Nessa terceira etapa tambem sao atualizadas os valores das outras variaveis
utilizadas no projeto, tais como contadores, temporizadores, variaveis de memoria
etc. Apos a realizacao das tres etapas, o ciclo atual e encerrado e um novo ciclo e
iniciado.
13
Figura 3.2: Ciclo de varredura do CLP
3.2 Linguagens de Programacao
As linguagens de programacao que sao utilizadas por CLPs sao regidas pela norma
internacional IEC 61131-3 [13], que determina que os CLPs podem ser programados
por 5 linguagens. Das 5 linguagens disponıveis, pode-se realizar divisao em duas
categorias: linguagens textuais e as linguagens graficas.
Textuais A
As linguagens de programacao textual sao semelhantes as utilizadas no setor
eletronico ou informativo, portanto, constituem um tipo de linguagem de
programacao com grande capacidade para atender as necessidades do projeto.
Dentro dessa categoria encontram-se:
• Lista de Instrucoes (IL): linguagem de baixo nıvel, semelhante ao Assembly,
isto e, uma linguagem que usa diretamente instrucoes do microcomputador,
e de caracterıstica puramente sequencial. Por se tratar de uma linguagem de
baixo nıvel, sua utilizacao e indicada para aplicacoes menores, ou para otimizar
partes de uma aplicacao mais complexa.
• Texto Estruturado (ST): linguagem de programacao de alto nıvel e muito
poderosa, por ser inspirada no Pascal e estruturada em blocos, contendo todos
os elementos essenciais de uma linguagem de programacao moderna, incluindo
as instrucoes condicionais (IF-THEN-ELSE e CASE OF ) e instrucoes de in-
teracoes (FOR, WHILE E REPEAT ). Essa linguagem pode ser usada para
expressar declaracoes complexas envolvendo variaveis que representem uma
14
ampla faixa de dados de diferentes tipos, compreendendo valores analogicos e
digitais. Ha tambem como trabalhar com dados especıficos de gerenciamento
de horas, datas e duracao de tempo.
Graficas A
A linguagem de programacao grafica sao semelhantes aos utilizados em es-
quema eletrico ou esquema de blocos. Dentro dessa categoria encontram-se:
• Sequenciamento Grafico de Funcoes (SFC): linguagem grafica que per-
mite a descricao das acoes sequenciais, paralelas e alternativas existentes numa
aplicacao de controle, essa linguagem foi desenvolvida na Franca com o nome
de linguagem Grafcet. A linguagem Grafcet fornece os meios para estruturar
um programa num conjunto de etapas separadas por transicoes.
• Diagrama de Blocos de Funcoes (FBD): linguagem grafica em que os
elementos sao expressos por blocos interligados, semelhantes aos utilizados em
eletronica digital. Essa linguagem e apropriada para aplicacoes que envolvam
fluxo de informacao entre os componentes de controle.
• Linguagem Ladder (LD): linguagem grafica baseada na logica de reles e
contatos eletricos para a realizacao de circuitos de comando de acionamentos.
O nome Ladder deve-se a representacao da linguagem parecer-se com uma
escada, na qual duas barras verticais paralelas sao interligadas pela logica de
controle, formando os degraus da escada.
Todo tipo de CLP esta de acordo com as caracterısticas, modo de funcionamento
e linguagens de programacao descritas anteriormente. Normalmente, a mudanca de
um fabricante para o outro esta no requisito tecnologia dos modulos de expansao,
e tambem, do software de programacao, que pode ser amigavel ou nao, contendo
novas logicas de programacao para melhorar o desempenho de funcionamento que o
usuario deseja.
Neste trabalho, a linguagem Ladder sera utilizada, e por esse motivo, uma des-
cricao mais aprofundada sera feita na proxima secao.
3.3 A Linguagem Ladder
A linguagem Ladder e umas das cinco linguagens definidas pela norma IEC 61131-3
[13] para a programacao de CLPs. Trata-se de uma linguagem na qual as funcoes
logicas sao representadas atraves de contatos e bobinas, de modo similar a esquemas
eletricos. Estao tambem disponıveis na linguagem Ladder diversos componentes, tais
como: temporizadores, contadores, instrucoes de comparacao, instrucoes de calculos
15
matematicos. Nesse trabalho utilizamos somente alguns desses componentes, os
quais serao apresentados abaixo.
3.3.1 Contatos
Os contatos sao uns dos principais componentes da linguagem Ladder, e representam
as entradas digitais do CLP ou as variaveis de memoria. Sao divididos em quatro
tipos:
Contatos NA
Os contatos normalmente aberto (NA) funcionam verificando o nıvel logico da
variavel booleana enderecada ao contato. Se a variavel booleana tiver nıvel logico 0,
o contato retorna nıvel logico falso, interrompendo a parte do trecho do diagrama
Ladder em que esta inserida. Caso a variavel booleana tenha nıvel logico 1, o contato
retorna nıvel logico verdadeiro, dando continuidade a parte do trecho do diagrama
Ladder em que esta inserida. A figura 3.3 ilustra um contato normalmente aberto.
Figura 3.3: Contato normalmente aberto
Contatos NF
O contato normalmente fechado (NF) funciona de forma inversa ao contato NA,
ou seja, se a variavel booleana tiver nıvel logico 0, o contato retorna nıvel logico
verdadeiro, dando continuidade a parte do trecho do diagrama Ladder em que esta
inserida. Caso a variavel booleana tiver nıvel logico 1, o contato retorna nıvel logico
falso, interrompendo a parte do trecho do diagrama Ladder em que esta inserida. A
figura 3.4 ilustra um contato normalmente fechado.
Figura 3.4: Contato normalmente fechado
16
Contatos “tipo P”
O contato detector de borda de subida (tipo P) tem funcionamento analogo ao
contato NA, porem se difere no modo de ativacao. Enquanto o contato NA retorna
verdadeiro quando detectado nıvel logico 1 na variavel associada, o contato “tipo
P” retorna verdadeiro quando detecta a passagem do valor logico de 0 para o valor
logico 1 (borda de subida), voltando a retornar nıvel logico falso no proximo ciclo de
varredura, ate que detecte outra borda de subida. A figura 3.5 ilustra um contato
do “tipo P”.
Figura 3.5: Contato tipo P
Contatos “tipo N”
O contato detector de borda de descida (tipo N), funciona de forma inversa ao
contato “tipo P”. O contato “tipo N” retorna verdadeiro quando detecta a passagem
do valor logico de 1 para o valor logico 0 (borda de descida), voltando a retornar
nıvel logico falso no proximo ciclo de varredura, ate que detecte outra borda de
descida. A figura 3.6 ilustra um contato do “tipo N”.
Figura 3.6: Contato tipo N
3.3.2 Bobinas
Assim como os contatos, as bobinas sao primordiais para o funcionamento do dia-
grama Ladder. As bobinas atualizam as informacoes de saıda modificando o estado
logico de variaveis booleanas. Sao divididas em tres tipos:
Bobina Simples
Em bobinas simples, se a logica que a antecede for verdadeira, a bobina se encontra
“energizada”, isto e, o seu valor logico passa de 0 para o valor logico 1. Se a logica se
17
tornar falsa, a bobina se encontra “desenergizada”, logo o valor logico e modificado
para 0. A figura 3.7 ilustra uma bobina simples.
Figura 3.7: Bobina simples
Bobina SET
Uma bobina SET, se a logica que a antecede for verdadeira, o seu valor logico passa
de 0 para o valor logico 1. Porem, se a logica se tornar falsa o valor logico se mantem.
Para que o valor logico volte a ser 0, e necessario que exista uma bobina RESET
associada a mesma variavel e que essa bobina seja energizada. A figura 3.8 ilustra
uma bobina SET.
Figura 3.8: Bobina SET
Bobina RESET
A bobina RESET funciona de forma inversa a SET, ou seja, se a logica que a
antecede for verdadeira, o valor logico da variavel associada sera igual a 0, ate que
uma bobina SET associada a mesma variavel seja energizada. A figura 3.9 ilustra
uma bobina RESET.
Figura 3.9: Bobina RESET
18
3.3.3 Temporizador TON
Os temporizadores sao utilizados para criar atrasos pre-programados. Dentre os
modelos disponıveis no diagrama Ladder, o temporizador timer ON e o modelo
de timer utilizado nesse trabalho. O temporizador TON inicia sua contagem no
momento em que e energizado. Nesse momento a entrada IN e ativada. Durante o
processo de contagem, ET e incrementado ao passo de milissegundos. Assim que ET
alcancar o valor predefinido em PT, a saıda Q e energizada. Se durante o processo de
contagem o sinal logico de entrada (IN) se tornar falsa antes que ET alcance o valor
preestabelecido, faz com este zere a contagem necessitando de nova alimentacao para
reiniciar sua temporizacao. A figura 3.10 ilustra um temporizador TON.
Figura 3.10: Temporizador TON
3.3.4 Estrutura de Funcionamento
O diagrama Ladder segue uma estrutura definida para que funcione adequadamente.
As regras basicas sao:
• A linhas verticais sao denominadas linhas de alimentacao ou linhas-mae;
• Das linhas verticais saem linhas horizontais que realizam ligacoes com os ele-
mentos do diagrama Ladder;
• As bobinas estao sempre a direita;
• O fluxo de execucao ocorre de cima para baixo e da esquerda para a direita.
Exemplo 3.3.1. No exemplo da figura 3.11, mostra-se o do funcionamento do di-
agrama Ladder, usando o acionamento de um motor para exemplificar. Se o botao
“STOP” nao estiver pressionado e o botao “START” for pressionado, o “MOTOR”
entrara em funcionamento, continuando ate que botao “STOP” seja pressionado.
Isso acontece por causa do contato NA associado a variavel “MOTOR” que criara
um caminho que mantera a bobina energizada.
19
Figura 3.11: Controle de partida / parada do motor com travamento
3.4 Conversao de RPICs para Ladder
As redes de Petri interpretadas para controle tem se mostrado uma ferramenta
adequada para representar sistemas a eventos discretos, fornecendo uma alta capa-
cidade de modelar e controlar plantas industriais. Entretanto, RPICs sao apenas
modelos teoricos e nao constituem um tipo de linguagem de programacao, conforme
estabelecido na norma IEC 1131-3 [13].
Pensando nisso, um metodo de conversao de RPICs para Ladder foi proposto
por MOREIRA et al. [14]. O metodo consiste em construir o diagrama Ladder
dividido em cinco modulos: (i) o modulo de eventos; (ii) o modulo de condicoes
para o disparo; (iii) o modulo da dinamica; (iv) o modulo de inicializacao; (v) o
modulo de acoes. Todos os modulos serao explicados em detalhes a seguir.
Observacao 3.4.1. Para explicarmos o metodo de conversao, utilizaremos o sistema
de sinal de transito, descrito no exemplo 2.3.1.
3.4.1 Modulo de Eventos
O modulo de eventos sao associados as bordas de subida ou descida dos sensores. A
mudanca do valor logico do sinal de um sensor e detectada usando um contato “tipo
P” ou um contato “tipo N”. Esses contatos fecham por um ciclo quando detectada
a mudanca de valor logico da variavel associada. O modulo de eventos possui um
numero de linhas igual ao numero de eventos externos do sistema.
20
3.4.2 Modulo de Condicoes para o Disparo
O modulo das condicoes para o disparo define as condicoes de habilitacao das
transicoes, tais como: um evento, um atraso, etc. Em que cada linha esta asso-
ciada a uma unica transicao. As condicoes sao definidas pela associacao em serie de
contatos NA, em que cada linha representa a conexao dos lugares de entrada com
as transicoes.
Na figura 3.12 esta representado o modulo de condicoes para o disparo correspon-
dente a rede de Petri da figura 2.7.
Figura 3.12: Modulo de condicoes para o disparo
3.4.3 Modulo da Dinamica
O modulo da dinamica atualiza o estado do sistema, distribuindo as fichas nos lugares
de acordo com o disparo de uma determinada transicao. No modulo da dinamica,
os lugares que receberam ficha apos o disparo da transicao sao representados por
bobinas SET e os lugares que perderao fichas sao representados por bobinas RESET.
21
Na figura 3.13 esta representado o modulo da dinamica correspondente a rede de
Petri da figura 2.7.
Figura 3.13: Modulo da dinamica
3.4.4 Modulo de Inicializacao
O modulo de inicializacao e formado por uma unica linha, que contem um contato
normalmente fechado (NF) associado a uma variavel binaria interna, durante o pri-
meiro ciclo de varredura, sao energizadas bobinas SET que estao associadas aos
22
lugares que possuem marcacao inicial. Terminado o primeiro ciclo de varredura, o
contato NF e fechado, nao permitindo que a linha seja novamente executada.
Na figura 3.14 esta representado o modulo de inicializacao correspondente a rede de
Petri da figura 2.7.
Figura 3.14: Modulo de inicializacao
3.4.5 Modulo de Acoes
O modulo de acoes associa uma bobina ao lugar que possuir uma acao. As acoes
somente sao executadas quando a marcacao de um lugar mudar o valor logico de
falso para verdadeiro. Cada bobina do modulo de acoes representa uma variavel
booleana que e associada a saıda do CLP. Alem disso, os contatos associados as
bobinas SET do modulo da dinamica acionam as bobinas simples em cada linha do
modulo das acoes.
Na figura 3.15 esta representado o modulo de acoes para o disparo correspondente
a rede de Petri da figura 2.7.
Figura 3.15: Modulo de acoes
23
3.5 Identificacao de Sistemas a Eventos Discretos
Dado um sistema controlado e livre de falhas, e possıvel gerar um modelo a eventos
discretos a partir dos sinais de entrada e saıda do controlador. Esse processo e
conhecido como identificacao. Em [9, 15, 16], sao propostos metodos de identificacao
de sistemas a eventos discretos. O objetivo desses metodos e a deteccao de falhas
com base na observacao do comportamento livre de falhas no sistema. E importante
ressaltar que a observacao sem falhas e feita atraves da aquisicao das entradas e
saıdas do controlador por um longo perıodo de tempo.
A figura 3.16 mostra a interacao entre os componentes de uma SED, em que os sinais
de entrada e saıda sao variaveis booleanas, ou seja, podem armazenar dois valores:
TRUE (1) ou FALSE (0).
Figura 3.16: Comunicacao entre os componentes em um SED em malha fechada.
Supondo que o controlador possui mo saıdas binarias e mi entradas binarias,
pode-se representar os estados alcancaveis do sistema criando um vetor de saıdas
(atuadores) e entradas (sensores) da seguinte maneira:
u(tj) =[
o1(tj) · · · omo(tj) i1(tj) · · · imi(tj)
]TO vetor u(t) representa o status do sistema em um instante t, em que ok(t) e o
valor da variavel da saıda ok e ip(t) e o valor da variavel da entrada ip no instante
t. O sistema permanecera no estado u(t) ate que algum dos elementos do vetor seja
alterado. Para ilustrar essa ideia, considere o exemplo a seguir.
Exemplo 3.5.1. Suponha que um sistema controlado e livre de falhas, com 1 atu-
ador e 2 sensores, gere a seguinte sequencia s1 de 3 vetores de saıdas e entradas
u(t1), u(t2) e u(t3):
s1 = [ 1 0 1 ]T , [ 0 1 0 ]T , [ 1 1 1 ]T
Isso significa que no instante t1, o atuador o1 e o sensor i2 estavam ligados.
Apos a subida do sensor i1, no instante t2, ambos foram desligados. E finalmente,
24
no instante t3, todos os sinais estao ligados. Neste trabalho, essas sequencias serao
rearranjadas em uma matriz cujas linhas representam vetores de entrada e saıdas, e
o 0 e substituıdo por “False” e 1 e substituıdo por “True”. Sendo assim, a sequencia
s1 pode ser representa pela matriz A1 tal que:
A1 =
True False True
False True False
True True True
As metodologias de identificacao desenvolvidas em [9, 15–18] utilizam os vetores
das entrada e saıdas, tornando o metodo de aquisicao de dados, uma das partes
mais importantes para obtencao de um bom modelo identificado. Por isso, o PLC
Connect e uma ferramenta muito util, pois permite ao usuario a gravacao dos dados
adquiridos em um arquivo pronto para ser utilizado em um modelo de identificacao.
Observacao 3.5.1. Este trabalho nao tem o objetivo de explorar as metodologias de
identificacao, envolvendo-se somente com a tarefa de coletar os sinais necessarios
para servir como entrada dos algoritmos de identificacao presentes na literatura.
25
Capıtulo 4
PLC Connect
Nos capıtulos anteriores foram apresentados os conceitos necessarios para o enten-
dimento do funcionamento do PLC Connect. Neste capıtulo sera apresentado o
programa, sua arquitetura, sua interface, seus recursos e a forma de utilizacao. Para
tanto, esse capıtulo esta estruturado da seguinte forma: Na secao 4.1 e apresentada
uma visao geral de seus recursos e as vantagens de sua utilizacao. A secao 4.2 contem
o guia de utilizacao do usuario.
4.1 Visao Geral
Dentre as maneiras de se obter os valores das entradas/saıdas de um sistema, pode-
mos dividir os metodos de aquisicao de dados em duas categorias. Na primeira, os
dados sao registrados continuamente e, na segunda, e utilizado um buffer, onde os
dados sao armazenados e registrados em intervalo de tempo predefinidos. A maneira
usual para fazer a aquisicao de dados em um CLP da Siemens e usando Datalogs
[4, 7]. Os Datalogs sao blocos que podem ser utilizados dentro do diagrama Ladder,
permitindo que os dados sejam armazenados no cartao de memoria do proprio CLP.
Contudo, esse metodo apresenta algumas restricoes:
• Necessidade de acesso e edicao do projeto
Para a aquisicao de dados na maiorias dos sistemas industriais, nao seriam per-
mitidas as alteracoes no projeto, ja que isso poderia levar um sistema funcional
a falhar devido as alteracoes.
• Conhecimento das funcoes necessarias para a gravacao
No ambiente de projeto da Siemens, chamado TIA PORTAL, existem blocos
que possuem as funcoes necessarias para a gravacao, apesar disso ainda e
necessario conhecimento de como utiliza-los, nao sendo uma tarefa trivial.
26
• Falta de confiabilidade na gravacao de dados
Durante o processo de aquisicao dos sinais, nenhum tipo de confirmacao e
dada, ou seja, e possıvel que o sistema esteja rodando sem que a aquisicao de
dados esteja acontecendo.
A ideia de desenvolver o PLC Connect surgiu pela necessidade de se obter os
valores das entradas/saıdas, sem que seja necessario fazer alteracoes no projeto. A
escolha de desenvolver esse programa em Python se deve pela versatilidade desta
linguagem de programacao: orientada a objetos , funcional, de tipagem dinamica e
forte e sem a necessidade da compra de uma licenca.
4.2 Guia do Usuario e Apresentacao da Interface
4.2.1 Instalacao
O PLC Connect possui um instalador simples e intuitivo, nao sendo necessario
nenhuma instalacao extra para que o programa funcione adequadamente.
Passo 01 - Ao iniciar o processo de instalacao, sera necessario escolher o idioma
do instalador, conforme a figura 4.1, o idioma padrao e “Portugues Brasileiro”. Apos
a escolha do idioma pode-se dar continuidade a instalacao clicando em “OK”.
Figura 4.1: Escolha do idioma do instalador
Passo 02 - Na proxima etapa mostrada na figura 4.2, e necessario escolher o
local de instalacao do programa, estando tudo certo, apenas clique em “Proximo”.
27
Figura 4.2: Escolha do destino para instalacao
Passo 03 - Nesse ponto e necessario informar se devera criar os ıcones e atalhos
do menu “Iniciar”, apenas clique em “Proximo”, conforme ilustra a figura 4.3.
Figura 4.3: Criar atalhos no menu iniciar
Passo 04 - Agora e necessario informar se devera criar o atalho da “area de
trabalho”, clique no checkbox para que um atalho seja criado e clique em “Proximo”
para continuar com a instalacao, como mostrado na figura 4.4.
28
Figura 4.4: Criar atalhos na area de trabalho
Passo 05 - Como mostrado na figura 4.5, somente e necessario confirmar as
informacoes passadas anteriormente, se estiver tudo certo, basta clicar em “Instalar”.
Figura 4.5: Confirmacao de instalacao
Passo 06 - Na parte final da instalacao, basta clicar em “Concluir”, conforme
ilustra a figura 4.6.
29
Figura 4.6: Concluir instalacao
Apos seguir essa breve demonstracao de como realizar a instalacao do programa,
o ıcone da figura 4.7 estara disponıvel na “area de trabalho”, caso contrario, o
encontrara no diretorio escolhido para instalacao.
Figura 4.7: Atalho do PLC Connect
4.2.2 Configuracoes Necessarias
O CLP Siemens S7-1200 (a partir da versao de firmware 4.0) e o S7-1500 possuem
firewall embutido, e por padrao, o nıvel maximo de protecao e ativado. Para estabe-
lecer a comunicacao com esses modelos de CLP e necessario ativar as comunicacoes
com dispositivos de terceiros, essa configuracao esta disponıvel no software de pro-
gramacao do TIA Portal, conforme explicado a seguir. Acesse as propriedades do
projeto e no item Protection, selecione Full access (no protection) e marque Permit
access with PUT/GET communication from remote partner, como na figura 4.8.
30
Figura 4.8: Propriedades do projeto no TIA Portal
Acesse as propriedades do banco de dados e desmarque Optimized block access,
como pode ser visto na figura 4.9.
Figura 4.9: Propriedades do banco de dados no TIA Portal
4.2.3 Interface
O PLC Connect possui uma interface simples, como exibido na figura 4.10, fa-
cilitando a aquisicao de dados, estando dividido em alguns GroupBox, isto e, os
elementos graficos do PLC Connect estao agrupados em quadros de acordo com
sua funcionalidade. A interface e dividida nos seguintes GroupBox : (i) Group-
Box Connection que e responsavel pela conexao entre os CLP e o PLC Connect;
(ii) GroupBox Outputs e Inputs que sao os campos onde serao inseridos os dados
do projeto; (iii) GroupBox Data logging to file utilizado para criar o arquivo de
gravacao; (iv) GroupBox Recording utilizado para iniciar ou parar a gravacao dos
31
sinais. Na figura 4.10, e mostrada a interface do PLC Connect com os Groupbox
citados anteriormente. Todos os Groupbox serao explicados em detalhes a seguir.
Figura 4.10: PLC Connect
GroupBox Connection
No GroupBox Connection serao inseridos as informacoes para realizar a conexao
entre o software e o CLP. Alem do endereco IP, existem outros dois parametros
que indexam a unidade: rack (0..7) e slot (1..31), encontrados na configuracao do
hardware [19]. No entanto, existem alguns casos especiais em que esses valores sao
fixos ou podem funcionar com um padrao. Tais valores podem ser resumidos na
tabela 4.1.
Tabela 4.1: Padrao de rack e slot de alguns dispositivos
Rack Slot
S7 300 CPU 0 2 Sempre
S7 400 CPU Nao fixado Veja na configuracao do hardware
WinAC CPU Nao fixado Veja na configuracao do hardware
S7 1200 CPU 0 0 Ou 0,1
S7 1500 CPU 0 0 Ou 0,1
WinAC IE 0 0 Ou veja na configuracao do hardware
32
A figura 4.11 mostra uma conexao bem-sucedida entre um CLP Siemens SIMA-
TIC S7-1500 e o PLC Connect.
Figura 4.11: Conexao bem-sucedida com o CLP
Caso a tentativa de conexao nao tenha exito, sera mostrada uma mensagem,
como pode ser visto na figura 4.12, sendo necessario verificar os parametros infor-
mados e entao fazer uma nova tentativa de conexao.
Figura 4.12: Erro na tentativa de conexao com o CLP
GroupBox Outputs e Inputs
Para inserir as variaveis definidas no projeto, existe dois metodos:
1. Inserindo manualmente as variaveis.
2. Utilizando um arquivo (*.xlsx) com todas as variaveis definidas no projeto,
conforme descrito no apendice C. Para isso, basta clicar na seta colorida em
amarelo no canto inferior esquerdo da figura 4.13 e selecionar o arquivo dese-
jado.
Os botoes demarcados em vermelho na figura 4.13, servem para inserir e remover
linhas de sua tabela correspondente .
33
Figura 4.13: Inserir variaveis do projeto
Observacao 4.2.1. O nome das variaveis inseridas nao necessitam ser iguais as
definidas no projeto, apenas o endereco e o tipo devem ser os mesmos.
GroupBox Data logging to file
No GroupBox Data logging to file serao adicionados o nome do arquivo (*.csv) em
que os dados serao inseridos e o intervalo (em segundos) em que esses dados serao
capturados. Para acessar o local do arquivo, utilize o atalho Ctrl + Q. A figura 4.14
ilustra a criacao de um arquivo csv.
Figura 4.14: Criando o arquivo *.csv
GroupBox Recording
No GroupBox Recording, os dois botoes sao utilizados para iniciar ou parar a
aquisicao de dados. A figura 4.15 ilustra a gravacao de um arquivo.
Figura 4.15: Gravar arquivo
34
Observacao 4.2.2. Inicialmente alguns botoes comecam desabilitados, sendo ha-
bilitados somente quando alguns dos GroupBoxs forem preenchidos. Uma possıvel
solucao e preencher os GroupBoxs na ordem apresentada nesta secao.
Retomemos agora o sistema de semaforos no cruzamento do exemplo 2.3.1, a fim
de ilustrar o resultado da sua aquisicao de entradas e saıdas, mostrado na figura
4.16. Note que esse sistema nao possui entrada e possui 6 saıdas representando os
atuadores de cada cor: as variaveis “Verde 01”, “Amarelo 01” e “Vermelho 01” re-
presentam as luzes indicativas do primeiro conjunto de semaforos do exemplo 2.3.1
e as variaveis “Verde 02”, “Amarelo 02” e “Vermelho 02” representam o segundo
conjunto de semaforos. Inicialmente, a luz verde do primeiro semaforo esta ligada,
enquanto no segundo semaforo a luz vermelha esta acionada. Ao passar o tempo
predefinido para essas luzes ficarem acessas, a luz amarela do primeiro semaforo e
acessa, seguida da luz vermelha. Entao a luz verde do segundo semaforo e acionada,
realizando o mesmo ciclo do primeiro semaforo. E importante ressaltar que a pri-
meira coluna da tabela da figura 4.16 mostra a hora exata em que cada foi gravado.
O intervalo de tempo de gravacao de dados segue a escolha definida no GroupBox
Data logging to file.
Figura 4.16: Aquisicao de dados do exemplo 2.3.1
35
Capıtulo 5
Projeto do Controlador e
Aquisicao de Dados de uma Planta
Virtual e de um Sistema de
Manufatura Real
Uma vez que o PLC Connect foi apresentado, iremos ilustrar e validar a sua uti-
lizacao com dois projetos de controladores a eventos discretos: um para uma planta
virtual e outro para uma planta real. A planta virtual foi construıda no software
de simulacao chamado Factory I/O, enquanto a planta real e um modulo seletor de
pecas que esta presente no Laboratorio de Controle e Automacao da UFRJ. Para
realizacao do projeto, primeiramente iremos modelar os sistemas utilizando RPIC
e em seguida converter para diagrama Ladder utilizando o algoritmo proposto por
MOREIRA e BASILIO [20]. Os diagramas entao serao inseridos em um CLP, para
que seja feito o controle dos mesmos. Por fim, apresentaremos os resultados forne-
cidos pelo PLC Connect.
Neste capıtulo serao apresentados os projetos das duas plantas. Na Secao 5.1
e apresentado o projeto da planta virtual e na Secao 5.2 e apresentado projeto da
planta real.
5.1 Projeto da Planta Virtual
Para desenvolvimento desta secao foi utilizado um software de simulacao de ambi-
entes virtuais Factory I/O, esse software permite a criacao e simulacao dos mais
variados ambientes industriais, por utilizar um motor fısico com execucao em tempo
real que resulta em cenarios realistas.
A Factory I/O fornece uma colecao de pecas com base nos equipamentos in-
36
dustriais mais comuns. Essas pecas estao organizadas em oito categorias: itens,
transportadores de carga pesada, transportadores de carga leve, sensores, operado-
res, estacoes, dispositivos de alerta e passarelas. Nesta secao, serao apresentadas as
informacoes sobre os dispositivos utilizados pelo autor ao longo desse trabalho.
5.1.1 Sensor Retrorreflexivo e Refletor
O sensor retrorreflexivo, mostrado na figura 5.1, e responsavel por detectar a pre-
senca de objetos, independente da superfıcie, cor ou material. Diferentemente dos
outros sensores, esse sensor necessita estar alinhado com um refletor para que funci-
one corretamente. Caso exista um objeto entre o sensor e o refletor, o sensor retorna
uma variavel booleana com valor “falso”, caso contrario retorna a variavel booleana
com valor “verdadeiro”.
Figura 5.1: Sensor retrorreflexivo e refletor. Extraıdo de [1]
5.1.2 Transportadores de Carga Pesada
Esta categoria inclui todas as pecas adequadas para o manuseio de cargas pesadas,
cujo proposito e transportar os itens ao longo da fabrica. Os equipamentos sao
robustos, largos, de baixa altura e opera em baixa velocidade.
Esteira Transportadora
As esteiras transportadoras sao bastantes comuns em instalacoes industriais, no
ambiente de simulacao do Factory existem 3 tipos de esteiras, variando apenas o
comprimento, sendo esteiras de 2m, 4m, 6m. A esteira possui dois modos de funci-
onamento: a digital e a analogica.
Na configuracao digital a esteira se move em apenas uma direcao com velocidade
constante ou permanece parada, obedecendo uma variavel booleana.
Na configuracao analogica e possıvel controlar a velocidade e o sentido de rotacao.
Nesse trabalho foi utilizada a esteira com configuracao digital. A figura 5.2 ilustra
uma esteira transportadora usada no software Factory I/O.
37
Figura 5.2: Esteira transportadora. Extraıdo de [1]
5.1.3 Transportadores de Carga Leve
Essa categoria inclui todas as pecas adequadas para o manuseio de carga leve, tendo
o mesmo proposito dos transportadores de carga pesada. Esse equipamento e proje-
tado para executar uma tarefa rapidamente e acompanhar o alto fluxo de trabalho
e por isso operam em alta velocidade.
Correia Transportadora
As configuracoes e tipos de correias disponıveis no Factory I/O sao iguais aos da
esteira transportadora. Assim como no caso da esteira transportadora, uma correira
de configuracao digital, foi utilizada neste trabalho, conforme ilustrado na figura 5.3.
Figura 5.3: Correia transportadora. Extraıdo de [1]
5.1.4 Itens
O Factory I/O possui muitos objetos que sao passıveis de serem transportados ao
longo da instalacao, tais como: paletes, caixas simples, caixas empilhaveis e pecas
de plastico. A figura 5.4 ilustra estes itens, respectiavamente.
38
Figura 5.4: Itens. Extraıdo de [1]
Caixas
Existem quatro tipos diferentes de caixas, cada uma com tamanho e peso diferentes.
Nesse trabalho foi utilizado a caixa de tamanho medio, mostrada na figura 5.5, pois
resultou em uma melhor configuracao para a planta proposta.
Figura 5.5: Caixa media. Extraıdo de [1]
Paletes
Os paletes de madeira sao utilizados para empilhar e transportar todos os tipos de
carga. A figura 5.6 ilustra o palete utilizado na planta virtual.
Figura 5.6: Palete. Extraıdo de [1]
5.1.5 Estacoes de Trabalho
Manipulador Robotico
O manipulador robotico (pick and place), mostrado na figura 5.7, possui 4 graus de
liberdade e dois modos de funcionamento: analogico e digital. No modo digital, o
39
utilizado nesse trabalho, o manipulador move seus bracos na horizontal ou na ver-
tical entre as suas posicoes de extremidade. Para segurar objetos, o manipulador
possui um sugador, que pode ser ligado ou desligado. E possıvel tambem girar o
manipulador sob o pilar central e girar a ventosa de succao. Alem disso, o mani-
pulador possui sensores de movimentos dos seus bracos e detector de presenca de
objetos na ventosa de succao.
Figura 5.7: Manipulador robotico. Extraıdo de [1]
5.1.6 Operadores
Botoes
Um push-button (botao de pressao) e um dispositivo que ao ser pressionado abre ou
fecha contato, normalmente os push-buttons possuem acao momentanea, ou seja, a
conexao e aberta ou fechada somente enquanto o botao estiver pressionado. Eles
podem ser normalmente abertos (NA) ou normalmente fechados (NF). A figura 5.8
ilustra os push-buttons utilizados no projeto do Factory I/O, o botao “START ” re-
presentado em verde e um botao NA, enquanto o “STOP” representado em vermelho
e um botao NF.
Figura 5.8: Botoes. Extraıdo de [1]
40
5.1.7 Emissor e Removedor
Emissor
O emissor e utilizado para emitir um item para ser utilizado na cena. Sendo possıvel
escolher o item que sera emitido, o tempo entre as emissoes, o numero de itens e se
a posicao/orientacao de ser levada em consideracao ou pode ser aleatoria. Conforme
ilustrado na figura 5.9, o emissor e representado por uma seta verde apontada para
baixo.
Figura 5.9: Emissor. Extraıdo de [1]
Removedor
O removedor retira um ou mais itens da cena quando eles cruzam seu volume. Con-
forme ilustrado na figura 5.10, o removedor e representado por uma seta vermelha
apontada para cima.
Figura 5.10: Removedor. Extraıdo de [1]
5.1.8 Driver
Para que haja a conexao entre o Factory I/O e o CLP, o simulador conta com muitos
drivers, cada um destinado a ser usado com uma tecnologia especıfica. A figura 5.11
mostra as duas formas para acessar a janela dos drivers.
41
Figura 5.11: I/O drivers. Extraıdo de [1]
Na figura 5.12 e mostrada a janela dos drivers, onde e realizada a escolha do
CLP que sera utilizado para controlar a planta do Factory I/O. O driver selecio-
nado fornece a conexao Ethernet aos CLP Siemens S7-1200 e S7-1500. Tambem e
necessario fazer a associacao dos sensores e atuadores da planta aos seus respectivos
enderecos definidos no projeto.
Figura 5.12: Janelas dos drivers. Extraıdo de [1]
Na figura 5.13 e mostrada a janela das configuracoes, onde serao inseridos o mo-
delo do CLP, o endereco IP, o driver de rede e a quantidade de enderecos necessarios
para o controle da planta.
42
Figura 5.13: Janelas das configuracoes. Extraıdo de [1]
5.1.9 Simulacao
A planta desenvolvida no Factory I/O, mostrada na figura 5.14, tem como objetivo
colocar duas caixas sobre o palete, utilizando o manipulador robotico. O projeto do
controlador desse sistema foi realizado utilizando RPIC e a conversao de RPIC para
Ladder. A RPIC e o diagrama Ladder referentes ao sistema da figura 5.14 podem
ser encontrados no apendice A e B, respectivamente.
O sistema da figura 5.14 conta com 6 saıdas (outputs) e 9 entradas (inputs),
numeradas da seguinte forma:
• o1: “Belt Conveyor”, que e o atuador relacionado a correia transportadora;
• o2: “Roller Conveyor 1 ”, atuador responsavel pelo movimento da primeira
parte da esteira;
• o3: “Roller Conveyor 2 ”, atuador que movimenta a segunda parte da esteira;
• o4: “Move X ”, atuador do manipulador robotico que permite o seu movimento
no eixo X;
• o5: “Move Z ”, atuador do manipulador robotico que permite o seu movimento
no eixo Z;
• o6: “Grab”, atuador do manipulador robotico que permite que objetos sejam
agarrados;
43
• i1: “Box at place”, sensor retrorreflexivo localizado na parte final da correia
transportadora;
• i2: “Pallet at place 1 ”, sensor retrorreflexivo que permite a parada da esteira
para posicionamento da primeira caixa;
• i3: “Pallet at place 2 ”, sensor retrorreflexivo que permite a parada da esteira
para posicionamento da segunda caixa;
• i4: “End Sensor”, sensor retrorreflexivo que permite a parada da segunda
esteira;
• i5: “Move X Sensor”, sensor que informa se o atuador “Move X” se encontra
ativado;
• i6: “Move Z Sensor”, sensor que informa se o atuador “Move Z” se encontra
ativado;
• i7: “Grab Sensor”, sensor que informa se existe algum objeto na ventosa de
succao do manipulador robotico;
• i8: “Start”, botao que inicializa a planta;
• i9: “Stop”, botao que informa o fim da aquisicao de dados.
Figura 5.14: Planta virtual, numerada da seguinte forma: de 1 ate 6 sao as saıdas(outputs) e de 7 a 15 sao as entradas (inputs).
O comportamento controlado e livre de falhas do sistema e descrito a seguir.
Apos o botao “START ” ser pressionado, a primeira parte da esteira transportadora
e a correia transportadora sao acionadas, estando ativada ate alcancarem os seus
respectivos sensores retrorreflexivos. Como pode ser visualizado na figura 5.15.
44
Figura 5.15: Caixa parada no sensor i1 e palete no sensor i2
Quando o palete e a caixa estiverem parados nos sensores, o manipulador robotico
e acionado, pegando a primeira caixa e a colocando no palete, como na figura 5.16.
Assim que a caixa e retirada da frente do sensor, a correia transportadora entra em
movimento.
Figura 5.16: Posicionamento da primeira caixa
Apos a primeira caixa ser posicionada no palete, a esteira e ligada ate que se
alcance o segundo sensor. Se a caixa ja estiver alcancado a extremidade da correia,
o manipulador robotico pegara a segunda caixa e a posicionara no palete, conforme
mostrado na figura 5.17.
45
Figura 5.17: Manipulador robotico pegando a segunda caixa
Assim que a segunda caixa estiver no palete, a primeira parte da esteira e ligada,
quando o palete sair do segundo sensor, a segunda parte da esteira tambem sera
ligada, conforme mostrado na figura 5.18.
Figura 5.18: Posicionamento da segunda caixa
Na figura 5.19 mostra a primeira parte da esteira realizando o mesmo ciclo des-
crito acima, porem a segunda parte da esteira se encontra ativa, levando o palete e
as caixas para serem removidas.
46
Figura 5.19: Acionamento da segunda esteira
Quando o palete com as caixas alcancarem o sensor posicionado em frente ao
“removedor”, apos alguns segundos a segunda parte da esteira e desligada, como
mostrada na Figura 5.20.
Figura 5.20: Eliminacao dos itens
No total do experimento foi realizada uma simulacao de 8h, gerando uma matriz
com 15 colunas (soma das saıdas e entradas) e 47917 linhas, representando o vetor de
saıdas e entradas descrito na secao 3.5. O longo tempo de aquisicao esta relacionado
com a eficacia dos modelos para identificacao de SEDs. Uma vez que a maioria dos
modelos sao do tipo “caixa-preta”, ou seja, nao ha o conhecimento da topologia do
sistema e nem o momento em que o sistema faz um ciclo, e necessario fornecer a
maior quantidade de informacoes possıvel sobre o comportamento da planta (vetor
de saıdas e entradas). Na figura 5.21 e 5.22 e mostrada uma pequena parte do
resultado, por uma questao de espaco. Assim que o botao “START ” e pressionado,
“Belt Conveyor” e “Roller Conveyor” sao acionadas, permanecendo assim ate que
os itens alcancem os sensores “Box at place” e “Pallet at place 1 ”, respectivamente.
47
Nesse momento, o manipulador robotico inicia seu movimento em X, seguido de Z,
logo em seguida a caixa e pega pelo manipulador.
Figura 5.21: Aquisicao dos outputs da planta virtual
Figura 5.22: Aquisicao dos inputs da planta virtual
Na figura 5.23 e mostrada a configuracao necessaria para a aquisicao de dados
utilizando o PLC Connect. Para isso, foi fornecido o IP, slot e rack para o CLP Sie-
mens S7-1500. Tambem e necessario informar os enderecos dos sensores e atuadores,
nome do arquivo de gravacao e tempo de leitura.
48
Figura 5.23: PLC Connect durante aquisicao dos dados da planta virtual
5.2 Sistema Didatico de Manufatura
O objetivo dessa secao e apresentar a aquisicao de sinais provenientes de uma planta
didatica de manufatura, cujo objetivo e efetuar a selecao de pecas. Antes de mostrar
o sistema como um todo, sera feita uma breve descricao dos componentes presentes
no sistema.
5.2.1 Pecas
As pecas podem ser de dois materiais, metal ou plastico, e as de plastico podem ser
brancas ou pretas. A figura 5.24 ilustra essas pecas.
Figura 5.24: Metades do cubo. Extraıdo de [2].
49
5.2.2 Sensores
Os sensores ilustrados na figura 5.25 sao utilizados para detectar a presenca da peca
e o tipo da mesma.
Figura 5.25: Conjunto de sensores. Editado de [2].
• O Sensor indutivo e um dispositivo eletronico capaz de detectar a proximi-
dade de objetos metalicos.
• O Sensor optico e capaz de determinar se a cor da peca presente na esteira
e diferente de preta.
• O Sensor ultrassonico e capaz de detectar a presenca de objetos, indepen-
dente da cor ou material de fabricacao, o sensor ultrassonico utilizado retorna
valores numericos.
5.2.3 Atuadores
Empurradores
A parte dos empurradores e formada por 3 grupos, como mostra a figura 5.26. Cada
grupo possui um cilindro pneumatico e um sensor de presenca e sao usados para
empurrar as pecas, dependendo da logica de classificacao e da peca identificada.
50
Figura 5.26: Conjunto de empurradores. Editado de [2].
Armazenador
O armazenador e uma unidade com o objetivo de armazenar as metades do cubo
a serem usadas. Cada compartimento possui um cilindro pneumatico e um sensor
de fim de curso. O cilindro e utilizado para extrair uma peca do fundo da pilha
e a chave de fim de curso serve para saber se a pilha esta vazia ou nao. Existem
tambem 2 sensores usados para saber se os cilindros sao estendidos ou retraıdos. O
armazenador pode ser visto na figura 5.27.
Figura 5.27: Armazenador. Editado de [2].
51
Correia Transportadora
A correia transportadora tem o objetivo de conduzir as pecas ate os empurradores.
A correia transportadora e mostrada na figura 5.28.
Figura 5.28: Correia transportadora. Editado de [2].
5.2.4 A Planta de Manufatura Didatica
A planta de manufatura localizada no Laboratorio de Controle e Automacao (LCA),
encontra-se na figura 5.29. A esteira possui sensores capazes de identificar a cor
de um objeto plastico (preto ou branco), o tipo de objeto (metalico ou plastico)
e a chegada de um objeto. Alem disso, ao longo da esteira, existem empurrado-
res para selecionar as pecas de acordo com a cor e material. O sistema separa as
pecas metalicas empurrando-as para fora da esteira pelo empurrador mais proximo
da entrada de pecas na esteira, separa as plasticas brancas utilizando o segundo
empurrador e as plasticas pretas usando o terceiro empurrador. O projeto do con-
trolador desse sistema foi realizado utilizando RPIC e a conversao de RPIC para
Ladder. A RPIC e o diagrama Ladder referentes ao sistema da figura 5.29 podem
ser encontrados no apendice A e B, respectivamente.
O sistema da figura 5.29 conta com 8 saıdas (outputs) e 18 entradas (inputs),
numeradas da seguinte forma:
• o1: Estica Rej3, atuador responsavel pelo acionamento do terceiro rejeitador;
• o2: Estica Rej2, atuador relacionado ao segundo rejeitador;
• o3: Estica Rej1, atuador responsavel pelo acionamento do primeiro rejeitador;
• o4: Estica E1, atuador que estica o primeiro empurrador;
• o5: Recua E1, atuador que recua o primeiro empurrador;
• o6: Estica E2, atuador que estica o segundo empurrador;
• o7: Recua E2, atuador que recua o segundo empurrador;
• o8: Liga Esteira, atuador relacionado a correia transportadora;
52
• i1: E1A, sensor que indica se o empurrador 1 se encontra esticado;
• i2: E1R, sensor que indica se o empurrador 1 se encontra recuado;
• i3: temPecaA1, sensor responsavel por verificar a presenca de peca no arma-
zenador 1;
• i4: E2A, sensor que indica se o empurrador 2 se encontra esticado;
• i5: E2R, sensor que indica se o empurrador 2 se encontra recuado;
• i6: temPecaA2, sensor responsavel por verificar a presenca de peca no arma-
zenador 2;
• i7: Rej3 A, sensor que informa se o rejeitador 3 se encontra esticado;
• i8: Rej3 R, sensor responsavel por informar se o rejeitador 3 esta recuado;
• i9: Rej2 A, sensor que indica se o rejeitador 2 esta esticado;
• i10: Rej2 R, sensor responsavel por indicar se o rejeitador 2 esta recuado;
• i11: Rej1 A, sensor que informa se o rejeitador 1 se encontra esticado;
• i12: Rej1 R, sensor que indica se o rejeitador 1 se encontra recuado;
• i13: Soptico, sensor optico;
• i14: Smetalico, sensor indutivo;
• i15: SP3, sensor de presenca relacionado ao rejeitador 3;
• i16: SP2, sensor de presenca relacionado ao rejeitador 2;
• i17: SP1, sensor de presenca relacionado ao rejeitador 1;
• i18: Su, sensor ultrassonico.
53
Figura 5.29: Planta de manufatura, numerada da seguinte forma: de 1 ate 8 sao assaıdas (outputs) e de 9 a 26 sao as entradas (inputs).
O comportamento controlado e livre de falhas do sistema e descrito a seguir.
As pecas sao colocadas na esteira utilizando-se dois empurradores1 (um para cada
armazenador de pecas) alternadamente. Antes de acionar os empurradores o4 e o6,
deve-se verificar a disponibilidade de pecas nos armazenadores. Isto e feito por meio
da leitura dos sensores i3 e i6, os quais indicam a presenca (ou nao) de peca. Uma
vez escolhido o armazenador, o empurrador correspondente e acionado, de modo
a colocar a peca na esteira. Neste projeto, o sensor i18 (ultrassonico) e utilizado
somente como um sensor de presenca. Uma vez detectada a presenca de uma peca,
sua identificacao e feita por meio da leitura dos sensores i14 (indutivo) e i13 (optico),
como pode ser visto na figura 5.30.
1Os outros empurradores, utilizados para selecionar as pecas ao longo da esteira, sao denomi-nados rejeitadores.
54
Figura 5.30: Planta de manufatura com metades do cubo posicionados
Para identificar o tipo de peca e utilizada a seguinte classificacao, em que, So e
Si, sao os sensores opticos e indutivos, respectivamente:
• So = 1 e Si = 0: peca branca;
• So = 1 e Si = 1: peca metalica;
• So = 0 e Si = 0: peca preta.
Apos a identificacao da peca, esta deve ser empurrada para fora da esteira pelo
rejeitador correspondente.
Foi realizada um simulacao de 2h, gerando uma matriz com 26 colunas (soma
das saıdas e entradas) e 5312 linhas, representando o vetor de saıdas e entradas. As
figuras 5.31 e 5.32 ilustram uma pequena parte do resultado proveniente do PLC
Connect para aquisicao dos dados das saıdas e entradas da planta mecatronica. Note
que de acordo com as tabelas da figuras 5.31 e 5.32, assim que a planta e iniciada,
o Estica E1 e acionado, apos seu recuo a esteira e ligada. Ao passar pelos sensores
Soptico e Smetalico, os dois valores estao em TRUE, identificando uma peca de
metal e no ultimo instante a peca e empurrada pelo Estica Rej1.
55
Figura 5.31: Aquisicao dos outputs da planta real
Figura 5.32: Aquisicao dos inputs da planta real
56
Capıtulo 6
Conclusoes
Este trabalho teve como objetivo o desenvolvimento de um programa capaz de ser-
vir como um sistema de aquisicao de dados para identificacao de sistemas a eventos
discretos. Este programa permite obter os sinais de entrada (sensores) e saıda (atua-
dores) provenientes de um controlador logico programavel e grava-los em um arquivo
que pode ser usado para gerar um modelo para o sistema. As principais vantagens
do programa em relacao a metodos implementados em [4, 7] sao: (i) confiabilidade
na gravacao de dados; (ii) nao necessita de alteracoes no programa do projeto do
controlador do sistema, e (iii) funciona de uma maneira “plug-and-play”.
Nos exemplos desenvolvidos nesse trabalho o PLC Connect mostrou-se bastante
versatil, sendo capaz de fazer a aquisicao de dados tanto de plantas de manufatura
reais quanto virtuais.
Apesar do PLC Connect cumprir com os objetivos deste projeto, existem melho-
rias a serem implementadas. Uma das maiores necessidades e ampliar o numero de
modelos de CLPs compatıveis, deixando de estar restrito aos CLPs da Siemens. Um
outro trabalho futuro interessante e a integracao do PLC Connect com o programa
DESLAB, permitindo a geracao automatica de modelos de SEDs apos um tempo
pre-programado de gravacao de dados.
57
Referencias Bibliograficas
[1] GAMES, R. “Manual”. Disponıvel em: <https://docs.factoryio.com/
manual/>.
[2] “Ausbildung”. Disponıvel em: <https://www.christiani.de/ausbildung/>.
[3] CASSANDRAS, C. G., LAFORTUNE, S. Introduction to discrete event systems
(2nd ed.). USA: Springer, New York, NY., 2008.
[4] NOGUEIRA, R. A. IDENTIFICATION OF A MECHATRONIC SYSTEM.
Projeto de Graduacao, Escola Politecnica, Universidade Federal do Rio
de Janeiro, 2019.
[5] MOREIRA, M. V., LESAGE, J.-J. “Fault diagnosis based on identified discrete-
event models”, Control Engineering Practice, v. 91, pp. 104101, 2019.
[6] MOREIRA, M. V., LESAGE, J.-J. “Discrete event system identification with
the aim of fault detection”, Discrete Event Dynamic Systems, v. 29, n. 2,
pp. 191–209, 2019.
[7] DE SOUZA, R. P. C. UM MODELO TEMPORIZADO PARA
IDENTIFICACAO DE SISTEMAS A EVENTOS DISCRETOS.
Projeto de Graduacao, Escola Politecnica, Universidade Federal do Rio
de Janeiro, 2019.
[8] ROTH, M., LESAGE, J.-J., LITZ, L. “Black-box identification of discrete event
systems with optimal partitioning of concurrent subsystems”. In: Proce-
edings of the 2010 American Control conference, pp. 2601–2606. IEEE,
2010.
[9] KLEIN, S., LITZ, L., LESAGE, J.-J. “Fault detection of discrete event systems
using an identification approach”, IFAC Proceedings Volumes, v. 38, n. 1,
pp. 92–97, 2005.
[10] ESTRADA-VARGAS, A. P., LOPEZ-MELLADO, E., LESAGE, J.-J. “A
black-box identification method for automated discrete-event systems”,
58
IEEE Transactions on Automation Science and Engineering, v. 14, n. 3,
pp. 1321–1336, 2015.
[11] DA SILVA VIANA, G., MOREIRA, M. V., BASILIO, J. C. “Implementacao
de controladores a eventos discretos usando diagrama ladder com modulo
sincronizante”, Simposio Brasileiro de Automacao Inteligente, XI SBAI,
Fortaleza, Brasil, 2013.
[12] MIYAGI, P. E. Controle programavel: Fundamentos do controle de sistemas a
eventos discretos. Editora Blucher, 1996.
[13] JOHN, K. H., TIEGELKAMP, M. IEC 61131-3: Programming Industrial Au-
tomation Systems Concepts and Programming Languages, Requirements
for Programming Systems, Decision-Making Aids. Springer Publishing
Company, Incorporated, 2010.
[14] MOREIRA, M. V., BOTELHO, D. S., BASILIO, J. C. “Ladder diagram imple-
mentation of control interpreted Petri nets: A state equation approach”,
IFAC Proceedings Volumes, v. 42, n. 21, pp. 78–83, 2009.
[15] MOREIRA, M. V., LESAGE, J.-J. “Enhanced discrete event model for system
identification with the aim of fault detection”, IFAC-PapersOnLine, v. 51,
n. 7, pp. 160–166, 2018.
[16] ROTH, M., LESAGE, J.-J., LITZ, L. “An FDI method for manufacturing
systems based on an identified model”, IFAC Proceedings Volumes, v. 42,
n. 4, pp. 1406–1411, 2009.
[17] KLEIN, S. Identification of discrete event systems for fault detection purposes.
Tese de Doutorado, Cachan, Ecole normale superieure, 2005.
[18] ROTH, M. Identification and Fault Diagnosis of Industrial Closed-loop Discrete
Event Systems: Identifikation und Fehlerdiagnose Industrieller Ereignis-
diskreter Closed-Loop-Systeme. Logos Verlag Berlin GmbH, 2010.
[19] NARDELLA, D. “Snap7 Reference manual”, Settimino Reference manual,
2016.
[20] MOREIRA, M. V., BASILIO, J. C. “Bridging the gap between design and
implementation of discrete-event controllers”, IEEE Transactions on Au-
tomation Science and Engineering, v. 11, n. 1, pp. 48–65, 2013.
59
Apendice A
Rede de Petri Interpretada para
Controle
Figura A.1: Rede de Petri da planta virtual
60
Figura A.2: Rede de Petri da planta real
61
Apendice B
Arquivos em Ladder
B.1 Arquivos Planta Virtual
B.1.1 Modulo de Condicoes para o Disparo
62
63
B.1.2 Modulo da Inicializacao
64
B.1.3 Modulo da Dinamica
65
66
67
68
B.1.4 Modulo de Acoes
69
70
B.2 Arquivos Planta Real
B.2.1 Modulo de Condicoes para o Disparo
71
72
B.2.2 Modulo da Inicializacao
73
B.2.3 Modulo da Dinamica
74
75
76
77
B.2.4 Modulo de Acoes
78
79
Apendice C
Como Exportar Tags Utilizando o
TIA PORTAL 14
Para fazer a exportacao das tags do projeto, basta seguir os passos a seguir:
Passo 01 - Clique duas vezes em “Show all tags” para abrir a tabela de tags,
conforme mostrado na figura C.1.
Figura C.1: Tabela de tags do projeto
80
Passo 02 - Em seguida, clique no ıcone “Export” e informe o caminho do
arquivo, conforme mostrado na figura C.2.
Figura C.2: Escolhendo caminho para salvar o arquivo
Passo 03 - Defina o nome do arquivo para exportacao e confirme com “Salvar”,
conforme ilustrado na figura C.3.
Figura C.3: Nome do arquivo que sera gerado
81
Passo 04 - Por fim, confirme a exportacao com “OK”, conforme ilustrado na
figura C.4.
Figura C.4: Confirmacao da exportacao
82
Apendice D
Implementacao em Python
Este capıtulo tem como intuito apresentar e explicar o codigo fonte do PLC Connect,
de modo que facilite a compreensao do projeto, facilitando a implementacao de
novas funcoes ou correcao de bugs por futuros desenvolvedores. O PLC Connect
foi desenvolvido em Python 3.7.6. O primeiro passo necessario para a configuracao
de um ambiente de desenvolvimento Python e fazer a instalacao das dependencias.
Para o correto funcionamento do projeto, as seguintes dependencias devem estar
instaladas:
• certifi==2019.11.28
• numpy==1.18.1
• pandas==0.25.3
• PyQt5==5.14.1
• PyQt5-sip==12.7.0
• python-dateutil==2.8.1
• python-snap7==0.10
• pytz==2019.3
• six==1.14.0
• wincertstore==0.2
• xlrd==1.2.0
D.1 Back-End
Back-End e a parte do algoritmo onde ficam as funcoes que garantem que todas as
funcionalidades disponıveis na interface sejam executadas.
83
D.1.1 Bibliotecas
Nessa subsecao as bibliotecas necessarias para o funcionamento do software sao
importadas, estando disponıveis para serem utilizadas ao longo do algoritmo.
Algoritmo D.1.1: Bibliotecas
1 """
2 Created on Wed Jan 8 23:58:16 2020
3
4 @author: Creison Maique
5 """
6 #!/usr/bin/env python
7 # coding: utf-8
8 from snap7 import client as s7
9 from logging import error
10 from ctypes import
c_int32,create_string_buffer,cast,pointer,c_uint8,POINTER↪→
11 from snap7.snap7types import S7DataItem, S7AreaPA,S7AreaPE, S7WLBit ,
S7WLByte , S7WLWord ,S7WLDWord,S7WLReal↪→
12 from snap7.util import get_bool,get_int,get_dword,get_real
13 from time import sleep
14 from threading import Thread, Event
15 from pandas import DataFrame,to_numeric,concat,Series
16 from datetime import datetime,timedelta
17 from os import getcwd
18 import re
19 from struct import unpack
20 from snap7.common import check_error
21
22 home_path = getcwd()
D.1.2 Importando Dados
Essa subsecao tem como objetivo o processamento dos dados fornecidos pelo usuario
nos GroupBoxs INPUTS e OUTPUTS. Esse trecho de codigo disponibiliza os dados
fornecidos de forma que o restante do algoritmo possa processa-los.
Algoritmo D.1.2: Importando Dados
1 class Import_Data():
2
3 def __init__(self,table,tipo,num):
4 self.table = table
5 self.OUTPUTS = []
6 self.INPUTS = []
7 self.dataframe = []
8 self.tipo = tipo
9 self.num = num
10 self.retorno = []
11 # creates a new df from qtables dimensions,
84
12 # copies qtable (data & headers) to the df and returns the df
13
14 def qtable_to_dataframe(self):
15 col_count = self.table.columnCount()
16 row_count = self.table.rowCount()
17 headers = [str(self.table.horizontalHeaderItem(i).text()) for
i in range(col_count)]↪→
18
19 # df indexing is slow, so use lists
20 df_list = []
21 for row in range(row_count):
22 df_list2 = []
23 for col in range(col_count):
24 if (col!=self.num):
25 table_item = self.table.item(row,col)
26 df_list2.append('' if table_item is None else
str(table_item.text()))↪→
27 else:
28 table_item = self.table.cellWidget(row,col)
29 df_list2.append('' if table_item is None else
str(table_item.currentText()))↪→
30
31 df_list.append(df_list2)
32
33 self.dataframe = DataFrame(df_list, columns=headers)
34 self.retorno = self.dataframe.copy()
35
36 print(self.retorno)
37 return(self.retorno)
D.1.3 PLC Controller
Essa subsecao e utilizada para que o software estabeleca a conexao com o CLP. Sao
realizadas tres tentativas de conexao em intervalos de 5 segundos, caso a conexao
nao seja estabelecida um warning sera gerado.
Algoritmo D.1.3: PLC Controller
1 class PLC_Controller():
2
3 def __init__(self, address,rack,slot):
4
5 self.address = address
6 self.rack = rack
7 self.slot = slot
8 global plc_client
9 plc_client = s7.Client()
10
11 def connect(self):
12
85
13 tries = 0
14 stop_tries = 2
15 freq = 5
16 while tries < stop_tries and not plc_client.get_connected():
17 try:
18 print(str(tries + 1) + 'º tentativa de conectar-se ao
PLC ...')↪→
19
20 sleep(freq)
21 plc_client.connect(self.address, self.rack,
self.slot)#('IP-address', rack, slot)↪→
22 if(plc_client.get_connected()==True):
23 print('O PLC foi conectado com sucesso')
24 retorno = plc_client.get_connected()
25 return retorno
26
27 except Exception as e:
28 error("Warning na conex~ao PLC >>{}".format(e))
29 sleep(freq)
30
31 if tries == (stop_tries - 1):
32 print('N~ao foi possıvel realizar a conex~ao com o
CLP')↪→
33 retorno = plc_client.get_connected()
34 return retorno
35
36 tries += 1
37
38 def disconnect(self):
39
40 plc_client.disconnect()
41 plc_client.destroy()
D.1.4 Generator File
Nessa subsecao o algoritmo e responsavel pela aquisicao dos dados diretamente do
CLP e a gravacao desse dados em arquivo.
Algoritmo D.1.4: Generator File
1 class generator_file():
2
3 def __init__(self,filename,outputs,inputs):
4
5 self.filename = filename
6 self.OUTPUTS = outputs
7 self.INPUTS = inputs
8 self.name_file_csv = self.filename + ".csv"
9 self.data_items = []
10 self.fmts = []
86
11 self.retorno_read = []
12 self.result_PA = []
13 self.result_PE = []
14
15 def create_dataitem(self):
16
17 self.data_items = (S7DataItem * (len(self.OUTPUTS) +
len(self.INPUTS)))()↪→
18
19 d1 = ['Bool','Byte','Word','DWord','Real']
20 d2 = ['S7WLBit','S7WLByte','S7WLWord','S7WLDWord','S7WLReal']
21 d3 = ['1','8','16','32' ,'32']
22 d4 = ['>?','>h','>l','>f','>f']
23 WordLen_dict = dict(zip(d1, d2))
24 Amount_dict = dict(zip(d1, d3))
25 Struct_dict = dict(zip(d1, d4))
26
27
28 for values in self.OUTPUTS["Type"].iteritems():
29 if (values[1] =="Bool"):
30 out_sep = re.split(r'[Q \.]',
self.OUTPUTS['Address'][values[0]])↪→
31 #(a*8 + b)
32 calc_out =
(to_numeric(out_sep[1]*8)+to_numeric(out_sep[2]))↪→
33 self.OUTPUTS['Address'][values[0]]= 'Q0' +
calc_out.astype(str)↪→
34
35
36 for values in self.INPUTS["Type"].iteritems():
37 if (values[1] =="Bool"):
38 inp_sep = re.split(r'[I \.]',
self.INPUTS['Address'][values[0]])↪→
39 #(a*8 + b)
40 calc_inp =
(to_numeric(inp_sep[1]*8)+to_numeric(inp_sep[2]))↪→
41 self.INPUTS['Address'][values[0]]= 'I0' +
calc_inp.astype(str)↪→
42
43
44
45 for i in range(0,len(self.OUTPUTS)):
46 self.data_items[i].Area = c_int32(S7AreaPA)
47 self.data_items[i].WordLen = c_int32(eval(
48 WordLen_dict[self.OUTPUTS.iloc[i]["Type"]]))
49 self.data_items[i].Result = c_int32(int(0))#Exemplo Q0.1:
o start representa o 0↪→
50 self.data_items[i].Start =
c_int32(int(self.OUTPUTS.iloc[i]["Address"][2]))
#Exemplo Q0.1: o start representa o 1
↪→
↪→
87
51 self.data_items[i].Amount =
c_int32(int(Amount_dict[self.OUTPUTS.iloc[i]["Type"]]))
# reading a BOOL, 1 bytes
↪→
↪→
52
53 self.fmts.append((
54 Struct_dict[self.OUTPUTS.iloc[i]["Type"]]))
55
56 for j in range (len(self.OUTPUTS),(len(self.data_items))):
57 ind = j - len(self.OUTPUTS)
58 self.data_items[j].Area = c_int32(S7AreaPE)
59 self.data_items[j].WordLen = c_int32(eval(
60 WordLen_dict[self.INPUTS.iloc[ind]["Type"]]))
61 self.data_items[j].Result = c_int32(0)
62 self.data_items[j].Start =
c_int32(int(self.INPUTS.iloc[ind]["Address"][2]))↪→
63 self.data_items[j].Amount =
c_int32(int(Amount_dict[self.INPUTS.iloc[ind]["Type"]]))
# reading a BOOL, 1 bytes
↪→
↪→
64
65 self.fmts.append((
66 Struct_dict[self.INPUTS.iloc[ind]["Type"]]))
67
68 # create buffers to receive the data
69 # use the Amount attribute on each item to size the buffer
70 for di in self.data_items:
71 # create the buffer
72 buffer = create_string_buffer(di.Amount)
73
74 # cast the pointer to the buffer to the required type
75 pBuffer = cast(pointer(buffer),
76 POINTER(c_uint8))
77 di.pData = pBuffer
78
79 def read_data(self):
80 try:
81 if(len(self.OUTPUTS) + len(self.INPUTS) <= 20):
82
83 result, self.data_items =
plc_client.read_multi_vars(self.data_items)↪→
84
85 for di in self.data_items:
86 check_error(di.Result)
87
88 # struct formats
89 #fmts = ['>?', '>?', '>?']
90 resultado = []
91 # unpack and print the result of each read
92 for i in range(0, len(self.data_items)):
93 fmt = self.fmts[i]
94 di = self.data_items[i]
88
95 foo = ''.join([chr(di.pData[i]) for i in range(0,
di.Amount)])↪→
96 fnum = unpack(fmt, bytes(foo,encoding='utf8'))[0]
97 resultado.append(fnum)
98 #print (resultado)
99 self.append_data_file(resultado)
100 else:
101
102 result_PA =
plc_client.read_area(S7AreaPA,0,0,S7WLDWord)↪→
103 result_PE =
plc_client.read_area(S7AreaPE,0,0,S7WLDWord)↪→
104
105 address_PA = self.OUTPUTS["Address"]
106 type_PA = self.OUTPUTS["Type"]
107 resultado_PA = []
108
109 for i in range(len(address_PA)):
110
111 if type_PA[i]=='Bool':
112 resultado_PA.append(
113 get_bool(result_PA,0,int(address_PA[i][2:])))
114 elif type_PA[i]=='Byte' or type_PA[i]=='Word':
115 resultado_PA.append(
116 get_int(result_PA,int(address_PA[i][2:])))
117 elif type_PA[i]=='Real':
118 resultado_PA.append(
119 get_real(result_PA,int(address_PA[i][2:])))
120 elif type_PA[i]=='DWord':
121 resultado_PA.append(
122 get_dword(result_PA,int(address_PA[i][2:])))
123
124 address_PE = self.INPUTS["Address"]
125 type_PE = self.INPUTS["Type"]
126 resultado_PE = []
127 for i in range(len(address_PE)):
128
129 if type_PE[i]=='Bool':
130 resultado_PE.append(
131 get_bool(result_PE,0,int(address_PE[i][2:])))
132 elif type_PE[i]=='Byte' or type_PE[i]=='Word':
133 resultado_PE.append(
134 get_int(result_PE,int(address_PE[i][2:])))
135 elif type_PE[i]=='Real':
136 resultado_PE.append(
137 get_real(result_PE,int(address_PE[i][2:])))
138 elif type_PE[i]=='DWord':
139 resultado_PE.append(
140 get_dword(result_PE,int(address_PE[i][2:])))
141
89
142 resultado = resultado_PA+resultado_PE
143
144 self.append_data_file(resultado)
145 self.retorno_read = True
146 return(self.retorno_read)
147
148 except:
149 print("Reading Error")
150 self.retorno_read = False
151 return(self.retorno_read)
152
153 def initialize_file(self):
154 columns = concat([Series(['Greenwich Mean Time
(GMT)']),self.OUTPUTS["Name"], self.INPUTS["Name"]],
ignore_index=True)
↪→
↪→
155 data_csv = DataFrame([columns.tolist()])
156 data_csv.to_csv(home_path
+'/data_logging/'+self.name_file_csv,index =
False,header=False,line_terminator='\n')
↪→
↪→
157
158 def append_data_file(self,result_read):
159 yourlist = [datetime.utcnow().strftime('%Y-%m-%d
%H:%M:%S.%f')[:-2]] + result_read↪→
160 data_csv_append=DataFrame([yourlist])
161 data_csv_append.to_csv(home_path
+'/data_logging/'+self.name_file_csv, mode='a',
header=False,index = False,line_terminator='\n')
↪→
↪→
D.1.5 Thread
Nessa subsecao utilizamos Thread, que permitem que linhas de codigo sejam executa-
das simultaneamente. Para que o programa nao fique congelado durante a gravacao
e leitura dos dados, permitindo que outras funcoes sejam executadas, como por
exemplo o clique do botao “STOP”. Essa classe e utilizada para chamar a funcao
que realiza a leitura dos I/Os em intervalo de tempo definido pelo usuario.
Algoritmo D.1.5: Thread
1 class Thread(Thread):
2
3 def __init__(self,tempo):
4 super(Thread, self).__init__()
5 self.kill = Event()
6 self.tempo = tempo
7
8 def run(self):
9 # Enquanto a thread n~ao estiver 'morta'
10 print("Thread executando")
11 while not self.kill.is_set():
90
12 start_time = datetime.now()
13 return_read = cfile.read_data()
14 if(return_read == False):
15 self.stop()
16 end_time = datetime.now()
17 duration = end_time - start_time
18 print(duration.total_seconds())
19 if (float(self.tempo)>duration.total_seconds()):
20 timedel =
timedelta(seconds=float(self.tempo))-duration↪→
21 else:
22 timedel = timedelta(seconds=0)
23 #deve ser informado pelo usuario
24 sleep(timedel.total_seconds())
25
26 def stop(self):
27 # Mata a thread
28 print("thread parando.")
29 self.kill.set()
D.1.6 Communication Classes
O objetivo dessa classe e realizar a comunicacao entre o Front-end e o Back-End,
ou seja, caso aconteca algum evento, como um “clique”, essa funcao sera executada
e entao chamara a funcao correspondente.
Algoritmo D.1.6: Communication Classes
1 class Communication_Classes():
2
3 def __init__(self,filename = None, outputs = None , inputs = None,
4 address = None, rack = None, slot = None,tempo =
None):↪→
5 self.filename = filename
6 self.outputs = outputs
7 self.inputs = inputs
8 self.address = address
9 self.rack =rack
10 self.slot = slot
11 self.tempo = tempo
12
13 def create_pressed(self):
14 global cfile
15 cfile = generator_file(self.filename,self.outputs,self.inputs)
16 if(len(self.outputs) + len(self.inputs) <= 20):
17 cfile.create_dataitem()
18 print(len(self.outputs) + len(self.inputs))
19
20 cfile.initialize_file()
21
91
22 def connect_pressed(self):
23 global plc
24 plc = PLC_Controller(self.address,self.rack,self.slot)
25 ret = plc.connect()
26 return ret
27
28 def disconnect_pressed(self):
29 plc.disconnect()
30
31 def start_pressed(self):
32 global thread
33 thread = Thread(self.tempo)
34 thread.start()
35 sleep(5)
36 retorno_error = True
37 if not thread.isAlive():
38 retorno_error = False
39 return retorno_error
40
41 def stop_pressed(self):
42 thread.stop()
D.2 Front-End
O front-end e responsavel por reunir as entradas do usuario e processa-la para
tornar-las adequadas para a utilizacao no back-end.
D.2.1 Bibliotecas
Nessa subsecao as bibliotecas necessarias para o funcionamento do software sao
importadas, estando disponıveis para serem utilizadas ao longo do algoritmo.
Algoritmo D.2.1: Bibliotecas
1 # -*- coding: utf-8 -*-
2 # Form implementation generated from reading ui file
'Connect_to_PLC_FrontEnd.ui'↪→
3 # Created by: PyQt5 UI code generator 5.13.1
4 # WARNING! All changes made in this file will be lost!
5
6 from PyQt5.QtWidgets import QMainWindow, QApplication, QWidget,
7 QPushButton,QAction,QGroupBox,QLineEdit,QLabel,QTableWidget,
8 QTableWidgetItem,QComboBox,QMenuBar,QMenu,QStatusBar,QMessageBox,
9 QFileDialog
10 from PyQt5.QtGui import QIcon,QPixmap,QFont
11 from PyQt5.QtCore import
Qt,QRect,QSize,QMetaObject,QCoreApplication,pyqtSlot,QDir↪→
12
92
13 #Incluir reiniciar e abrir pasta de arquivos
14 from connect_to_plc import Import_Data
15 from connect_to_plc import Communication_Classes
16 from os import getcwd,startfile
17 home_path = getcwd()
18 from pandas import read_excel
19
20 from sys import argv,exit
D.2.2 Janela Principal UI
Nessa secao estao os codigos responsaveis por criar a interface grafica, para criar
essa parte foi utilizado o QT Designer uma ferramenta Qt para projetar e criar
interfaces graficas de usuario (GUIs), porem essa ferramenta implementa interfaces
em C++. Para realizar a ligacao entre o Python e o QT, utilizou-se a biblioteca
PyQt5.
Algoritmo D.2.2: Ui MainWindow
1 class Ui_MainWindow(object):
2 def setupUi(self, MainWindow):
3 MainWindow.setObjectName("MainWindow")
4 MainWindow.resize(853, 586)
5 self.centralwidget = QWidget(MainWindow)
6 MainWindow.setWindowFlags(Qt.WindowCloseButtonHint |
Qt.WindowMinimizeButtonHint)↪→
7 self.centralwidget.setObjectName("centralwidget")
8 self.setWindowIcon(QIcon(home_path +'/icons/automation.svg'))
9 #Icon made by [Good Ware] from www.flaticon.com
10
11 self.g_connect = QGroupBox(self.centralwidget)
12 self.g_connect.setGeometry(QRect(10, 10, 411, 111))
13 self.g_connect.setObjectName("g_connect")
14 self.b_connect = QPushButton(self.g_connect)
15 self.b_connect.setEnabled(False)
16 self.b_connect.setGeometry(QRect(10, 20, 93, 28))
17 self.b_connect.setStyleSheet("QPushButton:pressed {\n"
18 " background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,\n"
19 " stop: 0 #dadbde, stop: 1
#f6f7fa);\n"↪→
20 "}")
21 self.b_connect.setObjectName("b_connect")
22 self.b_disconnect = QPushButton(self.g_connect)
23 self.b_disconnect.setEnabled(False)
24 self.b_disconnect.setGeometry(QRect(10, 60, 93, 28))
25 self.b_disconnect.setStyleSheet("QPushButton:pressed {\n"
26 " background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,\n"
27 " stop: 0 #dadbde, stop: 1
#f6f7fa);\n"↪→
93
28 "}")
29 self.b_disconnect.setObjectName("b_disconnect")
30 self.line_IP = QLineEdit(self.g_connect)
31 self.line_IP.setGeometry(QRect(230, 20, 151, 22))
32 self.line_IP.setInputMask("")
33 self.line_IP.setMaxLength(15)
34 self.line_IP.setObjectName("line_IP")
35 self.text_ip = QLabel(self.g_connect)
36 self.text_ip.setGeometry(QRect(150, 20, 71, 16))
37 self.text_ip.setObjectName("text_ip")
38 self.text_rack = QLabel(self.g_connect)
39 self.text_rack.setGeometry(QRect(150, 50, 55, 16))
40 self.text_rack.setObjectName("text_rack")
41 self.text_slot = QLabel(self.g_connect)
42 self.text_slot.setGeometry(QRect(150, 80, 55, 16))
43 self.text_slot.setObjectName("text_slot")
44 self.line_rack = QLineEdit(self.g_connect)
45 self.line_rack.setGeometry(QRect(230, 50, 51, 22))
46 self.line_rack.setInputMask("")
47 self.line_rack.setText("")
48 self.line_rack.setMaxLength(1)
49 self.line_rack.setCursorPosition(0)
50 self.line_rack.setObjectName("line_rack")
51 self.line_slot = QLineEdit(self.g_connect)
52 self.line_slot.setGeometry(QRect(230, 80, 51, 22))
53 self.line_slot.setInputMask("")
54 self.line_slot.setMaxLength(2)
55 self.line_slot.setObjectName("line_slot")
56 self.discon_icon = QPushButton(self.g_connect)
57 self.discon_icon.setEnabled(True)
58 self.discon_icon.setGeometry(QRect(110, 65, 18, 18))
59 self.discon_icon.setAcceptDrops(False)
60 self.discon_icon.setStyleSheet("")
61 self.discon_icon.setInputMethodHints(Qt.ImhNone)
62 self.discon_icon.setText("")
63 icon = QIcon()
64 icon.addPixmap(QPixmap(home_path +'/icons/Box_Red.ico'),
QIcon.Normal, QIcon.Off)↪→
65 self.discon_icon.setIcon(icon)
66 self.discon_icon.setAutoExclusive(False)
67 self.discon_icon.setFlat(True)
68 self.discon_icon.setObjectName("discon_icon")
69 self.conne_icon = QPushButton(self.g_connect)
70 self.conne_icon.setEnabled(True)
71 self.conne_icon.setGeometry(QRect(110, 25, 18, 18))
72 self.conne_icon.setStyleSheet("")
73 self.conne_icon.setText("")
74 icon1 = QIcon()
75 icon1.addPixmap(QPixmap(home_path +"/icons/Box_Green.ico"),
QIcon.Normal, QIcon.Off)↪→
94
76 self.conne_icon.setIcon(icon1)
77 self.conne_icon.setAutoDefault(False)
78 self.conne_icon.setDefault(False)
79 self.conne_icon.setFlat(True)
80 self.conne_icon.setVisible(False)
81 self.conne_icon.setObjectName("conne_icon")
82 self.help = QPushButton(self.g_connect)
83 self.help.setGeometry(QRect(290, 52, 18, 18))
84 self.help.setText("")
85 icon2 = QIcon()
86 icon2.addPixmap(QPixmap(home_path
+"/icons/Info_Box_Blue.ico"), QIcon.Normal, QIcon.Off)↪→
87 self.help.setIcon(icon2)
88 self.help.setFlat(True)
89 self.help.setObjectName("help")
90 self.g_record = QGroupBox(self.centralwidget)
91 self.g_record.setGeometry(QRect(430, 10, 161, 111))
92 self.g_record.setObjectName("g_record")
93 self.b_start = QPushButton(self.g_record)
94 self.b_start.setEnabled(False)
95 self.b_start.setGeometry(QRect(20, 20, 93, 28))
96 self.b_start.setStyleSheet("QPushButton:pressed {\n"
97 " background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,\n"
98 " stop: 0 #dadbde, stop: 1
#f6f7fa);\n"↪→
99 "}")
100 self.b_start.setFlat(False)
101 self.b_start.setObjectName("b_start")
102 self.b_stop = QPushButton(self.g_record)
103 self.b_stop.setEnabled(False)
104 self.b_stop.setGeometry(QRect(20, 60, 93, 28))
105 self.b_stop.setStyleSheet("QPushButton:pressed {\n"
106 " background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,\n"
107 " stop: 0 #dadbde, stop: 1
#f6f7fa);\n"↪→
108 "}")
109 self.b_stop.setObjectName("b_stop")
110 self.start_icon = QPushButton(self.g_record)
111 self.start_icon.setEnabled(True)
112 self.start_icon.setGeometry(QRect(120, 25, 18, 18))
113 self.start_icon.setText("")
114 self.start_icon.setIcon(icon1)
115 self.start_icon.setCheckable(False)
116 self.start_icon.setChecked(False)
117 self.start_icon.setAutoDefault(False)
118 self.start_icon.setDefault(False)
119 self.start_icon.setVisible(False)
120 self.start_icon.setFlat(True)
121 self.start_icon.setObjectName("start_icon")
122 self.stop_icon = QPushButton(self.g_record)
95
123 self.stop_icon.setEnabled(True)
124 self.stop_icon.setGeometry(QRect(120, 65, 18, 18))
125 self.stop_icon.setText("")
126 self.stop_icon.setIcon(icon)
127 self.stop_icon.setCheckable(False)
128 self.stop_icon.setDefault(False)
129 self.stop_icon.setFlat(True)
130 self.stop_icon.setObjectName("stop_icon")
131 self.g_datalog = QGroupBox(self.centralwidget)
132 self.g_datalog.setGeometry(QRect(600, 10, 241, 111))
133 self.g_datalog.setObjectName("g_datalog")
134 self.l_filename = QLabel(self.g_datalog)
135 self.l_filename.setGeometry(QRect(10, 20, 55, 16))
136 self.l_filename.setObjectName("l_filename")
137 self.line_name = QLineEdit(self.g_datalog)
138 self.line_name.setGeometry(QRect(80, 20, 151, 22))
139 self.line_name.setMaxLength(20)
140 self.line_name.setObjectName("line_name")
141 self.b_create = QPushButton(self.g_datalog)
142 self.b_create.setEnabled(False)
143 self.b_create.setGeometry(QRect(60, 80, 93, 28))
144 self.b_create.setStyleSheet("QPushButton:pressed {\n"
145 " background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,\n"
146 " stop: 0 #dadbde, stop: 1
#f6f7fa);\n"↪→
147 "}")
148 self.b_create.setCheckable(False)
149 self.b_create.setChecked(False)
150 self.b_create.setAutoDefault(False)
151 self.b_create.setDefault(False)
152 self.b_create.setFlat(False)
153 self.b_create.setObjectName("b_create")
154 self.create_icon = QPushButton(self.g_datalog)
155 self.create_icon.setGeometry(QRect(160, 85, 18, 18))
156 self.create_icon.setText("")
157 icon3 = QIcon()
158 icon3.addPixmap(QPixmap(home_path +"/icons/check-mark.ico"),
QIcon.Normal, QIcon.Off)↪→
159 self.create_icon.setIcon(icon3)
160 self.create_icon.setFlat(True)
161 self.create_icon.setVisible(False)
162 self.create_icon.setObjectName("create_icon")
163 self.time = QLabel(self.g_datalog)
164 self.time.setGeometry(QRect(10, 50, 111, 16))
165 self.time.setObjectName("time")
166 self.time_aquisi = QLineEdit(self.g_datalog)
167 self.time_aquisi.setGeometry(QRect(80, 50, 71, 22))
168 self.time_aquisi.setInputMask("")
169 self.time_aquisi.setText("")
170 self.time_aquisi.setMaxLength(5)
96
171 self.time_aquisi.setCursorPosition(0)
172 self.time_aquisi.setObjectName("time_aquisi")
173 self.help_2 = QPushButton(self.g_datalog)
174 self.help_2.setGeometry(QRect(160, 52, 18, 18))
175 self.help_2.setText("")
176 self.help_2.setIcon(icon2)
177 self.help_2.setFlat(True)
178 self.help_2.setObjectName("help_2")
179 self.groupBox = QGroupBox(self.centralwidget)
180 self.groupBox.setGeometry(QRect(10, 130, 411, 401))
181 font = QFont()
182 font.setPointSize(8)
183 self.groupBox.setFont(font)
184 self.groupBox.setObjectName("groupBox")
185 self.table_out = QTableWidget(self.groupBox)
186 self.table_out.setGeometry(QRect(10, 20, 391, 326))
187 font = QFont()
188 font.setPointSize(8)
189 self.table_out.setFont(font)
190 self.table_out.setStyleSheet("QHeaderView::section {\n"
191 "border-top: 0px solid grey;\n"
192 "border-bottom: 1px solid grey;\n"
193 "border-right: 1px solid grey;\n"
194 "background:white;}")
195 self.table_out.setRowCount(8)
196 self.table_out.setObjectName("table_out")
197 self.table_out.setColumnCount(3)
198 item = QTableWidgetItem()
199 font = QFont()
200 font.setPointSize(8)
201 item.setFont(font)
202 self.table_out.setHorizontalHeaderItem(0, item)
203 item = QTableWidgetItem()
204 font = QFont()
205 font.setPointSize(8)
206 item.setFont(font)
207 self.table_out.setHorizontalHeaderItem(1, item)
208 item = QTableWidgetItem()
209 font = QFont()
210 font.setPointSize(8)
211 item.setFont(font)
212 self.table_out.setHorizontalHeaderItem(2, item)
213 self.table_out.horizontalHeader().setVisible(True)
214 self.table_out.horizontalHeader().
215 setCascadingSectionResizes(False)
216 self.table_out.horizontalHeader().setHighlightSections(True)
217 self.table_out.horizontalHeader().setSortIndicatorShown(False)
218 self.table_out.horizontalHeader().setStretchLastSection(True)
219 self.table_out.verticalHeader().setVisible(True)
220 self.table_out.verticalHeader().setHighlightSections(True)
97
221 self.table_out.setColumnWidth(0, 150)
222 self.table_out.setColumnWidth(1, 90)
223 self.table_out.setColumnWidth(2, 90)
224 self.table_out.setHorizontalScrollBarPolicy(
225 Qt.ScrollBarAlwaysOff)
226 combo_box_options = ['Bool','Byte','Word','DWord','Real']
227
228
229 for index in range(8):
230 combo = QComboBox()
231 for t in combo_box_options:
232 combo.addItem(t)
233 self.table_out.setCellWidget(index,2,combo)
234
235 self.b_plus_out = QPushButton(self.groupBox)
236 self.b_plus_out.setGeometry(QRect(330, 350, 30, 30))
237 self.b_plus_out.setStyleSheet("QPushButton:pressed {\n"
238 " background-color: gray;\n"
239 "}")
240 self.b_plus_out.setText("")
241 icon4 = QIcon()
242 icon4.addPixmap(QPixmap(home_path +"/icons/plus_sign.ico"),
QIcon.Normal, QIcon.Off)↪→
243 self.b_plus_out.setIcon(icon4)
244 self.b_plus_out.setIconSize(QSize(30, 30))
245 self.b_plus_out.setFlat(True)
246 self.b_plus_out.setObjectName("b_plus_out")
247 self.b_minus_out = QPushButton(self.groupBox)
248 self.b_minus_out.setGeometry(QRect(370, 350, 30, 30))
249 self.b_minus_out.setStyleSheet("QPushButton:pressed {\n"
250 " background-color: gray\n"
251 "}")
252 self.b_minus_out.setText("")
253 icon5 = QIcon()
254 icon5.addPixmap(QPixmap(home_path +"/icons/minus_sign.ico"),
QIcon.Normal, QIcon.Off)↪→
255 self.b_minus_out.setIcon(icon5)
256 self.b_minus_out.setIconSize(QSize(30, 30))
257 self.b_minus_out.setFlat(True)
258 self.b_minus_out.setObjectName("b_minus_out")
259 self.b_upload = QPushButton(self.groupBox)
260 self.b_upload.setGeometry(QRect(20, 360, 30, 30))
261 self.b_upload.setStyleSheet("QPushButton:pressed {\n"
262 " background-color: gray;\n"
263 "}")
264 self.b_upload.setText("")
265 icon6 = QIcon()
266 icon6.addPixmap(QPixmap(home_path +"/icons/upload.svg"),
QIcon.Normal, QIcon.Off)↪→
267 self.b_upload.setIcon(icon6)
98
268 self.b_upload.setIconSize(QSize(30, 30))
269 self.b_upload.setFlat(True)
270 self.b_upload.setObjectName("b_upload")
271 self.upload_help = QPushButton(self.groupBox)
272 self.upload_help.setGeometry(QRect(60, 368, 18, 18))
273 self.upload_help.setText("")
274 self.upload_help.setIcon(icon2)
275 self.upload_help.setFlat(True)
276 self.upload_help.setObjectName("upload_help")
277
278
279
280 self.group_input = QGroupBox(self.centralwidget)
281 self.group_input.setGeometry(QRect(430, 130, 411, 401))
282 font = QFont()
283 font.setPointSize(8)
284 self.group_input.setFont(font)
285 self.group_input.setObjectName("group_input")
286 self.table_in = QTableWidget(self.group_input)
287 self.table_in.setGeometry(QRect(10, 20, 391, 326))
288 font = QFont()
289 font.setPointSize(8)
290 self.table_in.setFont(font)
291 self.table_in.setStyleSheet("QHeaderView::section {\n"
292 "border-top: 0px solid grey;\n"
293 "border-bottom: 1px solid grey;\n"
294 "border-right: 1px solid grey;\n"
295 "background:white;}")
296 self.table_in.setRowCount(8)
297 self.table_in.setObjectName("table_in")
298 self.table_in.setColumnCount(3)
299 item = QTableWidgetItem()
300 font = QFont()
301 font.setPointSize(8)
302 item.setFont(font)
303 self.table_in.setHorizontalHeaderItem(0, item)
304 item = QTableWidgetItem()
305 font = QFont()
306 font.setPointSize(8)
307 item.setFont(font)
308 self.table_in.setHorizontalHeaderItem(1, item)
309 item = QTableWidgetItem()
310 font = QFont()
311 font.setPointSize(8)
312 item.setFont(font)
313 self.table_in.setHorizontalHeaderItem(2, item)
314 self.table_in.horizontalHeader().
315 setCascadingSectionResizes(False)
316 self.table_in.horizontalHeader().setSortIndicatorShown(False)
317 self.table_in.horizontalHeader().setStretchLastSection(True)
99
318 self.table_in.verticalHeader().setVisible(True)
319 self.table_in.verticalHeader().
320 setCascadingSectionResizes(False)
321 self.table_in.verticalHeader().setSortIndicatorShown(False)
322 self.table_in.verticalHeader().setStretchLastSection(False)
323 self.table_in.setColumnWidth(0, 150)
324 self.table_in.setColumnWidth(1, 100)
325 self.table_in.setColumnWidth(2, 100)
326 self.table_in.setHorizontalScrollBarPolicy(
327 Qt.ScrollBarAlwaysOff)
328
329 for index in range(8):
330 combo = QComboBox()
331 for t in combo_box_options:
332 combo.addItem(t)
333 self.table_in.setCellWidget(index,2,combo)
334
335
336 self.b_plus_in = QPushButton(self.group_input)
337 self.b_plus_in.setGeometry(QRect(330, 350, 30, 30))
338 self.b_plus_in.setStyleSheet("QPushButton:pressed {\n"
339 " background-color: gray\n"
340 "}")
341
342 self.b_plus_in.setText("")
343 self.b_plus_in.setIcon(icon4)
344 self.b_plus_in.setIconSize(QSize(30, 30))
345 self.b_plus_in.setCheckable(False)
346 self.b_plus_in.setFlat(True)
347 self.b_plus_in.setObjectName("b_plus_in")
348 self.b_minus_in = QPushButton(self.group_input)
349 self.b_minus_in.setGeometry(QRect(370, 350, 30, 30))
350 self.b_minus_in.setStyleSheet("QPushButton:pressed {\n"
351 " background-color: gray\n"
352 "}")
353 self.b_minus_in.setText("")
354 self.b_minus_in.setIcon(icon5)
355 self.b_minus_in.setIconSize(QSize(30, 30))
356 self.b_minus_in.setFlat(True)
357 self.b_minus_in.setObjectName("b_minus_in")
358 MainWindow.setCentralWidget(self.centralwidget)
359 self.menubar = QMenuBar(MainWindow)
360 self.menubar.setGeometry(QRect(0, 0, 853, 26))
361 self.menubar.setObjectName("menubar")
362 self.menuMain = QMenu(self.menubar)
363 self.menuMain.setObjectName("menuMain")
364 self.menuAbout = QMenu(self.menubar)
365 self.menuAbout.setObjectName("menuAbout")
366
367 MainWindow.setMenuBar(self.menubar)
100
368 self.statusbar = QStatusBar(MainWindow)
369 self.statusbar.setObjectName("statusbar")
370 MainWindow.setStatusBar(self.statusbar)
371 self.actionAbout = QAction(MainWindow)
372 self.actionAbout.setObjectName("actionAbout")
373 self.actionAbout.triggered.connect(self.about)
374
375 self.actionOpen_File_Location = QAction(MainWindow)
376 self.actionOpen_File_Location.
377 setObjectName("actionOpen_File_Location")
378 self.actionOpen_File_Location.setShortcut("Ctrl+Q")
379 self.actionOpen_File_Location.
380 triggered.connect(self.open_folder)
381
382 #self.actionReset_Program = QAction(MainWindow)
383 #self.actionReset_Program.setObjectName("actionReset_Program")
384 #self.actionReset_Program.setShortcut("Ctrl+R")
385 #self.actionReset_Program.triggered.connect(self.restart)
386
387 self.actionProgram_Help = QAction(MainWindow)
388 self.actionProgram_Help.setObjectName("actionProgram_Help")
389 self.actionProgram_Help.setShortcut("F1")
390 self.actionProgram_Help.triggered.connect(self.open_help)
391
392 self.menuMain.addSeparator()
393 self.menuMain.addAction(self.actionOpen_File_Location)
394
395 #self.menuMain.addAction(self.actionReset_Program)
396 self.menuAbout.addSeparator()
397 self.menuAbout.addAction(self.actionProgram_Help)
398 self.menuAbout.addAction(self.actionAbout)
399 self.menubar.addAction(self.menuMain.menuAction())
400 self.menubar.addAction(self.menuAbout.menuAction())
401
402 self.retranslateUi(MainWindow)
403 QMetaObject.connectSlotsByName(MainWindow)
404
405 def retranslateUi(self, MainWindow):
406 _translate = QCoreApplication.translate
407 MainWindow.setWindowTitle(_translate("MainWindow", "PLC
Connect"))↪→
408 self.g_connect.setTitle(_translate("MainWindow",
"Connection"))↪→
409 self.b_connect.setText(_translate("MainWindow", "Connect"))
410 self.b_disconnect.setText(_translate("MainWindow",
"Disconnect"))↪→
411 self.text_ip.setText(_translate("MainWindow", "IP address"))
412 self.text_rack.setText(_translate("MainWindow", "Rack"))
413 self.text_slot.setText(_translate("MainWindow", "Slot"))
101
414 self.help.setToolTip(_translate("MainWindow",
"<html><head/><body><p>See the hardware
configuration.</p></body></html>"))
↪→
↪→
415 self.g_record.setTitle(_translate("MainWindow", "Recording"))
416 self.b_start.setText(_translate("MainWindow", "Start"))
417 self.b_stop.setText(_translate("MainWindow", "Stop"))
418 self.g_datalog.setTitle(_translate("MainWindow", "Data logging
to file"))↪→
419 self.l_filename.setText(_translate("MainWindow", "Filename"))
420 self.b_create.setText(_translate("MainWindow", "Create File"))
421 self.time.setText(_translate("MainWindow", "Step time"))
422 self.help_2.setToolTip(_translate("MainWindow",
"<html><head/><body><p>I / O acquisition time in
second.</p></body></html>"))
↪→
↪→
423 self.groupBox.setTitle(_translate("MainWindow", "Outputs"))
424 item = self.table_out.horizontalHeaderItem(0)
425 item.setText(_translate("MainWindow", "Name"))
426 item = self.table_out.horizontalHeaderItem(1)
427 item.setText(_translate("MainWindow", "Address"))
428 item = self.table_out.horizontalHeaderItem(2)
429 item.setText(_translate("MainWindow", "Type"))
430 self.b_plus_out.setToolTip(_translate("MainWindow",
"<html><head/><body><p>Add row to
table</p></body></html>"))
↪→
↪→
431 self.b_plus_out.setWhatsThis(_translate("MainWindow",
"<html><head/><body><p><br/></p></body></html>"))↪→
432 self.b_minus_out.setToolTip(_translate("MainWindow",
"<html><head/><body><p>Remove table
row</p></body></html>"))
↪→
↪→
433 self.upload_help.setToolTip(_translate("MainWindow",
"<html><head/><body><p>Add the TIA portal tag
file.</p></body></html>"))
↪→
↪→
434 self.group_input.setTitle(_translate("MainWindow", "Inputs"))
435 item = self.table_in.horizontalHeaderItem(0)
436 item.setText(_translate("MainWindow", "Name"))
437 item = self.table_in.horizontalHeaderItem(1)
438 item.setText(_translate("MainWindow", "Address"))
439 item = self.table_in.horizontalHeaderItem(2)
440 item.setText(_translate("MainWindow", "Type"))
441 self.b_plus_in.setToolTip(_translate("MainWindow",
"<html><head/><body><p>Add row to
table</p></body></html>"))
↪→
↪→
442 self.b_minus_in.setToolTip(_translate("MainWindow",
"<html><head/><body><p>Remove table
row</p></body></html>"))
↪→
↪→
443 self.menuMain.setTitle(_translate("MainWindow", "Main"))
444 self.menuAbout.setTitle(_translate("MainWindow", "Help"))
445 self.actionAbout.setText(_translate("MainWindow", "About"))
446 self.actionOpen_File_Location.setText(_translate("MainWindow",
"Open File Location"))↪→
102
447 #self.actionReset_Program.setText(_translate("MainWindow",
"Restart Program"))↪→
448 self.actionProgram_Help.setText(_translate("MainWindow",
"Program Help"))↪→
D.2.3 Janela Principal
Nessa subsecao sao definidos os eventos para cada acao que pode ser realizada no
PLC Connect, como por exemplo: os cliques dos botoes, adicoes de linhas na tabela,
habilitacao de um botao, entre outros.
Algoritmo D.2.3: MainWindow
1 class MainWindow(QMainWindow, Ui_MainWindow):
2 def __init__(self, parent=None):
3 super(MainWindow, self).__init__(parent)
4 self.setupUi(self)
5 #Ativando e desativando botoes
6 self.line_IP.textChanged.connect(
7 self.on_text_changed_b_connect)
8 self.line_rack.textChanged.connect(
9 self.on_text_changed_b_connect)
10 self.line_slot.textChanged.connect(
11 self.on_text_changed_b_connect)
12
13 self.line_name.textChanged.connect(
14 self.on_text_changed_b_create)
15 self.time_aquisi.textChanged.connect(
16 self.on_text_changed_b_create)
17
18 #Adicionando e removendo colunas nas tabelas
19 self.b_plus_out.clicked.connect(self.add_row_out)
20 self.b_minus_out.clicked.connect(self.remove_row_out)
21
22 self.b_plus_in.clicked.connect(self.add_row_in)
23 self.b_minus_in.clicked.connect(self.remove_row_in)
24
25 #Configurando funcoes dos botoes
26 self.b_create.clicked.connect(
27 self.button_b_create_pressed)
28 self.b_connect.clicked.connect(
29 self.button_b_connect_pressed)
30 self.b_disconnect.clicked.connect(
31 self.button_b_disconnect_pressed)
32
33
34 self.b_start.clicked.connect(self.button_b_start_pressed)
35 self.b_stop.clicked.connect(self.button_b_stop_pressed)
36 self.b_upload.clicked.connect(
37 self.button_b_upload_pressed)
103
38 #Para manter bot~ao desativado ate clicar em outro
39
40 self.enable_b_connect = False
41 self.enable_b_start = False
42
43 self.enable_create = False
44 self.select_qtable = 2
45
46 #Eventos
47 @pyqtSlot()
48 def on_text_changed_b_connect(self):
49 self.b_connect.setEnabled(bool(self.line_IP.text()) and
bool(self.line_rack.text()) and
bool(self.line_slot.text()))
↪→
↪→
50
51 @pyqtSlot()
52 def on_text_changed_b_create(self):
53 self.b_create.setEnabled(bool(self.line_name.text()) and
bool(self.time_aquisi.text()))↪→
54
55 @pyqtSlot()
56 def on_b_start(self):
57 self.b_start.setEnabled(self.enable_b_start and
self.enable_create)↪→
58
59
60 @pyqtSlot()
61 def add_row_out(self):
62 rowcount = self.table_out.rowCount()
63 self.table_out.setRowCount(rowcount+1)
64 combox_add = QComboBox(self)
65 combox_add.addItems(['Bool','Byte','Word','DWord','Real'])
66 self.table_out.setCellWidget(rowcount, 2, combox_add)
67
68 @pyqtSlot()
69 def add_row_in(self):
70 rowcount = self.table_in.rowCount()
71 self.table_in.setRowCount(rowcount+1)
72 combox_add = QComboBox(self)
73 combox_add.addItems(['Bool','Byte','Word','DWord','Real'])
74 self.table_in.setCellWidget(rowcount, 2, combox_add)
75
76 @pyqtSlot()
77 def remove_row_out(self):
78 if self.table_out.rowCount() > 0:
79 self.table_out.removeRow(self.table_out.rowCount()-1)
80
81
82 @pyqtSlot()
83 def remove_row_in(self):
104
84 if self.table_in.rowCount() > 0:
85 self.table_in.removeRow(self.table_in.rowCount()-1)
86
87 @pyqtSlot()
88 def button_b_create_pressed(self):
89 for row in reversed(range(self.table_in.rowCount())):
90 widget = self.table_in.item(row, 0)
91 widget2 = self.table_in.item(row, 1)
92
93 if (widget == None or widget2 == None):
94 self.table_in.removeRow(row)
95
96 for row in reversed(range(self.table_out.rowCount())):
97 widget_out = self.table_out.item(row, 0)
98 widget2_out = self.table_out.item(row, 1)
99
100 if (widget_out == None or widget2_out == None):
101 self.table_out.removeRow(row)
102
103 #Checando se as tabelas est~ao vazias
104 if (self.table_out.rowCount() != 0 and
self.table_in.rowCount() != 0):↪→
105
106
107 self.enable_create = True
108 self.on_b_start()
109
110 import_out = Import_Data(
111 self.table_out,"OUTPUTS",self.select_qtable)
112 self.outputs = (import_out.qtable_to_dataframe())
113
114 import_in = Import_Data(
115 self.table_in,"INPUTS",self.select_qtable)
116 self.inputs = (import_in.qtable_to_dataframe())
117 communicate = Communication_Classes(filename=
self.line_name.text(),↪→
118 outputs = self.outputs,
119 inputs = self.inputs)
120 communicate.create_pressed()
121
122
123 self.create_icon.setVisible(True)
124 self.line_name.setEnabled(False)
125 self.time_aquisi.setEnabled(False)
126 self.b_create.setEnabled(False)
127
128 self.b_plus_out.setEnabled(False)
129 self.b_minus_out.setEnabled(False)
130 self.b_plus_in.setEnabled(False)
131 self.b_minus_in.setEnabled(False)
105
132 else:
133 QMessageBox.about(self, "ERROR", "Empty input / output
table")↪→
134
135 @pyqtSlot()
136 def button_b_connect_pressed(self):
137 print ("Pressionado")
138
139 communicate = Communication_Classes(address =
self.line_IP.text(),↪→
140 rack = int(self.line_rack.text()),
141 slot= int(self.line_slot.text()))
142
143 retorno = communicate.connect_pressed()
144
145 if (retorno == True):
146 self.enable_b_start = True
147 self.on_b_start()
148 self.conne_icon.setVisible(True)
149 self.discon_icon.setVisible(False)
150 self.b_disconnect.setEnabled(True)
151 self.b_connect.setEnabled(False)
152 self.line_IP.setEnabled(False)
153 self.line_rack.setEnabled(False)
154 self.line_slot.setEnabled(False)
155 else:
156 QMessageBox.critical(self, "Error", "Unable to make a
connection to the PLC")↪→
157
158 @pyqtSlot()
159 def button_b_disconnect_pressed(self):
160
161 communicate_dis = Communication_Classes()
162 communicate_dis.disconnect_pressed()
163
164 self.enable_b_start = False
165 self.on_b_start()
166 self.conne_icon.setVisible(False)
167 self.discon_icon.setVisible(True)
168 self.b_disconnect.setEnabled(False)
169 self.b_connect.setEnabled(True)
170 self.line_IP.setEnabled(True)
171 self.line_rack.setEnabled(True)
172 self.line_slot.setEnabled(True)
173
174
175
176
177 @pyqtSlot()
178 def button_b_start_pressed(self):
106
179 print ("Pressionado")
180 communicate = Communication_Classes(tempo =
float(self.time_aquisi.text()))↪→
181 read_error = communicate.start_pressed()
182
183
184 self.start_icon.setVisible(True)
185 self.stop_icon.setVisible(False)
186 self.b_stop.setEnabled(True)
187 self.b_start.setEnabled(False)
188
189 self.create_icon.setVisible(True)
190 self.line_name.setEnabled(False)
191 self.time_aquisi.setEnabled(False)
192 self.b_create.setEnabled(False)
193 if(read_error == False):
194 self.button_b_stop_pressed()
195 QMessageBox.critical(self, "Error", "Reading error -
Probably error when reading the variables DWord or
Real")
↪→
↪→
196
197
198 @pyqtSlot()
199 def button_b_stop_pressed(self):
200 communicate_stop = Communication_Classes()
201 communicate_stop.stop_pressed()
202 self.start_icon.setVisible(False)
203 self.stop_icon.setVisible(True)
204 self.b_start.setEnabled(True)
205 self.b_stop.setEnabled(False)
206
207 self.create_icon.setVisible(False)
208 self.line_name.setEnabled(True)
209 self.time_aquisi.setEnabled(True)
210 self.b_create.setEnabled(True)
211
212
213 @pyqtSlot()
214 def button_b_upload_pressed(self):
215 print ("Pressionado")
216 file_path, _ = QFileDialog.getOpenFileName(self, 'Single
File', QDir.rootPath() , '*.xlsx')↪→
217 if (file_path != ''):
218 data_frame = read_excel(file_path)
219 data_frame = data_frame[[data_frame.columns[0]
220 ,data_frame.columns[3],data_frame.columns[2]]]
221 data_frame.columns = ['Name', 'Address','Type']
222 data_frame = data_frame.replace({'%':''}, regex=True)
223
224 routputs = data_frame[data_frame.iloc[:,1].
107
225 str.startswith(('Q'))]
226 routputs = routputs.sort_values('Address')
227 routputs = routputs.loc[routputs.Type.
228 isin(['Bool','Byte','Word','DWord','Real'])]
229 routputs = routputs.reset_index(drop = True)
230
231
232 rinputs = data_frame[data_frame.iloc[:,1].
233 str.startswith(('I'))]
234 rinputs = rinputs.sort_values('Address')
235 rinputs = rinputs.reset_index(drop = True)
236
237 self.printed_table(self.table_out,routputs)
238 self.printed_table(self.table_in,rinputs)
239 self.b_plus_out.setEnabled(False)
240 self.b_minus_out.setEnabled(False)
241 self.b_plus_in.setEnabled(False)
242 self.b_minus_in.setEnabled(False)
243 @pyqtSlot()
244 def printed_table(self, table_name,table):
245 self.select_qtable = 3
246 table_name.setRowCount(0)
247 table_name.setColumnCount(len(table.columns))
248 table_name.setRowCount(len(table.index))
249 table_name.setHorizontalHeaderLabels(table.columns)
250
251 for row_num, row in enumerate(table.index):
252 for col_num, col in enumerate(table.columns):
253 item = QTableWidgetItem(str(table.loc[row,col]))
254
255 table_name.setItem(row_num, col_num, item)
256
257 item.setFlags(Qt.ItemIsSelectable |
Qt.ItemIsEnabled)↪→
258
259 #table_name.resizeColumnsToContents()
260 #table_name.resizeRowsToContents()
261 #table_name.verticalHeader().setVisible(False)
262 #Eventos do menu
263 def open_folder(self):
264 startfile(home_path+'\data_logging')
265
266 def open_help(self):
267 startfile(home_path+'\help\help_file.pdf')
268
269 def about(self):
270 QMessageBox.about(self, "About", "This program is part of
a bachelor's thesis")↪→
271
272 def restart(self):
108
273 QMessageBox.about(self, "Sorry", "Still does not work")
274
275
276
277
278
279 if __name__ == "__main__":
280
281 app = QApplication(argv)
282 w = MainWindow()
283 w.show()
284 exit(app.exec_())
109