Pessoal, dia 26 e 27 de agosto o ICEx vai receber a III Maratona de Software Livre de Volta Redonda. Entre as atraçōes estão a palestra de abertura do Thadeu Penna, a minha palestra e o meu curso de Introdução ao arduino. Há muitas outras palestras e cursos. Para ver a programação e se inscrever basta acessar:
http://www.iaesmevr.org/maratona2011/
domingo, 21 de agosto de 2011
III Maratona de software livre de Volta Redonda
segunda-feira, 18 de julho de 2011
Projeto: Fazendo o jogo do Pong com o arduino

A imagem acima dá uma idéia melhor de como o jogo funciona. A idéia deste projeto é utilizar dois potenciômetros ao arduino e enviar a posição angular do potenciômetro para o computador através da comunicação serial. Utilizando o processing, vamos ler a porta serial e utilizar os dados recebidos para definir a posição das raquetes. A montagem do circuito é trivial.
O código do arduino é igualmente simples. Vamos ler os valores das portas analógicas e passá-los através da comunicação serial, no seguinte formato: os dois valores dos potenciômetros separados por ";".
void setup(){
Serial.begin(9600);
}
void loop(){
Serial.print(analogRead(A0));
Serial.print(";");
Serial.println(analogRead(A2));
}
Simples assim, sem nenhum mistério. Agora só precisamos fazer o código do processing para receber e interpretar as informações. Não irei colocar muitos comentários sobre o código, se alguém tiver alguma dúvida, pode postar nos comentários que eu respondo.
// Importa a biblioteca de comunicação serial
import processing.serial.*;
Serial myPort; // Cria um objeto
float raio = 20; //Raio da bola
int X, Y; //Posição X e Y da bola
float vx=2, vy=2; // Componentes X e Y da velocidade da bola
float vx0=vx, vy0=vy; // Velocidades iniciais
int p1=0; //Pontuação do jogador 1 e 2
int p2=0;
int x1=15; // Posição X das duas "raquetes"
int x2=785;
float y1=0; // Posição Y das duas "raquetes"
float y2=0;
int tam=100; // tamanho da raquete
String[] vector;
void setup(){
size( 800, 400 ); //tamanho da janela
myPort = new Serial(this, Serial.list()[0], 9600); // Inicia a comunicação com a porta serial 0
PFont f = createFont("SansSerif", 40, true); //Define a fonte utilizada no placar
textFont(f,40);
strokeWeight( 1 ); // Largura das linhas
frameRate( 44 ); // Velocidade dos quadros
X = width / 2;
Y = (height-100) / 2;
myPort.bufferUntil('\n'); //Só inicia quando houver a primeira comunicação serial.
}
void draw(){
background( 255 ); //Define a cor de fundo
////////////////////////////////////////////////////
// Pega as informações recebidas pela porta
// serial e atribui as posições X e Y das raquetes
////////////////////////////////////////////////////
if(myPort.available()>1){
String inString= myPort.readString(); // Lê tudo que foi obtido pela porta serial
String[] teste =split(inString,"\n"); // Divide em linhas
String[] vector = split(teste[teste.length-2],";"); // pega a penúltima e separa num vetor
y1 = float(vector[0]);
y2 = float(vector[1]);
y1 = map(y1, 0, 1023, 0, height-tam-100); // renormaliza pelo tamanho útil da janela.
y2 = map(y2, 0, 1023, 0, height-tam-100);
}
fill( 0, 121, 184 );
ellipse( X, Y, raio, raio );
fill(255,0,0);
rect(x1,y1,-10,tam);
fill(0,0,255);
rect(x2,y2,10,tam);
X+=vx;
Y+=vy;
////////////////////////////////////
// Colisão com as raquetes
////////////////////////////////////
if(X < x1+raio/2 && (Y > y1 && Y < y1+tam)){
X-=vx;
vx*=-1.1;
}
if(X > x2-raio/2 && (Y > y2 && Y < y2+tam)){
X-=vx;
vx*=-1.1;
}
////////////////////////////////
//Fronteiras horizontais
////////////////////////////////
if(X > x2-raio/2 || X < x1-raio/2){
if(X > x2-raio/2){
p1++;
}
if(X < x1-raio/2){
p2++;
}
X = width / 2;
Y = (height-100) / 2;
vx0=-1*vx0;
vx=vx0;
vy=vy0;
fill( 0, 121, 184 );
ellipse( X, Y, raio, raio );
vx=vx0;
vy=vy0;
delay(2000);
}
/////////////////////////////////////////
// Fronteiras verticais
////////////////////////////////////////
if(Y > height-100-raio/2 || Y < raio/2){
Y-=vy;
vy*=-1;
}
/////////////////////////////////////////
// Placar
/////////////////////////////////////////
fill(0);
line(0,height-100,width,height-100);
text("Placar:",10,height-10);
fill(255,0,0);
text(p1, 350, height-10);
fill(0);
text("X",400,height-10);
fill(0,0,255);
text(p2, 450, height-10);
}
segunda-feira, 4 de julho de 2011
Resultado da segunda tarefa.
Bom, mais uma vez o Flávio Alvarenga fez o melhor trabalho. Quem será capaz de fazer um projeto melhor que ele hein? Abaixo segue o diagrama do Fritzing que ele fez e os dois códigos (Arduino + Processing):
Código Arduino
int V[3] = {6,5,3}; // 6, 5 e 3 escolhidas por serem saídas PWM, capazes de emular um sina analógico.
int PotRed = 0; // potenciometro que controla a cor vermelha
int PotGre = 1; // potenciometro que controla a cor verde
int PotBlu = 2; // potenciometro que controla a cor azul
int redVal = 0; //acumula o valor da luz vermelha
int greVal = 0; // acumula o valor da luz verde
int bluVal = 0; //acumula o valor da luz azul
void setup() {
for (int i=0; i<3; i++){ //declara os pinos 9, 6 e 3 como saída
pinMode(V[i], OUTPUT);
}
Serial.begin(9600);
}
void loop() {
redVal = (analogRead(PotRed)/4); // como o valor do potenciometro varia de 0 a 1023 dividindo o valor por 4 obtem-se valores entre 0 e 255* (Pois a variavel e um inteiro).
greVal = (analogRead(PotGre)/4); // Faz a leitura dos potenciometros e iguala ao acumulador da sua respectiva cor.
bluVal = (analogRead(PotBlu)/4);
redVal = map(redVal, 0, 1023, 0,255); //Ajusta o valor lido para ficar no intervalo [0,255]
gredVal = map(greVal, 0, 1023, 0,255);
bluVal = map(bluVal, 0, 1023, 0,255);
RGB(redVal,greVal,bluVal); // chama a função RGB
Serial.print("R");
Serial.println(analogRead(PotRed)/4); //importa para a porta Serial o valor lido na saida analogica 0 e atribui para a cor vermelha
Serial.print("G");
Serial.println(analogRead(PotGre)/4); //importa para a porta Serial o valor lido na saida analogica 1 e atribui para a cor verde
Serial.print("B");
Serial.println(analogRead(PotBlu)/4); //importa para a porta Serial o valor lido na saida analogica 2 e atribui para a cor azul
delay(100);
}
void RGB(int redVal,int greenVal, int blueVal){ // Transmite o valor lido pelo potenciometro para a porta PWM responsavel pelas cores red, green, blue.
analogWrite(V[0], redVal); // Escreve o valor do PWM do led vermelho
analogWrite(V[1], greenVal); // Escreve o valor do PWM do led verde
analogWrite(V[2], blueVal); // Escreve o valor do PWM do led azul
}
No código arduino ele definiu uma função chamada RGB() que define a cor do LED. Poderia ter feito uma função para mandar os dados para a porta serial.
Código Processing:
import processing.serial.*;
String buff = "";
int rval = 0, gval = 0, bval = 0;
int NEWLINE = 10;
Serial port;
void setup()
{
size(800, 800);
// Imprima uma lista no caso de a COM1 não funcionar
println("Portas seriais disponíveis:");
println(Serial.list());
//port = new Serial(this, "COM1", 9600);
// Use a primeira porta disponível
port = new Serial(this, Serial.list()[0], 9600);
}
void draw()
{
while (port.available() > 0) {
serialEvent(port.read());
}
background(rval, gval, bval);
}
void serialEvent(int serial)
{
// Se a variável "serial" não for igual ao valor de um caracter
// nova linha, inclua o valor à variável "buff". Se for igual,
// guarde o valor do buffer na variável "val".
if(serial != NEWLINE) {
buff += char(serial);
} else {
// O primeiro caractere diz-nos a qual cor se refere
char c = buff.charAt(0);
// Remova-o da string
buff = buff.substring(1);
// Descarte o retorno de carro ao final do buffer
buff = buff.substring(0, buff.length()-1);
// Converta a string para inteiro
if (c == 'R')
rval = Integer.parseInt(buff);
else if (c == 'G')
gval = Integer.parseInt(buff);
else if (c == 'B')
bval = Integer.parseInt(buff);
// Esvazie "buff"
buff = "";
}
}quarta-feira, 29 de junho de 2011
ICExDuino no Youtube
Seguindo os nossos planos de expansão e dominação mundial abrimos um canal no youtube: http://www.youtube.com/ICExDuino
Avisem seus colegas, parentes e até seus inimigos.
Este é o nosso primeiro vídeo, o resultado da primeira tarefa. Quem fez este projeto foi o Daniel "Cayan" e o diferencial foi que ele adicionou um cronômetro ao semáforo. Logo mais vamos colocar o projeto deste semáforo no blog.
domingo, 26 de junho de 2011
Projeto: Usando microfone com o Arduino
Seguindo a série de projetos resolvemos estudar o CI LM386. O LM386 é um amplificador de aúdio de baixa potência. Ele é um CI com oito pinos e a função de cada pino está descrito abaixo. O funcionamento é simples, basicamente, você liga um microfone de eletreto nas portas 2 e 3 e tem o sinal amplificado na porta 5. Lembrando que na porta 2 devemos ligar o GND e na 6 o +5V do arduino.
Para aumentar a amplificação, podemos adicionar um capacitor ligando as portas 1 (+) e 8 (-). Para melhorar a qualidade do sinal, podemos adicionar alguns capacitores e resistores. Na rede há diversos circuitos que mostram como fazer a ligação com o arduino. O que achei mais simples foi esse aqui. Para seguir o padrão do nosso site, fiz o diagrama fritzing do circuito que montamos.
Os capacitores C1, C2 e C3 são capacitores de 10microF e o C4 é de 100nF. O resistor de 10K pode ser substituído por um potenciômetro, o potenciômetro funcionará como um botão de volume.
Este é o esquema para um microfone, o que nós fizemos foi montar dois circuitos iguais a esse e ligar no mesmo arduino. Um microfone foi ligado na porta analógica 0 (como mostrado no diagrama) e o outro ligamos na porta 2.
Abaixo segue o código arduino para enviar o sinal dos microfones para o computador. Enviamos uma string com os valores lido nas duas portas analógicas, separados por ";".
int A0 = 0;int A1 = 2;int var0, var1;int passo=1;void setup(){ Serial.begin(9600);}void loop(){ var0=var1=0; for(int i=0; i var0+=analogRead(0); var1+=analogRead(2); } Serial.print(int(var0/passo)); Serial.print(";"); Serial.println(int(var1/passo));}
// Importa a biblioteca de comunicação serial
import processing.serial.*;
// Cria um objeto para comunicação
Serial myPort;
float xPos = 1;
float yPos0 = 1;
float yPos1 = 1;
float dt=1;
int i=0;
float inY0, inY1;
void setup () {
// Define o tamanho da janela
size(800, 300);
//Conecta-se com o primeiro dispositivo da lista
myPort = new Serial(this, Serial.list()[0], 9600);
// Espera receber o primeiro sinal da usb
myPort.bufferUntil('\n');
// Define a cor de fundo da janela
background(255);
}
void draw () {
// Nada será feito aqui
}
void serialEvent (Serial myPort) {
// Pega a primeira linha recebida na porta serial
String inString = myPort.readStringUntil('\n');
// Se a linha não estiver em branco
if (inString != null) {
// remove os espaços em branco
inString = trim(inString);
// Divide a string num vetor separado por ;
String[] vector = split(inString,';');
// converte para int e muda os limites (map):
inY0 = map(float(vector[0]), 0, 1023, 0, 350);
inY1 = map(float(vector[1]), 0, 1023, 0, 350);
// Desenha as linhas:
stroke(255,0,0);
line(xPos,yPos0, xPos+dt, height - inY0);
yPos0=height-inY0;
stroke(0,0,0);
line(xPos,yPos1, xPos+dt, height - inY1);
yPos1=height-inY1;
// Se chegar no final da janela, volta para o início
if (xPos >= width) {
xPos = 0;
background(255);
}else {
xPos+=dt;
}
}
}
O resultado desse código é um gráfico como este abaixo.
Terceira Tarefa
A tarefa dessa semana é bem simples. Ligar um motor servo ao arduino e utilizar o computador para controlar a posição do motor.
Funções utilizadas:
- analogRead();
- incluir a biblioteca Servo.h;
- map();
- Servo.write();
A explicação de como ligar um potenciômetro ao motor servo está aqui. Na tarefa anterior tem a explicação de como interagir o arduino com o computador.
Nível 2
Conectar dois motores servos no carrinho e fazer ele descrever um quadrado e depois um oito.
sexta-feira, 24 de junho de 2011
Tutorial: Entendendos os transistores.
Existem diversos tipos de transistores: NPN, PNP, FET, MOSFET etc. Neste post vou explicar como funcionam os transistores do tipo NPN e PNP e montar uma ponte-H diferente desta.
Em termos gerais estes dois transistores funcionam como interruptores. Todos os dois possuem 3 conectores: 1-Emissor, 2-Base e 3-Coletor. Na ligação a corrente deve circular no sentido do Coletor para o Emissor. O sinal da base é que vai determinar se o circuito está fechado (passando corrento) ou aberto (sem passar corrente). No transistor NPN, o circuito fica aberto enquanto a tensão na base for 0V e fica fechado se na base houver uma tensão maior que 0V (mesmo uma tensão de mV é o suficiente para fechar o circuito). O transistor PNP funciona ao contrário do NPN (fechado se a Base for igual a 0V e aberto se for maior que 0V).
Não sou um "expert" em eletrônica, basicamente quando preciso de um transistor do tipo NPN eu compro o BC548 e quanto quero um PNP compro o BC558. A regra geral é, transistores do tipo BC54X são NPN e BC55X são PNP. O X é um número qualquer, para cada número existe uma tensão máxima de funcionamento (no caso do BC548 a tensão máxima é 20V). Existem outros detalhes mais técnicos sobre os transistores, mas chega de conversa fiada e vamos para um exemplo prático utilizando arduino. Observe o circuito abaixo:
O transistor P é um transistor PNP e N um NPN. Ao ligarmos esse circuito, o led amarelo, que está ligado ao transistor P, ficará aceso e o led verde desligado. Quando enviarmos um sinal de +5V para a porta 11 (digitalWrite(11,HIGH)) o led amarelo irá apagar e se enviarmos um sinal para a porta 3 o led verde irá acender.
Qual a diferença entre esse tal transistor e fazer a ligação diretamente na porta digital?
A resposta é bem simples, vamos supor que você tenha um motor (corrente contínua) que precise de uma tensão de 12V (como a maioria dos motores) para funcionar. Se você fizer a ligação diretamente na porta digital o motor não irá funcionar, as portas digitais só tem 5V. Então você vai precisar uma fonte externa ligada ao motor e vai querer usar o arduino para controlar o motor.
Um recurso interessante ao se ligar os motores DC é a ponte-H. Ela permite, utilizando duas portas digitais, controlar o sentido de rotação do motor. Um exemplo de ponte-H, utilizando apenas transistores NPN pode ser vista aqui. O que vou apresentar agora é uma outra ponte-H, que utiliza transistores NPN (2x) e PNP (2x).
Uma dúvida comum ao se trabalhar com motores no arduino é como fazer a alimentação do arduino. É muito comum ver alguém ligando um motor na porta digital e o motor não funcionar (principalmente motor servo). Neste diagrama, vou mostrar como devemos ligar o motor a uma fonte de energia externa.
Aqui Q1N e Q2N são transistores do tipo NPN e Q1P e Q2P transistores do tipo PNP. Note que no diagrama não conectamos a porta +5V do arduino, pois a energia virá de uma fonte externa. Contudo, precisamos conectar o GND (ground ou terra) do arduino no GND ou Negativo da fonte externa. Isso serve para informar ao arduino uma referência.
Assinar:
Postagens (Atom)






