Tutorial: Como criar sua própria interface gráfica para seus projetos utilizando Processing e Garagino

Olá Garagistas! Neste tutorial mostraremos como você pode criar sua própria interface gráfica. Como demonstração criaremos uma aplicação onde ela nos mostrará qual o estado do nosso hardware no mundo físico e também nos permitirá interagir com ele.

Material Utilizado:

1x Kit Garagino Rev. 1 Básico (Garagino + Conversor USB/Serial)

1x Mini Proto Shield para Garagino

1x Potenciômetro

1x Chave Táctil

1x LED 3mm Vermelho

1x LED 3mm Verde

2x Resistor 330R

1x Resistor 10K

Alguns Fios

Estação de Solda

Solda (Estanho)

1. Introdução

1.1) Interface Gráfica (Supervisório)

Uma interface gráfica nada mais é que uma demonstração visual para o seu circuito/projeto. Os supervisórios são um tipo de interface gráfica, eles destinam-se à capturar e armazenar em um banco de dados, informações sobre um processo de produção. Essas informações vem de sensores que capturam dados específicos (conhecidos como variáveis de processo) de uma planta industrial.

Existem diversos softwares supervisórios onde você pode utilizar das ferramentas de que ele oferece para montar e representar sua aplicação na tela do seu computador, porém, dependendo do que você deseja fazer você pode acabar ficando limitado pelas ferramentas desses softwares ou até mesmo pelo custo de um plugin ou ferramenta de software comerciais.

A ideia então é você poder criar sua própria interface gráfica para sua placa de controle ou processo, e para isso utilizaremos um software chamado Processing.

1.2) Processing

Processing é uma linguagem de programação de código aberto e ambiente de desenvolvimento integrado (IDE), construído para as artes eletrônicas e comunidades de projetos de artes visuais com o objetivo de ensinar noções básicas de programação de computador em um contexto visual. É muito útil para realizar trabalho gráfico, tanto em 2D como em 3D. Trata-se de uma linguagem de código aberto com o qual os programadores podem criar imagens, animação e interação por meio de uma série de funções de alto nível que permitem fazer grande variedade de desenhos, aos que se podem atribuir, inclusive, movimentos e responder às ações do usuário.

Resumidamente, Processing é para programação de artes visual (gráfico) para computadores, assim como Arduino é para a eletrônica. Você pode encontrar várias semelhanças entre ambos, incluindo a linguagem de programação, IDE e a quantidade de informações disponível na internet.

Para executar o Processing não é necessário instalar, basta você  efetuar o download, descompactar a pasta e clicar no executável. O download do Processing pode ser efetuar clicando aqui.

2. Funcionamento

2.1) Hardware/Circuito

Na figura abaixo está o circuito que montamos no Mini Proto Shield:

Figura 1 - Esquemático do circuito no Mini Proto Shield

Nas imagens abaixo você pode verificar como ficou a montagem:

Imagens 1 e 2 - Montagem do circuito no Mini Proto Shield

Utilizamos uma Mini Proto Shield e nela montamos um circuito com uma chave táctil (botão) que irá ter seu estado (Ligado/Desligado) representado nos LEDs e também um potenciômetro que terá seu cursor representado na tela da interface gráfica por um ponteiro.

2.2) Interface Gráfica

Na figura abaixo temos a interface gráfica:

Figura 2 - Tela da Interface Gráfica

Nela temos um gráfico com um ponteiro que representa a posição do cursor de nosso potenciômetro no circuito, 2 LEDs que nos mostram qual o estado do botão se o mesmo tiver habilitado pela interface ou caso não esteja, poderemos controlar da interface o estado desses LEDs (Ligado/Desligado) apenas clicando em cima deles. 

2.3) Comunicando o Processing com o Garagino

Figura 3 - Comunicação do Processing com o Arduino

Processing: Ele irá rodar a interface gráfica e ficará trocando informações com o Garagino através de uma comunicação Serial, assim, em nossa tela teremos um gráfico que nos mostra a todo momento a posição do potenciômetro em nosso hardware e também teremos 2 LEDs que irão nos indicar o estado do botão, tanto na na tela do supervisório quanto no circuito que montamos.

