Uma vez mais na Campus Party São Paulo um desafio para criação de robôs autônomos e criativos foi laçado, mas neste ano há mais um desafio, quem leva o robô mais legal e feito de materiais que são desprezados como lixo . Desta vez a equipe da Cajuina Labs decide participar destas competições.

O Material

Foram fornecidos alguns componentes e muitas ferramentas para trabalhar na construção destes robôs:
IMG_2534.JPGWebcam.png

Obs:. Está é a lista inicial, mais alguns itens foram somados, como você verá ao longo da postagem!

1x Bateria de Polímero de Lítio, 2 células, 7.4v, 2200Ah;
3x Light Dependent Resistor, popular Sensor de Luz LDR;
2x Mini Servo Motores da HobbyKing, HK15138, 38g, 4.3kg, 0.17s, 4.8v~6v;
1x Sonar Trigger/Echo HC-SR04;
1x Infra Red, Sharp 2Y0A02 F;
10x Braçadeiras de plástico;
10x Parafusos de 3,3cm  e 0.6cm de diametro;
1x Terceira Roda;
50x Jumpers, tamanhos e cores variadas;
1x Arduino Duemilanove + Cabo USB;

Obs:. Nosso robô foi construído 100% com peças e ferramentas cedidos no evento.

As Competições

Como nossa ideia é construir um robô que seja capaz de participar de duas competições:

Desafio de Robótica Livre - Construir um robô autônomo que navegue por um labirinto encontrando o maior foco de luz que está dentro do mesmo.

Concurso Leve Seu Robô - Construir um robô inteligente feito de materiais descartados (LIXO).

Mais material

Então, recolhemos alguns materiais que ajudariam nesta tarefa de alguns lixeiros devidamente posicionados no pavilhão da Campus Party:

IMG_2535.JPG


Obs:. Todos estes materiais abaixo podem ser facilmente substituindo por outros materiais de mesmo propósito.

3x Latas de refrigerante, Variados;
2x Latas de energético, Variados;
1x Espuma de envolver NoBreak;
3x CUP Noodles, 2 do lixo e um de um cara que estava vendendo;
1x Copinho de café;
10x Ligas elásticas de segurar fios;
1x Liga elástica de segurar dinheiro;
4x Tampinhas de garrafa D'Agua;
1x Suporte de loja que o alicate vem de loja;

Então, como falou o Henrique (Um dos organizadores) na abertura da competição, hora de mandar brasa.

O Projeto

Na montagem do projeto veio a primeira dificuldade: Eu tenho 1x IR e 1x Sonar, dois ótimos sensores de distância, porem só com eles dois não há como fazer uma navegação com um coeficiente de segurança aceitável.
Então fui até a organização para negociar, ofereci o nosso 1x Sensor de IR por um Servo Motor, então por gentileza a organização na pessoa do Frederico (Outro organizador) me cedeu:

1x Micro Servo motor da Hobby King,  HK15148, 17g, 2.5kg,  0.14s, 4.8v~6v;
+ 1x Light Dependent Resistor, agora tenho 4x LDR

Um servo menor que os outros dois, mas perfeito para o nosso propósito, acompanhe o projeto:sketch.jpg

Não sei se dá para entender perfeitamente, então vou detalhar:

Com os 2x Mini Servos (Contínuos) e o 1x 3º Roda deve ser feita a mecânica de locomoção, com os dois servos controlados pelo Arduino.

Os 4x LDR devem ser posicionados um na frente, um atrás, um na esquerda e um na direita.

Um sensor de distância (Não decidimos ainda qual o melhor para a aplicação se o Sonar ou o Infra Vermelho) deve ser acoplado no 1x Micro Servo na parte superior do robô para que ele meça as distancias laterais e frontais. (Obs:. Inicialmente havia pensando em um Motor de Passo fazendo esse trabalho, pois com ele teria maior precisão e poderia medir a distancia em todas as direções)

A 1x Bateria de PL deve ser guardada em um compartimento traseiro feito de lata de Red Bull, e o1x Arduino deve ser montado no interior do corpo feito de Cup Noodles.

A Montagem

A primeira tarefa de montagem é fazer um Hack dos 2x Mini Servos para que eles possam rodar em rotação contínua, para isso, seguimos o tutorial encontrado aqui na robolivre.org Hackeando servomotor

IMG_2542.JPG
IMG_2544.JPG

Não tem segredo nem dificuldades, é só seguir o passo a passo da postagem quem tudo ira funcionar perfeitamente. Neste caso particular, destes servos o potenciometro é de 5KR então utilizamos resistores de 2.5KR, no nosso caso, para conseguir essa resistência usamos 4x Resistores de 10KR em paralelo, e como são dois motores e duas fiações por motor foram utilizados no total:

16x Resistores de 10KR

Para finalizar o processo das rodas, foram cortadas três latinhas de refrigerante e uma energético (mesma espesura das de refrigerante), com 1.5cm no fundo, e então os unindo em pares para formar as rodas:

IMG_2538.JPG
IMG_2539.JPG

e por fim colando com cola quente um estrelinha que vem acompanhando todo servo motor na roda, para fazer a fixação:

Webcam2.png

Revesti as rodas com uma borracha que encontrei no chão, na área das barracas da CP.

Webcam-1359726686.png

Feito as rodas é a hora de montar o sensores de luz. Primeiramente, para montar um sensor de luminosidade você deve entender o que é e como funciona um LDR.
Como o próprio nome já diz, o LDR é um resistor que dependendo da intensidade de luz que insidie sobre ele, varia sua resistência, para fazer o Arduino medir essa "quantidade de luz" temos que fazer um:

Divisor de voltagem: Colocar dois resistores em serie (Um fixo e Um LDR) e medir a voltagem entre os dois.
volt-div.png
Como mostrado na imagem acima, o R1 é o LDR e o R2 é um resistor fixo, como o Arduino trabalha com 5v, por segurança escolhei um resistor de 10KR para ser o R2 (Mas pode ser bem menos,  por exemplo 500R, como você verá na programação isso tem um impacto). Resumindo, o VCC de 5V vai no LDR o LDR se liga no R2 e o R2 vai no GND, entre os dois, um fio se liga em alguma das portas analógicas do Arduino. Para determinar a voltagem (Que irá variar de acordo com a quantidade de luz sobre o LDR) podemos usar a formula da imagem. Mais detalhes serão dados em breve na montagem do código.

Como conectar na placa:

ldr-arduino.jpeg

Função de leitura do LDR:

int readLight(int pin){ // Passo o pino ANALOGICO que o LDR está conectado
unsigned int total = 0; // soma de todas as distâncias nas iteracoes

// LIGHT_NUM_READING - É a quant. de iterações para fazer a média. Ex:. 10
 for(int i=0; i < LIGHT_NUM_READING; i++){
total = total + analogRead(pin);
delay(lightReadPERIOD); // Um pequeno delay para aumentar a precisão. Ex. 25 ms
}
return (total / LIGHT_NUM_READING); // Média aritmética
}

Compreendendo isso, montamos os 4x LDR mais 4x resisteores de 10KR , os LDR foram montados dentro de quatro tampinhas de água, uma tentativa de deixar o sensor mais direcional, tentando evitar focos de luzes indesejados.

2013-01-31%252009.12.52.jpg


Lembrando que eu já havia utilizado 16x resitores de 10KR que somados com mais estes x4 ficam:

agora são 20x Resistores de 10KR

Bem, chegou a hora de montar as peças que já foram construídas em uma base, como não encontramos nenhum material nos lixeiros da Campus Party que fosse suficientemente duro e passível de trabalhar para sustentar nosso robô, recorremos ao ACRILICO que foi fornecido as equipes para que montassem seus robôs.

Cortamos um circulo do tamanho da "boca" do copo de Cup Noodles e pequenas peças que foram coladas com cola quente para então fixar os 2x Mini Servos e a 1x Terceira Roda, como pode ser visto nestas foto:

IMG_2547.JPG

IMG_2549.JPG

Uma lata de Red Bull foi cortada em um tamanho adequado para guardar a bateria e a fiação, então colada ao copo de Cup Noodles.

2013-01-31%252009.30.34.jpg

O passo seguinte foi fixar os 4x LDR na estrutura.

IMG_2552.JPG


