Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
66
que as cercam. Cada objeto traz consigo um conjunto de características que o fazem
existir, com um conjunto de informações a seu respeito e um conjunto de operações ou
funcionalidades que eles desempenham, formando um comportamento claro e bem
definido de suas ações no meio que se aplicam.
Este estudo remete ainda a idéia da aplicação do termo "Internet das Coisas" (ou,
em inglês, Internet of Things - IoT), que significa a existência de objetos ao nosso
redor, os quais possuem capacidade de interação através de componentes sensores e
atuadores, oferecendo desta forma alguns serviços pela interação na forma de trocas
de mensagens. Segundo Correia, Internet das coisas é a capacidade de conectar
objetos da vida real que lhes permitam alcançar um maior valor e serviço através do
intercâmbio de dados e informações. Hoje em dia, plataformas como Arduino, placas
Intel Edison, BeagleBone ou o Raspberry Pi estão oferecendo aos programadores da
Internet das Coisas um grande ecossistema de hardware que pode ser usado
facilmente para fazer um protótipo e até mesmo ir para produção
67
passam a ser utilizados pelas pessoas no dia a dia através de um mundo formado de
dispositivos e aplicações conectados.
68
para o desenvolvimento da programação de objetos criados na plataforma Arduino, de
tal forma que o conceito de abstração deste objeto fosse levado ao nível de
desenvolvimento esperado, bem como que fossem passíveis da aplicação das técnicas
mais recentes de programação orientada a objetos e padrões de projeto, conforme
descrito no capítulo 3 (Programação Orientada a Objetos e Padrões de Projeto).
Desta forma, o projeto foi batizado como Java.ino (Java com Arduino), tendo como
objetivo principal propor uma arquitetura de desenvolvimento em alto nível de
abstração, utilizando os conceitos e princípios da programação orientada a objetos em
Java, composta de uma solução de Software implementada com as linguagens C
(linguagem do Arduino) e Java, baseado na aplicação real de dispositivos criados na
plataforma Arduino. Alguns termos utilizados na proposta arquitetural deste trabalho
foram utilizados em inglês, por escolha do autor.
69
Figura 16 - Esquema de componentes envolvidos na arquitetura proposta
Fonte: Produzida pelo autor
Ainda como parte da PoC, foi criado de um protótipo de semáforo de trânsito com as
fases de "Pare", "Atenção" e "Siga". A criação do protótipo foi implementada em
hardware na plataforma Arduino através de LEDs indicadores dos estados do
semáforo, e a implementação de software foi feita utilizando o Java com os devidos
componentes da arquitetura proposta, de tal forma que fique totalmente transparente
para o desenvolvedor do programa a estrutura de hardware montada no Arduino e sua
linguagem de programação especifica. A interação do código criado em Java com a
placa será realizada através de protocolo de comunicação chamado JIP (Java.ino
Protocol), criado especificamente para estabelecer o nível de comandos de aplicação
necessários para atuação no microcontrolador, que estará executando um Sketch
especializado para tratar os comandos nas portas de comunicação do Arduino, de
70
forma totalmente transparente, tudo isso estabelecido pelo meio de comunicação
utilizado (comunicação Serial).
71
plataforma Arduino (Uno, Mega, Due, etc.), conforme apresentado no capítulo
8 (Plataforma de Programação Java no Arduino), bem como as classes que
implementam o protocolo de comunicação em Java, e também os respectivos
meios de comunicação com o Arduino (Serial, Bluetooth, Ethernet, Wifi, etc.),
conforme detalhes de projeto e implementação apresentados no capítulo 7
(Solução de Comunicação com Arduino).
72
7. SOLUÇÃO DE COMUNICAÇÃO COM ARDUINO
Diante dos desafios postos para a integração das tecnologias Java e Arduino,
inicialmente foi elaborado o projeto de comunicação entre elas, o que levou à
concepção de um protocolo de comunicação bilateral, o qual permite que o
componente Java, do projeto Java.ino como descrito no capítulo anterior, envie
comandos reconhecidos no Sketch Arduino para execução de controles nas portas de
comunicação da placa (hardware). Esta forma de comunicação é essencial para que se
estabeleça uma interface comum, que permita as duas partes envolvidas se
comunicarem e sejam reconhecidas, uma pela outra.
73
No lado da plataforma Arduino, está a implementação do Sketch executado pelo
microcontrolador da placa, tratando as mensagens ou comandos recebidos,
executando as operações enviadas, e gerando um retorno para o componente
solicitante da operação. Como exemplo, um comando de saída para uma porta
específica acionada para operação, sendo escrita realizada pelo microcontrolador na
porta acionada. Exemplos de aplicação como este e outros serão apresentados no
capítulo 8 (Plataforma de Programação Java no Arduino). Conforme citado no capítulo
anterior, este componente recebe a identificação SKPn (SKetch Protocol "n"),
implementado conforme o meio de comunicação utilizado. Abaixo uma lista dos SKPs
projetados para implementação.
74
envolvidos no processo de execução no projeto Java.ino. Estes formatos são
especificados a seguir.
75
TABELA INICAL DE COMANDOS, REFERÊNCIAS, OPERAÇÔES E PARÂMETROS
IMPLEMENTADA NA POC DO PROJETO Java.ino
PD N (inteiro) H/1 - Escrita de tensão alta na porta digital (5V)
PD N (inteiro) L/0 - Escrita de tensão baixa na porta digital (0V)
PD N (inteiro) I - Configura porta digital para Input (Entrada/Leitura)
PD N (inteiro) O - Configura porta digital para Output (Saída/Escrita)
PD N (inteiro) R - Leitura do valor de tensão na porta digital
PA N (inteiro) R - Leitura do nível de tensão na porta analógica
SR X BG - Inicia Comunicação Serial (Begin)
SR X BG N (int) Inicia Comunicação Serial (Begin) com velocidade
SR R AV - Verifica se há dado disponível para leitura na
comunicação serial (Available)
SR R RD - Leitura de dado da comunicação serial (Read)
SR W PR - Saída de dados caracteres (String) através da rotina
print da comunicação serial
SR W PL - Saída de dados caracteres (String) através da rotina
println da comunicação serial
76
Formato da mensagem no protocolo (ERRO):
!ERR&.MSG.#
• ERR: identificador de erro gerado (mnemônico fixo)
• MSG: mensagem de texto referente à descrição do erro
Seu formato inicia-se com o caractere '!' para identificação da mensagem do tipo
"ERRO", seguido do mnemônico fixo 'ERR' e o caractere '&' separando o texto de
descrição da situação de erro ocorrida. Ao final o caractere '#' indicará o fim da
mensagem enviada, seguindo a partir de então para o tratamento pela componente
Java.ino.
Seguindo o código de retorno, como mostrado, ocorre uma lista opcional de dados
separados pelo caractere '&' definindo possíveis valores adicionais de retorno que
poderão ser encaminhados na resposta ao cliente, permitindo desta forma uma maior
flexibilidade de retorno, aumentando a escalabilidade da comunicação. Ao final o
77
caractere '#' indicará o fim da mensagem enviada, seguindo a padrão das mensagens
anteriores.
78
Figura 18 - Diagrama de Classes para implementação da Comunicação do Projeto
Fonte: Produzida pelo autor
79
classes chamada API RXTXcomm, como principal API utilizada na comunicação Serial
do Java com a plataforma Arduino. Esta biblioteca (API) RXTXcomm é responsável
pela leitura e escrita da porta serial, sendo a solução aplicada para tornar possível o
envio de mensagens de comando através da comunicação serial para o Arduino, bem
como capturar as informações enviadas através das mensagens pelo Arduino, que são
enviadas/recebidas pela porta Serial onde o Arduino estará conectado ao computador.
Através desta biblioteca e com o tratamento específico das mensagens enviadas
de/para o Arduino, as classes Java demonstradas no diagrama anterior fazem a
comunicação Serial com o Arduino, permitindo assim a implementação do protocolo no
componente do projeto Java.ino (Java.ino Protocol - JIP) descrito anteriormente.
80
8. PLATAFORMA DE PROGRAMAÇÃO JAVA NO ARDUINO
81
Figura 19 - Diagrama de Classes para implementação de placas Arduino
Fonte: Produzida pelo autor
82
Figura 20 - Diagrama de Classes das portas de comunicação da placa Arduino
Fonte: Produzida pelo autor
83
Figura 21 - Diagrama de Classes de abstrações de placas Arduino
Fonte: Produzida pelo autor
84
Figura 22 - Diagrama de Classes de componentes conectáveis às placas Arduino
Fonte: Produzida pelo autor
Para o diagrama acima, estão representados dois componentes básicos que foram
implementados na PoC desenvolvida para esta pesquisa, conforme apresentada em
detalhes na sequência. Os componentes representados abaixo são o LED (Light
Emitting Diode), que pode ser usado para a emissão de luz em locais específicos, onde
se torna conveniente a sua utilização no lugar de uma lâmpada (muito utilizado em
produtos de microeletrônica como sinalizador de avisos, de forma visual), também pode
ser encontrado em tamanho maior, como em alguns modelos de semáforos. Também
foi utilizado no modelo, uma chave comutadora (Switch), também conhecida como
interruptor, que é um dispositivo simples usado para abrir ou fechar circuitos elétricos.
São utilizados na abertura de aparelhos eletrônicos, basicamente na maioria das
situações que envolvem o ligamento ou desligamento para passagem de corrente
elétrica, e que poderá ser controlada por uma porta digital na placa Arduino.
85
apresentada, algumas classes foram criadas de tal forma a trazer os benefícios
apresentados pelas soluções de padrões de projeto na construção de software, sendo
estas classes representadas abaixo, como segue:
Para validar a arquitetura proposta foi implementada uma prova de conceito (PoC,
(sigla do inglês, Proof of Concept) utilizando todas as classes apresentadas na
modelagem descrita neste capítulo, de tal forma a comprovar os resultados obtidos
com a programação orientada a objetos para a plataforma Arduino, aplicando os
princípios de orientação a objetos (OO) e a abstração em alto nível dos objetos criados.
86
A PoC contempla dois projetos implementados no hardware da plataforma Arduino,
conforme ilustração mostrada, representando a ligação da placa Arduino aos
componentes controlados pelo programa em Java, através de suas portas de
comunicação.
87
com que o LED acenda e apague em intervalos fixos de 1 segundo, de forma contínua
(um LED piscante).
88
try { Thread.sleep(1000); }
catch (InterruptedException e) { }
led1.desligar();
try { Thread.sleep(1000); }
catch (InterruptedException e) { }
}
}
}
89
Figura 25 - Esquema de ligação física dos componentes para um semáforo
Fonte: Google (Imagens)
90
plataforma Arduino, obtido pela aplicação da metodologia de programação orientada a
objetos, tornando uma forma totalmente transparente ao programador de dispositivos
embarcados, que estejam desenvolvendo projetos com prototipação através da
plataforma Arduino, considerando a plataforma física do hardware e a linguagem
específica utilizada por esta plataforma para controle das operações nas portas de
comunicação e na programação do microcontrolador.
Portanto, a plataforma proposta tem como objetivo aproveitar o melhor de cada uma
das metodologias e tecnologias adotadas. Como resultado adicional, nota-se a
facilidade de divisão de tarefas de projeto, uma vez que torna as plataformas de
software e hardware praticamente independentes, permitindo alocar equipes
especializadas em diferentes tarefas, em cada uma destas plataformas.
91
9. CONCLUSÃO
92
a conexão de sensores e/ou atuadores, através de objetos instanciados com
comportamento definindo pelos conceitos da orientação a objetos.
93
Finalmente como sugestão para avanços e evolução do projeto Java.ino, a
realização de testes funcionais e de desempenho com análise quantitativa, com o fim
de garantir sua aplicação em projetos que tenham maior grau de complexidade, dada a
simplicidade adotada na PoC realizada devido as restrições do tempo de
desenvolvimento.
94
REFERÊNCIAS BIBLIOGRÁFICAS
BANZI, Massimo. Getting Started with Arduino - 2 ed. Sebastopol, CA: O'Reilly,
2011.
CORREIA, Nuno. Internet das Coisas com SAP HANA. Lisboa: Ui5 Community
Network.
DEITEL, Paul J.; DEITEL, Harvey M. Java como programar – 8 ed. São Paulo:
Pearson Prentice Hall, 2010.
JANDL Jr., Peter. Java Guia do Programador - 2 ed. São Paulo: Novatec Editora,
2013.
LEITE, Mario; RAHAL Jr., Nelson Abu Sanra. Programação Orientada ao Objeto:
uma abordagem didática. Agosto, 2002. Disponível em:
<http://www.ccuec.unicamp.br/revista/navegacao/infotec.html>. Acesso em:
04/02/2016.
MONK, Simon. 30 Arduino Projects for the Evil Genius. New York: McGraw-Hill,
2010.
SCHILDT, Herbert. Java: A Referência Completa - 8 ed. Rio de Janeiro: Alta Books,
2014.
95
SILVEIRA, Paulo; SILVEIRA, Guilherme; LOPES, Sérgio; MOREIRA, Guilherme;
STEPPAT, Nico; KUNG, Fabio. Introdução à Arquitetura e Design de Software:
Uma visão sobre a plataforma Java. Rio de Janeiro: Elsevier, 2012.
96
APÊNDICE A
Código de implementação do SKP0
(SKetch Protocol 0 - implementação do protocolo JIP na comunicação Serial)
struct TComando {
String CMD;
String REF;
String OPR;
String VAL;
};
byte byteRead;
String strComando;
String strResposta;
struct TComando vComando;
void piscaPino13();
String lerCMD();
void limparSerial();
String converteBase2(byte);
String converteBase2Invertido(byte);
struct TComando separarCMD(String);
void lerValores(struct TComando, String[], byte&);
void executarCMD(struct TComando);
void execPD(struct TComando);
void execPA(struct TComando);
void execSR(struct TComando);
////////////
void setup()
////////////
{
pinMode(13, OUTPUT);
Serial.begin(9600);
}
97
///////////
void loop()
///////////
{
strComando = lerCMD();
Serial.println("CMD:> "+strComando);
piscaPino13();
if (strComando[0] == ERR_START)
{
strResposta = strComando;
}
else
{
strResposta = String(RSP_START) + "RSP&";
if (strComando[0] == CMD_START)
{
vComando = separarCMD(strComando);
executarCMD(vComando);
}
}
Serial.println("RSP>>> "+strResposta);
}
/////////////////////////////////////
void executarCMD(struct TComando cmd)
{
if(cmd.CMD == "PD")
execPD(cmd);
if(cmd.CMD == "PA")
execPA(cmd);
if(cmd.CMD == "SR")
execSR(cmd);
strResposta += CMD_END;
}
////////////////////////////////
void execPD(struct TComando cmd)
{
byte porta=0;
byte valor=0;
byte coderro=0;
if (cmd.REF.length() == 0 || cmd.OPR.length() == 0)
coderro+=pow(2,0);
if (cmd.REF.length() > 2 || cmd.OPR.length() != 1)
coderro+=pow(2,1);
porta = (byte)cmd.REF.toInt();
if (cmd.REF != String(porta))
coderro+=pow(2,2);
if (porta < 0 || porta > MAX_DIGITAL)
coderro+=pow(2,3);
if (String("IORH1L0").indexOf(cmd.OPR.charAt(0)) < 0)
coderro+=pow(2,4);
98
if (coderro == 0)
{
switch(cmd.OPR.charAt(0))
{
case 'O':
Serial.println("EXEC> pinMode("+String(porta)+",
OUTPUT);");
pinMode(porta, OUTPUT);
break;
case 'I':
Serial.println("EXEC> pinMode("+String(porta)+",
INPUT);");
pinMode(porta, INPUT);
break;
case 'R':
Serial.println("EXEC>
digitalRead("+String(porta)+");");
valor = digitalRead(porta);
break;
case 'H':
case '1':
Serial.println("EXEC> digitalWrite("+String(porta)+",
HIGH);");
digitalWrite(porta, HIGH);
break;
case 'L':
case '0':
Serial.println("EXEC> digitalWrite("+String(porta)+",
LOW);");
digitalWrite(porta, LOW);
break;
}
}
strResposta += String(coderro)+"&"+converteBase2Invertido(coderro);
if (cmd.OPR.charAt(0) == 'R' && coderro == 0)
strResposta += "&"+String(valor);
}
////////////////////////////////
void execPA(struct TComando cmd)
{
String val[20];
byte valcont=0;
byte porta=0;
int valor=0;
byte coderro=0;
if (cmd.REF.length() == 0 || cmd.OPR.length() == 0)
coderro+=pow(2,0);
if (cmd.REF.length() > 2 || cmd.OPR.length() != 1)
coderro+=pow(2,1);
porta = (byte)cmd.REF.toInt();
if (cmd.REF != String(porta))
coderro+=pow(2,2);
if (porta < 0 || porta > MAX_ANALOG)
99
coderro+=pow(2,3);
if (String("RW").indexOf(cmd.OPR.charAt(0)) < 0)
coderro+=pow(2,4);
if (cmd.OPR.charAt(0)=='W' && cmd.VAL.length() == 0)
coderro+=pow(2,5);
if (cmd.OPR.charAt(0)=='W')
{
lerValores(cmd,val,valcont);
for (int i=0; i<valcont; i++)
{
Serial.println("VAL["+String(i)+"]="+val[i]);
}
if (valcont != 1 || val[0].length() == 0)
coderro+=pow(2,6);
}
if (coderro == 0)
{
switch(cmd.OPR.charAt(0))
{
case 'R':
Serial.println("EXEC>
analogRead("+String(porta)+");");
valor = analogRead(porta);
break;
case 'W':
valor = val[0].toInt();
if (val[0]!=String(valor) || valor < 0 || valor >
255)
coderro+=pow(2,7);
else
{
Serial.println("EXEC>
analogWrite("+String(porta)+", "+valor+");");
analogWrite(porta, valor);
}
break;
}
}
strResposta += String(coderro)+"&"+converteBase2Invertido(coderro);
if (cmd.OPR.charAt(0) == 'R' && coderro == 0)
strResposta += "&"+String(valor);
}
////////////////////////////////
void execSR(struct TComando cmd)
{
String val[20];
byte valcont=0;
int velocidade=9600;
byte valor;
byte coderro=0;
if (cmd.REF.length() == 0 || cmd.OPR.length() == 0)
coderro+=pow(2,0);
100
if (cmd.REF.length() != 2 || cmd.OPR.length() > 2)
coderro+=pow(2,1);
if (cmd.REF != "RW")
coderro+=pow(2,2);
if (String("BG|AV|RD|PR|PL").indexOf(cmd.OPR) < 0)
coderro+=pow(2,3);
if (String("PR|PL").indexOf(cmd.OPR) >= 0 && cmd.VAL.length() == 0)
coderro+=pow(2,4);
if (String("BG|PR|PL").indexOf(cmd.OPR) >= 0)
{
lerValores(cmd,val,valcont);
for (int i=0; i<valcont; i++)
{
Serial.println("VAL["+String(i)+"]="+val[i]);
}
}
if (String("PR|PL").indexOf(cmd.OPR) >= 0)
if (valcont < 1 || val[0].length() == 0)
coderro+=pow(2,5);
if (cmd.OPR == "BG")
if (coderro == 0)
{
if (cmd.OPR == "BG")
{
Serial.println("EXEC> Serial.begin("+String(velocidade)
+");");
Serial.begin(velocidade);
}
if (cmd.OPR == "AV")
{
Serial.println("EXEC> Serial.available();");
valor = Serial.available();
}
if (cmd.OPR == "RD")
{
Serial.println("EXEC> Serial.read();");
valor = Serial.read();
}
if (cmd.OPR == "PR")
{
Serial.println("EXEC> Serial.print(\"xxx\");");
Serial.print(val[0]);
101
}
if (cmd.OPR == "PL")
{
Serial.println("EXEC> Serial.println(\"xxx\");");
Serial.println(val[0]);
}
}
strResposta += String(coderro)+"&"+converteBase2Invertido(coderro);
if (cmd.OPR == "AV" && coderro == 0)
strResposta += "&"+String(valor);
if (cmd.OPR == "RD" && coderro == 0)
strResposta += "&"+(char)valor;
}
//////////////////
void piscaPino13()
{
// pisca pino 13 (LED onboard)
digitalWrite(13, HIGH);
delay(200);
digitalWrite(13, LOW);
delay(100);
}
///////////////////
void limparSerial()
{
char ch;
Serial.print("<lixo>");
while (Serial.available())
{
ch = Serial.read();
Serial.print(ch);
if (ch == CMD_END)
break;
delay(10);
}
}
//////////////////////////////
String converteBase2(byte val)
{
String aux = "";
while (val > 0)
{
aux = (val%2) + aux;
val = val/2;
}
while (aux.length() < 8)
aux = "0"+aux;
return aux;
}
//////////////////////////////
String converteBase2Invertido(byte val)
{
String aux = "";
while (val > 0)
{
102
aux = aux + (val%2);
val = val/2;
}
while (aux.length() < 8)
aux = aux + "0";
return aux;
}
///////////////
String lerCMD()
{
String strCMD;
byte control = 0;
while (true)
{
if (! Serial.available())
continue;
if (strCMD.length() == 250)
{
strCMD = ERR_START + "ERR&Estouro no comprimento da linha
de comando!#";
limparSerial();
break;
}
byteRead = Serial.read();
Serial.write(byteRead);
delay(10);
if (byteRead == CMD_END)
{
strCMD += (char)byteRead;
break;
}
if (control == 0)
{
if (byteRead == CMD_START)
{
strCMD += (char)byteRead;
control ++;
}
continue;
}
if (control == 1)
{
if (byteRead >= 'A' && byteRead <= 'Z')
strCMD += (char)byteRead; else
if (byteRead == CMD_SPLIT) {
strCMD += (char)byteRead;
control ++;
}
continue;
}
103
if (control == 2)
{
if (byteRead >= 'A' && byteRead <= 'Z')
strCMD += (char)byteRead; else
if (byteRead >= '0' && byteRead <= '9')
strCMD += (char)byteRead;
else
if (byteRead == CMD_SPLIT) {
strCMD += (char)byteRead;
control ++;
}
continue;
}
if (control == 3)
{
if (byteRead >= 'A' && byteRead <= 'Z')
strCMD += (char)byteRead;
else
if (byteRead >= '0' && byteRead <= '9')
strCMD += (char)byteRead;
else
if (byteRead == CMD_SPLIT) {
strCMD += (char)byteRead;
control ++;
}
continue;
}
if (control == 4)
{
strCMD += (char)byteRead; }
}
Serial.println("/");
Serial.println("strCMD> "+strCMD);
if (control < 3)
strCMD = "!ERR&Comando invalido! Faltando campos obrigatorios.#";
Serial.println("--x--");
return strCMD;
}
//////////////////////////////////////
struct TComando separarCMD(String cmd)
{
struct TComando aux;
String strAux;
byte control = 0;
104
if (i < cmd.length())
{
if ((control>3 || cmd[i]!=CMD_SPLIT) && cmd[i]!=CMD_END) {
// SPLIT
strAux = strAux + cmd[i];
continue;
}
}
switch(control)
{
case 1:
aux.CMD = strAux; break;
case 2:
aux.REF = strAux; break;
case 3:
aux.OPR = strAux; break;
case 4:
aux.VAL = strAux; break;
}
strAux = "";
control++;
}
Serial.println("vCMD> "+aux.CMD);
Serial.println("vREF> "+aux.REF);
Serial.println("vOPR> "+aux.OPR);
Serial.println("vVAL> "+aux.VAL);
return aux;
}
//////////////////////////////////////////////////////////////
void lerValores(struct TComando cmd, String val[], byte& cont)
{
String strAux = "";
cont = 0;
Serial.println("VAL="+cmd.VAL);
if (cmd.VAL.length() <= 0)
return;
val[cont++] = strAux;
strAux = "";
}
105
APÊNDICE B
Código de implementação da PoC referente ao objeto
representando a abstração de um Semáforo de Trânsito,
utilizando o projeto Java.ino
private SemaforoJavaino()
{
arduino = FabricaArduino.criarArduino(EModeloArduino.UNO,"Projeto
Semaforo","semaforo");
arduino.setPortaSerial(portaArduino);
arduino.openComunicacao(CommunicationType.SERIAL);
ledAberto = new Led("ledAberto",arduino,portaAberto);
ledFechado = new Led("ledFechado",arduino,portaFechado);
ledAtencao = new Led("ledAtencao",arduino,portaAtencao);
}
106
public void semaforoFechado()
{
resetSemaforo();
this.ledFechado.ligar();
}
107