Robótica com Android e Arduino

Nesse artigo, pretendo descrever o processo de criação de um robô baseado na plataforma Arduino e integrado ao Android, através da camada de script SL4A.

[ Hits: 87.829 ]

Por: João Victor em 16/04/2014


Programando



O Arduino é uma plataforma de prototipagem livre, baseada em um microcontrolador Atmega, o objetivo do Arduino é facilitar a criação de soluções práticas, desenvolvendo a criatividade dos usuários.

Para programação, é utilizada Wiring, uma linguagem derivada de C/C++, os programas escritos para Arduino são chamados de sketches. Um sketch, apresenta uma estrutura dividida em configuração (setup) e loop, além das funções definidas normalmente, como em C/C++.

Para a criação do sketch do robô, utilizaremos a IDE oficial disponível no site:
O próprio site mostra como instalar a IDE em diversas distribuições.

Para trabalhar com o sensor ultrassônico, é necessária uma biblioteca, disponível em:
Após o download, basta extrair a biblioteca no diretório libraries, dentro do diretório da IDE do Arduino.

Antes de criarmos o código, precisamos nos familiarizar com alguns conceitos:
  • Comunicação Serial :: é o processo de enviar uma informação, bit a bit, sequencialmente. O número de vezes em que um bit pode mudar durante um segundo, é o que chamamos de Baud Rate. Quando enviamos informações de um dispositivo a outro, devemos certificar que eles estejam sincronizados, ou seja, que possuam um mesmo valor de baud rate.
  • Tempo :: em várias partes do código, vamos encontrar a função delay(tempo) nessa função, além de pausar o código durante algum tempo, para que um motor se mova até uma posição, por exemplo. Também permite criar sinais, um tópico de eletrônica que não entrarei em detalhes.
  • Estados: para integração com alguns dispositivos, vamos descer a nível de linguagem de máquina pura, mas, não há o que se preocupar, na maioria dos casos apenas iremos desligar ou ligar algum componente. Para usarmos uma porta com sinal digital, primeiro a definimos como entrada ou saída e depois, definimos seu estado como HIGH (true , 1 ou 5v) ou LOW (false,0 ou 0v). Ainda, há a possibilidade de usarmos PWM, um sinal analógico usado para controlar a potência através do intervalo entre um pulso alto e um pulso baixo.

O principio de funcionamento do robô, é o seguinte:
  • Passo 0: Inicializar todas as funções;
  • Passo 1: Aguardar a interação com o usuário;
  • Passo 3: Realizar a leitura dos dados fornecidos através da porta Serial;
  • Passo 4: Realizar a ação desejada;
  • Passo 5: Se houver dados retorná-los ao usuário;
  • Passo 6: Voltar ao passo 1.

O código abaixo, basicamente, lê três coordenadas:
  • X :: define a direção do robô (esquerda e direita),
  • Y :: sentido do robô (frente e trás)
  • Z :: posição do Servo, que direciona o sensor ultrassônico e retorna à distância lida pelo sensor.

Vamos ao código:

// Algoritmo de controle

//Importacao de bibliotecas

#include // Biblioteca do sensor
#include // Biblioteca do servo


//Pinos usados
// Ponte H
#define pot1Pin 9 //potencia motor1
#define dir1Pin 13 //sentido motor1
#define pot2Pin 10 //potencia motor2
#define dir2Pin 8 //sentido motor2

//Servo
#define servoPin 3 // Servo motor

Servo servo;

//Sensor ultrasonico

#define echoPin 5 // echo - comunicacao com o sensor
#define trigPin 6 // trigger - gatilho para ativar o sensor
#define vccPin 7 // vcc -Alimentacao do sensor

Ultrasonic ultrasonic(trigPin,echoPin);     //Instacia o objeto que controla o sensor


//Variaveis

char buffer[18];
int cordx,cordy,cordz;

void setup() {
 // Configuracao dos pinos (entrada e saida)

 pinMode(dir1Pin,OUTPUT);
 pinMode(dir2Pin,OUTPUT);

 pinMode(echoPin,INPUT);
 pinMode(trigPin,OUTPUT);
 pinMode(vccPin,OUTPUT);

 //Sensor ultrassonico
 digitalWrite(vccPin,HIGH);    // Define sinal alto para servir como alimentacao

 //Definimos um sinal alto por 10ms para ativar o sensor

 digitalWrite(trigPin, HIGH);
 delayMicroseconds(10);
 digitalWrite(trigPin, LOW);

 //Servo
 servo.attach(servoPin);     // Instancia o objeto servo
 servo.write(90);     // Posiciona o servo a 90º


//Comunicacao serial

Serial.begin(57600);     // Inicia a comunicacao serial com 57600 pulsos por segundo
}


//Criamos as funcões que definem os movimentos do robô
//void movimento(){
// digitalWrite(pino,ESTADO); Definimos o estado do motor em HIGH(frente) ou LOW(tras)
// analogWrite(pino,POTENCIA); Definimos velocidade do motor(0-255) usando PWM.



void frente(){
 digitalWrite(dir1Pin,HIGH);
 analogWrite(pot1Pin,0);
}
void tras(){
 digitalWrite(dir1Pin,LOW);
 analogWrite(pot1Pin,255);
}
void parar(){
 digitalWrite(dir1Pin,HIGH);
 analogWrite(pot1Pin,255);
}
void direita(){
 digitalWrite(dir2Pin,HIGH);
 analogWrite(pot2Pin,0);
}
void esquerda(){
 digitalWrite(dir2Pin,LOW);
 analogWrite(pot2Pin,255);
}
void centro(){
 digitalWrite(dir2Pin,LOW);
 analogWrite(pot2Pin,0);
}