Chegou a hora de montar o sensor mais importante, o que medirá a distância. Como mencionado antes, estávamos em dúvida se usaríamos o Infra Vermelho ou o Sonar. A prova a qual seremos submetidos é um pequeno labirinto que possui uma lâmpada no final. Como a lâmpada é muito forte, e emite ruido de infra vermelho, escolhi o sonar. Isso não quer dizer que ele seja livre de ruídos, a pesar do sonar trabalhar em uma faixa de frequência fixa e bem incomum, as palmas da platéia por exemplo, podem  interferir.

Para posicionar o sensor na parte superior do robô, cortei o copo de Cup Noodles e fixei o 1x Micro Servo (NÃO HACKEADO).

IMG_2588.JPG

Construí uma estrutura em forma de "L" feita de colheres de plástico para mexer café então fixei o sonar na frente, desta forma eu posso controlar a direção do meu sensor com o servo, e medir em varias direções, veja:

Como conectar o sonar ao Arduino:

sonar-arduino.png 

O sonar que recebemos possui duas caixas que é bem mais confiável de se trabalhar usaremos uma como ECHO e outra como TRIGGER: O de TRIGGER irá emitir a onde sonora, e o de ECHO para receber o pulso, e então calcular a distância pelo tempo de propagação do som.
Código:

// Variaveis dos Servo Motores
const int HEAD_PIN = 3;
const int RIGHT_WELL_PIN = 6;
const int LEFT_WELL_PIN = 5;

// Em um servo motor normal, quando passo servoVar.write(x), x é o ângulo de rotação
const int HEAD_TO_LEFT = 180;
const int HEAD_TO_FRONT_LEFT = 135;
const int HEAD_TO_FRONT = 90;
const int HEAD_TO_FRONT_RIGHT = 45;
const int HEAD_TO_RIGHT = 0;
// tenho cinco direções de rotação

const int HEAD_D_LEFT = -1; //Para indicar q a última leitura foi da direita p esquerda
const int HEAD_D_RIGHT = 1; // Inverso
int headLastDirection = HEAD_D_RIGHT;
// Variaveis doSonar
const int SONAR_NUM_READING = 10; // Num de leituras para fazer uma media, evitar ruidos
const int ECHO_PIN = 7;
const int INIT_PIN = 8;
const int SONAR_PERIOD = 50;
unsigned long distances[5] = {
10, 10, 10, 10, 10}; // Cinco direções cinco distancia, em cm
unsigned long distancesReadAt = 0;
const long DISTANCES_READ_EVERY = 5000;
const int TO_CM_CONSTANT = 58;
// indices para saber qual direção pertence a qual posição no array
const int SONAR_LEFT = 0;
const int SONAR_FRONT_LEFT = 1;
const int SONAR_FRONT = 2;
const int SONAR_FRONT_RIGHT = 3;
const int SONAR_RIGHT = 4;
void readDistances(){
switch(headLastDirection){
case HEAD_D_LEFT: // Se última leitura direita para esquerda, então
head.write(HEAD_TO_LEFT);
distances[SONAR_LEFT] = readSonar();

head.write(HEAD_TO_FRONT_LEFT);
distances[SONAR_FRONT_LEFT] = readSonar();

head.write(HEAD_TO_FRONT);
distances[SONAR_FRONT] = readSonar();

head.write(HEAD_TO_FRONT_RIGHT);
distances[SONAR_FRONT_RIGHT] = readSonar();

head.write(HEAD_TO_RIGHT);
distances[SONAR_RIGHT] = readSonar();

headLastDirection = HEAD_D_RIGHT;
break;
case HEAD_D_RIGHT: //Se última leitura esquerda para direita, então
head.write(HEAD_TO_RIGHT);
distances[SONAR_RIGHT] = readSonar();

head.write(HEAD_TO_FRONT_RIGHT);
distances[SONAR_FRONT_RIGHT] = readSonar();

head.write(HEAD_TO_FRONT);
distances[SONAR_FRONT] = readSonar();

head.write(HEAD_TO_FRONT_LEFT);
distances[SONAR_FRONT_LEFT] = readSonar();

head.write(HEAD_TO_LEFT);
distances[SONAR_LEFT] = readSonar();

headLastDirection = HEAD_D_LEFT;
break;
}
}

Mas o grande segredo de como um sonar deve trabalhar com o Arduino está aqui:

unsigned long readSonar(){
unsigned long total = 0; // soma de todas as distancias nas iteracoes
unsigned long pulseTime = 0; // pulse em Microsegundos

// SONAR_NUM_READING - É a quant. de iterações para fazer a média. Ex:. 10
for(int arrayIndex=0; arrayIndex < SONAR_NUM_READING; arrayIndex++){
// send 10 microsecond pulse
digitalWrite(INIT_PIN, HIGH); //Enviando pulso
delayMicroseconds(10); // Espero por 10 micro segundos
digitalWrite(INIT_PIN, LOW); // Parar de enviar pulso

pulseTime = pulseIn(ECHO_PIN, HIGH); // Aguardo por pulso no echo

total = total + (pulseTime / TO_CM_CONSTANT);
/* Para converter para centimetro, dividir pela constante de conversao do ambiante
e soma com o total.
UM IMPORTANTE DETALHE NO VALOR DESTA CONSTANTE, É QUE ELA DEPENDE DA TEMPERATURA
AMBIENT E HUMIDADE DO AR, PARA CONDIÇÕES NORMAIS (TEMP ENTRE: 30ª E 40º E CLIMA
SECO, USO 58;
*/

delay(SONAR_PERIOD); // delay para evitar reverberacao
}

return (total / SONAR_NUM_READING); // retorna a media
}

Bem, feito isso, chegou a hora de ligar tudo na carcaça, decidi ligar a força de todos os servos atreves  de um CI regulador de voltagem, então a direção da prova me cedeu 3x L7805 e 6x Capacitores de Poliester de 100nanoF, para eliminar o ruido na corrente.

Este CI é muito fácil de se trabalhar, Olhando ele de frente, ponha a voltagem de entrada (Até 24V) no pino 1 conecte o pino 2 ao Terra e o pino 3 sairá a voltagem regulada em 5V com uma variação máxima de 2% para mais ou para menos.


IMG_2581.JPG

Esquema de ligação dos servos ao Arduino:

servo-arduino.jpeg 

Lembrando que o VCC e o GND vem do CI REgulador, isso evita que toda a corrente seja drenada direto do Arduino, para proteger os dois.

Agora só falta ligar a bateria ao Arduino para a parte ELÉTRICA e MECâNICA ficar completa.

Vamos para a lógica da programação:

Para resolver o problema do labirinto, adotei uma técnica chamada de ESTRATÉGIA GULOSA, vejamos:

void loop(){
timeToNow = millis();
// Iniciar processo após 5s de
if(timeToNow > PROGRAM_STARTS_BEFORE and run == true){
c2w.forward(45); //Ir em frente

readDistances(); // Ler distâncias

if(distances[SONAR_FRONT] < 25 and distances[SONAR_FRONT] > 0){
c2w.stop(); // Parar para analizar
readDistances(); // Ler distâncias
readLights() // Ler direção da luz
if(lights[RIGHT_LDR_PIN] > lights[LEFT_LDR_PIN]){ // Decide o lado para dobrar
c2w.bend(90); // dobrar para direita em 90 graus
}else{
c2w.bend(-90); // dobrar para a esquerda em 90 graus
}
}
// critério de parada
if(distances[SONAR_FRONT] < 25 and lights[RIGHT_LDR_PIN] > 700){
run = false;
}
}
delay(PERIOD);
}

Explicando rapidamente, o robô segue o sabirinto, analiza as distancias das paredes e direção da luz, escolhe um lado para dobrar, essa estratégia se repete até ele atingir o critério de parada.

Notem que usei uns comandos, por exemplo:

c2w.bend(-90); // dobrar para a esquerda em 90 graus

Isso é uma biblioteca que fiz para facilmente controlar um robô com rodas de Servo Motores, mais informações podem ser encontrada em: ZeRoKoL.com

De última hora decidimos por um escudo, para que o robô, se eventualmente encostar nas paredes, deslizar.

IMG_2536.JPG

Cortei uma espuma de embalar equipamentos (Possivelmente de um NoBreak), colei colheres de plástico nas laterais do robô e colei a espuma com uma camada de garrafa PET.

IMG_2643.JPG

Bem, isso é tudo! Agora é ver o que ele consegue fazer na competição!!!

Abraços.

IMG_2591.JPG
IMG_2590.JPG
IMG_2606.JPG

IMG_2642.JPG


Atividades recentes