terça-feira, 28 de dezembro de 2010

Sensor IR



Como prometi na postagem sobre o Robô lutador de sumô mostro aqui o sensor infravermelho usado.
O circuito é bem simples e barato, mas muito eficiente. Quando alimentado com 5v se estiver a cerca de 2cm de uma superfície branca sua saída ficará em nível alto 5v, se a superfície for preta a saída ficara em nível baixo 0v.



A base do circuito é formada por um fotodiodo e um led infravermelho facilmente encontrados em lojas de eletrônica. O led fica aceso sempre que o circuito estiver alimentado. O resistor de 470R, que limita a corrente no led, pode ser substituído dependendo do led utilizado. O fotodiodo é polarizado reversamente e não conduz enquanto não houver incidência de luz infravermelho sobre ele o que permitie que o transistor seja polarizado pelo resistor de 10k o que coloca a saída em nível baixo. Como o foto diodo esta ao lado do led a proximidade de uma superfície branca reflete a luz do led e o foto diodo conduz, impedindo a polarização do transistor pelo resistor de 10k, o que faz a saída ficar em nível alto graças ao resistor de 4k7.

Exemplo de utilização

No exemplo  do vídeo a cada vez que arduino recebe o sinal 1 (5V) do sensor IR  ele inverte a rotação do motor através da ponte H L298. Quando o sinal é 0 (0V) ele para o motor e aguarda 2 segundos até fazer nova leitura do sensor. O código, que é grosseiro, pois a intenção é apenas ilustrar o funcionamento de sensor IR, pode ser baixado aqui.

O layout da placa do sensor pode ser baixado clicando aqui.

Obs.: Os arquivos estão compactados com o 7zip.

O ExepressPCB pode ser baixado gratuitamente aqui.


segunda-feira, 27 de dezembro de 2010

Arduino sensor de som


Se preferir assista no Youtube

Um irmão me propôs montar um sistema de luz rítmica com o arduino.
Como nunca fiz nada do tipo fui pesquisar e encontrei alguma coisa que não usava microcontrolador mas um transformador ligado à saída de um amplificador como casador de impedância, uma etapa pré-amplificadora e SCRs ou TRIACs para acionar lâmpadas incandescentes para 110v ou 220v. Pensei então em usar um sensor de som no arduino e uma etapa de potência com TRIACs, SCRs ou Relés. Por conveniência escolhi usar relés que apesar de ter a limitação ser ON/OFF, não há possibilidade de controle da intensidade luminosa como nos TRIACs e SCRs e de seus contatos sofrerem desgaste com operações repetitivas, funcionaram satisfatoriamente.

O Sensor

Existe à venda o Arduino sound sensor, mas decidi adaptar um sensor simples e barato publicado pela editora Saber no livro Eletrônico Básica para Mecatrônica de Newton C. Braga. O circuito pode não ter a sensibilidade do sensor comercial, mas, atendeu muito bem ao propósito proposto. O microfone usado é de eletreto.

O Circuito

ATENÇÃO: TENHA MUITO CUIDADO AO  UTILIZAR TENSÃO DA REDE ALTERNADA 110V OU 220V. PARA ESSAS TENSÕES CHOQUES PODEM SER, NO MÍNIMO, DESAGRADAVÉIS.
                                                                                                                                                                
                                                                                                                                                                  
As lâmpadas usadas foram de um pisca-pisca comum com 100 lâmpadas e 8 funções. Ele tem quatro conjuntos de lâmpadas, cada conjunto ligado em série. A centralzinha de controle foi removida ficando cinco fios um de cada conjunto de lâmpada que foram ligados a cada um dos contatos normalmente abertos de quatro relés e, um fio comum ligado diretamente à rede 110V. O transistores usados para acionar os relés são BC548 e os resistores de 1k. 

A lógica é bem simples. O sensor é lido pelo arduino, através da entrada analógica, 0 (zero) que verifica três níveis de sinal e chama a função acende que gera um byte aleatório e usa os quatro primeiros bits para aciona as lâmpadas através dos relés isto é, bit 1 liga o relé correspondente bit 0 desliga o relé correspondente o que, por sua vez, acende ou apaga as lâmpadas respectivamente. Para cada nível de sinal é aplicado um delay, que determina quanto tempo a lâmpadas ficarão no estado atual antes de uma próxima leitura do sensor. No caso da faixa de mais alta a função acende é chamada duas vezes para causar um efeito diferenciado.

