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
Alguns Fios
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:
http://playground.arduino.cc/Interfacing/Processing
http://www.automacaoindustrial.info/o-que-sao-sistemas-supervisorios/
Comentar
Descobrir o problema esta em port name mudei o valor de 0 para 1.
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
Tutorial bem completo, Parabéns.
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.
Só pra agradecer o tutorial, q ajudou bastante em pontos cruxiais:
Bem-vindo a
Laboratorio de Garagem (arduino, eletrônica, robotica, hacking)
© 2024 Criado por Marcelo Rodrigues. Ativado por
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)