Escola de engenharia de lorena



Baixar 1.06 Mb.
Pdf preview
Página4/5
Encontro21.07.2020
Tamanho1.06 Mb.
1   2   3   4   5

Descrição do código 

 

Os LEDs que constituem a lâmpada humor são de 



cores  vermelho,  verde  e  azul.  Da  mesma  forma 

que o seu monitor de computador é feito de cores 

vermelho minúsculo, verde e (RGB) pontos azuis, 

o  mapa  pode  gerar  diferentes  cores,  ajustando  o 

brilho  de  cada  um  dos  três  LEDs  de  tal  maneira 

que  nos  dê  um  valor  RGB  e  tons  de  cores 

diferentes. 

Um valor RGB de “255,0,0” nos daria o vermelho 

puro.  O  valor  “0,255,0”  daria  verde  puro  e 

“0,0,255” a cor azul pura. Ao misturar essas cores 

dos  LEDs,  podemos  obter  diversas  cores.  Você 

ainda  pode  fazer  diferentes  cores,  como  nesta 

tabela  com  alguns  exemplos  de  combinação  de 

cores: 


 

 

 



Ao ajustar o brilho usando PWM, podemos obter 

também  todas  as  outras  cores.  Ao  colocar  os 

LEDs juntos e misturando seus valores, o espectro 

de luz das três cores somadas faz uma única cor.  

A gama total de cores que podemos fazer usando 

a  saída  PWM  é  de  0  a  255  é  16.777.216  cores 

(256x256x256),  sendo  este  valor  muito  maior  do 

que nós precisamos. 

No  código,  começamos  desligados  (pontos  com 

valor  0),  declarando  alguns  pontos  flutuantes 

(

float


)  da  matriz  de  pontos  e  também  algumas 

variáveis  inteiras  que  irão  armazenar  os  nossos 

valores RGB, bem como um valor de incremento. 

 

float 



RGB1[3]; 

float 


RGB2[3]; 

float 


INC[3]; 

int 


red, green, blue;

 

 



Na função de configuração temos 

 

randomSeed



(

analogRead

(0));

 

 



O  comando  randomSeed  é  utilizado  para  criar 

números 


aleatórios 

(na 


verdade, 

pseudo 


aleatórios). Chips de computador não são capazes 

de  produzir  números  aleatórios  de  modo  que 

tendem  a  olhar  para  dados  numa  parte  da  sua 

memória  que  podem  ser  diferentes  ou  olhar  para 

uma tabela de valores diferentes e utilizá-las como 

um  número  pseudo-aleatório.  Neste  caso,  o  do 

valor  que  será  dado  ao  randomSeed  é  um  valor 

lido  a  partir  do  pino  analógico  0.  Como  nós  não 

temos nada ligado ao pino analógico 0 tudo o que 

será lido é um número aleatório criado pelo ruído 

analógico.  

Uma vez que tenhamos definido um início para o 

nosso  número  aleatório,  esse  poderá  criar  outro 

número usando a função 

random()

. Em seguida, 

temos 

dois 


conjuntos 

de 


valores 

RGB 


armazenados  em  um  elemento  de  três  matrizes. 

RGB1  são  os  valores  RGB  que  queremos  que  a 

lâmpada  comece  (neste  caso,  todos  em  zero  ou 

desligados). 

 

RGB1[0] = 0; 



RGB1[1] = 0; 

RGB1[2] = 0;

 

 

Em  seguida,  a  matriz  RGB2  é  um  conjunto  de 



valores  aleatórios  RGB  que  queremos  que  a 

lâmpada tenha para produzir o efeito aleatório: 

 

RGB2[0] = 



random

(256); 


RGB2[1] = 

random


(256); 

RGB2[2] = 

random

(256);


 

 

Neste  caso,  teremos  um  conjunto  de  números 



aleatórios (256) que vai dar um número entre 0 e 

255  inclusive  (como  o  número  sempre  varia  de 

zero para cima). 

Se  indicarmos  um  número  para  a  função 

random()

, ele então irá processar um valor entre 

0  e  1  a  menos  do  que  o  número  indicado,  por 

exemplo, 

random(1000)

 irá retornar um número 

entre 0 e 999.  

Caso  queira  um  intervalo  definido  de  números, 

forneça  os  dois  números  como  parâmetros,  dessa 

forma: 


random(50,400)

.  Então, 

random 


irá 

prodessar  um  número  aleatório  entre  o  menor 



16 

 

número  e  o  máximo  número  (-1).  Por  exemplo, 



random(10,100)

  irá  retornar  um  número 

aleatório entre 10 e 99.  

No  loop  principal  do  programa  que  vimos 

primeiro  no  início  e  terminar  valores  RGB  e 

descobrir o que é valor necessário. 

No entanto, é necessário um incremento para que 

haja a mundaça de um valor para o outro e utilizar 

as  256  combinações  (com  o  valor  de  PWM 

podemos  combinar  entre  0  e  255).  Fazemos  isso 

assim: 

 

for 



(

int 


x=0; x<3; x++) { 

INC[x] = (RGB1[x] - RGB2[x]) / 256; }

 

 

Este  loop  define  os  valores  pelo  incremento  nos 



canais  R,  G  e  B  por  meio  do  resultado  da 

diferença  entre  os  dois  valores  de  brilho  e 

dividindo-os por 256. 

Temos, então, outro laço 

for

 

 

for 



(

int 


x=0; x<256; x++) { 

red = 


int

(RGB1[0]); 

green = 

int


(RGB1[1]); 

blue = 


int

(RGB1[2]); 

analogWrite 

(RedPin, red); 

analogWrite 

(GreenPin, green); 

analogWrite 

(BluePin, blue); 

delay

(100); 


RGB1[0] -= INC[0]; 

RGB1[1] -= INC[1]; 

RGB1[2] -= INC[2]; 

}

 



 

Isso  define  as  cores  vermelho,  verde  e  azul  para 

os  valores  da  matriz  RGB1,  e  transfere  esses 

valores  para  os  pinos  9,  10  e  11,  depois  deduz  o 

valor  do  incremento,  em  seguida,  repete  este 

processo  256  vezes  até  desaparecer  lentamente  a 

partir de uma cor aleatória para o próximo passo. 

O atraso de 100 ms entre cada passo garante uma 

lenta  e  constante  progressão  das  combinações  de 

cores.  É  possível  ainda  ajustar  esse  valor  para 

mais  lento  ou  mais  rápido  ou  podemos  ainda 

adicionar um potenciômetro para permitir que um 

usuário defina a velocidade que desejar. 

Depois  de  ter  tomado  256  passos  lentos  de  uma 

cobinação  de  cor  para  outra,  a  matriz  RGB1  terá 

os mesmos valores (quase) como a matriz RGB2. 

Precisamos agora decidir sobre outro conjunto de 

três valores aleatórios prontos para a próxima vez. 

Fazemos isso com outro 

for


 

for 



(

int 


x=0; x<3; x++) { 

RGB2[x] = 

random

(556)-300; 



RGB2[x] = 

constrain

(RGB2[x], 0, 255); 

delay


(1000); 

}

 



 

O  número  aleatório  é  escolhido  num  intervalo 

entre  0  e  556  (256  +  300)  e,  em  seguida  é 

subtraído de 300. A razão pela qual fazemos isso 

é  para  tentar  produzir  cores  primárias  de  tempos 

em  tempos  para  garantir  que  nem  sempre 

tenhamos somente tons pastel. 

Temos  300  chances  fora  de  556  de  obter  um 

número  negativo  e,  portanto,  forçando  à  uma 

tendência de termos um ou mais de dois canais de 

cor.O  próximo  comando  faz  certeza  de  que  os 

números  enviados  para  os  pinos  PWM  não  são 

negativos usando a função 

constrain()

A  função  de  restringir 



constrain()

  requer  três 

parâmetros - x, a e b como 

constrain(x,a,b)

onde  x  é  o  número  queremos  restringir,  a  é  a 



extremidade inferior da gama e b é a extremidade 

superior. Assim, a função 

constrain()

 observa 

o  valor  de  x  e  garante  que  ele  se  encontra  dentro 

do intervalo entre a e b. Se é menor que a, então o 

define para a, se é maior do que b o define para b. 

No  nosso  caso,  teremos  certeza  de  que  o  número 

está entre 0 e 255, que é o intervalo da nossa saída 

PWM. 


Como  usamos  números  aleatórios  [(556)  -300] 

para  os  nossos  valores  RGB,  alguns  desses 

valores  serão  menores  que  zero  e  a  função 

constrain()



 garante que o valor enviado para o 

PWM não é menor que zero. 

Aplicando uma tendência para uma ou mais cores 

assegurando  tons  mais  vibrantes  e  menos  cores 

pastel  e  assegurando  também  que  ao  longo  do 

tempo  um  ou  mais  canais  estão  desligados 

completamente  dando  uma  mudança  mais 

interessante de luzes (ou humores). 

 

 

Projeto 9 - Efeito fogo com LED 



 

O  Projeto  9  vai  utilizar  LEDs  piscando 

aleatoriamente  produzindo  um  belo  efeito, 

utilizando novamente a saída PWM para recriar o 

efeito de uma chama. 

Se o conjunto for colocado dentro de um ambiente 

apropriado  (uma  minilareira,  por  exemplo), 

poderia criar um efeito especial de fogo, ou ainda 

pode-se  colocá-lo  em  uma  farsa  casa  em  chamas 

para  dar  um  efeito  de  fogo.  Este  é  um  simples 

exemplo  de  como  os  LEDs  podem  ser  utilizados 

para  criar  efeitos  para  filmes,  peças  teatrais, 

novelas, etc. 

 

O que você precisa 



17 

 

 

 

Montagem 



 

 

Abra o IDE Arduino e digite o seguinte código: 



 

// Projeto 9 – Efeito de LED de fogo 

int 

ledPin1 = 9; 



int 

ledPin2 = 10; 

int 

ledPin3 = 11; 



void 

setup() 


pinMode


(ledPin1, 

OUTPUT


); 

pinMode


(ledPin2, 

OUTPUT


); 

pinMode


(ledPin3, 

OUTPUT


); 

void 



loop() 

analogWrite



(ledPin1, 

random


(120)+135); 

analogWrite

(ledPin2, 

random


(120)+135); 

analogWrite

(ledPin3, 

random


(120)+135); 

delay


(random(100)); 

}

 



 

Agora  pressione  o  botão  Verificar  /  Compilar  no 

topo da IDE para se certificar de que não há erros 

em seu código. Se este é bem sucedido agora você 

pode  clicar  no  botão  Upload  para  carregar  o 

código para o Arduino. 

Se  tudo  estiver  certo  poderemos  ver  agora  os 

LEDs em cintilação de uma maneira aleatória para 

simular uma chama ou efeito de fogo. 

Agora  vamos  dar  uma  olhada  no  código  e 

hardware e descobrir como ambos trabalham. 

 

Descrição do código 

 

Primeiro  nós  declaramos  e  inicializamos  algumas 



variáveis inteiras  que  conterão  os  valores  para  os 

pinos  digitais  que  vamos  conectar  os  nossos 

LEDs,  como  já  foi  realizado  em  projetos 

anteriores. 

 

int 


ledPin1 = 9; 

int 


ledPin2 = 10; 

int 


ledPin3 = 11;

 

 



Em seguida, configurá-los para serem saídas. 

 

pinMode



(ledPin1, 

OUTPUT


); 

pinMode


(ledPin2, 

OUTPUT


); 

pinMode


(ledPin3, 

OUTPUT


);

 

 



O  laço  principal  do  programa,  em  seguida,  envia 

um  valor  aleatório  entre  0  e  120  e,  em  seguida, 

adiciona 135 a ele para obter o máximo de brilho 

dos LEDs, para os pinos de PWM conectados aos 

números 9, 10 e 11. 

 

analogWrite



(ledPin1, 

random


(120)+135); 

analogWrite

(ledPin2, 

random


(120)+135); 

analogWrite

(ledPin3, 

random


(120)+135);

 

 



Então,  finalmente,  temos  um  atraso  aleatório 

proposital entre ligado e o tempo de 100 ms. 

 

delay


(random(100));

 

 



O  laço  principal,  em  seguida,  começa  novamente 

causando o efeito de luz que se pode ver. 

Utilizando um cartão branco onde possa se refletir 

as  luzes  ou  uma  armação  como  um  abajur  você 

poderá ver um efeito de chama muito realista. 

Como  a  construção  do  hardware  é  bem  simples, 

vamos pular para o próximo Projeto. 

 

 



Projeto10 – LEDs controlados 

 

Para  este  projeto  utilizaremos  o  mesmo  circuito 



anterior  (Projeto  9),  mas  agora  vamos  mergulhar 

no  mundo  da  comunicação  serial  e  controlar  a 

nossa luz, enviando comandos a partir do PC para 

o  Arduino  usando  o  “Serial  Monitor”  no  IDE 

Arduino,  que  é  uma  tela  de  interface  com  o 

hardware  do  arduino.  Este  projeto  também 

introduz  como  manipular  sequências  de  texto. 

Então  deixe  a  configuração  do  hardware  do 

mesmo jeito de antes e introduza o novo código: 

 

// Projeto 10 – Lampada RGB controlada 



char 

buffer[18]; 

int 

red, green, blue; 



int 

RedPin = 11; 

int 

GreenPin = 10; 



int 

BluePin = 9; 

 

void setup() 



Serial.begin

(9600); 

Serial.flush

(); 

pinMode


(RedPin, 

OUTPUT


); 

pinMode


(GreenPin, 

OUTPUT


); 

18 

 

pinMode



(BluePin, 

OUTPUT


); 

 



void loop() 

if 



(

Serial.available

() > 0) { 

  int 


index=0; 

  delay


(100); 

// Aguarda encher o buffer 

  int 

numChar = 



Serial.available

(); 


  if 

(numChar>15) { 

    numChar=15; 

  } 


  while 

(numChar--) { 

    buffer[index++] = 

Serial.read

(); 

  } 


  splitString(buffer); 



 

void splitString

(

char


* data) { 

Serial.print

("Data entered: "); 

Serial.println

(data); 

char


* parameter; 

parameter = strtok (data, " ,"); 

while 

(parameter != NULL) { 



  setLED(parameter); 

  parameter = strtok (NULL, " ,"); 

// Limpa o texto e os buffers seriais 



for 

(

int 



x=0; x<16; x++) { 

  buffer[x]='\0'; 

Serial.flush



(); 

 



void 

setLED(


char

* data) { 

if 

((data[0] == 



'r'

) || (data[0] == 

'R'

)) 


  int 


Ans = strtol(data+1, NULL, 10); 

  Ans = 


constrain

(Ans,0,255); 

  analogWrite

(RedPin, Ans); 

  Serial.print

(

"Red is set to: "



); 

  Serial.println

(Ans); 



if 



((data[0] == 

'g'


) || (data[0] == 

'G'


)) 

  int 



Ans = strtol(data+1, NULL, 10); 

  Ans = 


constrain

(Ans,0,255); 

  analogWrite

(GreenPin, Ans); 

  Serial.print

(

"Green is set to: "



); 

  Serial.println

(Ans); 



if 



((data[0] == 

'b'


) || (data[0] == 

'B'


)) 

  int 



Ans = strtol(data+1, NULL, 10); 

  Ans = 


constrain

(Ans,0,255); 

  analogWrite

(BluePin, Ans); 

  Serial.print

(

"Blue is set to: "



); 

  Serial.println

(Ans); 



}



 

 

Uma  vez  que  você  verificou  o  código,  enviá-lo 



para o seu Arduino. 

Agora,  quando  você  carregar  o  programa  nada 

parece  acontecer.  Isto  porque  o  programa  está 

esperando  por  sua  entrada.  Inicie  o  “Serial 



Monitor” clicando no respectivo ícone na barra de 

tarefas no IDE do Arduino. 

Na  janela  de  texto  “Serial  Monitor”  você  pode 

entrar  com  os  valores  de  R,  G  e  B  para  cada  um 

dos três LEDs  manualmente e o brilho dos  LEDs 

será alterado e a cor de efeito resultante será a que 

você programar. 

Por  exemplo,  Se  você  digitar  R255  o  LED 

vermelho irá exibir pleno brilho. 

Se  você  digitar  R255,  G255,  em  seguida,  os  

LEDs  vermelho  e  verde  irão  exibir  brilho 

máximo. 


Agora entre com os comandos R127, G100, B255, 

e você obterá uma cor aparentemente arroxeada. 

Se  você  digitar,  r0,  g0,  b0  todos  os  LEDs  serão 

desligados. 

O  texto  de  entrada  é  projetado  para  aceitar  tanto 

uma letra minúscula ou maiúscula caso de R, G e 

B  e,  em  seguida,  um  valor  entre  0  e  255. 

Quaisquer valores acima de 255 serão descartados 

para  no  máximo  255.  Você  pode  inserir  uma 

vírgula  ou  um  espaço  entre  os  parâmetros  e  você 

pode entrar 1, 2 ou 3 valores de LED em qualquer 

momento um. Por exemplo, 

 

R255  b100,  r127  b127  G127,  G255  B0, 



B127, R0, G255 . 

 

Descrição do código 

 

Este  projeto  apresenta  uma  série  de  conceitos 



novos, incluindo a comunicação serial, ponteiros e 

manipulação  de  textos.  Então,  mantenha-se 

atento, pois teremos várias explicações. 

Primeiro  vamos  definir  uma  matriz  de  char 

(caracteres)  para  manter  nossa  cadeia  de  texto. 

Fizemos  de  18  caracteres,  cujos  são  mais  longos 

do  que  o  máximo  de  16,  o  que  nos  permitirá 

garantir  que  não  teremos  erros  de  sobrecargas  ao 

sistema. 

 

char 



buffer[18];

 

 



Em  seguida,  iremos  configurar  os  números 

inteiros  para  manter  os  valores  das  cores 

vermelho, verde e azul, bem como os valores para 

os pinos digitais. 

 

int 


red, green, blue; 

int 


RedPin = 11; 

int 


GreenPin = 10; 

int 


BluePin = 9;

 

 



Na  nossa  configuração  definiremos  os  três  pinos 

digitais para serem saídas. Mas, antes disso temos 

o comando Serial.begin

 

void setup() 



Serial.begin

(9600); 


19 

 

Serial.flush



(); 

pinMode


(RedPin, 

OUTPUT


); 

pinMode


(GreenPin, 

OUTPUT


); 

pinMode


(BluePin, 

OUTPUT


); 

}

 



 

Serial.begin  diz  ao  Arduino  para  começar  a 

comunicação  serial  e  o  número  dentro  dos 

parêntesis,  neste  caso  9600,  define  a  taxa  de 

transmissão  (caracteres  por  segundo)  que  a  linha 

serial irá comunicar. 

Obs.: Você  deve  alterar  a taxa  de transmissão  no 



Serial Monitor para 9600 baud. 

O  comando  Serial.flush  irá  limpar  qualquer 

caractere  indevido  na  linha  de  série  e  deixá-lo 

vazio e pronto para a entrada/saída de comandos. 

A  linha  de  comunicação  serial  é  simplesmente 

uma  forma  de  o  Arduino  se  comunicar  com  o 

mundo  exterior,  neste  caso  através  do  PC  e  do 

IDE  Arduino  Serial  Monitor  para  o  hardware 

construído. 

No  circuito  principal,  temos  uma  instrução  if.  A 

condição é verificar  

 

if 


(

Serial.available

() > 0) {

 

 



O comando Serial.available verifica se caracteres 

foram enviados para a linha do monitor serial. Se 

qualquer  caractere  foi  recebido,  em  seguida,  as 

condição e declarações do código dentro do bloco 



if é executada. 

 

if 



(

Serial.available

() > 0) { 

int 


index=0; 

delay


(100); 

// let the buffer fill up 

int 

numChar = 



Serial.available

(); 


if 

(numChar>15) { 

numChar=15; 

while 



(numChar--) { 

buffer[index++] = 

Serial.read

(); 


splitString(buffer); 

}

 



 

Um  inteiro  chamado  index  é  declarado  e 

inicializado  como  zero.  Este  inteiro  vai  manter  a 

posição de um ponto para os caracteres dentro da 

matriz de char, como uma referência. 

Em  seguida,  define-se  um  atraso  de  100.  O 

propósito  disto  é  assegurar  que  o  serial  buffer  (o 

lugar  na  memória  onde  os  dados  são  recebidos  e 

armazenados  antes  do  processamento)  está  cheio 

antes  de  continuar  o  processo  com  os  dados.  Se 

não  fizer  isso,  é  possível  que  a  função  execute  e 

começe  a  processar o  comando  enviado, antes de 

termos  enviado  todos  os  dados.  A  linha  de 

comunicação serial é muito lenta em comparação 

com a velocidade do resto do código de execução. 

Quando  você  envia  uma  sequência  de  dados,  a 

função 

Serial.available



  terá  imediatamente 

um valor superior a zero e a função 

if

  começará 



a  ser  executada.  Se  não  houvesse  o  atraso,  o 

código  dentro  do 

if

  começaria  a  ser  executado  



antes  de  toda  a  informação  de  texto  ter  sido 

recebida e o dados seriais poderiam ser apenas os 

primeiros caracteres de texto inserido. 

Depois  de  ter  esperado  100  ms,  para  preencher  o 



buffer  serial  com  os  dados  enviados,  nós  então 

declaramos  e  inicializamos  o  inteiro 

numChar

 

para ser o número de caracteres dentro do texto. 

Por  exemplo,  se  enviamos  este  texto  para  o 

monitor: R255, G255, B255. 

Em  seguida,  o  valor  de 

numChar


  é  17  e  não  16, 

como no final de cada linha de texto, onde há um 

caractere  invisível  chamado  de  “NULL”  .  Este  é 

um  símbolo  de  vazio  e  simplesmente  diz  ao 

Arduino que o fim da linha de texto foi atingido. 

A  próxima  instrução  if  verifica  se  o  valor  de 



numChar  é  superior  a  15  ou  não  e  se  assim  se 

define  como  sendo  de  15.  Isso  garante  que  nós 

não estouraremos o array 

char


 buffer [18]

Depois vem um comando 



while

. É um comando 

que  nós  ainda  não  nos  deparamos  antes,  então 

segue a explanação. 

Nós  já  usamos  o  laço 

for


,  que  irá  percorrer  um 

determinado número de vezes numa sequência. A 

instrução 

while


  é  também  um  laço,  mas  que 

executa  somente  enquanto  uma  condição  é 

verdadeira. 

A sintaxe é: 

 

while


(expression) { 

  // statement(s) 

   } 

 

Em nosso código ficou como: 



 

    while 

(numChar--) { 

    buffer[index++] = 

Serial.read

(); 


}

 

 



A  condição  é  verificada  simplesmente  através  do 

numChar


, portanto, em outras palavras, é verificar 

se o valor armazenado no inteiro 

numChar

 não é 


zero.  Isto  é  conhecido  como  um  pós-decremento. 

Em  outras  palavras,  o  valor  é  decrementado 

depois  que  é  usado.  No  nosso  caso,  o  loop  while 

verifica  o  valor  de 

numChar

  e,  em  seguida, 

subtraí  uma  unidade  a  partir  dele.  Se  o  valor  de 

numChar

 não era zero antes do decremento, então 

executa  o  código.  Está  definido  para  o 

comprimento  da  seqüência  de  texto  que  entraram 

na  janela  do  Monitor  Serial.  Assim,  o  código 

dentro  do  loop  while  irá  ser  executado  muitas 

vezes. O código dentro do laço 

while

 é: 


 

20 

 

buffer[index++] = 



Serial.read

();


 

 

Que  define  cada elemento da  matriz  tampão  para 



cada  caractere  lido  a  partir  da  linha  de  série.  Em 

outras  palavras,  ele  enche  o  buffer  array  com  os 

dados  que  inserimos  na janela  do Serial Monitor. 

O  comando



 

Serial.read()

  lê  a  série  de  dados 

de entrada, um byte de cada vez. 

Portanto,  agora  que  a  nossa  matriz  de  caracteres 

foi  preenchida  com  os  dados  que  entraram  no 

Serial  Monitor,  o 

while


  terminará  assim  que 

numChar


 chegar a zero. Depois temos: 

 

splitString(buffer);



 

 

Que  é  uma  chamada  para  uma  das  duas  funções 



que  criamos  e  chamamos  de 

splitString()

Essa função é descrita a seguir: 



 

void splitString

(

char


* data) { 

Serial.print

("Data entered: "); 

Serial.println

(data); 

char


* parameter; 

parameter = strtok (data, " ,"); 

while 

(parameter != NULL) { 



setLED(parameter); 

parameter = strtok (NULL, " ,"); 

for 


(

int 


x=0; x<16; x++) { 

buffer[x]='\0'; 

Serial.flush



(); 

}

 



 

Podemos  ver  que  a  função  não  retorna  nenhum 

tipo  de  dado,  portanto  podemos  ver  que  seu  tipo 

foi  criado  para  anular  possíveis  continuidades. 

Passamos  o  parâmetro  de  uma  função  que  é  um 

tipo de 


char

(caractere) e que trataremos como de 

dados. 

No 


entanto, 

nas 


linguagens 

de 


programação  C  e  C++  você  não  tem  permissão 

para  enviar  uma  matriz  de  caracteres  para  uma 

função.  Temos  que  contornar  isso,  usando  um 

parâmetro. Nosso parâmetro será um asterisco (*) 

e foi adicionada ao (*) o nome de dados variáveis. 

Parâmetros são bastante avançados no C de modo 

que  não  vamos  entrar  em  muitos  detalhes  sobre 

eles. Tudo que você precisa saber agora é que por 

declaração  de  dados  como  um  parâmetro, 

simplesmente  uma  variável  aponta  para  outra 

variável.  

Você  pode  apontá-lo  para  o  endereço  que  a 

variável  é  armazenada  na  memória  usando  o 

símbolo  &,  ou  em  nosso  caso,  para  o  valor 

armazenado a esse endereço de memória usando o 

símbolo *. Usaremos isso para enganar o sistema, 

como  nós  não  temos  permissão  para  enviar  um 

caractere  à  matriz  para  uma  função.  No  entanto, 

estamos  autorizados  a  enviar  um  indicador  para 

uma matriz de caracteres para a nossa função. 

Assim,  nós  declaramos  uma  variável  do  tipo  de 

dados 


char

  e  chamamos  de  dados,  mas  o 

símbolo  *,  isso significa  que  está  apontando para 

o valor armazenado dentro do  buffer. 

Quando chamamos 

splitString



 enviamos para 

o  seu  conteúdo  o  buffer  (na  verdade  o  parâmetro 

para ele, como vimos acima). 

 

splitString(buffer);



 

 

Então nós chamamos a função e passamos para o 



seu conteúdo a matriz de caracteres do buffer. 

O primeiro comando é 

 

Serial.print



("Data entered: ");

 

 



e esta é a nossa forma de enviar dados de volta do 

Arduino  para  o  PC.  Neste  caso,  o  comando  de 

impressão  envia  o  que  está  dentro  do  parêntese 

para  o  PC,  através  do  cabo  USB,  onde  podemos 

ler no Serial Monitor. 

Neste  caso,  já  enviámos  as  palavras 

"Data 

entered:"



.  O  texto  deve  ser  colocado  entre 

aspas " ". A linha seguinte é semelhante 

 

Serial.println



(data);

 

 



E  mais  uma  vez,  enviou  dados  para  o  PC.  Por 

exemplo: 

 

R255 G127 B56



 

 

Em seguida, 



 

Serial.println

(data);

 

 



Este  comando  irá  enviar  essa  sequência  de  texto 

para  o  PC  e  imprimi-lo  na  janela  do  Serial 

Monitor, se algo for digitado na janela do Serial. 

Desta  vez,  o  comando  de  impressão  tem  “ln”  no 

fim  torná-lo  println.  Isto  simplesmente  significa 

impressão/imprimir na linha do Serial Monitor. 

Quando imprimir utilizando o comando 

print


, o 

cursor  (o  ponto  onde  o  símbolo  irá  aparecer) 

permanece  no  final  de  tudo  o  que  tenha 

imprimido. 

Quando  usamos  o  comando 

println


  um 

comando  de  avanço  de  linha  é  emitido  ou  em 

outras  palavras,  as  impressões  de  texto  e,  em 

seguida, o cursor cai para a linha seguinte. 

 

Serial.print



("Data entered: "); 

Serial.println

(data);

 

 



Se  olharmos  para  os  nossos  dois  comandos  de 

impressão,  o  primeiro  imprime  "Os  dados 

inseridos:" e então o cursor permanece no final do 


21 

 

texto.  A  próxima  impressão  vai  imprimir  os 



dados,  ou  em  outras  palavras,  o  conteúdo  da 

matriz chamado tampão e depois emitir uma linha 

de  alimentação,  ou  deixar  cair  o  cursor  para  a 

próxima  linha.  Isto  significa  que,  se  emitir  outra 

impressão  ou  declaração  println  após  isso  tudo 

que  é  impresso  na  janela  do  Serial  Monitor  será 

exibido na próxima linha por baixo da última. 

Em  seguida,  criamos  um  novo  tipo  de  dados 

char

 chamado parâmetro. 

 

Char



* parameter;

 

 



e  como  vamos  usar  essa  variável  para  acessar 

elementos  da  matriz  de  dados,  ele  deve  ser  do 

mesmo tipo, portanto o símbolo *. Você não pode 

passar  dados  de  um  tipo  de  variável  para  outro 

tipo  de  variável,  os  dados  devem  ser  convertidos 

em primeiro lugar. Esta variável é outro exemplo 

de alguém que tem o escopo local. Pode ser visto 

apenas  pelo  código  dentro  dessa  função.  Se  você 

tentar acessa-la fora parâmetro da variável função 

splitString

 você obterá um erro. 

Em seguida, usamos um comando 

strtok

, que é 


um    comando  muito  útil  para  nos  capacitar  para 

manipular textos de comando. 

strtok

 é a junção 



do  nome  de  string  e  Token  e  o  seu  objetivo  é 

dividir um texto usando símbolos. No nosso caso 

o  símbolo  que  estamos  procurando  é  um  espaço 

ou  uma  vírgula.  Ele  é  usado  para  dividir 

sequências  de  caracteres  de  texto  em  partes 

menores  e  legíveis  ao  programa.  Passamos  a 

matriz de dados para o comando 

strtok


 como o 

primeiro  argumento  e  os  símbolos  (incluído  o 

dentro das aspas) como o segundo argumento. Por 

isso: 


 

parameter ´strtok(data,”,“); 

 

E  ele  divide  a  sequência  nesse  ponto.  Portanto, 



estamos  a  usá-lo  para ajustar  o  parâmetro  a  ser  a 

parte  da  cadeia  até  um  espaço  ou  uma  vírgula. 

Então, se a nossa cadeia de texto foi 

 

R127 G56 B98 



 

Então,  após  esta  declaração  o  valor  do  parâmetro 

será 

 

R127



 

 

O  comando  strtok  simplesmente  divide  a 



sequência  digitada  para  a  primeira  ocorrência  de 

um espaço ou de uma vírgula. 

Depois de ter definido o parâmetro variável para a 

parte da cadeia de texto que queremos retirar (ou 

seja,  o  bit  do  primeiro  espaço  ou  vírgula)  em 

seguida,  daremos  um  comando  de  fim  de 

comando.  

 

while



(parameter != NULL) {

 

 



Dentro do loop que chamamos de nossa segunda 

função 


 

setLED(parameter);

 

 

Que veremos mais tarde. Em seguida, ele define o 



parâmetro  variável  para  a  próxima  parte  da 

seqüência  para  o  próximo  espaço  ou  vírgula. 

Fazemos  isso  passando  para  strtok  um  parâmetro 

NULL 


 

parameter = strtok(NULL, " ,");

 

 

Isso informa ao programa para continuar de onde 



parou. 

Então, temos toda essa parte da função: 

 

char


* parameter; 

parameter = strtok(data, " ,"); 

while 

(parameter != NULL) { 



setLED(parameter); 

parameter = strtok(NULL, " ,"); 

}

 

 



é simplesmente a cadeia de comandos que permite 

ajustar a próxima função chamada 

setLED()

 

A parte final desta função simplesmente preenche 

o buffer com conjunto  dos caracteres, que é feito 

com o “/0”  símbolo que nivela e em seguida, os 

dados  de  série  estão  prontos  para  o  próximo 

conjunto de dados que poderão ser inseridos. 

 

// Clear the text and serial buffers 



for 

(

int 



x=0; x<16; x++) { 

  buffer[x]='\0'; 

Serial.flush



();

 

 



A função 

setLED()


 vai identificar cada parte da 

sequência 

de 

texto 


definir 


LED 


correspondente à cor que se escolher. Assim, se a 

sequência de texto é: 

 

G125 B55


 

 

A função 



splitString()

 divide o texto em dois 

componentes separados 

 

G125 



B55

 

 



e  envia  essa  seqüência  de  texto  abreviado  para  o 

setLED()


 da função, que vai lê-lo, definir o LED 

que  escolhido  e  configurá-lo  para  o  brilho 

correspondente do valor. 


22 

 

Então  vamos  dar  uma  olhada  na  segunda  função 



chamada 

setLED():

 

 

void 



setLED(

char


* data) { 

if 


((data[0] == 

'r'


) || (data[0] == 

'R'


)) 

int 



Ans = strtol(data+1, NULL, 10); 

Ans = 


constrain

(Ans,0,255); 

analogWrite

(RedPin, Ans); 

Serial.print

(

"Red is set to: "



); 

Serial.println

(Ans); 



if 



((data[0] == 

'g'


) || (data[0] == 

'G'


)) 

int 



Ans = strtol(data+1, NULL, 10); 

Ans = 


constrain

(Ans,0,255); 

analogWrite

(GreenPin, Ans); 

Serial.print

(

"Green is set to: "



); 

Serial.println

(Ans); 



if 



((data[0] == 

'b'


) || (data[0] == 

'B'


)) 

int 



Ans = strtol(data+1, NULL, 10); 

Ans = 


constrain

(Ans,0,255); 

analogWrite

(BluePin, Ans); 

Serial.print

(

"Blue is set to: "



); 

Serial.println

(Ans); 



}



 

 

Podemos  ver  que  esta  função  contém  três 



comandos  muito  semelhantes  de 

if

.  Por  isso 



vamos  dar  uma  olhada  em  apenas um  deles,  pois 

os outros dois são quase idênticos. 

 

if 


((data[0] == 

'r'


) || (data[0] == 

'R'


)) { 

int 


Ans = strtol(data+1, NULL, 10); 

Ans = 


constrain

(Ans,0,255); 

analogWrite

(RedPin, Ans); 

Serial.print

(

"Red is set to: "



); 

Serial.println

(Ans); 

}

 



 

A instrução 

if

 verifica se o primeiro caractere no 



campo de dados da sequência ( 

data[0]


 ) é uma 

letra  r  ou  R  (maiúscula  ou  minúsculas  são 

totalmente  diferentes  para  a  linguagem  em  C). 

Usamos  o  comando  lógico  OR  cujo  símbolo  é  || 

para verificar se a letra é maiúscula ou minúscula. 

Sabendo  que  é  um  r  ou  um  R,  a  instrução 

if

  irá 


agora dar o comando de brilho do LED vermelho 

e assim executa o código dentro da sequência. 

Primeiro nós declaramos um inteiro chamado Ans 

(que  tem  valor  temporário)  e  usamos  o  comando 

strtol

  para  converter  os  caracteres  após  a  letra 

digitada  inicialmente,  sendo  ela  r  ou  R,  para 

valores inteiros. 

O  comando 

strtol

  tem  três  parâmetros  que são 



levados  em  consideração;  estes  são:  a  sequência 

que estamos utilizando, um ponto após o caractere 

inteiro  (NULL)  e,  em  seguida,  a  base  que,  no 

nosso  caso  é  base  igual  a  10,  como  estamos 

usando  números  decimais  normais  (ao  contrário 

de  binário,  octal  ou  hexadecimal  que  seriam  de 

base  2,  8  e  16,  respectivamente).  Assim,  em 

outras  palavras,  declaramos  uma  série  de 

comandos  que  identificarão  um  inteiro  e  irão 

configurá-lo  para  o  valor  de  brilho  do  led 

escolhido. 

Usamos  o  comando 

constrain

  (restringir)  para 

certificar-se que o número em 

Ans


 vai de 0 a 255 

e  não  mais  que  isso.  Em  seguida,  o  comando 

analogWrite

  envia  para  o  pino  de  saída  e  o 

valor  de  Ans.  As  outras  duas  declarações  if 

executam comandos idênticos ao explicado. 

É  necessário  que  se  estude  mais  a  fundo  os 

comandos  citados  até  aqui,  pois  têm  diversas 

outras  aplicações  e  funções  diferentes,  além  das 

utilizadas  até  agora.  Tivemos  uma  introdução 

básica de novos conceitos nestes projetos. 

 

 



Projeto  11  –  Acionamento  de  um 

motor CC 

 

Este projeto trabalhará com acessórios diferentes, 



como fontes, motores, diodos, etc. 

 

O que você precisa 



 

 


23 

 

 



 

 

int potPin = 0; // Analog in 0 



connected to the potentiometer 

int transistorPin = 11 

; // connected to the base of the 

transistor 

int potValue = 0; // value returned 

from the potentiometer 

void setup() { 

// set the transistor pin as output: 

pinMode(transistorPin, OUTPUT); 

void loop() { 



// read the potentiometer, convert it 

to 0 - 255: 

potValue = analogRead(potPin) / 4; 

// use that to control the 

transistor: 

analogWrite(transistorPin, potValue); 

}

 

 



Antes  de  ligar  o  circuito,  verifique  se  tudo  foi 

conectado corretamente e em especial o diodo que 

tem polarização. Se ligá-lo de maneira errada, isso 

pode resultar em danos permanentes ao o Arduino 

e  componentes.  Quando  estiver  certo    que  as 

ligações  estão  corretas,  faça  o  upload  do  seu 

código. 

 

int potPin = 0; 



int transistorPin = 11; 

int potValue = 0; 

void setup() { 

pinMode(transistorPin, OUTPUT); 

void loop() { 



potValue = analogRead(potPin) / 4; 

analogWrite(transistorPin, potValue); 

}

 

 



Este  código  é  muito  simples.  Declaramos  3 

inteiros  que  armazenam  os  valores dos  pinos que 

se ligam ao nosso potenciômetro, ao pino que liga 

ao  transistor  e  ao  valor  lido  a  partir  do 

potenciômetro. 

Na  função  setup  ()  vamos  configurar  o  pinMode 

do pino do transistor para saída. 

O  potValue  do  loop  principal  está  definido  para 

ler  o  valor  lido  a  partir  do  pino  analógico  0 

(potPin) e, em seguida, é dividido por 4. 

Temos que dividir o valor lido por 4, para fazer a 

relação com o valor analógico que irá variar de 0 a 

0  volts  a  1023  para  5  volts.  O  valor  do  pino  do 

transistor  só  pode  variar  de  0-255,  de  modo  que 

dividindo o valor do pino analógico 0 (max 1023) 

por  4  obtemos  o  valor  máximo  de  255  para  a 

fixação  do  pino  digital  11  (usando  analogWrite 

por isso estamos usando PWM). 

O  código,  em  seguida,  escreve  para  o  pino  do 

transistor  o  valor  ajustado  no  potenciômetro.  Em 

outras 

palavras, 



quando 

você 


gira 

potenciômetro,  diferentes  valores  são  lidos 



(variam de 0 a 1023) e estes são convertidos para 

a  faixa  de  0  a  255  e,  em  seguida,  esse  valor  é 

escrito  (via  PWM)  para  o  pino  digital  11  que 

muda a velocidade do motor de corrente contínua. 

Gire  o  potenciômetro  todo  para  a  esquerda  e  o 

motor desliga, vire para a direita e ele acelera até 

que atinja a velocidade máxima. 

 

Visão geral do hardware 

 

O hardware para o Projeto 11 é como abaixo: 



 

 

 



O  circuito  é  essencialmente  dividido  em  duas 

seções:  (a)  A  seção  1  é  o  nosso  potenciômetro, 

que  está  ligado  à  +3,3  V  e  ao  terra  com  o  pino 

central de entrada no pino analógico A0. Como o 

potenciômetro  é  giratório,  a  variação  de 

resistência  permite  tensões  de  0  a  3,3  V,  onde  o 

valor  é  lido  usando  o  pino  analógico  A0.  (b)  A 


24 

 

segunda seção é a que controla o motor. Os pinos 



digitais  do  Arduino  fornecem  um  máximo  de 

40 mA. O motor requer em torno de 500 mA para 

funcionar em alta velocidade e isto é, obviamente 

muito  alto  para  o  Arduino.  Se  fôssemos  tentar 

conduzir o motor diretamente a partir de um pino 

do Arduino um  grave e permanente dano poderia 

ocorrer.  Portanto,  precisamos  encontrar  uma 

maneira de fazê-lo de maneira indireta. 

Este  projeto  controla  a  velocidade  do  motor,  por 

isso precisamos de uma maneira de controlar essa 

tensão para acelerar ou retardar o motor. Este é o 

lugar onde o transistor TIP-120 atua. 

Um  transistor  é  essencialmente  um  comutador 

digital.  Ele  também  pode  ser  utilizado  como  um 

amplificador  de  potência.  O  símbolo  eletrônico 

para um transistor bipolar é mostrado a seguir: 

 

 

O transistor tem três pernas, uma é a base, outra é 



o  coletor  e  a  terceira  é  o  emissor.  Estes  são 

identificados como B, C e E na figura abaixo. 

 

 

 



No  nosso  circuito,  temos  3,3  volts  indo  para  o 

coletor através  do  motor. A  base  é  ligada  através 

de  um  resistor  de  1  kΩ  ao  pino  digital  11.  O 

emissor  é  ligado  ao  pino  terra.  Enviamos  pulsos 

via  PWM  ao  pino  11,  e  esta  tensão  é  reduzida 

usando um resistor de 1 kΩ. Sempre que se aplica 

uma  tensão  à  base,  através  do  pino  11,  o  que 

permite  que  corrente  flua  através  do  coletor  ao 

emissor  e,  portanto,  acionar  o  motor,  que  está 

ligado em série com este circuito. 

Um  motor  é  um  eletroímã  que  tem  um  campo 

magnético  induzido  enquanto  uma  tensão  é 

fornecida.  Quando  a  energia  é  removida,  o 

colapso  do  campo  magnético  pode  produzir  uma 

tensão  reversa.  Isso  pode  danificar  seriamente  o 

seu  Arduino  e  é  por  isso  que  o  diodo  foi 

introduzido  no  circuito.  A  listra  branca  marcada 

no  diodo  indica  o  lado  que  se  liga  no  terra.  Ele 

filtra o fluxo a partir do lado positivo para o lado 

negativo. O diodo irá funcionar como uma válvula 

para  impedir  refluxo  de  corrente.  O  diodo  em 

nosso circuito é, portanto, inserido para proteger o 

Arduino. 

 

 



Circuito equivalente do transistor TIP120. 

 

Projeto 12 – Atuador piezelétrico  

 

Neste projeto vamos usar um simples circuito para 



produzir  sons  usando  um  Arduino  e  uma  sirene 

piezelétrica. 

O que você precisa 

 

 



 

 

Montagem 

 

Quando você executar esse código o Arduino fará 



soar  um  som  muito  semelhante  aos  irritantes 

cartões de aniversário que você pode comprar em 

qualquer  banca  de  jornais  e  que  quando  são 


25 

 

abertos  tocam  uma  música.  Vamos  dar  uma 



olhada  neste  código  e  ver  como  funciona  e 

descobrir o que é um disco piezo. 

 

Descrição do código 

 

// Projeto 12 – Atuador piezeletrico 



int 

speakerPin = 9; 

int 

length = 15; 



// Numero de notas 

char 


notes[] = "ccggaagffeeddc "; 

// 


Espaco representa uma pausa 

int 


beats[] = { 1, 1, 1, 1, 1, 1, 2, 1, 

1, 1, 1, 1, 1, 2, 4 }; 

int 

tempo = 300; 



 

void 


playTone(

int 


tone, 

int 


duration) { 

for 


(

long 


i=0; i < duration*1000L; 

i+=tone*2) { 

  digitalWrite

(speakerPin, 

HIGH

); 


  delayMicroseconds

(tone); 


  digitalWrite

(speakerPin, 

LOW

); 


  delayMicroseconds

(tone); 


 



void 

playNote(

char 

note, 


int 

duration) { 

char 

names[] = { 'c', 'd', 'e', 'f', 'g', 



'a', 'b', 'C' }; 

int 


tones[] = { 1915, 1700, 1519, 1432, 

1275, 1136, 1014, 956 }; 

// Toca o tom corresponde ao nome da nota 

for 


(

int 


i = 0; i < 8; i++) { 

  if 


(names[i] == note) { 

    playTone(tones[i], duration); 

  } 





 

void 


setup

() { 


pinMode

(speakerPin, 

OUTPUT

); 


 

void 



loop() { 

for 


(

int 


i = 0; i < length; i++) { 

  if 


(notes[i] == ' ') { 

    delay

(beats[i] * tempo); // rest 

  } 


else 

    playNote(notes[i], beats[i] * tempo); 



  } 

  // Pausa entre notas 

  delay

(tempo / 2); 



 



 

Neste  projeto  estamos  fazendo  sons  usando  um 

disco  piezelétrico.  Um  disco  piezo  pode  fazer 

nada mais do que uma vibração quando se aplica 

uma  tensão ao  mesmo.  Assim,  para obter  os tons 

que  podemos  ouvir,  precisamos  fazer  várias 

vibrações  e  muitas  vezes  num  instante  rápido  o 

suficiente  para  que  ele  realize  uma  nota 

reconhecível e que seja audível. 

O  programa  começa  por  estabelecer  as  variáveis 

necessárias. No piezo de sirenes, o cabo vermelho 

é positivo e é ligado ao pino 9 do Arduino. 

 

 

 



A  música  que  vamos  tocar  é  composta  de  15 

notas. 


 

 

 



As  notas  da  melodia  são  armazenadas  em  uma 

matriz de caracteres como um texto. 

 

 

 



Outra  matriz,  desta  vez  de  números  inteiros,  é 

configurada  para  armazenar  o  comprimento  de 

cada nota. 

 

 



 

E,  finalmente,  definir  um  tempo  para  a  música  a 

ser tocada: 

 

 



 

Em  seguida,  você  vai  perceber  que  nós 

declaramos duas funções antes do nosso setup() e 

loop()  .  Não  importa  se  colocarmos  nossas 

próprias  funções,  antes  ou  depois  setup  ()  e  loop 

().  Quando  o  programa  é  executado,  o  código 

dentro  dessas  duas  funções  não  será  executado 

antes  do  setup  ()  pois  ainda  não  chamamos  essas 

funções ainda. 

Vamos  olhar  para  as  funções  de  configuração  e 

loop antes de olharmos para o playTone e funções 

playNote. Tudo  o  que  acontece  no  setup  ()  é  que 

atribuir o alto-falante no pino (9) como uma saída. 

 

 



No loop principal do programa, temos um if / else 

declaração dentro de um loop for. 

 

 

 



Como  você  pode  ver,  a  primeira  instrução  “if  ” 

tem como condição, que o elemento da matriz [i] 

contém um caractere de espaço. 

 

 



 

26 

 

Se for verdadeiro, então o código de dentro do seu 



bloco é executado. 

 

 



 

e isso simplesmente  provoca um atraso nas notas. 

Temos, então, outra declaração. 

 

 



 

Depois  de  uma  afirmação  se  pode  estendê-lo 

como outra declaração. Um else é executado se o 

condição  dentro  do  if  é  falsa.    Assim,  por 

exemplo,  vamos  dizer  que  tivemos  um  teste 

inteiro  e seu valor era de 10 e esta declaração if / 

else: 

 

 



 

Então se o teste teve um valor de 10 o ledPin seria 

definido  como  Alto.  Se  o  valor  do  teste  foi 

diferente  de  10,  o  código  dentro  da  outra 

declaração seria realizada e em vez disso o ledPin 

seria definido como Baixo.  

A declaração adiante chama uma função chamada 

playNote  e  passa  dois  parâmetros.  O  primeiro 

parâmetro é o valor das notas [i] e o segundo é o 

valor calculado a partir de batidas [i] ritmo *. 

 

 



Após  instrução  if  /else  realizada,  há  um  atraso 

cujo valor é calculado  dividindo ritmo por 2. 

 

Vamos  agora  dar  uma  olhada  nas  duas  funções 



que criamos para este projeto. 

A  primeira  função  que  é  chamada  a  partir  do 

programa principal loop é playNote

 

void 



playNote(

char 


note, 

int 


duration) { 

char 


names[] = { 'c', 'd', 'e', 'f', 'g', 

'a', 


'b', 'C' }; 

int 


tones[] = { 1915, 1700, 1519, 1432, 

1275, 


1136, 1014, 956 }; 

// play the tone corresponding to the 

note name 

for 


(

int 


i = 0; i < 8; i++) { 

   if 


(names[i] == note) { 

      playTone(tones[i], duration); 

   } 





 

Dois  parâmetros  foram  passados  para  a  função  e 

dentro  da  função  à  estes  foram  dados  os  nomes 

das  notas  (names  -  caracteres)  e  duração 

(duration-inteiro). 

A  função cria uma  matriz  local  variável  de  dado. 

Esta variável tem locais de escopo que só é visível 

para essa função e não fora dela.  

Em  seguida,  criar  outra  matriz  de  dados  do  tipo 

inteiro  e  esta  matriz  armazena  os  números  que 

correspondem à frequência dos tons, em kilohertz, 

de cada uma das notas nos nomes da matriz. 

 

int 


tones[] = { 1915, 1700, 1519, 1432, 1275, 

1136, 1014, 956 }; 

 

Depois  de  configurar  as  duas  matrizes  existe  um 



loop que olha através das 8 notas e compara com 

a nota enviada para a função. 

 

for 


(

int 


i = 0; i < 8; i++) { 

if 


(names[i] == note) { 

playTone(tones[i], duration); 

}

 



 

A  música  que  é  enviada  para  este  função  é 

Ccggaagffeeddc



” para a primeira nota será um 

meio C. 


O loop for compara a nota com as notas da matriz 

e  se  houver  uma  correspondência,  chama  a 

segunda  função,  chamada  playTone,  para  jogar  o 

tom correspondente. 

A segunda função é chamado playTone. 

 

void 



playTone(

int 


tone, 

int 


duration) 

for 



(

long 


i = 0; i < duration * 

1000L; i += 

tone * 2) { 

digitalWrite

(speakerPin, 

HIGH


); 

delayMicroseconds

(tone); 

digitalWrite

(speakerPin, 

LOW


); 

delayMicroseconds

(tone); 



 

Dois parâmetros são passados para esta função. O 

primeiro  é  o  tom  (em  quilohertz)  que  queremos 

que o piezo altofalante reproduza e a segunda é a 

duração  (composto  por  cálculo  através  da  função 

beats [i] * ritmo. A função inicia um loop 

 

for 


(

long 


i = 0; i < duration * 

1000L;       i += tone * 2) 

 

À  medida  que  cada  loop  deve  ter  de  um 



comprimento  diferente  para  fazer  com  que  cada 

nota tenha a mesma duração (como o atraso difere 



27 

 

entre  vibrações  para  produzir  a  frequência 



desejada)  o  loop  será  executado  e  a  duração 

multiplicada por 1000 e o incremento do loop é o 

valor de tonalidade multiplicado por dois. 

Dentro 


do 

loop 


podemos 

observar 

que  

simplesmente  o  pino  conectado  ao  ao  piezo-



elétrico tem uma ordem de sinal de saída ALTO, 

espera-se um curto período de tempo, em seguida, 

é enviado um sinal BAIXO, então espera-se mais 

um  curto  período  de  tempo,  depois  o  processo  é 

retomado. 

 

digitalWrite



(speakerPin, 

HIGH


); 

delayMicroseconds

(tone); 

digitalWrite

(speakerPin, 

LOW


); 

delayMicroseconds

(tone); 

 

Esses  cliques  repetitivos,  de  comprimentos 



diferentes 

com 



diferentes 

pausas 


(de 

microssegundos  apenas)  entre  os  intervalos,  faz 

com que o piezo produza um som gerado a partir 

de diferentes frequências. 

 

Visão geral do hardware 

 

A única parte de hardware utilizada neste projeto 



é  uma  sirene  piezoelétrica  ou  piezelétrica.  Este 

dispositivo  simples  é  constituído  por  uma  fina 

camada de cerâmica ligada a um disco metálico.  

Materiais  piezelétricos,  são  alguns  cristais  e 

cerâmica,  que  têm  a  habilidade  de  produzir 

eletricidade  a  partir  da  tensão  (stress)  mecânica 

quando aplicado a eles.  

Têm aplicações, tais como a produção e detecção 

de som, a geração de elevada tensões, geração de 

frequência  eletrônica,  microbalanças  e  trabalho 

em ultrafinas de focagem ópticas. 

O  efeito  também  é  reversível,  em  que,  se  um 

campo  elétrico  é  aplicada  através  do  material 

piezelétrico irá fazer com que o material mude de 

forma  (por  menos  que  seja  0,1%  em  alguns 

casos). 


Para  produzir  os  sons  de  um  disco  piezo,  um 

campo elétrico é ligado e desligado muito rápido, 

para fazer o material mudar de forma e, portanto, 

causar uma vibração (como um tambor pequeno). 

Por  mudar  a  frequência  dos  pulsos,  o  disco 

deforma-se  centenas  ou  milhares  de  vezes  por 

segundo  e,  consequentemente,  causando  o  som. 

Ao  alterar  a  frequência  das  vibrações  e  o  tempo 

entre 

eles, 


notas 

específicas 

podem 

ser 


produzidas. 

 

 



 

Exercícios 

1.  Alterar  as  notas  e  batidas  para  fazer  outras 

músicas, como feliz Aniversário ou Feliz Natal. 

2.  Escreva  um  programa  para  fazer  um  tom 

subindo  e  descendo  do  piezo,  semelhante  a  um 

alarme de carro ou sirene da polícia. 

 

 



Projeto  13  –  Sensor  de  temperatura 

com o CI LM35 

 

Neste  projeto  mostraremos  como  construir  um 



sensor de temperatura usando o circuito integrado 

LM35. 


 

O que você precisa 

Circuito integrado LM35 

 

 



Montagem: 

 

 



 

Um sensor de temperatura embutido no CI LM35 

lê uma resistência elétrica, que é processada no CI 

e convertida no valor de temperatura em ºC. 

O  CI  LM35  é  um  circuito  integrado  que  é 

alimentado  com  tensão  de  +5  Vcc.  Esta  tensão  é 

adequada  para  o  Arduino  já  que  ele  possui  um 

pino de saída de 5 V. O CI possui três terminais: 

dois  para  alimentação  de  5  V  e  um  terceiro  do 

sinal de saída analógico. 

O terminal de saída analógica fornece uma tensão 

que  é  diretamente  proporcional  à temperatura  em 

ºC.  De  acordo  com  a  Figura  abaixo,  o terminal  2 


28 

 

fornece uma saída de 1 mV/0,1ºC (ou 10 mV/ºC). 



Assim, para determinar a temperatura em ºC deve-

se ler a tensão em mV do terminal 2 e dividir por 

10  para  ter  o  valor  de  temperatura  em  ºC.  Por 

exemplo,  se  o  terminal  2  fornece  uma  leitura  de 

tensão de 315 mV corresponderá a temperatura de 

31,5ºC. 


 

 

Visão do hardware 

 

O  terminal  1  do  CI  recebe  a  tensão  +5  V  e  o 



terminal 3 é aterrado no pino GND do Arduino. O 

terminal  2  é  conectado  ao  pino  A0  de  entrada 

analógica  do  Arduino,  conforme  mostra  a  Figura 

abaixo. 


 

 

 



O  mesmo  circuito  pode  ser  esquematizado  como 

segue. 


 

 

Projeto 13 – Descrição do código 

 

// Define o pino de saída do CI LM35 



int outpin= 0; 

 

void setup() 



Serial.begin(9600); 

 

// Laço principal 



void loop() 

int rawvolt= analogRead(outpin); 



float milivolt= (rawvolt/1024.0) * 5000; 

float celsius= milivolt/10; 

Serial.print(celsius); 

Serial.print(" graus Celsius, "); 

delay(5000); 

 



O sinal de tensão de saída do CI LM35 é lido na 

variável 

rawvolt

.  Este  valor  é  proporcional  à 



tensão  de  5000  mV,  dividido  por  1024  (que  é  o 

máximo valor inteiro lido pela porta analógica do 

Arduino). O valor resultante de tensão (em mV) é 

gravado  na  variável 

milivolt

.  Por  último,  a 

temperatura  em  ºC  é  calculada  dividindo 

milivolt


  por  10  (fator  de  conversão  de  tensão 

em mV para temperatura ºC). 

No  final  do  sketch  é  colocado  um  atraso  de  5  s 

para leitura da temperatura do sensor LM35. Este 

valor pode ser ajustado conforme a necessidade. 

 

 



 

 

Projeto  14  -  Sensor  de  temperatura 



Termistor NTC 10 k

Ω 

29 

 

 



Neste  projeto  mostraremos  como  construir  um 

sensor de temperatura usando o termistor NTC de 

10 kΩ. 

 

O que você precisa 



Termistor NTC 10 kΩ 

 

Montagem 



 

 

Termistores 

Termistores são resistores termicamente sensíveis. 

Os termistores são muito utilizados em aplicações 

que  necessitem  de  uma  alta  sensibilidade  com 

mudança 


à 

temperatura, 

pois 

eles 


são 

extremamente sensíveis a mudanças relativamente 

pequenas de temperaturas. 

Todavia  não  são  lineares.  A  resposta  da  variação 

de  temperatura  não  é  linear  à  variação  de  sua 

resistência,  mas  pode-se  obter  a  relação  entre  a 

resistência  e  a  temperatura  para  faixas  pequenas 

de variação de temperatura através da equação de 

Steinhart-Hart. 

Existem  dois  tipos  de  termistores:  o  PTC 

(Coeficiente  Positivo  de  Temperatura)  e  o  NTC 

(Coeficiente  Negativo  de  Temperatura),  essa 

distinção  é  devida  ao  material  de  sua  construção. 

Esses  dispositivos  são  construídos  a  partir  de 

misturas de óxidos semicondutores, como titanato 

de  bário  para  os  PTCs  e  óxidos  de  magnésio, 

níquel,  cobalto,  titânio,  ferro  e  cobre  para  os 

NTCs. 


Os  termistores  NTC  são  sensíveis  a  variações  de 

temperatura. Sua resistência diminui à medida que 

a  temperatura  aumenta.  Desenvolvidos  com 

uma tecnologia que permite tolerância de variação 

de 1%. 

São  usados  principalmente  para  faixas  de 



medições  entre  -55º  a  150ºC.  Devido  ao  baixo 

custo  e  ao  excelente  desempenho,  o  termistor 

NTC  possui  uma  ampla  utilização  nas  indústrias, 

seja para refrigeração, condicionamento de ar, em 

automóveis,  controle  de  temperatura,  sistemas  de 

detecção e alarmes contra incêndio, dentre outras. 

A  curva  que  define  o  comportamento  da 

resistência  em  função  da  temperatura  tem  um 

comportamento exponencial, como pode ser visto 

no gráfico abaixo. 

 

 

Tensão de saída do circuito 



Para este circuito divisor de tensão determina-se a 

equação  para  o  sinal  de  saída  injetado  ao 

microcontrolador da seguinte maneira: 

 

 



 

Como a tensão de saída Vout = VR1, temos: 

 

Como  V


out

  do  circuito  é  igual  à  V

in

  da  entrada 



analógica  do  Arduino,  pode-se  adaptar  a  equação 

e inseri-la ao código do programa para determinar 

corretamente o valor da resistência do NTC. Este 

valor  de  resistência  será  utilizado  na  equação  de 

Steinhart-Hart: 

 

 



 

Equação de Steinhart-Hart 

Analisando 

gráfico 


da 

curva 


resistiva 

característica  de  um  termistor  NTC  10  kΩ, 

observa-se que a resposta do sensor à variação da 

temperatura  medida  não  é  linear,  desta  forma,  a 



30 

 

interpretação  do  sinal  de  entrada  injetado  ao 



microcontrolador  precisar  ser  tratada  através  de 

uma  equação  que  torne  precisa  qualquer 

temperatura medida. 

A relação entre resistência e temperatura no NTC 

é dada pela equação de Steinhart-Hart: 

 

 



Para utilizá-la, selecionam-se as constantes a, b e 

c definidas no manual do fabricante do Termistor 

NTC ou através de medições realizadas em ensaio 

quando 


estas 

informações 

não 

estiverem 



disponíveis. 

As constantes para o sensor do kit são: 

a = 0,0011303 

b = 0,0002339 

c = 0,00000008863 

Basta  agora  aplicar  estes  valores  à  fórmula 

inserida  no  programa  do  microcontrolador  para 

determinar  a  correta  leitura  de  temperatura  em 

tempo real. 

 

Projeto 13 – Descrição do código 

 

// Termistor_10k Sensor de temperatura  



int sensorPin = 1;  

 

void setup()  



{  

Serial.begin(9600);  

 

void loop()  



  float Valor = analogRead(sensorPin);  

  float Volt = 5*Valor/1024;  

  float Res=(10000*Volt/(5-Volt));  

  Serial.print("Resistencia = "); 

  Serial.print(Res,0); 

  Serial.print("  ohm\n"); 

  //  Constantes  da  equação  de  Steinhart-

Hart 

  float a = 0.0011224922;  



  float b = 0.0002359132;  

  float c = 0.000000074995733;  

  float X = b*(log(Res));  

  float Y = 

c*(log(Res))*(log(Res))*(log(Res)); 

  float Temp = 1.0/(a + X + Y) - 273; 

  Serial.print("Temperatura = "); 

  Serial.print(Temp,2); 

  Serial.print("  graus C\n"); 

  Serial.print("\n"); 

  delay(1000);  

 



 

31 

 

 



Referências 

 

McROBERTS, M. R. Arduino starter kit manual. 



A  complete  beginners  guide  to  the  Arduino. 

Earthshine Design, 2009. 

 

FREETRONICS  Experimenters  kit  project  guide 



v.1.4.  Freetronics,  Austrália,  2014.    Disponível 

online em:  

 

ROBOCORE. Arduino kit iniciante v.6.1. 



Disponível online em: 


Baixar 1.06 Mb.

Compartilhe com seus amigos:
1   2   3   4   5




©bemvin.org 2020
enviar mensagem

    Página principal
Prefeitura municipal
santa catarina
Universidade federal
prefeitura municipal
pregão presencial
universidade federal
outras providências
processo seletivo
catarina prefeitura
minas gerais
secretaria municipal
CÂmara municipal
ensino fundamental
ensino médio
concurso público
catarina município
reunião ordinária
Dispõe sobre
Serviço público
câmara municipal
público federal
Processo seletivo
processo licitatório
educaçÃo universidade
seletivo simplificado
Secretaria municipal
sessão ordinária
ensino superior
Universidade estadual
Relatório técnico
Conselho municipal
técnico científico
direitos humanos
científico período
pregão eletrônico
Curriculum vitae
espírito santo
Sequência didática
Quarta feira
conselho municipal
prefeito municipal
distrito federal
língua portuguesa
nossa senhora
educaçÃo secretaria
Pregão presencial
segunda feira
recursos humanos
educaçÃO ciência
Terça feira
agricultura familiar