O código, que também é muito simples, pode ser visto abaixo.

 int soundPin = 0;  
 int lmpPin4 = 13;  
 int lmpPin3 = 12;  
 int lmpPin2 = 11;  
 int lmpPin1 = 10;  
 int val, val2;  
 byte Seq =0;  
 void setup()  
 {  
  pinMode(soundPin, INPUT);  
  pinMode(lmpPin4, OUTPUT);  
  pinMode(lmpPin3, OUTPUT);  
  pinMode(lmpPin2, OUTPUT);  
  pinMode(lmpPin1, OUTPUT);  
 }  
 void loop()  
 {  
   val2 = analogRead(soundPin); //le o sensor de som  
   val = map( val2, 0,1024,0,200); //muda de escala de 0-1024 para 0-200   
   if(val > 70 )  
   {  
   acende();  
   delay(100);  
   acende();  
   delay(100);  
   }  
   else if(val > 40 )  
   {  
   acende();  
   delay(200);  
   }  
   else if(val > 30 ) // nivel minimo valores menores são desprezados  
   {  
   acende();  
   delay(300);  
   }  
 }  
 void acende()  
 {  
 Seq = random(1,0xF);  // gera um byte aleatorio e armazena em Seq   
  if(bitRead(Seq,0 )==0)  
  digitalWrite(lmpPin1, LOW);  
  else  
  digitalWrite(lmpPin1, HIGH);  
  if(bitRead(Seq,1)==0)  
  digitalWrite(lmpPin2, LOW);  
  else  
  digitalWrite(lmpPin2, HIGH);  
  if(bitRead(Seq,2)==0)  
  digitalWrite(lmpPin3, LOW);  
  else  
  digitalWrite(lmpPin3, HIGH);  
  if(bitRead(Seq,3)==0)  
  digitalWrite(lmpPin4, LOW);  
  else  
  digitalWrite(lmpPin4, HIGH);   
 }  

Para baixar o código fonte  clique aqui.

Para baixar o layout da placa do sensor, feito no expressPCB clique aqui.

Para baixar o layout da placa dos relés, feito no expressPCB clique aqui.

Obs.: Os arquivos estão compactados com o 7zip.

Neste site você pode baixar gratuitamente o expressPCB.

Esta é apenas uma aplicação simples para o sensor de som. Usando a criatividade é possível implementar muita coisa com ele.

domingo, 26 de dezembro de 2010

Robô de sumô





No primeiro semestre deste ano surgiu a oportunidade de participar de uma guerra de robôs de sumô promovida pela faculdade em que eu estudo.
As regras foram as mesmas usadas em vários campeonatos que existem para robôs de sumo com limite de peso em três quilos exceto por uma peculiaridade, não permitia o uso de microcontroladores. Toda a lógica do robô deveria ser feita com portas lógicas e timers além de componente eletrônicos discretos como resistores capacitores e transistores.
Convidei um colega de curso, formamos uma dupla e nos escrevemos na guerra.


A estrutura física e a tração

 
Para mover o robô usamos dois motores de vidro elétrico. Na ponta do eixo de cada motor foi soldada uma porca para possibilitar a fixação de parafusos que serviriam de eixo para as rodas.
Um dos quatro pontos de fixação do motor foi serrado para que fosse possível usar rodas menores, que significam maior torque além de fazer com que os motores, parte mais pesada 
do conjunto, fiquem mais próximo ao solo aumentando a estabilidade.
Inicialmente os motores foram presos um ao outro com o uso de barra roscada de 4mm, porcas e arruelas,  então as laterais, feitas em compensado de 4mm, foram fixadas nas barras.
.

 



 

 Como eixo das rodas traseiras foi usado um pedaço de barra roscada presa nas laterais por quatro porcas. A intenção era prender o eixo e deixar as rodas girando livres.

   

Um detalhe importante é a tração nas quatro rodas,conseguida com a utilização de uma corrente e engrenagens do cambio de bicicleta. Uma solução simples porém eficiente.
Como as rodas usadas são de borracha maciça ficou fácil prender as engrenagens nelas com parafusos.










Funcionamento

 A figura ao lado mostra o diagrama lógico simplificado onde é possível ver como funciona o Eniac acompanhando a descrição abaixo.

  • Depois de contado o tempo para iniciar o funcionamento por  TM liga, os motores rodam para frente;
  • Os motores são acionados por dois relés cada como mostrado na figura ao lado. Alimentar as bobinas inverte a rotação do motor;
  • Quando um dos sensores de linha esta SLE ou  SLD  encontra a linha branca este aciona os dois timers que determinam quanto tempo cada motor respectivamente terá sua rotação invertida ou por quanto tempo a procura ao oponente será inibida no caso do timer direito;
  • De tempo em tempo o TM BUSC manda um sinal para inverter a rotação do motor direito fazendo o robô girar em torno do próprio eixo. Antes de chegar ao motor esse sinal passa por um AND com o sinal do sensor de busca e o sinal do timer direito. Se o sensor de busca encontrar algo ele manda 1 que negado, interrompe a procura. A procura também é interrompida quando o sensor de linha direito é acionado, já que se afastar da linha é mais importante que procurar o oponente;
  • As chaves CH1 e CH2  combinadas permitem alguns modos de funcionamento mostrado abaixo.

A montagem da lógica

Não poder usar microcontrolador foi o meu maior desafio. Depois de varias tentativas, simulando a associação de portas lógicas em um simulador da CLP Zelio, onde você arrasta e solta blocos lógicos. Percebi a possibilidade de fazer blocos lógico físicos com os CIs de portas lógicas e o TIMER 555 e, através de jumper, alteras a “programação” do robô o quanto fosse necessário. Disso também surgiu a idéia do nome Eniac. - O Eniac foi o primeiro computador eletrônico construído. Nele alterar o programa executado significava fazer uma reorganização de jumpers e chaves.

A idéia foi montar pequenas placas, uma contendo um CI porta NOT outra placa com um CI de porta OR, outra com a porta AND e outras quatro com timers tendo como base o LM555.
Blocos lógicos

Os potenciômetros dos timers ficam na parte de cima do robô possibilitando alterações de seu comportamento até mesmo nos intervalos das lutas.

O robô deveria esperar 5 segundos antes de começar funcionar. Para isso foi usado um dos timers que recebe um pulso negativo assim que o interruptor geral do Eniac é ligado, o que mantém sua saída em nível alto pelo tempo determinado por seu potenciômetro. Esta saída negada aciona através de  transistores  três reles,  dois  ligados  em
Time
paralelo para alimentar o circuito de força. Após o tempo determinado a saída do timer volta a zero o que iria desenergizar os reles, isso não acontece por causa do terceiro relé, que serve como contato de retenção mantendo o conjunte de reles acionados até que a chave geral seja desligada.


Outros detalhes

Para fixar a parte eletrônica foram usadas barras roscadas na vertical e placas quadradas  de compensado de 4mm de espessura e 18cm  de lado. A bateria usada, Lipo 2200 mAh , foi colocada em cima dos motores de forma que ficasse fácil troca-lá pela reserva caso fosse necessário. Logo acima da bateria na primeira plataforma ficou a parte de força composta por duas placas com relés (detalhe mostrados acima). A primeira é acionada pelo timer LIGA. Na segunda placa é feito o controle do sentido de rotação dos motores. Na segunda plataforma de baixo para cima estão os blocos lógicos. Todos os timers foram colocados na ultima plataforma, feita em alumínio, presos apenas pelos potenciômetros.

Fico devendo os detalhes sobre os timers e os sensores de linha para uma próxima postagem.


Críticas e comentários construtivos serão sempre bem vindos.




segunda-feira, 11 de outubro de 2010

PICAXE



O sistema PICAXE, como é chamado pelos seus criadores no site oficial,  é um sistema britânico baseado em uma série de PICs da Microchip que possuem de 08 a 40 pinos.  Na prática é um PIC com um firmware como é o caso do Basic Stamp ou do Basic Step. É relativamente barato e muito fácil de ser usado, pois pode ser gravado diretamente graças ao  firmware, não necessitando de
Pinagem do PICAXE-08
gravador, mas de apenas um cabo serial simples. O PICAXE parece ser bom pra quem está começando a usar microcontroladores. O ambiente de desenvolvimento é gratuito e utiliza o BASIC como linguagem além de poder ser programado por fluxograma. O PICAXE mais simples ou mais limitado é o PICAXE-08 que possui oito pinos dos quais cinco podem ser usados como entrada ou saída I/O incluindo ADC (conversor analógico digital) de baixa resolução.

Este site tem um material interessante sobre o PICAXE. (em inglês)
Aqui você pode obter o manual  do PICAXE. (em inglês).

Aqui você tem o software para programar, simular e gravar. Eu instalei mesmo sem ter o chip. Ele é bastante interessante, traz muitos exemplos e a simulação do programa é muito didática. Quando está simulando o software mostra paralelamente o que está acontecendo com seu programa e com os pinos do PICAXE.
Neste site tem um projeto, passo a passo, de um robô com sensor IR usando o PICAXE. (em português).
Estou pretendendo compra um  PICAXE-08M. Depois de testá-lo eu postarei os resultados.

segunda-feira, 27 de setembro de 2010

Arduino tocando xilofone







Essa é minha primeira postagem neste blog. Minha intenção é compartilhar um pouco do que estou aprendendo sobre microcontroladores e outros assuntos relacionados. Contribuições, sugestões e criticas serão sempre bem vindas.


A idéia de fazer o Arduino tocar um xilofone surgiu quase que por acaso. Eu estava vendo alguns vídeos sobre CNC, pois queria construir algo para confecção de placas de circuito impresso, percebi que não seria tão fácil assim. Lembrei então do pequeno xilofone de minha filha de três anos e tive a idéia de fazer com que o arduino o tocasse.


O Arduino


Foto do site arduino.cc
Pra quem ainda não conhece o Arduino. Ele é um hardware livre, você pode baixar o esquema e montá-lo ou comprá-lo pronto de algumas lojas de eletrônica ou até no mercado livre. Ele integra um microcontrolador da Atmel no meu caso Atmega 168, e demais componentes necessários para o funcionamento, inclusive gravação, do microcontrolador. Outra característica do arduino é o bootloader - programa que é executado assim que o arduino é ligado . O Arduino, a depender do modelo escolhido, pode ser conectado ao micro para gravação através da porta serial ou USB. O site oficial http://www.arduino.cc/ disponibiliza gratuitamente o programa para elaboração e gravação do código para o arduino usando uma linguagem baseada em C++. O site trás também muitos tutoriais e exemplos de utilização.

O funcionamento básico

O carro é movido até a primeira nota a ser tocada. Após tocar a primeira nota começa a contar o tempo de intervalo entre esta e a segunda nota enquanto move o carro para tocá-la . Ao se posicionar para tocar a segunda nota verifica se o tempo de interva-lo  foi concluido. Se sim  toca a segunda nota imediatamente, caso contrario aguara a conclusão da contagem de tempo antes de tocar. Esse processo se repete para todas as notas até o fim da música. É importante notar que a capacidade de movimento do conjunto limita o andamento máximo da música.

A estrutura mecânica

                                                                                                                                                                             

A parte mecânica é composta basicamente de rosca sem fim e carro, peças retiradas de  uma velha impressora matricial que eu estava guardando há muito tempo sem saber se um dia serviria para algo. A estrutura onde foi montado o conjunto foi feita em madeira, improvisei rolamentos nas extremidades do sem fim para facilitar o giro. O que eu chamo de carro é o conjunto formado por pequeno cilindro plástico com uma espécie de rosca interna que, quando acoplado ao sem fim se movimenta horizontalmente em função da rotação deste e uma chapa fina de alumínio dobrada de modo à  funcionar como uma mola. Esta chapa carrega uma pequena solenóide retirada de uma antiga secretária eletrônica e a baqueta que é acionada pela solenóide, e retorna a posição de descanso pela força da chapa de alumínio.



A estrutura eletroeletrônica

O motor usado é um motor dc com redução, 24v (por questão de coveniência, no circuito é usada apenas com 12v). Este motor tem a função de girar o eixo sem fim que, por sua vez movimenta o carro até a nota a ser tocada. O sentido de rotação do motor implica no avanço ou retorno do carro. Pra garantir o posicionamento correto do carro para que a baqueta acerte apenas a nota desejada foi usado um potenciômetro como sensor de posição. O potenciômetro foi acoplado extremidade do eixo oposta ao motor através de engrenagens e retorna um valor de 0 a 5v proporcional a posição de seu eixo que, por sua vez é proporcional a posição do carro. O sinal é aplicado a uma entrada analógica do Arduino que converte esse valor para um número entre 0 a 1023 que é usado convenientemente no programa que será mencionado mais tarde. Usando um programinha, no arduino, que lê este valor e o mostra no terminal foi possível, posicionando o carro manualmente, determinar o valor retornado em cada nota. Esse valor é usado para associar a nota a ser tocada à posição do carro.
Para controlar o sentido de rotação do motor foram usados dois relés. Cada relé quando acionado pelo arduino faz o motor gira em um sentido. Um TIP 120 foi adicionado para possibilita o controle da rotação do motor por PWM mas, com os testes prático ficou melhor usar sempre o PWM máximo.


O programa

O programa funciona mas ainda esta longe de ser o ideal. Preciso trocar os vetor int por char usar strlen pra não precisra informar a quantidade de notas da música a ser tocada. Vou tentar também faser alterações para poder enviar a musica via serial no formato MIDI. 

Abaixo você tem o código comentado. A idéia pricipal é a seguinte:
  •  A música é armazenada em  um vetor;
  • As notas são armazanadas neste vetor seguidas do multiplicador do tempo de intervalo entre uma nota e a proxima.   { nota, intervalo, nota, intervalo, ..........};
  •  Para represntar as notas foi usada a notação: C , D, E, F, G, A, B, c  para respectivamente dó (mais grave), ré mi, fá, sol, lá, sí, dó (mais agudo).
  • Como para cada posição do carro é atribuido um valor inteiro. O valor referente a nota a ser tocada é comparado com o valor da posição atual do carro. A partir dessa comparação decide-se o sentido de movimentação do carro.


Código




int C = 1000;  // dó mais grave
int D = 905;
int E = 808;
int F = 710;
int G = 614;
int A = 516;
int B = 417;
int c = 334;  // dó mais agudo

int tempo = 130;    // pausa entre notas
long previousMillis = 0;   // usada para cotar o tempo que o carro leva para ir de uma noa para outra

int potPin = 0;        // pino do potenciometro (usado como sensor de posição)
int baquetaPin = 2;    // pino que acionara a solenoide (ligada abaqueTA)
int esquerdaPin = 3;   // pino do relé sentido horario ( carro para esquerda)
int direitaPin = 5;    // pino do relé sentido antihorario ( carro para direita)
int pwmPin = 9;        // pino PWM velocidade de rotação do motor
 int i=0;
  float soma =0;

float val;

////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
//////////////////// MUSICAS//////////////////////////////////


int qtdNotas = 164;
int quero_ver[195] = {E,1,D,1,C,1,D,1,E,1,F,1,E,1,D,1,E,1,F,1,  
                      G,1,F,1,E,1,F,1,G,1,A,1,G,1,F,1,E,1,F,1,
                      D,4,
                      E,1,D,1,C,1,D,1,E,1,F,1,E,1,D,1,E,1,F,1, 
                      G,1,F,1,E,1,F,1,G,1,A,1,G,1,F,1,G,1,A,1,
                      B,4,
                      c,1,B,1,A,1,G,1,A,1,B,1,A,1,G,1,F,1,G,1,
                      A,1,G,1,F,1,E,1,F,1,D,4,
                      D,1,E,1,F,1,G,1,F,2,E,2,E,1,F,1,G,1,A,1,
                      G,2,F,2,F,1,G,1,A,1,B,1,A,2,G,1,B,4,c,1,
                      B,1,A,1,G,1,A,1,B,1,A,1,G,1,F,1,G,1,A,1,
                      G,1,F,1,E,1,F,1,D,4,E,2,F,2,D,4,C,8,0};
                      
                      
/*int ia_ia_oh[105] =  {F,2,F,2,F,1,C,1,D,2,D,2,C,1,A,2,A,2,G,2,
                      G,2,F,4,
                              F,2,F,2,F,1,C,1,D,2,D,2,C,1,A,2,
                      A,2,G,2,G,2,F,4,
                                      C,2,C,1,F,2,F,2,F,1,C,1,
                      D,3,                
                          C,2,C,1,F,2,F,2,F,1,C,2,D,3,
                                                      C,2,C,1,
                      F,2,F,2,F,1,C,2,D,2,D,2,C,1,A,2,
                                                      A,2,G,2,
                      G,2,F,16,0};*/
                      
                      
                      
                      
 int asa_br[164] =     {C,2,D,2,E,4,G,4,G,4,E,4,F,12,C,2,D,2,E,4,
                        G,4,G,4,F,2,E,10,
                        C,2,C,1,D,2,E,5,G,6,G,2,F,2,E,2,C,3,F,5,E,2,E,2,D,2,D,3,E,6,D,2,D,2,C,2,C,5,
                        
                        C,2,C,1,D,2,E,5,G,6,G,2,F,2,E,2,C,3,F,5,E,2,E,2,D,2,D,3,E,6,D,2,D,2,C,2,C,5,
                        
                        c,1,A,1,B,1,G,1,A,1,F,1,G,1,E,1,F,1,D,1,E,1,
                        C,2,C,2,D,4,C,4,
                        c,1,A,1,B,1,G,1,A,1,F,1,G,1,E,1,F,1,D,1,E,1,
                        C,2,C,2,D,4,C,8};
                   
                   
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////


void setup()
{

  pinMode(potPin, INPUT);
  pinMode(baquetaPin, OUTPUT);
  pinMode(esquerdaPin, OUTPUT);
  pinMode(direitaPin, OUTPUT);
  pinMode(pwmPin, OUTPUT);
  
}

//////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////

void loop()
{
 val = analogRead(potPin);
 int  i ;
 int *aux;
 
 aux = asa_br;
 
 posicione(aux[0]);           // move o carro para primeira nota

 for(i=0;i<qtdNotas; i=i+2)    // toca todas as notas
 tocar(aux[i+2], aux[i+1]);   // chama a função tocar passando a px nota e o tempo
 
}  
   
//////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
   
 
 void tocar(int nota, int pausa)     // função tocar
 {
   
   previousMillis = millis();        // millis retorna o tempo de excução do programa até este ponto
   
   digitalWrite(baquetaPin, HIGH);    // toca a nota
   delay(10);                         //
   digitalWrite(baquetaPin, LOW);     //
  
   posicione(nota);
    
   if( (tempo * pausa) > int(millis() - previousMillis))       // se pausa entre notas for maior que o tempo gasto para
   delay((tempo * pausa) -  int(millis() - previousMillis) );  // mover o carro ate a nota completa a pausa antes de tocar
   
}
 
//////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////


void posicione(int nota)        // posiciona o carro na posição da nota a ser tocada
{
  while(val < nota -5 || val > nota + 5)   // tolerancia da posição + ou - 5
    {


  if(val > nota + 5)             // se o carro estiver a esquerda da nota a ser tocada
  {
  digitalWrite(direitaPin, HIGH);  // move o carro para a direita
  analogWrite(pwmPin,255);         // manda o pulso PWM por 200 microsegundos
  delayMicroseconds(150);          //
  analogWrite(pwmPin,0);           // zera PWM
  digitalWrite(direitaPin,LOW);    // abre relé
  val = analogRead(potPin);        // lê posição
  }
  
  else if(val < nota - 5)    // se o carro estiver a direita da nota a ser tocada
  {
  digitalWrite(esquerdaPin, HIGH);   // move o carro para a esquerda alimenta o relé correspondente
  analogWrite(pwmPin,255);           // manda o pulso PWM 
  delayMicroseconds(150);            // por 200 microsegundos
  analogWrite(pwmPin,0);             // zera PWM
  digitalWrite(esquerdaPin,LOW);     // abre relé
  val = analogRead(potPin);          // lê posição
  }
 
 
}

}