Garagino: Ele irá rodar um código onde ficará trocando informações com o Processing via comunicação serial, assim, ele fica enviando os dados de estado da posição do cursor do potenciômetro e também o estado da chave táctil (botão) e também recebe informações da interface quando nela a leitura do botão estiver desabilitada. Na imagem abaixo você pode ver a tela da interface gráfica com o botão desabilitado:

Figura 4 - Botão Desabilitado na Interface

3. Montagem e Execução

3.1) Conecte a Mini Proto Shield no Garagino e conecte-os ao seu PC pelo Conversor USB/Serial com o cabo:

Imagem 3 - Montagem

3.2) Transfira o programa para o Garagino clicando um Upload:

Figura 5 - Upload Para o Garagino

3.4)  Feito o Upload para o Garagino, feche a Arduino IDE.

3.5) Execute o Processing e insira a programação, após isso salve o programa:

Figura 6 - Salvando o Programa

3.6)  Após salvo o código, feche o Processing.

3.7) Dentro da pasta onde foi salvo o programa, crie uma pasta com o nome "data":

Figura 7 - Criando a Pasta "data"

3.8) Dentro dessa pasta ("data") descompacte as imagens da interface que estão disponível para download, clicando aqui:

Figura 8 - Imagens da Interface Gráfica dentro da Pasta "data"

3.9) Por último, abra seu software no Processing e clique em RUN para rodar a interface:

Figura 9 - Clicando em Run no Processing

4. Códigos

4.1) Garagino

int valor_recebido; //Cria uma variável para armazenar os valores recebidos pela Serial
char valor_enviado; //Cria uma variável para armazenar os valores que serão enviados pela Serial

boolean estadoBotao=false; //Cria uma variável para armazenar o estado do botão
boolean estadoBotao_anterior=false; //Cria uma variável para armazenar o estado anterior do botão
boolean habilita_botao=true; //Variável para habilitar o enviado dos dados do botão

void setup()
{
  Serial.begin(9600); //Inicia uma comunicação Serial com Baud Rate de 9600
  pinMode(2, OUTPUT); //Define o pino 2 como saída
  pinMode(3, OUTPUT); //Define o pino 3 como saída
  pinMode(8, INPUT_PULLUP); //Define o pino 8 como entrada e com resistor de pull-up ativo
}

void loop()

  int valor_pot = 0; //Inicia a variável para armazenar os valores do potenciômetro com 0
  
  for(int i=0;i<100;i++) //Efetua 100 vezes a leitura do potenciômetro
  {
  int leitura = map(analogRead(A0), 0, 1023, 0, 180); //Le o valor do potenciômetro,
                                                       //Converte para uma escala de 0 a 180
                                                       //e Armazena na variável leitura
  valor_pot += leitura; //Soma a variável leitura ao valor anterior de valor_pot (que inicia com 0)
  }
  
  valor_pot = valor_pot/100; //Divide o valor_pot por 100 para tirar a média das leituras
  
  Serial.write(valor_pot); //Envia para a interface (Processing) o valor lido pelo potenciometro
                           //que será um valor de 0 a 180
  
  estadoBotao = digitalRead(8); //Faz a leitura do botão

  if (estadoBotao != estadoBotao_anterior) //Se o estado for diferente do estado anterior
  {
    
    if(habilita_botao == true) //Se a variável que habilita o bota for igual a true
    {
    if (estadoBotao == HIGH) //Se o estado do botão for igual a HIGH
    {
    valor_enviado = 255; //Armazena 255 na variável que será enviada para a interface
    digitalWrite(3, LOW); //Apaga o LED verde
    digitalWrite(2, HIGH); //Acende o LED Vermelho
    }
    
    else
    {
    valor_enviado = 254; //Armazena 254 na variável que será enviada para a interface
    digitalWrite(2, LOW); //Apaga o LED Vermelho
    digitalWrite(3, HIGH); //Acende o LED Verde
    }
    
    Serial.write(valor_enviado); //Envia a variável valor_enviado
    }
    
  }
  
  estadoBotao_anterior = estadoBotao; //Armazena o estado na variável estadoBotao_anterior
 
  delay(50); //Aguarda 50 milissegundos
  
  if(Serial.available()> 0) //Se algo for recebido pela serial
  {
    valor_recebido = Serial.read(); //Armazena o que foi recebido na variável valor_recebido
    
    if(valor_recebido == 255) //Se o que foi recebido for igual a 255
    {
      digitalWrite(2, !(digitalRead(2))); //Inverte o valor do LED vermelho
    }
    
    else if(valor_recebido == 254) //Senão, se o que foi recebido for igual a 254
    {
      digitalWrite(3, !(digitalRead(3))); //Inverte o valor do LED verde
    }
    
    else if(valor_recebido == 253) //Senão, se o que foi recebido for igual a 253
    {
      digitalWrite(2, LOW); //Apaga LED Vermelho
      digitalWrite(3, LOW); //Apaga LED Verde
      habilita_botao = !habilita_botao; //Inverte o estado da variável habilita_botao
      if(habilita_botao == true) digitalWrite(2, HIGH); //Se a variável habilita_bota for igual a true
                                                        //Aciona o LED vermelho
    }
  }
  
  
}