//Funcao que retorna a distancia do robo ate o obstaculo
int sensor() {
 delay(30);
 int d = ultrasonic.Ranging(CM);    // Faz a medicao em centimetros
 return d;
}

//Funcao que faz com que o sensor se vire em determinado agulo e retorne o valor da distancia.
int visao(int angulo){
 servo.write(angulo);
 delay(500);
 int distancia = sensor();
 Serial.println(distancia);
 return distancia;
}

// Funcao que separa as coordenas(x,y,x)
void dividir(char* data){
 char * parameter;
 parameter = strtok(data, " ,");
 while(parameter != NULL){
  motor(parameter);
  parameter = strtok(NULL, " ,");
 }
 for(int x=0; x < 16; x++){
  buffer[x]='{TEXTO}';
 }
 Serial.flush();
}

// Funcao que chama as funcoes de acordo com as coordenadas: X=Direcao,Y=Sentido.Z=Posicao do servo

void motor(char* data){
 if ((data[0] == 'x') || (data[0] == 'X')){     // Se o determinante for igual a x ou X
  cordx = strtol(data+1, NULL, 10);     // Coordenada de x recebe o valor que acompanha o detereminante (x255 cordx = 255)
 }
 else if ((data[0] == 'y') || (data[0] == 'Y')){
  cordy = strtol(data+1, NULL, 10);
 }
 else if ((data[0] == 'z') || (data[0] == 'z')){
  cordz = strtol(data+1, NULL, 10);
  visao(cordz);     //Chama a funcao visao e passa a posicao do servo
 }
 if(cordy > 0){
  frente();
 }else if(cordy < 0){     // Coordenada de y > 0 va para frente
  tras();     // Coodenada de y < 0 va para tras
 }else if(cordy == 0){
  parar();     // Coordenada de y = 0 fique parado
 }
 if(cordx > 0 ){
  esquerda();
 }else if(cordx < 0){
  direita();
 }else if(cordx == 0){
  centro();
 }

}

// O loop e onde o programa roda chamando as funcoes

void loop() {
 if(Serial.available() > 0){     //Se houver dados
  int index=0;
  delay(100);
  int numChar = Serial.available();     //Tamanho do buffer
  while (numChar--){     // Enquanto o buffer e maior que zero
   buffer[index++] = Serial.read();     // Buffer recebe caracetere
  }
  dividir(buffer);
  Serial.flush();
 }
}

Após digitarmos o código, devemos fazer o upload para o Arduino e, finalmente, testarmos. No caso, estamos utilizando uma mesma porta Serial para comunicação USB e Bluetooth, então, devemos desconectar o pino 5v do módulo Bluetooth, antes de fazermos o upload.

Após o upload, finalmente, podemos testar. Abrimos o Serial monitor e digitamos x-2, o robô deverá virar as rodas dianteiras para esquerda.

Notem que, em nenhum momento, usamos algo relacionado ao Bluetooth, isso porquê, para usarmos o Bluetooth, devemos apenas conectar o módulo ao Arduino e garantir alguma forma de comunicarmos com o módulo via Serial.

Com cerca de 5 linhas de código em Python, podemos criar uma linha de comunicação entre o Python (SL4A) e Arduino via Bluetooth, assunto à algumas páginas a frente.

Página anterior     Próxima página

Páginas do artigo
   1. Introdução
   2. Montagem do robô
   3. Programando
   4. Bluetooth
   5. Integrando recursos
   6. Aplicação de controle
   7. Conclusão
Outros artigos deste autor

Python com SL4A - A camada de script do Android

Leitura recomendada

OAK: Câmera Open Source de Visão Computacional com AI

Interagindo com servidores HTTP com Python

Criando um leitor de RSS com Python

Python: automatizando a extração de informações na web com expressões regulares

Splash Screen para Inkscape

  
Comentários
[1] Comentário enviado por albfneto em 16/04/2014 - 19:46h

Muito bom isso! favoritado

[2] Comentário enviado por vikitor566 em 16/04/2014 - 23:02h

Muito obrigado albfneto

[3] Comentário enviado por Lisandro em 16/04/2014 - 23:18h

Excelente! Parabéns pelo artigo e pela paciência. Por várias vezes pensei em fazer um artigo semelhante e sei bem o trabalho que dá.
Já está nos meus favoritos.

[4] Comentário enviado por mcnd2 em 17/04/2014 - 13:19h

Muito interessante.

Artigo muito bem explicado e de fácil entendimento.

10!

[5] Comentário enviado por vikitor566 em 17/04/2014 - 14:03h

Muito obrigado a todos, o trabalho é recompensado quando o artigo consegue compartilhar a idéia pelo qual foi feito.

[6] Comentário enviado por Sandro1 em 17/04/2014 - 21:24h

Excelente artigo e como já disseram está muito bem explicado, qualquer pessoa vai conseguir fazer esse robô!

[7] Comentário enviado por k_cesar em 20/04/2014 - 13:52h

Parabéns pelo artigo.
Excelente!

[8] Comentário enviado por matiasalexsandro em 22/04/2014 - 23:56h

excelente artigo favoritado pra projetos futuros

[9] Comentário enviado por vikitor566 em 23/04/2014 - 09:59h

Muito obrigado a todos

[10] Comentário enviado por JFurio em 19/05/2014 - 09:14h

Realmente, nota 10 mesmo ! Cheguei até a estudar um orçamento e ligar em umas lojas para ver uns orçamentos, e realmente não é tão caro ! Vou tentar montar um dia, e independente do resultado, posto aqui ! Vlw !


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts