Arduino Introducao e Recursos Avancados
Arduino Introducao e Recursos Avancados
Arduino Introducao e Recursos Avancados
ESCOLA NAVAL
DEPARTAMENTO DE ENGENHEIROS NAVAIS
RAMO DE ARMAS E ELECTRÓNICA
Arduino
Introdução e Recursos Avançados
[email protected]
[email protected]
2009
Índice
1. Introdução ............................................................................................................................ 7
2. Hardware vs Software ......................................................................................................... 8
2.1. Hardware ...................................................................................................................... 8
2.1.1. Microprocessador ................................................................................................ 9
2.1.2. Microcontrolador ................................................................................................. 9
2.1.3. Tipos e Quantidades de Memória Disponíveis ................................................ 11
2.1.4. Pinout Disponível ............................................................................................... 12
2.2. Software ..................................................................................................................... 15
2.2.1. Instalação e Utilização ...................................................................................... 15
2.2.2. Ciclo de Desenvolvimento ................................................................................ 17
2.2.3. Interacção do Arduino com outro Software .................................................... 18
3. Índice de Instruções ........................................................................................................... 18
3.1. Funções Base ............................................................................................................. 19
3.1.1 void setup()......................................................................................................... 19
3.1.2 void loop()........................................................................................................... 19
3.1.3. Resumindo ......................................................................................................... 20
3.2. Ciclos ........................................................................................................................... 21
3.2.1 Ciclo If…….else .................................................................................................. 21
3.2.2 Ciclo for ............................................................................................................... 22
3.2.3 Ciclo switch / case .............................................................................................. 23
3.2.4 Ciclo while .......................................................................................................... 24
3.2.5 Ciclo do….while ................................................................................................. 25
3.3. Tipos de variáveis disponíveis .................................................................................. 26
3.3.1 Variável do Tipo Boolean .................................................................................. 26
3.3.2. Variável do tipo char vs unsigned char ............................................................. 27
3.3.3. Variável do tipo byte ......................................................................................... 27
3.3.4. Variável do tipo int vs unsigned int .................................................................. 28
3.3.5. Variável do tipo long vs unsigned long ............................................................. 28
3.3.6. Variável do tipo float vs double ........................................................................ 29
3.3.7. Variável do Tipo array e a Noção de string ...................................................... 29
3.4. Converter tipos de variáveis ..................................................................................... 30
3.4.1. char(x) ................................................................................................................. 30
3.4.2. byte(x) ................................................................................................................ 30
3.4.3. int(x).................................................................................................................... 30
3.4.4. long(x)................................................................................................................. 30
3.4.5. float(x) ................................................................................................................ 30
3.5. Funções....................................................................................................................... 31
3.5.1. Input/Output digital ............................................................................................... 31
3.5.1.1. pinMode() ....................................................................................................... 31
3.5.1.2 digitalWrite() ...................................................................................................... 32
3.5.1.3. digitalRead()................................................................................................... 33
3.5.2. Input/Output analógico ......................................................................................... 34
3.5.2.1 analogRead() ...................................................................................................... 34
3.5.2.2 analogWrite() ..................................................................................................... 35
3.5.3. Tempo ..................................................................................................................... 36
3.5.3.1. millis() ............................................................................................................. 36
3.5.3.2. micros() ........................................................................................................... 36
3.5.3.3. delay (milisegundos) ..................................................................................... 37
3.5.3.4. delayMicroseconds (microsegundos)........................................................... 37
3.5.4. Funções Matemáticas ........................................................................................... 39
3.5.4.1. min(valor1,valor2) ......................................................................................... 39
3.5.4.2. max(valor1,valor2) ........................................................................................ 39
3.5.4.3. abs(valor) ........................................................................................................ 39
3.5.4.4. constrain(valor, valor1.,valor2) .................................................................... 40
3.5.4.5. map(X,valor1,valor2,para valor1,para valor2) ............................................ 40
3.5.4.6. pow(valor, expoente) .................................................................................... 41
3.5.4.7. sqrt(valor) ....................................................................................................... 41
3.5.5. Funções Trigonométricas ..................................................................................... 42
3.5.5.1. sen(valor) ........................................................................................................ 42
3.5.5.2. cos(valor) ........................................................................................................ 42
3.5.5.1. tan(valor) ........................................................................................................ 42
3.5.6. Números Aleatórios .............................................................................................. 43
3.5.6.1 randomSeed(valor) ............................................................................................ 43
3.5.6.2. random() ......................................................................................................... 43
3.5.7. Interrupts................................................................................................................ 45
3.5.7.1. attachInterrupt(interrupt, função,modo) ................................................... 45
3.5.7.2. detachInterrupt(interrupt)............................................................................ 46
5. Conclusão ........................................................................................................................... 68
6. Bibliografia ......................................................................................................................... 69
1. Introdução
Este tutorial tem como principal objectivo ser uma referência para a utilização da placa
de desenvolvimento Arduino, não só para quem se está a iniciar no assunto, mas, também,
para quem procura aprofundar mais o seu conhecimento sobre o tema.
O Arduino é uma ferramenta de desenvolvimento open source , tendo surgido de um
projecto académico - quem sabe um projecto seu não poderá ter o mesmo sucesso?... Como
ferramenta é usualmente associado à filosofia de Physical Computing , ou seja, ao conceito
que engloba a criação de sistemas físicos através do uso de Software e Hardware capazes de
responder a inputs vindos do mundo real.
Podemos designar o Arduino simplesmente como uma peça de Hardware ou um
Software de desenvolvimento, mas é muito mais que isso. Devido ao sucesso que tem vindo a
alcançar ao longo do tempo, existe uma enorme comunidade de utilizadores/seguidores em
todo o Mundo, podendo afirmar-se que o Arduino representa também uma enorme
comunidade. As razões para tal sucesso baseiam-se no seu baixo custo - dadas as suas
funcionalidades -, a simplicidade na utilização e a possibilidade de utilização em vários
sistemas operativo, como o Windows, Macintosh OS e Linux - capacidade essa denominada
por Cross-platform .
O estudo do Arduino abre-nos portas à compreensão de uma importante ferramenta de
desenvolvimento através de uma aprendizagem simples mas dedicada, onde podemos fazer
desde robots a domótica entre muitas outras aplicações, bastando simplesmente ter
imaginação.
Devido à sua enorme utilização, como foi referido anteriormente, torna-se um assunto
quase que obrigatório a abordar, sendo o seu conhecimento uma mais-valia para todos os
interessados pela electrónica (e não só).
Assim, espera-se que este tutorial seja uma pequena ajuda para a aquisição de
conhecimento sobre a temática em estudo, que deverá pautar pela dedicação.
2. Hardware vs Software
Antes de começar a trabalhar propriamente com esta plataforma de desenvolvimento,
torna-se necessário começar por perceber o seu funcionamento, para tal descrever-se-á neste
capítulo o funcionamento do Arduino, em termos de Hardware e Software.
Espera-se assim de certa forma iluminar o caminho neste estudo, fazendo com que
toda a percepção do assunto a tratar se torne mais simples, ou seja, serão aqui apresentadas
as bases para a sua compreensão.
2.1. Hardware
De seguida, far-se-á uma exposição do tema incidindo na placa Arduino Duemilinove
(disponível na Escola Naval -EN), em tudo semelhante em termos de utilização à placa de
desenvolvimento Arduino Mega. Contudo verificam-se pequenas diferenças como a diferença
na sua capacidade de armazenamento (memória disponível), o número de pinos analógicos, o
número de pinos digitais e as dimensões.
O Arduino Duemilinove (Fig. 1) apresenta-se com o microcontrolador ATMega168 ou
ATMega328, enquanto o Arduino Mega (Fig.2) apresenta-se com um microcontrolador
ATMega1280.
Vão ser abordados neste subcapítulo dois temas de grande importância relativamente
ao Arduino Duemilinove, são eles: Tipos e quantidades de memória disponíveis e o pinout
disponível . Mais informações relativas ao microcontrolador em estudo, ou qualquer outro,
devem ser consultados os respectivos datasheet.
Mas antes de abordar os temas referidos anteriormente torna-se necessário fazer a
distinção entre microprocessador e microcontrolador, que por vezes é alvo de confusão.
2.1.1. Microprocessador
Um microprocessador, basicamente, é constituído por um circuito integrado com a
capacidade de executar determinadas instruções, sendo a sua velocidade de processamento
determinada por um circuito que produz um determinado Clock (kHz, MHz ou GHz).
O seu poder de processamento é afectado por características como Bits, quantidade de
núcleos, arquitectura apresentada, tipo de instruções, entre outras. Como factor de grande
importância tem-se ainda a existência de memória externa, onde estão armazenados os
programas que serão executados.
Microprocessador
Periféricos
Clock
2.1.2. Microcontrolador
Um microcontrolador, ao contrário de um microprocessador, é desenhado e construído
de forma a integrar diversos componentes num único circuito integrado, evitando, assim, a
necessidade de adicionar componentes externos ao microcontrolador, que permitiriam as
suas funcionalidades.
Etc Etc
CPU ROM Porta Série
Pela análise da figura acima, pode-se ter uma noção de alguns exemplos de
componentes que se encontram disponíveis, conseguindo reunir uma grande quantidade de
recursos num único circuito integrado.
Na figura seguinte, é apresentado um diagrama de blocos de um microcontrolador
ATMega168 – em tudo idêntico a um ATMega328 – em que é possível identificar todos os
seus constituintes.
Como podemos constatar pela análise da tabela 1, o ATMega1280 leva clara vantagem
em termos de capacidade. Uma das memórias mais importantes , além da memória Flash
que permite o armazenamento do bootloader e do programa – sketch - a ser executado, é a
memória SRAM (Static Random Access Memory), que se comporta de forma semelhante à
RAM nos nossos computadores. É na SRAM que o programa, ao ser executado, cria e modifica
todo o tipo de variáveis necessárias à sua execução. Este tipo de memória apenas mantém os
dados enquanto se encontra alimentada, o mesmo não acontece com a memória EEPROM
(Electrically-Erasable Programmable Read-Only Memory) e memória Flash.
A memória Flash é nos dias de hoje comummente utilizada em cartões de memória,
pendrives, memória de armazenamento em câmaras de vídeo, telemóveis, PDA (Personal
Digital Assistant), entre muitas outras aplicações. Podemos resumir o tipo de memória, em
função da sua utilização, da seguinte forma:
Com vista a ser poupada memória SRAM, necessária para a correcta execução do
programa, por vezes são guardadas constantes (p.ex. o número �) na memória Flash e
EEPROM. Para tal, recorrem-se a bibliotecas próprias que possibilitam essa leitura e escrita,
para a EEPROM pode-se recorrer à biblioteca <EEPROM.h> e para a memória Flash pode-se
recorrer è biblioteca <pgmspace.h> ou <Flash.h>.
Neste tutorial apenas vão ser abordadas a biblioteca <EEPROM.h> e <Flash.h> ,
mas, devido ao carácter open source , existem muitas outras bibliotecas disponíveis para as
mesmas finalidades, devendo o leitor procurar trabalhar com a que se sente mais à vontade e
obtém os melhores resultados. A abordagem a estas duas bibliotecas encontra-se no capítulo
4 – Recursos Avançados .
14
Pinos de I/O digitais
(6 com Pulse Width Modulation (PWM))
Pinos analógicos 6
Pinos de Ground (GND) 3
Pinos de 5 V 1
Pinos de 3.3 V 1
Pinos de Analog Reference (AREF) 1
Pinos de reset (RESET) 1
Tabela 2 – Pinout disponível (Arduino Duemilinove)
É ainda importante referir que a corrente máxima por cada pino analógico e digital é de
40 mA, à excepção da saída que providencia 3.3 V (visível na figura 1 e figura 5), que permite
correntes máximas de 50 mA.
De acordo com Sousa and Lavinia, 2006, a capacidade de utilizar Pulse Width
Modulation (PWM), é muito importante, pois permite obter uma tensão analógica a partir de
um sinal digital, ou seja, de um sinal que apenas pode assumir o estado lógico 0 (0V) ou 1 (5
V). O conceito de PWM é utilizado para referir sinal que possua uma frequência constante e
um duty cicle variável.
A teoria por detrás deste fenómeno pode ser facilmente descrita. Analisemos a
seguinte equação:
�
� = ∫�
� ⇒
� ={
⇒ <
Nota: Na equação anterior representa a duração do impulso, e � representa
a tensão do impulso do sinal PWM.
��
� = ∫ �� +∫
�
Ficando pois:
� = ∗ ��
Podemos concluir, pela análise da equação anterior, que a tensão média � " é
directamente proporcional ao duty cicle do sinal PWM. Esta característica permite-nos fazer
variar a tensão, neste caso específico, variar a tensão entre 0 e 5 V (Arduino).
Após uma breve descrição sobre o modo de funcionamento de um sinal PWM, vamos
agora aprofundar um pouco mais a conversão A/D. Este factor é de grande interesse e a sua
compreensão é fundamental para perceber os valores obtidos nos pinos analógicos. O
microcontrolador utilizado possui um conversor analógico digital de 10 bits, fazendo as
contas:
=
Como a tensão máxima de referência, por definição, se encontra nos 5V,
correspondendo ao valor 1023, obtemos a seguinte resolução:
÷ ≅ , V≅ mV
Em caso de aplicações que possuam sensores analógicos, por vezes 5 mV não é uma
resolução aceitável - existindo uma grande perda de resolução. Uma possível solução, sem
recorrer a electrónica externa, é apresentada de seguida.
Para a resolução da questão, existe um pino de entrada denominado AREF, que
significa Analog Reference . Este pino permite mudar a referência analógica do standard 5V
para o valor de entrada. Ficando todas as entradas analógicas com a referência introduzida.
Simplificando, se for introduzido no pino AREF a tensão de 2V obtém-se a seguinte
resolução:
÷ ≅ . mV ≅ mV
É importante ter em conta que todos os pinos analógicos ficam com esta referência,
sendo necessária também a sua declaração por Software pela forma
analogReference(tipo) . A referência analógica pode, assim, ser de três tipos:
2.2. Software
2.2.1. Instalação e Utilização
Neste capítulo, vai ser efectuada uma breve descrição de como instalar e utilizar o
Software de desenvolvimento Arduino.
O Software de desenvolvimento Arduino é bastante fácil e intuitivo de utilizar, não
havendo qualquer nível de dificuldade. Foram estruturados passos de forma a simplificar a sua
utilização e instalação.
A última versão disponível aparecerá na parte superior da página, como mostra a figura
abaixo, sendo só necessário escolher a versão apropriada para o sistema operativo que nos
encontramos a trabalhar. Actualmente, a versão mais actual é a 0016, mas quando estiver a
ler este tutorial muito provavelmente já deve haver uma versão mais avançada.
Opção Tools
Fig.14 – Botão para compilar o Sketch elaborado Fig.15 – Botão para efectuar uploading
3. Índice de Instruções
Neste capítulo, vão ser referidas as mais importantes instruções base do ambiente de
desenvolvimento Arduino, sem recorrer a bibliotecas externas, sendo estas enumeradas por
tipo de aplicação. Antes de abordar algumas das instruções possíveis numa linguagem de alto
nível, podemos fazer uma breve abordagem para analisar qual a classificação a atribuir ao
microcontrolador em estudo.
De acordo com Arroz, Monteiro et al. 2007, pág. 732, podemos classificar os
processadores tendo em conta o seu conjunto de instruções em duas categorias:
CISC (Complex Instruction Set Computers)
RISC (Reduced Instruction Set Computers)
Baseando-se a arquitectura CISC num conjunto de instruções com modos de
endereçamento bastante complexos, ao utilizar este tipo de arquitectura é permitido elaborar
programas bastante compactos e codificáveis ao recorrer a um uso reduzido de instruções.
Alguns dos inconvenientes deste tipo de arquitectura são baseados no elevado tempo de
ciclos de relógio, necessários para executar cada uma das suas instruções. Outro
inconveniente é a existência de variados modos de endereçamento.
Por outro lado os processadores baseados em arquitecturas do tipo RISC, apresentam
um conjunto de instruções bastante reduzido, possibilitando assim obter uma enorme
simplicidade e um tempo de execução menor por instrução que a arquitectura CISC.
Conseguindo, assim, com um conjunto de instruções básicas com tempo de execução
menores, obter, no final, velocidades de processamento mais elevadas que a arquitectura
CISC.
Na sua versão mais simples, baseando a análise em Arroz, Monteiro et al. 2007 pág.
733, pode afirmar-se que os processadores RISC possuem os seguintes tipos de instruções:
Instruções lógicas e aritméticas sobre registos;
Instruções de transferência de dados entre memória e registos;
Instruções de controlo.
No datasheet dos microcontroladores utilizados nos modelos do Arduino, pode-se
perceber que estamos perante microcontroladores baseados numa arquitectura advanced
RISC . Segundo Tecnology 1992 pág. 14, em que é efectuado uma revisão completa à
arquitectura advanced R)SC , é referido que esta arquitectura foi desenvolvida para ser uma
especificação standard para uma família de microprocessadores baseada na família MIPS.
Exemplo:
(1) int botao=3; // Declaração de uma variável do tipo integer, com o nome botao
inicializada com o valor 3 .
(2) void setup() {
(3) Serial.begin(9600); // Permite a inicialização da comunicação Série
(4) pinMode(botao,INPUT); // Permite definir o pino 3 como )NPUT
(5) }
(6) void loop(){
(7) (……….)
(8) }
Exemplo:
(1) int botao=3,val; // Declaração de uma variável do tipo integer, com o nome
botao inicializada com o valor 3 e de uma variável do mesmo tipo com o nome
val
(2) void setup() {
(3) Serial.begin(9600); // Permite a inicialização da comunicação Série
(4) pinMode(botao,INPUT); // Permite definir o pino 3 como )NPUT
(5) pinMode(13,OUTPUT); // Permite definir o pino 13 como OUTPUT
(6) }
(7) void loop(){
(8) val=analogRead(botao); // Permite a leitura analógica do valor do pino 3
atribuindo o seu valor à variável val
(9) if(val>=500){ // Ciclo if que testa a condição – val>=500 (maior ou igual a 500)
3.1.3. Resumindo
As funções void setup e void loop são de carácter obrigatório, ou seja,
mesmo que não necessária a sua utilização deverão constar no código utilizado.
E apenas serão chamadas funções externas que constem na função void
loop .
Um resumo dos subcapítulos anteriores encontra-se expresso no exemplo
seguinte:
Exemplo:
3.2. Ciclos
3.2.1 Ciclo If…….else
Descrição: É utilizado para descrever uma condição, ou seja, quando uma
variável for: igual, maior, menor ou diferente (de acordo com a declaração
efectuada) que um determinado valor é executada uma determinada condição.
Podem-se usar vários ciclos if….else encadeados, de forma a verificar diversas
condições.
Sintaxe:
if(condição){
Instrução 1;
Instrução 2;
…..
}
else{
Instrução 3;
Instrução 4;
…..
}
if(condição){
Instrução 1;
Instrução 2;
…..
}
X == Y X igual a Y
X diferente de Y (não igual)
X != Y
X maior que Y
X>Y
X maior ou igual a Y
X >= Y
X menor que Y
X<Y
X menor ou igual a Y
X <= Y
Tabela 4 – Condições possíveis
Exemplo:
(1) int botao=3,val; // Declaração de uma variável do tipo integer, com o nome
botao inicializada com o valor 3 e de uma variável do mesmo tipo com o nome
val
(2) void setup() {
(3) Serial.begin(9600); // Permite a inicialização da comunicação Série
(4) pinMode(botao,INPUT); // Permite definir o pino 3 como )NPUT
Sintaxe:
A inicialização é apenas efectuada uma vez, no início do ciclo. Cada vez que o
ciclo é efectuado a condição é testada. Caso a condição se verifique é efectuado
o incremento, caso a condição não se verifique o ciclo termina a sua execução. A
condição, referida anteriormente, é declarada à semelhança da condição
utilizada no ciclo if. O exemplo abaixo mostra um exemplo de implementação
do ciclo for, face às regras expostas acima.
Exemplo:
(9) f[i]=val; //Atribui o valor da variável val ao vector f[i] , ou seja, permite
preencher o vector com 11 valores do pino analógico 3
(10) }
(11) }
Sintaxe:
switch(variável){
case 1:
Instrução a executar quando variável for 1 (variável == 1)
break;
case 2:
Instrução a executar quando variável for 2 (variável == 2)
break;
…..
default:
Conjunto de instruções a executar se nenhuma das condições for verificada. A
utilização desta condição é opcional.
break;
}
Exemplo:
Sintaxe:
while(condição){
Instrução 1;
Instrução 2;
…..
}
É necessário fazer com que a condição se torne falsa, caso se queira finalizar o
ciclo para executar outras instruções. Pois caso contrário o ciclo vai ser
executado indefinidamente.
Exemplo:
Sintaxe:
do{
Instrução 1;
Instrução 2;
…..
}
while(condição);
Exemplo:
Sintaxe:
Exemplo:
Sintaxe:
Exemplos:
Sintaxe:
Exemplos:
Sintaxe:
Exemplos:
Sintaxe:
Exemplos:
Sintaxe:
Exemplos:
Sintaxe:
Exemplos:
Descrição: Converte um valor de x, que pode ser de qualquer tipo, para uma
variável do tipo char.
Sintaxe:
3.4.2. byte(x)
Descrição: Converte um valor de x, que pode ser de qualquer tipo, para uma
variável do tipo byte.
Sintaxe:
3.4.3. int(x)
Descrição: Converte um valor de x, que pode ser de qualquer tipo, para uma
variável do tipo integer.
Sintaxe:
3.4.4. long(x)
Descrição: Converte um valor de x, que pode ser de qualquer tipo, para uma
variável do tipo long.
Sintaxe:
3.4.5. float(x)
Descrição: Converte um valor de x, que pode ser de qualquer tipo, para uma
variável do tipo float.
Sintaxe:
3.5. Funções
Sintaxe:
Exemplo:
(1) int botao=3,val; // Declaração de uma variável do tipo integer, com o nome
botao inicializada com o valor 3 e de uma variável do mesmo tipo com o nome
val não inicializada com nenhum valor
(2) void setup() {
(3) Serial.begin(9600); // Permite a inicialização da comunicação Série
(4) pinMode(botao,INPUT); // Permite definir o pino 3 como )NPUT
(5) pinMode(13,OUTPUT); // Permite definir o pino 13 como OUTPUT
(6) }
(7) void loop(){
(8) val=analogRead(botao); // Permite a leitura analógica do valor do pino 3
atribuindo o seu valor à variável val
(9) if(val>=500) // Ciclo if que testa a condição – val>=500 (maior ou igual a 500)
(10) digitalWrite(13,HIGH); // Se a condição for verificada, é atribuído ao pino
digital 13 a condição ()G( 5 V)
(11) }
(12) }
3.5.1.2 digitalWrite()
Descrição: Possibilita, nos pinos configurados como output através da instrução
pinMode , estabelecer a saída dos respectivos pinos com o valor lógico 1
(HIGH – 5 V) ou com o valor lógico 0 (LOW – 0V)
Sintaxe:
Exemplo:
(1) int botao=3,val; // Declaração de uma variável do tipo integer, com o nome
botao inicializada com o valor 3 e de uma variável do mesmo tipo com o nome
val não inicializada com nenhum valor
(2) void setup() {
(3) Serial.begin(9600); // Permite a inicialização da comunicação Série
(4) pinMode(botao,INPUT); // Permite definir o pino 3 como )NPUT
(5) pinMode(13,OUTPUT); // Permite definir o pino 13 como OUTPUT
(6) }
(7) void loop(){
(8) val=analogRead(botao); // Permite a leitura analógica do valor do pino 3
atribuindo o seu valor à variável val
(9) if(val>=500) // Ciclo if que testa a condição – val>=500 (maior ou igual a 500)
(10) digitalWrite(13,HIGH); // Se a condição for verificada, é atribuído ao pino
digital 13 a condição ()G( 5 V)
(11) }
(12) }
3.5.1.3. digitalRead()
Descrição: Possibilita a leitura de uma entrada digital específica, retornando um
valor no formato integer (int). Se obtivermos um valor de retorno de 1 ,
estamos perante uma leitura do tipo ()G( valor lógico 1). Se tal não se
verificar, e tivermos um valor de retorno igual a 0 , estamos perante uma
leitura do tipo LOW valor lógico 0).
Sintaxe:
Exemplo:
(1) int botao=3,val; // Declaração de uma variável do tipo integer, com o nome
botao inicializada com o valor 3 e de uma variável do mesmo tipo com o nome
val não inicializada com nenhum valor
(2) void setup() {
(3) Serial.begin(9600); // Permite a inicialização da comunicação Série
(4) pinMode(botao,INPUT); // Permite definir o pino 3 como )NPUT
(5) pinMode(13,OUTPUT); // Permite definir o pino 13 como OUTPUT
(6) }
(7) void loop(){
(8) val=digitalRead(botao); // Permite a leitura do valor do pino 3 digital
atribuindo o seu valor à variável val
(9) if(val==1) // Ciclo if que testa a condição – val>=500 (maior ou igual a 500)
(10) digitalWrite(13,HIGH); // Se a condição for verificada, é atribuído ao pino
digital 13 a condição ()G( 5 V)
(11) }
(12) else{ // Caso a condição do ciclo if não se verifique
(13) digitalWrite(13,LOW); // Se a condição não for verificada, é atribuído ao pino
digital 13 a condição LOW 0 V)
(14) }
(15) }
Sintaxe:
Exemplo:
(1) int botao=3,val; // Declaração de uma variável do tipo integer, com o nome
botao inicializada com o valor 3 e de uma variável do mesmo tipo com o nome
val não inicializada com nenhum valor
(2) void setup() {
(3) Serial.begin(9600); // Permite a inicialização da comunicação Série
(4) pinMode(botao,INPUT); // Permite definir o pino 3 como )NPUT
(5) pinMode(13,OUTPUT); // Permite definir o pino 13 como OUTPUT
(6) }
(7) void loop(){
(8) val=analogRead(botao); // Permite a leitura analógica do valor do pino 3
atribuindo o seu valor à variável val
(9) if(val>=500) // Ciclo if que testa a condição – val>=500 (maior ou igual a 500)
(10) digitalWrite(13,HIGH); // Se a condição for verificada, é atribuído ao pino
digital 13 a condição ()G( 5 V)
(11) }
(12) }
3.5.2.2 analogWrite()
Descrição: Possibilita a utilização dos pinos PWM (Pulse Width Modulation) da
placa Arduino. O sinal PWM mantém-se até ser modificado através de uma
outra instrução que afecte esse pino, a frequência do sinal PWM criado é de ≅
��.
Sintaxe:
Exemplo:
(1) int botao=3,val; // Declaração de uma variável do tipo integer, com o nome
botao inicializada com o valor 3 e de uma variável do mesmo tipo com o nome
val não inicializada com nenhum valor
(2) void setup() {
(3) Serial.begin(9600); // Permite a inicialização da comunicação Série
(4) pinMode(botao,INPUT); // Permite definir o pino 3 como )NPUT
(5) pinMode(13,OUTPUT); // Permite definir o pino 13 como OUTPUT
(6) }
(7) void loop(){
(8) val=analogRead(botao); // Permite a leitura analógica do valor do pino 3
atribuindo o seu valor à variável val
(9) if(val>=500) // Ciclo if que testa a condição – val>=500 (maior ou igual a 500)
(10) analogWrite(9,255); // Instrução com a mesma função que
digitalWrite 9,()G(
(11) }
(12) else{
(13) analogWrite(9,0); // Instrução com a mesma função que
digitalWrite 9,LOW
(14) }
(15) }
3.5.3. Tempo
3.5.3.1. millis()
Descrição: Possibilita o retorno da quantidade de tempo, em milisegundos na
forma de uma variável do tipo unsigned long . O valor retornado representa o
tempo que, passou desde que o programa actual começou a ser executado. O
overflow (voltar ao início, valor zero) do contador ocorre passado um tempo de
≅ 50 dias.
Sintaxe:
Exemplo:
(1) unsigned long tempo; // Declarada uma variável do tipo unsigned long com o
nome tempo
(2) void setup() {
(3) …..
(4) }
(5) void loop(){
(6) tempo = millis(); // Atribui à variável tempo o valor em milisegundos desde
que o sketch actual começou a ser executado
(7) }
3.5.3.2. micros()
Descrição: Possibilita o retorno da quantidade de tempo, em microsegundos na
forma de uma variável do tipo unsigned long . O valor retornado representa o
tempo que, passou desde que o programa actual começou a ser executado. O
overflow (voltar ao início, valor zero) do contador ocorre passado um tempo de
≅ 70 minutos.
Sintaxe:
Exemplo:
(1) unsigned long tempo; // Declarada uma variável do tipo unsigned long com o
nome tempo
(2) void setup() {
(3) …..
(4) }
(5) void loop(){
(6) tempo = micros(); // Atribui à variável tempo o valor em microsegundos
desde que o sketch actual começou a ser executado
(7) }
Sintaxe:
Exemplo:
(1) int led_pin=13; // Declaração de uma variável do tipo integer com o nome
led_pin , sendo-lhe atribuída o valor 13
(2) void setup() {
(4) pinMode(led_pin,OUTPUT); // Permite definir o pino 13 como OUTPUT
(5) Serial.begin(9600); // Permite a inicialização da comunicação Série
(6) }
(7) void loop(){
(8) digitalWrite(led_pin,HIGH); // É atribuído ao pino digital 13 a condição ()G(
(5 V)
(9) delay(200); // É efectuado um delay de 200 ms, antes de efectuar a próxima
instrução
(10) digitalWrite(led_pin,LOW); // É atribuído ao pino digital 13 a condição LOW
(0 V)
(11) delay(600); // É efectuado um delay de 600 ms, antes de efectuar a próxima
instrução, neste caso a função void loop recomeça
(12) }
Sintaxe:
Exemplo:
(1) int led_pin=13; // Declaração de uma variável do tipo integer com o nome
led_pin , sendo-lhe atribuída o valor 13
(2) void setup() {
(4) pinMode(led_pin,OUTPUT); // Permite definir o pino 13 como OUTPUT
(5) Serial.begin(9600); // Permite a inicialização da comunicação Série
(6) }
(7) void loop(){
(8) digitalWrite(led_pin,HIGH); // É atribuído ao pino digital 13 a condição ()G(
(5 V)
Sintaxe:
Exemplo:
3.5.4.2. max(valor1,valor2)
Descrição: Instrução que retorna o maior de dois valores.
Sintaxe:
Exemplo:
3.5.4.3. abs(valor)
Descrição: Instrução que retorna o modulo de um número.
Sintaxe:
Módulo = abs(valor);
�alor ⇒ �alor
Módulo = {
−�alor ⇒ �alor <
Exemplo:
int modulo=0;
modulo = abs(-5) // O valor atribuído à variável modulo seria o valor 5
Sintaxe:
Exemplo:
Sintaxe:
Valor num novo intervalo = map(Valor, valor1, valor2, Para valor1, Para valor2);
Exemplo:
Sintaxe:
Exemplo:
int valor=0;
valor = pow(2,2) // O valor atribuído à variável valor seria o valor 4 , pois =
.
3.5.4.7. sqrt(valor)
Descrição: Permite o cálculo da raiz quadrado de um determinado valor.
Sintaxe:
Exemplo:
int valor=0;
valor = sqrt(9) // O valor atribuído à variável valor seria o valor 3 , pois √ = .
Sintaxe:
Com Resultado � [− ; ]
3.5.5.2. cos(valor)
Descrição: Instrução que retorna o cálculo do coseno, de um valor em radianos.
Sintaxe:
Com Resultado � [− ; ]
3.5.5.1. tan(valor)
Descrição: Instrução que retorna o cálculo da tangente, de um valor em
radianos.
Sintaxe:
Sintaxe:
randomSeed(Valor);
Exemplo:
3.5.6.2. random()
Descrição: Instrução que permite gerar números aleatórios (ou melhor
escrevendo - pseudo-aleatórios).
Sintaxe:
Exemplo:
3.5.7. Interrupts
3.5.7.1. attachInterrupt(interrupt, função,modo)
Descrição: Instrução que permite definir o funcionamento de interrupts
externos. Ocorrendo a definição através desta instrução da função a executar,
do pino onde vai ocorrer o interrupt e o modo como se deve responder à
variação do sinal de entrada no pino a considerar.
Sintaxe:
3.5.7.2. detachInterrupt(interrupt)
Descrição: Possibilita desabilitar um interrupt previamente estabelecido
utilizando a instrução attach)nterupt .
Sintaxe:
detachInterrupt(interrupt);
3.5.7.3. interrupts()
Descrição: Instrução que permite voltar a activar o uso de interrupções, depois
de esta funcionalidade ter sido desactivada. O uso de interrupts encontra-se por
defeito activado.
Sintaxe:
interrupts();
Exemplo:
3.5.7.4. noInterrupts()
Descrição: Instrução que permite desactivar o uso de interrupções. O uso de
interrupts encontra-se por defeito activado.
Sintaxe:
noInterrupts();
Exemplo:
(3) }
(4) void loop(){
(5) noInterrupts(); // Instrução que desactiva o uso de interrupts
(6) Instrução 1;
7 …..
(8) interrupts(); // Instrução que activa o uso de interrupts
9 …..
(10) }
Sintaxe:
Exemplo:
(1) int leitura_serie=0; //Declaração de uma variável do tipo integer com o nome
leitura_serie , inicializada com o valor 0
(2) void setup() {
(3) Serial.begin(9600); // Permite a inicialização da comunicação Série
(4) }
(5) void loop(){
(6) if(Serial.available()>0) // Condição if que verifica se estão a ser recebidos dados
por Série
(7) leitura_serie=Serial.read(); // Caso se estejam a receber dados por série, o seu
valor é guardado na variável integer leitura_serie
(8) }
(9) }
Exemplo:
(1) int leitura_serie=0; //Declaração de uma variável do tipo integer com o nome
leitura_serie , inicializada com o valor 0
(2) void setup() {
(3) Serial.begin(9600); // Permite a inicialização da comunicação Série
(4) }
(5) void loop(){
(6) if(Serial.available()>0) // Condição if que verifica se estão a ser recebidos dados
por Série
(7) leitura_serie=Serial.read(); // Caso se estejam a receber dados por série, o seu
valor é guardado na variável integer leitura_serie
(8) }
(9) }
3.5.8.3. Serial.read()
Descrição: Permite a leitura dos dados recebidos por série. Esta função retorna
o valor -1 se não houver dados disponíveis.
Sintaxe:
Exemplo:
(1) int leitura_serie=0; ; //Declaração de uma variável do tipo integer com o nome
leitura_serie , inicializada com o valor 0
(2) void setup() {
(3) Serial.begin(9600); // Permite a inicialização da comunicação Série
(4) }
(5) void loop(){
(6) if(Serial.available()>0) ) // Condição if que verifica se estão a ser recebidos
dados por Série
(7) leitura_serie=Serial.read(); // Caso se estejam a receber dados por série, o seu
valor é guardado na variável integer leitura_serie
(8) }
(9) }
3.5.8.4. Serial.flush()
Descrição: Efectua o flush apaga de todos os dados presentes no buffer de
entrada no momento de execução da instrução. O buffer de entrada tem uma
capacidade de armazenamento de 64 bytes.
Sintaxe:
Serial.flush();
Exemplo:
Descrição: Instrução que permite o envio de dados pela porta série. A única
diferença entre Serial.print e Serial.println é que a segunda instrução
adiciona ao dado enviado o caracter \r carriage return e o caracter \n
new line .
Sintaxe:
Serial.print(dado a enviar);
Serial.print(dado a enviar, formato);
O formato de envio pode ser decimal (DEC), hexadecimal (HEX), octal (OCT) ou
binário (BIN). O dado a enviar também pode tomar o formato de uma string.
Exemplo:
3.5.8.1. Serial.write()
Descrição: Permite enviar dados em binário pela porta série. Esses dados
podem ser enviados como um único byte ou um conjunto de bytes.
Sintaxe:
Serial.write(valor);
Serial.write(string);
Serial.write(vector, comprimento);
A variável valor acima define o valor a ser enviado em binário pela porta série,
o mesmo pode ser efectuado enviando uma string como um conjunto de
bytes. Na última instrução apresentada acima, é enviado um vector vector
de tamanho comprimento .
4. Recursos Avançados
Este capítulo tem como objectivo explorar algumas bibliotecas existentes para a
plataforma de desenvolvimento Arduino, possibilitando assim expandir as suas possibilidades.
As bibliotecas a ser expostas neste capítulo são as mais usadas nos projectos de
desenvolvimento, mas não representam a totalidade das bibliotecas existentes. Será também
aprofundado neste capítulo a temática taxa de amostragem no nosso contexto de estudo,
tentando que a sua compreensão se torne maior.
4.1. Flash
A quantidade de memória SRAM disponível é normalmente muito mais pequena do que
a memória flash disponível e em programas em que é necessário recorrer à utilização de
muitas variáveis facilmente a memória disponível se torna uma limitação. Uma solução óbvia,
tendo em conta o que foi referido anteriormente, seria gravar o valor de algumas variáveis em
flash. Mas existe uma limitação, na medida que a gravação de dados na memória flash apenas
pode ser efectuada quando o programa se encontra a ser carregado (durante o uploading)
para a memória flash. O que leva a que apenas os valores de variáveis constantes devam ser
armazenados na memória flash, sendo utilizadas só quando necessário (não se encontrando já
a ocupar espaço em SRAM).
Para utilizar esta funcionalidade vais ser utilizada a biblioteca <Flash.h> , devendo a
mesma ser declarada no nosso sketch, esta biblioteca não se encontra disponível no software
de desenvolvimento devendo o seu download ser efectuado do site Arduiniana
(http://arduiniana.org/libraries/flash/). Esta biblioteca baseia-se na biblioteca
<avr/progmen.h> , tentado simplificar assim o seu uso.
Existe mais sintaxe possível por parte desta biblioteca, mas sem dúvida foi aqui
apresentado o mais importante (Guardar e ler). Para mais informações pode ser
consultado o site oficial desta biblioteca, já referido anteriormente.
4.2. EEPROM
O microcontrolador disponível na placa de desenvolvimento Arduino Duemilinove
(ATMega168) possui 512 bytes de memória EEPROM, segundo o datasheet do respectivo
microcontrolador.
Este tipo de memória tem a vantagem de manter a sua informação armazenada,
mesmo após desligarmos a sua alimentação, visto que pode ser de grande importância
conseguir manter certos dados, dependo da aplicação a implementar. Uma outra vantagem é
a possibilidade de guardar conteúdo nesta memória enquanto executamos o nosso sketch, o
que não acontece com o armazenamento em flash. Esta biblioteca já se encontra disponível
no Software de desenvolvimento Arduino, não necessitando de ser adicionada.
A principal limitação da memória EEPROM está na existência de um limite de ciclos de
leitura/escrita. O que pode ser uma limitação a curto prazo em aplicações que recorram muito
a este tipo de armazenamento (este tipo de informação encontra-se discriminada no
datasheet do microcontrolador). O tempo de escrita num ATMega168 é de ≅ 3.3 ms
(informação retirada do seu datasheet).
Exemplo:
4.3. Servomotor
Um servomotor é um pequeno dispositivo cujo veio pode ser posicionado numa
determinada posição angular de acordo com um sinal de entrada. Enquanto esse sinal se
mantiver constante e for enviado para o servomotor, o servo irá manter a sua posição angular.
Ao variar o sinal de entrada possibilita uma variação a posição angular do veio. Os
servomotores são muito usados no controlo de aviões telecomandados, robots, barcos
telecomandados, helicópteros telecomandados, entre outras possíveis aplicações.
Um servomotor, como se pode ver na figura 19, possui três entradas. Uma entrada é a
alimentação (normalmente 5V para servomotores standard), outra será a massa e a última
que falta referir será o sinal de entrada. Este sinal de entrada será um impulso PWM, em que
fazendo variar o seu duty cicle , podemos variar a posição angular do servomotor. Isto em
servomotores de posição, pois também existem servomotores de rotação contínua. Nesses
servomotores a variação do duty cicle fará variar não a posição angular, mas a velocidade e
sentido de rotação do servomotor. Existe possibilidade de modificar, sem grande dificuldade,
um servomotor de posição para rotação contínua. Esta modificação é permanente, não
podendo ser reversível. No entanto, o objectivo deste subcapítulo não se centra nisso, mas
sim em como fazer a sua interacção com a plataforma de desenvolvimento Arduino.
4.3.1.2. detach()
Descrição: Permite eliminar a ligação entre uma variável do Servo a um dos pinos
possíveis de utilizar pela biblioteca <Servo.h> Pinos 9 e 10). Se nenhum dos pinos
possíveis estiver atribuído a uma variável do tipo Servo , os pinos 9 e 10 podem ser
utilizados normalmente.
Sintaxe:
Servo.detach();
Exemplo:
(1) #include<Servo.h> // Declaração da biblioteca <Servo.h>
(2) Servo Exemplo; // Criação de uma variável do tipo Servo, com o nome de Exemplo
(3) void setup(){
(4) Exemplo.attach(10); // Atribuição da variável do tipo Servo Exemplo , ao pino digital
10
(5 …..
(6) void loop(){
(7) Exemplo.detach(); // Elimina a ligação entre a variável do tipo Servo Exemplo e pino
digital 10
(8) analogWrite(10, 255); // Como nenhuma variável do tipo Servo se encontra atribuída,
podem-se usar as funcionalidades PWM dos pinos 9 e 10
(9) }
4.3.1.3. write()
Descrição: Permite movimentar o eixo de um servomotor de posição para o ângulo
pretendido. No caso de um servomotor de rotação contínua o valor 0 corresponderá à
velocidade de rotação máxima num sentido, o valor 180 a velocidade de rotação
máxima noutro sentido e o valor 90 será o ponto em que o servomotor se encontrará
parado.
Sintaxe:
Servo.write(Ângulo);
(3) Servo Exemplo_2; // Criação de uma variável do tipo Servo, com o nome de
Exemplo_2
(4) void setup(){
(5) Exemplo.attach(10); // Atribuição da variável do tipo Servo Exemplo , ao pino digital
10
(6) Exemplo_2.attach(9); // Atribuição da variável do tipo Servo Exemplo_2 , ao pino
digital 9
(7 …..
(8) void loop(){
(9) Exemplo.write(0); // Faz com que um servomotor p.ex. de posição se movimente para a
posição correspondente ao ângulo 0
(1) Exemplo_2.write(90); // Faz com que um servomotor p.ex. de rotação contínua pare a
sua rotação
(11) }
4.3.1.4. read()
Descrição: Instrução que retorna o valor do último ângulo utilizado, recorrendo à
instrução Servo.write Ângulo .
Sintaxe:
Ângulo (int) = Servo.read();
4.3.1.5. attached()
Descrição: )nstrução que permite verificar se uma variável do tipo Servo se encontra
atribuída a um pino específico.
Sintaxe:
Estado (int) = Servo.attached();
Servo nome_a_atribuir;
Estado � { , }, ou seja, só pode tomar o valor true valor 1 ou false valor
0 .
Exemplo:
(1) #include<Servo.h> // Declaração da biblioteca <Servo.h>
(2) int atribuido=0; // Declaração de uma variável do tipo integer de nome atribuido ,
atribuindo-lhe o valor de 0
(3) Servo Exemplo; // Criação de uma variável do tipo Servo, com o nome de Exemplo
(4) void setup(){
(5) Exemplo.attach(10); // Atribuição da variável do tipo Servo Exemplo , ao pino digital
10
(6 …..
(7) void loop(){
(8) atribuido = Exemplo.attached(); // Atribui o valor 1 à variável atribuído caso a variável
do tipo Servo Exemplo se encontra associada a algum pino, caso contrário retorna o
valor 0
(9) if (atribuido ==1){ //Se a variável estiver do tipo Servo Exemplo estiver atribuída a
condição é verificada
(10) Exemplo.write(180); // Faz com que um servomotor p.ex. de posição se movimente
para a posição correspondente ao valor 180
(11) }
(12) …..
(13) }
O uso desta biblioteca simplifica a operação com servomotores, o que não implica que a
movimentação dos servomotores não seja feita com recurso directamente à instrução
analogWrite , ou seja, gerar os sinais PWM directamente. Tal é, obviamente, possível mas
mais trabalhoso, existindo esta biblioteca para simplificar esse trabalho de implementação.
Com este subcapítulo espera-se dar noções básicas de funcionamento e uso de
servomotores, estando a partir daqui apenas dependente da criatividade de cada um na
implementação e aprofundamento do conhecimento sobre esta temática.
Exemplo:
(1) #include<SoftwareSerial.h> // Declaração da biblioteca <SoftwareSerial.h>
(2) SoftwareSerial Exemplo = SoftwareSerial(4,5); // Declaração de uma variável do tipo
SoftwareSerial de nome Exemplo , atribuindo-lhe o pino de Rx 4” e o pino de Tx 5”
(3) void setup(){
(4) pinMode(4, INPUT); // Define o pino 4 como )NPUT
(5) pinMode(5, OUTPUT); // Define o pino 5 como OUTPUT
4.4.1.3. read()
Descrição: Instrução que possibilita a leitura de um caracter proveniente do pino
definido como Rx. A instrução SoftwareSerial.read espera que chegue um caracter
e retorna o seu valor, sendo preciso ter em atenção que os dados que cheguam sem
haver uma leitura a aguardar serão perdidos não existência de buffer de recepção).
Sintaxe:
Valor Leitura (int/char) = SoftwareSerial.read();
SoftwareSerial – Variável do tipo SoftwareSerial , sendo definida da seguinte
forma:
SoftwareSerial Nome_variável = SoftwareSerial(Pino de Rx, Pino de Tx);
Exemplo:
(1) #include<SoftwareSerial.h> // Declaração da biblioteca <SoftwareSerial.h>
(2) SoftwareSerial Exemplo = SoftwareSerial(4,5); // Declaração de uma variável do tipo
SoftwareSerial de nome Exemplo , atribuindo-lhe o pino de Rx 4” e o pino de Tx 5”
(3) char recebido; //Declaração de uma variável do tipo char de nome recebido
(4) void setup(){
(5) pinMode(4, INPUT); // Define o pino 4 como )NPUT
(6) pinMode(5, IOUTPUT); // Define o pino 5 como OUTPUT
(7) Exemplo.begin(9600); // Define a velocidade de comunicação com uma Baud rate de
9600
(8) void loop(){
(9) recebido = Exemplo.read(); //Possibilita guardar um valor recebido no pino de Rx, na
variável do tipo char recebido
(10) }
SoftwareSerial.println(dado a enviar);
SoftwareSerial – Variável do tipo SoftwareSerial , sendo definida da seguinte
forma:
SoftwareSerial Nome_variável = SoftwareSerial(Pino de Rx, Pino de Tx);
Exemplo:
(1) #include<SoftwareSerial.h> // Declaração da biblioteca <SoftwareSerial.h>
(2) SoftwareSerial Exemplo = SoftwareSerial(4,5); // Declaração de uma variável do tipo
SoftwareSerial de nome Exemplo , atribuindo-lhe o pino de Rx 4” e o pino de Tx 5”
(3) char recebido; //Declaração de uma variável do tipo char de nome recebido
(4) void setup(){
(5) pinMode(4, INPUT); // Define o pino 4 como )NPUT
(6) pinMode(5, IOUTPUT); // Define o pino 5 como OUTPUT
(7) Exemplo.begin(9600); // Define a velocidade de comunicação com uma Baud rate de
9600
(8) void loop(){
(9) recebido = Exemplo.read(); //Possibilita guardar um valor recebido no pino de Rx, na
variável do tipo char recebido
(10) Exemplo.print(recebido); // Envia a variável do tipo char de nome recebido , através
do pino definido com Tx (pino 5)
(11) }
�� 1 � 2 �̂ 3
C/D Quantizer Encoder
Ao respeitarmos este teorema estão garantidas as condições para não ocorrer aliasing
e o sinal original poderá ser reconstruído a partir da sua amostra, recorrendo a um simples
filtro passa baixo (Hayes 1999). É referido como aliasing a distorção causada por uma taxa de
amostragem insuficiente (Vasegui 2006).
Mas no entanto existe uma forma de configurar este factor de divisão , fazendo variar
o conteúdo do bit ADPS0, ADPS1 e ADPS2 (Como se pode constatar pela análise da figura
27).
Estes bits são parte integrante do registo ADCSRA, que é constituído da seguinte
forma:
Bit 7 6 5 4 3 2 1 0
(0x7A) ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
Valor
0 0 0 0 0 0 0 0
Inicial
Pela análise da tabela anterior, podemos afirmar então que a maior frequência de
amostragem que poderemos obter se situa nos 8 MHz. O que leva a que a que para haver uma
reconstrução sem perda de informação de um possível sinal amostrado, o mesmo deverá ter
uma frequência máxima de 4 MHz. No entanto os valores apresentados na tabela 8 são
5. Conclusão
Espera-se com este tutorial abrir as portas para um entendimento mais aprofundado
desta plataforma de desenvolvimento. Não correspondendo este documento a tudo o que
existe para aprender e desenvolver sobre este tema. Muitos assuntos ficaram por abordar e
caberá ao leitor caso tenha manifesto interesse (confunde-se muitas vezes com necessidade),
pesquisar e desenvolver uma temática específica.
A placa de desenvolvimento Arduino encontra-se em franca expansão, estando a sua
utilização generalizada quer na área da electrónica, artes e muitas mais. O que leva a que esta
plataforma tenha muitos seguidores e estando a crescer e a desenvolver-se a cada minuto que
passa. O que agora é uma novidade de implementação, muito provavelmente quando estiver
a ler este tutorial será uma coisa comum. Pois o Arduino está a conquistar o seu espaço, e já é
uma referência.
Quem diria que um projecto académico chegaria tão longe, provavelmente ninguém
diria. O que faz com que as pessoas que acreditaram, estejam desde já de parabéns pelo
magnífico trabalho. Deste exemplo real só podemos retirar que a persistência e dedicação são
o que nos leva mais longe, pois os criadores desta plataforma de desenvolvimento não são os
melhores. Mas sim os que acreditaram e trabalharam para isso, o que se revela sempre muito
importante.
O que é preciso é ter uma atitude de contínua procura pelo conhecimento….
6. Bibliografia
Arduiniana. (2009). "Arduino software jewellry and wisdom." Retrieved 4 August 2009,
2009, from http://arduiniana.org/.
Arduino. (2006, 14 July 2009). Retrieved 21 July 2009, 2009, from
http://www.arduino.cc.
Arroz, G., J. Monteiro, et al. (2007). Arquitectura de Computadores dos Sistemas
Digitais aos Microprocessadores. Lisboa, IST Press.
AVR. (2009). "pgmspace reference." Retrieved 31 July 2009, 2009, from
http://www.nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html.
Hayes, M. H. (1999). Schaum´s Outline of Theory and Problems of Digital Signal
Processing. Washington DC, USA, McGraw-Hill.
Igoe, T. (2007). Making Things Talk. Sebastopol, USA, O´REILLY.
Santos, A. (2007). "Servomotores." Retrieved 31 July 2009, 2009, from
http://www.esen.pt/on/file.php/45/Cerqueira/Servo_Motor.pdf.
Santos, N. P. (2008) "Introdução ao Arduino." Revista PROGRAMAR, 39-44.
Santos, N. P. (2009) "Arduino e a Aquisição de dados." Revista PROGRAMAR, 24-26.
Shiffman, D. (2008). Learning Processing - A beginner´s Guide to Programming
Images, Animation, and Interaction. Burlington, USA, Morgan Kaufmann.
Sousa, D. J. d. S. and N. C. Lavinia (2006). Conectando o PIC 16F877A Recursos
Avançados. São Paulo, Brazil.
Tecnology, M. (1992). Advanced RISC Computing Specification. California, USA, MIPS
Technology.
Vasegui, S. V. (2006). Advanced Signal Processing and Noise Reduction. Wiltshire,
England, Wiley.