4.2) Processing

Copie o código disponível na interface do Processing e após tudo montado e pronto clique em RUN

import processing.serial.*; //Importa a biblioteca para abrir uma comunicação Serial
Serial myPort; //Instância a biblioteca para a comuniação Serial

//Cria uma instância para cada imagem da interface
PImage fundo; //Background
PImage ponteiro; //Ponteiro
       
PImage ledOff; //LED desligado
PImage ledVerdeOn; //LED Verde (ligado)
PImage ledVermelhoOn; //LED Vermelho (ligado)
       
PImage botaoOn; //Botão em estado pressionado (Ligado)
PImage botaoOff; //Botão em estado pressionado (desligado)
PImage botaoNot; //Botão Desabilitado
//=======================

int valor_recebido; //Cria uma variável para armazenas o valor recebido pela serial
int valor_pot; //Cria uma variável para armazenar o valor do potenciometro
int valor_botao; //Cria uma variável para armazenar o valor do botão

boolean habilita_botao = true; //Cria uma variável para habilitar o botão da interface
boolean estadoLEDvermelho = false; //Cria uma variável para armazenar o estado do LED Vermelho
boolean estadoLEDverde = false; //Cria uma variável para armazenar o estado do LED Verde

int ajuste_y=14; //Variável para ajusta o eixo x na tela (Centralizar)
                 //Se não precisar de ajuste deixe com valor 0

void setup()
{
    
  String portName = Serial.list()[0]; //Lista as portas COM (Serial) encontradas
                                      //Pega a primeira porta (Posição 0 em "Serial.list()[0]" e
                                      //armazena na variável portName
                                      //Se você tiver mais de uma porta COM, identifique qual a do Garagino
  
  myPort = new Serial(this, portName, 9600); //Abre uma comunicação Serial com baud rate de 9600
  
  size(800, 600); //Define o tamanho da tela

  //Carrega as imagens e armazena elas em suas respectivas instâncias
  fundo = loadImage("fundo.jpg");
  ponteiro = loadImage("ponteiro.png");
  ledVerdeOn = loadImage("ledVerdeOn.png");
  ledVermelhoOn = loadImage("ledVermelhoOn.png");
  ledOff = loadImage("ledOff.png");
  botaoOn = loadImage("botaoOn.png");
  botaoOff = loadImage("botaoOff.png");
  botaoNot = loadImage("botaoNot.png");
  //================================================================
  
}

void draw()
{
  
  if (myPort.available() > 0) //Se algo for recebido pela serial
  {
    valor_recebido = myPort.read(); //Armazena o que foi lido dentro da variável valor recebido
    
    if (valor_recebido<181) valor_pot = valor_recebido; //Se o valor recebido for menor que 181,
                                                        //armazena esse valor dentro da variável valor_pot
                                                        
    else if (valor_recebido == 254 || valor_recebido == 255) valor_botao = valor_recebido;
    //Senão, se o valor recebido for 254 eu 255 armazena esse valor dentro da variável valor_botao
  }

  background(fundo); //Atualiza a imagem de fundo (backgroud) da interface

  translate(width/2, height/2+ajuste_y); //Posiciona o ponto 0 da interface no centro da tela
                                         //Com ajuste de 14 pixels em y (height)


  //***************************************
  //***************************************
  //Descomente "borda_mouse();" para visualizar as bordas das imagens clicáveis
  //E a visualização do centro da tela
            //borda_mouse();
  //***************************************
  //***************************************
  
  
  
  //********************************************************
  if (habilita_botao == true) //Se o botão estiver habilitado
  {
    if (valor_botao == 255) //Se o valor do botão for igual a 255
    {
      image(botaoOff, -(botaoOff.width/2), 125); //Coloca a imagem do botão desligado (Off)
                                                 //Centralizado no eixo x (width/2)
                                                 //e na posição 125 em y (height)
                                                 
      image(ledOff, -(ledOff.width*3), 50); //Coloca a imagem de LED desligado na posição do LED Verde
      image(ledVermelhoOn, ledVermelhoOn.width*2, 50); //Coloca a imagem do LED Vermelho ligada na posição x,y/width,height (65, 50)
    }
    else if (valor_botao == 254) //Se o valor do botão for igual a 254
    {
      image(botaoOn, -(botaoOn.width/2), 125); //Coloca a imagem do botão ligado (On)
                                               //Centralizado no eixo x (width/2)
                                               //e na posição 125 em y (height)
      image(ledVerdeOn, -65*3, 50); //Coloca a imagem do LED Verde ligado na posição x,y/width,height (-130, 50)
      image(ledOff, ledOff.width*2, 50); //Coloca a imagem de LED desligado na posição do LED Vermelho
    }
  }
  //OBS: "botaoOff.width" equivale ao tamanho da imagem em width,
  //nesse caso a imagem possui 65x100(width x height),
  //logo, botaoOff.width = 65
  //=======================================================
  
  
  
  //********************************************************
  else //Se não se o botão não estiver habilitado
  {
    image(botaoNot, -(152/2), 125); //Coloca a imagem do botão desabilitado (Bloqueado)
                                    //Centralizado no eixo x (width/2)
                                    //e na posição 125 em y (height)
    if (estadoLEDverde==false) image(ledOff, -65*3, 50); //Se o estado do LED verde for false (desligado)
                                                         //Atualiza a imagem do LED Verde para o LED apagado
    else image(ledVerdeOn, -65*3, 50); //Senão, se o estado do LED verde for true (aceso)
                                       //Atualiza a imagem do LED apagado para o LED Verde
                                       
    if (estadoLEDvermelho==false) image(ledOff, 65*2, 50); //Se o estado do LED vermelho for false (desligado)
                                                         //Atualiza a imagem do LED vermelho para o LED apagado
    else image(ledVermelhoOn, 65*2, 50); //Senão, se o estado do LED vermelho for true (aceso)
                                       //Atualiza a imagem do LED apagado para o LED Vermelho
  }
  //=======================================================


  
  //float c = radians(valor_pot-90); //Pega o valor lido referendo ao potenciômetro
                                   
  rotate(radians(valor_pot-90)); //Pega o valor lido referendo ao potenciômetro,
                                 //Subtrai 90 desse valor, converte para radianos e
                                 //Executa a função de rotação da tela
                                 
  image(ponteiro, -(ponteiro.width/2), -ponteiro.height+(7)); //Posiciona o centro do furo do ponteiro
                                                              //Na posição central do gráfico na imagem de fundo
  
}


void mouseClicked()
{
  
  //Se o mouse for clicado em cima da imagem do botão
  if (mouseX>= ((width/2)-76) && mouseX<= (width/2+76) && mouseY>=(height/2+125+ajuste_y) && mouseY<=(height/2+277+ajuste_y) )
  {
    habilita_botao = !habilita_botao; //Inverte o estado do botão
    myPort.write(253); //Envia o valor 253 para o Garagino
    estadoLEDvermelho = false; //Altera o estado do LED vermelho na tela para false
    estadoLEDverde = false; //Altera o estado do LED verde na tela para false
  }
  //================================================
  
 //Se o mouse for clicado em cima da imagem do LED esquerda
  else if (mouseX>= ((width/2)-(65*3)) && mouseX<= (width/2) && mouseY>=(height/2+50+ajuste_y) && mouseY<=(height/2+150+ajuste_y) )
  {
    if (habilita_botao == false) //Se o botão estiver desabilitado
    {
      estadoLEDverde = !estadoLEDverde; //Inverte a variável de estado do LED verde
      myPort.write(254); //Envia o valor 254 para o Garagino
    }
  }
//==========================================================
  
  //Se o mouse for clicado em cima da imagem do LED direita
  else if (mouseX>= (width/2+65*2) && mouseX<= (width/2+195) && mouseY>=(height/2+50+ajuste_y) && mouseY<=(height/2+150+ajuste_y) )
  {
    if (habilita_botao == false) //Se o botão estiver desabilitado
    {
      estadoLEDvermelho = !estadoLEDvermelho; //Inverte a variável de estado do LED vermelho
      myPort.write(255);  //Envia o valor 255 para o Garagino
    }
  }
  //=========================================================
  
}

void borda_mouse()
{

  textSize(32); //Define o tamanho da letra
  fill(204, 102, 0); //Define a cor Laranja (R, G, B)
  text("MouseX = " + (mouseX-width/2), -400, 250); //Escreve MouseX + o valor da posição do mouse na tela
  text("MouseY = " + (mouseY-height/2), -400, 280); //Escreve MouseY + o valor da posição do mouse na tela
  fill(255, 255, 255); //Define a cor Branca (R, G, B)
  
  //Cria Cruz central
  line(-width/2, 0, width/2, 0);
  line(0, -height/2, 0, height/2);
  //==
   
   //Cria borda do Botao
   rect(-(botaoOn.width/2), 125, 152, 152);
   //==
   
   //Cria borda do LED da esquerda
   rect(-(ledOff.width*3), 50, 65, 100);
   //==
   
   //Cria borda do LED da direita
   rect(ledOff.width*2, 50, 65, 100);
   //==
 
}

5. Criando Executável

5.1) Você também pode criar um executável para sua interface gráfica, basta clicar em Export Aplication (Ctrl+E):

Figura 10 - Criando Aplicação

5.2) Basta selecionar a plataforma, que ele irá criar o executável da sua Interface Gráfica:

Figura 11 - Selecionando a Plataforma

OBS: Para criar o executável Mac OS X, você precisar executar esses procedimentos em um computador com Mac OS X.

Então é isso Garagstas! Com esse tutorial você pode criar a interface que quiser para seu projeto, vale lembrar também que você pode criar um executável para sua interface, podendo copila-lo e executá-lo para sistemas operacionais Windows, Linux e Mac OS

Referências:

https://processing.org/

http://playground.arduino.cc/Interfacing/Processing

http://www.automacaoindustrial.info/o-que-sao-sistemas-supervisorios/

Exibições: 37836

Comentar

Você precisa ser um membro de Laboratorio de Garagem (arduino, eletrônica, robotica, hacking) para adicionar comentários!

Entrar em Laboratorio de Garagem (arduino, eletrônica, robotica, hacking)

Comentário de Mário Pires Mamona em 15 agosto 2016 às 22:10

Descobrir o problema esta em port name mudei o valor de 0 para 1.

Comentário de Mário Pires Mamona em 15 agosto 2016 às 3:29

Olá perfeito o tutorial sou iniciante e infelizmente ao executar só aparece a imagem de fundo sem os leds e sem o botão ! Estou usando um arduino UNO seria este o problema ? usei em várias IDE's e a mesma coisa. Uma luz por gentileza . Grato

Comentário de Eduardo castellani em 27 novembro 2015 às 19:58

Tutorial bem completo, Parabéns.

Comentário de Jeder Vieira em 30 junho 2015 às 2:26

muito bom o tutorial, parabens!!! Estou com uma duvida...nao estou conseguindo ler 2 ou mais entradas analogicas pela porta serial para mostrar os valores na tela separadamente. alguma dica? obrigado.

Comentário de Alexandre em 23 março 2015 às 15:09

Só pra agradecer o tutorial, q ajudou bastante em pontos cruxiais:

https://www.youtube.com/watch?v=_CYLvNpfnkg

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço