Conteúdo voltada para os artefatos referentes ao projeto Aspirador do Colégio de Aplicação da UFPE que tem como objetivo construir um robô para o auxílio da limpeza das salas de aula.
Requisitos funcionais:
- Servos Motores Hackeados - desempenhando a função de locomoção. Serão utilizados 2 servos.
- Sensor de InfraVermelho - desempenhando a função de corrigir a tendência ao erro nas curvas para dar continuidade ao trajeto com um menor desvio. Serão utilizados 2 sensores de InfraVermelho.
- Sensor de UltraSom – Acoplado com um servo motor e posicionado na parte superior frontal do robô, ele o auxiliará na navegação de forma que ele saiba a distância ideal pra fazer a curva na posição correta do trajeto.
- Chave do tipo liga/desliga – Com a função de interação do robô com o meio, para ligar e desligar o robô.
- Motor de Corrente contínua – acoplado com as pás eólicas (ventoinha) o motor irá permitir ao robô a função de aspiração. Será utilizado 1 motor de corrente contínua, de potencia ainda não definida.
- Alimentação – ainda indefinida a forma de alimentação, que poderá ser feita por baterias recarregáveis.
Requisitos não funcionais:
- Estrutura física: O robô será feita com placas de náilon para fácil corte
- Locomoção: Rodas, que terá diâmetro e espessura definidos quando decidir a potência do servo motorhackeado que irá utilizar.
- Estrutura de aspiração: ainda não se sabe ao certo como será o projeto físico do aspirador propriamente dito.
- Programação: Utilizar os sensores para saber quando parar e quando virar. Correção de imprecisões: Função do crescimento do erro --- Derrapagem (Corrigido através do servo motor, dos sensores InfraVermelho e dois botões).
Etapa do dia 26 de setembro e 3 de outubro:
Construção do protótipo e teste dos sensores infra-vermelho
Na etapa do dia 26 de setembro de 2012 da construção do “Robô Aspirador” foi idealizada a preparação de um protótipo com objetivo de observar o funcionamento dos sensores infravermelhos. Deste modo será possível identificar previamente os possíveis erros que podem aparecer no projeto final e mais rapidamente estes problemas serem solucionados.
Como a aplicação dos sensores infravermelhos no robô se deve à fatos de alinhamento do mesmo no caminho de aspiração da sala (evitando assim que áreas deixem de ser aspiradas), o protótipo não necessitava de grande complexidade, nem de tamanho e forma idênticos ao aspirador. Foi então cortado um quadrado do mesmo material da construção do robô e os servo-motores hackeados, que já estavam previamente acoplados às duas rodas do robô (atividade realizada no encontro anterior), foram agora encaixados no quadrado serrado.
Para a introdução dos sensores infravermelhos no protótipo foi necessário o uso da furadeira de bancada para a realização de um furo destinado à aplicação de um parafuso (bem pequeno). Após o furo foi necessário fazer o enroscamento do mesmo, de modo que fosse possível a entrada do parafuso e a sua eficácia. Esse enroscamento foi feito posicionando o parafuso no furo em que ele iria ser encaixado e girando-o, de modo que as “curvinhas” do parafuso fossem moldadas no buraco.
Após o preparo do protótipo seguimos para a parte da programação do sensor infravermelho possibilitando-o realizar o devido alinhamento do protótipo, foi a etapa em que encontramos o primeiro problema. Conectamos os sensores infravermelhos ao Arduíno, mas por serem dois sensores não haviam entradas suficientes, foi então necessário o auxílio de uma protoboard pequena.
Na interface Arduíno baseando-se em alguns exemplos já presentes no programa e em informações que pesquisamos montamos a programação inicial. Houve a verificação de erros por parte do programa e não houve identificação. Porém, quando o grupo passou essa informação para o sensor, e aproximávamos um objeto dele nenhuma alteração era identificada, independentemente de um objeto estar rente ao sensor, ou nenhum obstáculo estivesse à sua frente, em ambas as situações o número indicado pelo serial monitor era zero. Ao identificar esse problema fomos em busca do modelo do infravermelho que estávamos utilizando para pesquisar informações sobre a programação deste, atividade que nos foi deixada para que pudéssemos solucionar o problema encontrado.
No encontro posterior, no dia 3 de outubro, resolvemos testar o sensor infravermelho na porta analógica em vez da digital - atividade que foi feita na aula passada onde acabamos encontrando problemas na execução -. Primeiramente, foi elaborado o seguinte código na IDE do arduíno:
int infra1; // declarando a variavel infra1
int infra2; // declarando a variavel infra 2
void setup() { // funçao que so sera realizada uma vez
Serial.begin (9600);
}
void loop () { // funçao que sera realizada repetidamente ate o desligamento do arduino
infra1 = analogRead (4); // declarando que a variavel 'infra1' equivale a leitura da porta analogica 4
infra2 = analogRead (5);
Serial.println ("infra1;" + infra1); // exibir no serial monitor a variavel anteriormente declarada e a palavra 'infra1'
Serial.println ("infra2;" + infra2);
}
Houve verificação de erros e não foi identificado nenhum. Porém quando o código foi passado para a placa o serial monitor não funcionava da maneira que esperávamos.
Descobrimos então que o erro estava na parte final do código:
Serial.println ("infra1;" + infra1); // exibir no serial monitor a variavel anteriormente declarada e a palavra 'infra1'
Serial.println ("infra2;" + infra2);
Por motivo ainda desconhecido pelo grupo, para que acha a execução correta do valor lido pela porta analógica e a palavra "infra1" para que possamos identificar no serial monitor que valor se refere à qual sensor infravermelho, dentro dos parênteses aquele "+" não funcionaria. Foi então feita uma alteração:
Serial.println("Infravermelho 1:"); // printar 'sensor infravermelho 1'
Serial.println(infra1); // printar o valor de infra 1 ja declarado
Serial.println("Infravermelho 2:");
Serial.println(infra2);
Passamos o código para a placa e testando de diversas maneiras (colocando objetos escuros e claros) o funcionamento dos sensores infravermelhos, tudo ocorreu bem.
Tão bem, que pudemos perceber que esse sensor não era o ideal para o próposito do alinhamento do robô, uma vez que este modelo identifica as cores da mesma maneira, independentemente da distância. Apostamos agora no sonar, nosso próximo teste com o protótipo construído.
Etapa do dia 10 de outubro
Etapa do dia 17 de outubro de 2012:
Progamando o sonar junto com o servo motor
Neste encontro nosso objetivo foi testar o sensor sonar junto com o motor servo (o não hackeado) localizado abaixo dele.
Primeiramente elaboramos o código baseado na biblioteca sobre o servo já presente no arduino.
#include
Servo myservo;
int direita = 0;
int frente = 90;
int esquerda = 180;
int pinosonar = 7;
/* acima cria-se variaveis para guardar as posicoes do servo: em nosso caso, a direita equivale a 0 graus, a frente 90 graus, a esquerda 180 graus. Na ultima linha criamos uma variavel para o pino onde o sonar esta, o 7. */
void setup() // tudo que esta aqui dentro so vai se realizar uma vez
{
myservo.attach(9); // atribuimos a variavel 'myservo' o pino 9.
Serial.begin (9600); // iniciamos a conexao
}
void sonar (){
long duracao,cm;
pinMode (pinosonar, OUTPUT); // declarando que o sonar esta como um pino OUTPUT
digitalWrite (pinosonar, LOW); // nao ligar o 'pinosonar'
delayMicroseconds (2); // esperar 2 microsegundos
digitalWrite (pinosonar, HIGH); // ligar o 'pinsonar'
delayMicroseconds (5); // esperar 5 microsegundos
digitalWrite (pinosonar, LOW); // nao ligar o 'pinosonar'
pinMode(pinosonar, INPUT); // tornando agora o sonar um pino do tipo INPUT
duracao = pulseIn(pinosonar, HIGH);
cm = microsecondsToCentimeters(duracao);
Serial.print(cm);
Serial.print("cm, ");
Serial.println ();
/* 'printar' no serial monitor o 'cm' anteriormente declarado junto com a identificacao desse numero, a palavra 'cm' */
}
void loop() { // tudo que está aqui vai se realizar ate o desligamento do arduino
long duracao,cm;
myservo.write (direita); // pede para o servo va para a variavel direita no inicio declarada
delay (1000); // espera 1 segundo
sonar ();
Serial.print("direita: ");
Serial.print(cm);
/* aqui o sonar ira printar o valor que encontrar em sua direita, uma vez que ele esta se movendo junto com o sonar */
myservo.write (frente); // pede para que o servo va para a frente
delay (1000); // espera 1 segundo
sonar ();
Serial.print("frente: ");
Serial.print(cm);
/* o sonar esta printando agora o valor que ele achar da frente */
myservo.write (esquerda); // pede para que o servo va pra a esquerda
delay (1000); // espera 1 segundo
sonar ();
Serial.print("esquerda: ");
Serial.print(cm);
/* o sonar printa aqui o valor que achar de sua esquerda */
}
long microsecondsToCentimeters(long microseconds){
return microseconds / 29 / 2;
}
Verificamos se havia algum erro de sintaxe no código e não houve identificação. Fizemos upload para a placa arduino e tudo ocorreu como planejado com exceção de alguns 'engasgamentos' que esperamos não atrapalhar no decorrer do projeto.
Etapa do dia 24 de outubro
Progamando o sonar, servo motor não hackeado do sonar e os 4 servo motores hackeados das rodas.
Etapa do dia 31 de outubro de 2012
Nessa etapa continuamos o desenvolvimento das informações obtidas com o sonar e o funcionamento do resto do robô.
Para isso, estabelecemos como primeiro objetivo fazer com que o robô parasse de acordo com uma distancia "x" (no teste utilizamos 30 cm), acreditávamos que seria rápido, porém tivemos problemas: o primeiro problema (proveniente da etapa passada - 24 de outubro de 2012) foi a programação, que no primeiro programa, a função sonar não retornava nenhum valor, e o segundo problema foi em relação ao sensor, que parou de funcionar, acarretando em muito tempo gasto até descobrirmos onde o erro estava (na programação ou na parte física do robô).
Resolvemos o primeiro problema colocando um "return cm" na função sonar e mudando o seu tipo para "long", pois desta forma a função sonar passaria a representar um valor, além disso, utilizamos a varável "cm" para guardarmos tal valor, que antes estava presente apenas na "função sonar", deixando assim de ser um "variável local" para uma "variável global". O segundo problema resolvemos apenas com a troca do sensor, por outro do mesmo tipo.
Etapa do dia 7 de Novembro de 2012
Aplicando os dois botões
Na etapa do dia 7 de novembro de 2012 trabalhamos o uso dos dois botões no projeto do aspirador.
Os botões no robô aspirador serão utilizados com objetivo de alinhar o robô após ter dado a curva, de modo que evite o acúmulo de erros ao longo do percurso.
Antes de iniciar com a programação do robô, aplicamos os dois botões ainda no protótipo.
Logo após, identificamos em que pontos do botão 'dava curto' com o multímetro, assim poderíamos fazer a conexão correta dos botões com o arduino.
Passando para a parte de programação, baseando-se na biblioteca do arduino que já possuía um código para botões e então adaptamos o programa para nossos propósitos: quando os dois botões fosse apertados ao mesmo tempo, seria porque o robô estaria alinhado à parede, então foi pedido que as duas rodas ligadas aos servos hackeados parassem (colocando o ponto zero do servo). Enquanto isso não ocorresse, a roda iria continuar a fazer o movimento que estava fazendo após a curva (parte que, por trazer algumas complicações, preferimos deixar para um pouco depois).
#include
int botaopin1 = 5;
int botaopin2 = 6;
Servo servo1;
Servo servo2;
void setup() {
Serial.begin(9600);
servo1.attach(9);
servo2.attach(10);
pinMode(botaopin1, INPUT);
pinMode(botaopin2, INPUT);
digitalWrite(botaopin1,HIGH);
digitalWrite(botaopin2,HIGH);
}
void loop() {
int botaoestado1 = digitalRead(botaopin1); // promover a leitura do botao 1
int botaoestado2 = digitalRead(botaopin2); // promover a leitura do botao 2
Serial.print(" botao1:"); // mostrar no serial monitor se o botao 1 esta ligado ou desligado
Serial.print(botaoestado1); // identificar que 'ligado' ou 'desligado' pertence ao botao 1
Serial.print(" botao2:"); // mostrar no serial monitor se o botao 2 esta ligado ou desligado
Serial.print(botaoestado2); // identificar que 'ligado' ou 'desligado' pertence ao botao 2
delay(1000); // delay de 1 segundo
if (botaoestado1 == 0 && botaoestado2 == 0){ // se o botao 1 e 2 estiverem apertados (0 neste programa correspondeu ao apertado) deve se realizar a seguinte condiçao:
servo1.write (82); // servo 1 vai para seu ponto zero
servo2.write (87); // servo 2 vai para seu ponto zero
}
else { // se a condiçao acima nao ocorrer, realizar a seguinte etapa:
servo1.write (90); // servo motor em velocidade qualquer, apenas um exemplo, so nao pode ser 82, uma vez que ela iria ficar parada
servo2.write (85);
}
}
Etapa do dia 14 de Novembro de 2012
Reestruturação e programação
Na etapa do dia 14 de novembro, durante o encontro foram discutidos alguns temas de grande relevância para o desempenho do robô-aspirador, entre eles, foi o de remontagem e reestruturação de seu sistema de aspiração onde foi decidido fazer algumas mudanças para que ele pudesse trabalhar de forma a obter um maior rendimento. A discussão culminou na decisão de qual seria o melhor filtro para armazenamento de resíduos (poeira e impurezas) que o robô irá capturar durante o seu trajeto, onde as opções seriam o filtro de aspirador comum (em forma de saco) e o filtro parecido com os que são utilizados em aparelhos de refrigeração de ambiente (náilon de fina espessura sobrepostos em posições ortogonais). Para isso, tivemos que repensar qual seria a melhor posição de colocar o motor, filtro, etc. para que o filtro pudesse ser retirado pelo usuário após sua máxima utilização. Então ficou decido uma nova posição para o motor e que o filtro que será utilizado vai ser o de ar-condicionado. As peças que serão utilizadas para fazer a estrutura do sistema de aspiração já foram projetadas e serão cortadas e encaixadas no próximo encontro.
Na área de programação continuamos com o que foi iniciado no trabalho anterior só que agora perfeiçoando o desenvolvimento. Os servos motores tiveram sua posição de “ponto zero” (parada) calibradas para que eles pudessem realmente parar no momento que os botões de alinhamento de posição fossem acionados pelo “choque” com a parede. Feito isso, começamos os testes e percebemos que o desempenho do protótipo estava bastante preciso e então avançamos um pouco mais na programação fazendo agora com que o giro do motor não só parasse, mas também invertesse de sentido quando o protótipo estivesse alinhado com a parede, sendo assim, o robô já estaria executando o movimento de alinhamento e depois prosseguindo com o seu trajeto de aspiração. O plano inicial para o próximo encontro é o de unir o código feito para o sonar (já feito em encontros passados) com o código aperfeiçoado na ultima reunião para que o protótipo desempenhe um movimento agora um pouco mais avançado.
Linhas de código :
Para calibragem dos servos
#include
Servo servo1;
Servo servo2;
void setup (){
Serial.begin (9600);
servo1.attach (9);
servo2.attach (10);
}
void loop (){
servo1.write (81);
servo2.write (85);
}
Para fazer o movimento de ré até o alinhamento com a parede e depois seguir em frente -
#include
int botaopin1 = 5;
int botaopin2 = 6;
int controle = 0;
Servo servo1;
Servo servo2;
void setup() {
Serial.begin(9600);
servo1.attach(9);
servo2.attach(10);
pinMode(botaopin1, INPUT);
pinMode(botaopin2, INPUT);
digitalWrite(botaopin1,HIGH);
digitalWrite(botaopin2,HIGH);
}
void loop() {
int botaoestado1 = digitalRead(botaopin1);
int botaoestado2 = digitalRead(botaopin2);
Serial.print(" botao1:");
Serial.print(botaoestado1);
Serial.print(" botao2:");
Serial.print(botaoestado2);
delay(10);
if (controle == 0){
servo1.write (66);
servo2.write (100);
}
if (botaoestado1 == 0 && botaoestado2 == 0){
servo1.write (81);
servo2.write (85);
controle = 1;
delay (1000);
Serial.print (controle);
}
if (controle == 1){
servo1.write (100);
servo2.write (60);
}
}
Etapa do dia 04 de Dezembro de 2012
Testes e Estrutura
Na etapa do dia 04 de Dezembro encontramos algumas dificuldades no que tange ao processo de testes no protótipo-aspirador.
Como havia ficado acordado, o encontro de hoje seria para a construção de um encoder mecanismo pelo qual se pode “contar” quantos giros a volta dá através de uma relação matemática discutida por nós no encontro passado. Entretanto surgiram alguns obstáculos que fizeram com que perdêssemos muito tempo e assim não foi possível a conclusão do encoder no encontro de hoje.
A primeira dificuldade foi com relação ao sensor de infravermelho, isso porque não conseguíamos encontrar uma posição ideal para o potenciômetro (componente que fica por trás do infra-vermelho que calibra a sua distância ideal para o reconhecimento e diferenciação das cores preto e branco, ou seja, ao girar o potenciômetro nós fazíamos com que o sensor visse o ‘preto’ mais de perto ou mais de longe, entretanto ainda não encontramos uma distância ideal para a percepção das fitas pretas que estão na roda. Após o insucesso com o potenciômetro tentamos verificar se o problema estava acontecendo na comunicação PC-Arduino-Protótipo fazendo testes com os servos motores que já estavam funcionando desde os encontros passados, só que após diversas tentativa de comunicação com os servos eles não apresentavam respostas o que nos fez ficar intrigados e então com ajuda dos monitores começamos a investigar qual era o possível erro e percebemos que o erro se tratava de algo muito simples mas de bastante relevância, acontecia que os motores não estavam ligados ao ‘gnd’ do arduino fazendo com que o arduino não tivesse um parâmetro para comparar com o sinal que estava sendo mandado, dessa forma o erro foi corrigido utilizando um jumper conectando o ‘gnd’ do arduino com o ‘gnd’ do circuito eletrônico, fazendo com que tudo voltasse a funcionar perfeitamente. Dessa forma, já que estávamos nos aproximando do fim do encontro reorganizamos os circuitos e decidimos ver o que podia ser feito na próxima semana para adiantar algumas partes, então, ficou decidido que o infravermelho vai ser reposicionado para mais próximo da roda, para ver se assim ele consegue ‘enxergar’ as fitas pretas e assim iniciar a junção de todos os códigos para que o robô possa desempenhar o percurso planejado completo.
A princípio, o encoder se baseará no código a seguir:
#include
Servo servo1;
int pininfra = 22;
int cont = 0;
void setup() {
Serial.begin(9600);
servo1.attach(25);
pinMode(pininfra, INPUT);
}
void loop (){
if(HIGH == digitalRead(pininfra)){
cont++;
}
if (cont == 10){
servo1.write (81);
}
}
Com relação ao sistema de aspiração hoje foram realizados testes com os três estilos de filtros adquiridos e o motor, de modo a selecionar o que mais se adequa à nossa situação. Por conter uma superfície que possibilita a filtração de partículas menores de sujeira, foi escolhido o tecido tule, facilmente encontrado em lojas de tecidos.
O grupo ainda está averiguando a questão da localização do filtro. No projeto feito no SketchUp e postado no conteúdo, foi apresentado o filtro entre um pequeno espaço entre duas placas, nesse caso, o filtro seria móvel. Outra opção seria colocar o filtro preso ao motor e a poeira que batesse no filtro cairia em uma região na frente deste, uma espécie de 'caixa' que seria móvel.
Também estão sendo cortadas todas as peças que irão compor o novo esquema do sistema de aspiração, reconstruído porque o sistema de filtração também mudou, e este precisaria de certos ajustes no aspirador em geral. Outro objetivo com o corte de novas placas, foi economizar espaço no robô, aproximando o motor da região de comunicação do chão e do aspirador, aumentando sua eficiência.
Etapa do dia 16 de dezembro de 2013
Durante o encontro o objetivo foi iniciar a juntar todos os códigos já realizados pelo grupo de modo a testar todo o funcionamento do protótipo (com exceção ao sistema de aspiração).
Houveram algumas dificuldades ao longo do processo, a fonte apresentou alguns problemas e o código, por motivos desconhecidos até agora, não estava funcionamento de modo adequado. O encoder feito pelo grupo para realizar a volta do robô também não funcionou.
Além de que os servos hackeados não estavam parando quando colocávamos o 'grau' que seria responsável por 'zero', atividade que ainda teremos que sincronizar.
Conteúdo criado na rede antiga por José Pinheiro, Erick Vilela, Manuella Valença e Leonardo Petty.
Ou