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.
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);
}
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 Eniacacompanhando 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 a 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.
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.
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
}
}
}