Bubblerob é uma derivação de "Bubble" + "Robot" ou em português literal "Robô Bolha". Surgiu da ideia de reciclar brinquedos de criança "destruídos" (quebrados), e por que não "aprimorar" o referido item?!

     O brinquedo escolhido da vez foi o exibido na Figura 1, uma pistola eletrônica de fazer bolhas de sabão.

                       DSC03085.JPG

                                         Figura 1 - Pistola eletrônica de fazer bolhas se sabão

     Este brinquedo tem um funcionamento muito simples. Ao apertar o gatilho a criança liga o circuito que tem como coração um motor de corrente contínua de 3V de tensão, este motor está encaixado em um aparato mecânico simples mais muito genioso, pois o mesmo, além de gerar o ar necessário para soprar em um arco e fazer as bolhas também faz a sucção do sabão no pote e envia para o arco de bolha, mas para a nossa facilidade essa mecânica pode ficar transparente ao nosso entendimento.

     O brinquedo só precisa atender a dois requisitos para que possamos transformar ele em um "robô bolha":

  1.    A mecânica que sopra o ar e suga o sabão não pode está danificada.
  2. O motor não pode está danificado (Esse item muito dificilmente ira acontecer, em breve explico por )

    Checado os dois quesitos podemos continuar:

     PARTE I

    
Após desparafusar a carcaça e abri-la ao meio o brinquedo ficará semelhante ao exibido na Figura 2.
         DSC03086.png
                                               Figura 2 - Brinquedo aberto ao meio
    
     O gatilho, como exibido, funciona como uma chave liga/desliga, ao pressionar o gatilho ele encosta uma pequena mola na carcaça do motor, fechando assim o circuito e fornecendo energia para o pequeno circuito que é responsável por tocar uma música infantil e acender alguns LEDs.

     ATENÇÃO:
           A mola que funciona como chave está ligada ao polo negativo da bateria (conjunto das 3 pilhas), em outras palavras ela é o terra (GND). O fio amarelo que sega-se a bateria no polo positivo (VCC).
           Motores de corrente contínua não são componentes polarizados, isso significa que não importa qual perna você ligar em qualquer dos polos de uma bateria, inverter esses polos na ligação só mudara o sentido que o motor gira. É de extrema importância manter a configuração de fábrica:
  1. Fará o motor girar umas hélices no sentido correto para a geração do vento que soprará e criará as bolhas.
  2. Se você quiser manter o circuito que toca música e acende LEDs, ele deve receber a tensão nessa configuração, pois nele há componentes que são polarizados, e precisão está corretamente ligados para funcionar e não queimar. (Geralmente nesse brinquedo, é essa placa que danifica e corta/abre o circuito, impossibilitando o brinquedo de funcionar)

    O que eu fiz foi, remover o gatilho e as molas de conexão, cortar todos os fios e remover o circuito que toca a música e acende os LEDs, deixando só o motor, soldei dois fios no motor, um verde e um vermelho, respeitando a configuração original de fábrica, onde convencionei que o verde é o GND e o vermelho é  VCC, e por fim serrei o espaço das baterias.

             DSC03090.JPG
                                          Figura 3 - Brinquedo após remoção.

     PARTE II

     Neste momento é necessário adicionar um segundo motor que desempenhará a segunda função do gatilho, levantar e descer uma aba que fica próxima ao arco de bolha e serve para ajudar na lubrificação com o sabão, está tarefa é de grande importância para o funcionamento do brinquedo.
     Para isso adicionei um mini servo motor 9g como o mostrado na Figura 4, amarrado a uma lixa de borracha para amarrar cédulas de dinheiro e desempenhar a tarefa, para o servo ficar melhor fixado usei também um pouco de massa epóx.

                                            DSC03093.JPG
                                                         Figura 4 - Mini servo motor 9g.

     A "gambiarra" fica como na Figura 5, é um misto de arte e improviso, mas funciona.
           Neste momento temos nosso primeiro item adicional:
                1x - Micro Servo Motor, Custo: ~ R$ 10.00
                DSC03097.JPG
                                             Figura 5 - Mini Servo ligado ao gatilho.

     O funcionamento pode ser visto no Vídeo 1.
 
     Agora toda a mecânica necessária para controlar automaticamente a pistola de bolhas por um Arduino está pronta, vamos passar para as ligações elétricas e a montagem do robô.

PARTE III

     Na Figura 6 você pode ver o esquema elétrico completo do Bubblerob, explicarei ele em detalhes.
         bubblebot_schem.png

                                                Figura 6 - Esquema elétrico do Bublerob


     Vamos começar com o CI (Circuito Integrado) IC1, esse CI é um regulador linear de corrente contínua, para se aprofundar no assunto visite zerokol.com, especificamente este, o LM7805 serve para regular um tensão de 7V até 32V para 5V, o suficiente para acionar todos os nossos motores e ao Arduino, o funcionamento dele é muito simples:

  1. Pino 1 - Tensão de entrada, entre 7V e 32V
  2. Pino 2 - Terra (GND)
  3. Pino 3 - Tensão de saída igual a 5V constantes

      Temos 3 servos motores na nossa aplicação, o detalhe é que dois são "Servo Motor de Rotação Contínua", esses são servos motores que trabalham de uma forma diferente da que foram projetados para funcionar. Todo servo motor é projetado para trabalhar recebendo um sinal de controle e se movimentar a um determinado angulo com precisão, geralmente sua rotação varia de 0 a 120º e mais comumente de 0 a 180º, para transformar um servo motor em um servo motor contínuo você deve hakear ele, qualquer servo pode ser hakeado, para saber mais detalhes e aprender como realizar esse processo, visite Hackeando um Servomotor aqui mesmo no robolivre.org.

     A vantagem de se ter esse tipo de servo motor é que como eles podem agora girar indefinidamente, podemos usar eles nas rodas do nosso robô. O Arduino IDE já vem com uma biblioteca chamada Servo que facilita muito o trabalho dos desenvolvedores, para mais detalhes, visite arduino.cc e quando for explicar o código entrarei mais em detalhes.

     Conectar os servos no Arduino é também uma tarefa simples, servo motores vêm com três fios, o que cada fio faz varia de fabricante para fabricante, por isso é de extrema importância que você quando comprar, antes de ligar procure as especificações exatas dos fios, pois servo motores queimam com muita facilidade se ligados incorretamente. Como exemplo, tenho os servos que usei na aplicação, veja na Figura 7 a correta relação dos fios.

                   content_motor.jpg
                                                 Figura 7 - Pinagem do Servo Motor

     Atenção que os pinos do meu servo motor não correspondem aos do esquema elétrico, então atenção na ligação. Outra ressalva é que deves lembrar que dois dos três servos foram hakeados, mas a pinagem de ligação não se alterou.

    O próximo item a ser discutido é o motor DC de 3V que faz as funções de soprar e lubrificar com sabão o arco de bolhas. Anteriormente nessa publicação já falei muitos detalhes sobre esse tipo de motor, e eles são realmente simples assim, mas no meu circuíto adicionei um transistor NPN (BC338) em série com o motor, esse transistor funciona como uma chave eletrônica para ligar e desligar a bomba.

   Existem dois tipos de transistores, NPNs e PNPs, o funcionamento de um transistor não é nada do outro mundo, mas também não pode ser curtamente explicado, então focarei no transistor que utilizei, como mostrado na Figura 8, o BC338, é um transistor NPN e como ele está posicionado após o motor, dizemos que ele é uma chave que fornece o ground para o motor, devido as propriedades de fabricação deste componente podemos usá-lo para chavear um motor de até 10V e 800mA.

                                    bc338.PNG

                                                  Figura 8 - Transistor BC338 (NPN)

     A lógica de funcionamento é a seguinte, o transistor recebe uma tensão "maior" no coletor (Pino 1), uma tensão "média" na base (Pino 2) e uma tensão "menor" no emissor (Pino 3), desta forma a corrente flui por dentro do transistor, sendo assim uma chave fechada, se eu impor na base uma tensão igual a do coletor ou do emissor a corrente não flui por dentro do transistor, assim sendo uma chave aberta o que desliga o motor da bomba. Significa então que o segredo está em controlar a tensão da base, isso é feito por uma porta digital do Arduino, que tem adicionalmente um resistor de 22R entre o pino do Arduino e a base do transistor, isso evita que quando o sinal for colocado em HIGH (Alto) ele não iguala a tensão do coletor.

     Na realidade existem mais algumas ressalvas que devem ser tomadas para se trabalhar com um transistor e esse circuito que montem só pode ser montado com um motor de até 5V, pois além disso excederíamos os limites do Arduino, pois há também uma relação da corrente imposta na base do transistor para a que passará pelo coletor-emissor, e na maioria das vezes você deve calcular o valor do resistor (o de 22R) corretamente para não danificar o transistor.

     O último a ser explicado é o diodo (1N4001) que está ligado ao pino VIN do arduino. Diodos são componentes polarizados que só conduzem eletricidade se corretamente ligados (Existem alguns diodos especiais que fogem a regra), caso contrário funcionam como uma resistência de valor infinito (Se a tensão exceder o limite do diodo, ele queima) assim bloqueando a condução.

                                                dido-pinout.png

                                                                    Figura 9 - Diodo

     O propósito deste diodo é evitar que o Arduino forneça energia para o sistema, não é uma boa prática drenar energia do Arduino para alimentar componentes externos, principalmente motores, pois se o limite de corrente de um determinado pino ou do todo do Arduino for ultrapassado há um grande risco de danificar o equipamento.

     Como o pino de VIN serve tanto para alimentar o Arduino como para drenar energia, colocar um diodo ligado o anodo (Polo positivo) a saída do regulador de tensão e o catodo (Polo negativo) ao pino de VIN, evita que por exemplo você está com o USB conectado no Arduino (O USB fornece 5V e 100mA ao Arduino, internamente ele escolhe a melhor fonte de energia, que é a bateria, então o pino de VIN está recebendo energia), e desliga a bateria, nesse momento o Arduino passa a ser alimentado pelo cabo USB, que está externo ao nosso circuito, então nosso circuito, se não houvesse o diodo tentaria drenar energia do VIN, que é o que não queremos que aconteça, então o diodo está ali como um componente de segurança.

     Agora que você já entende toda a parte elétrica e a parte mecânica da pistola, tudo que tem que fazer é colocar tudo sobre um chassi com rodas.

PARTE IV

       O Chassi utilizado foi o exibido na Figura 10, ele foi modelado no Blender (Software de modelagem tri-dimensional) e impresso em uma Impressora 3D

content_componentes.JPG

                                              Figura 10 - Itens que formam o chassi

     Realmente importante e necessário para a aplicação são:

2x - Mini Servo Motor

2x - Rodas de carrinho

1x - Rodizio para ser usado como 3º roda.

1x - Arduino

1x - Bateria de no mínimo 7v

1x - Placa de prototipação

1x - Arduino (Na imagem o Arduino Standalone, o usado foi um Arduino Nano)

     Lembrando que estabilidade e precisão nos movimentos não é o foco deste robô, então tudo pode ser montado sobre por exemplo uma folha de papelão resistente. Repetindo, como o chassi não é parte fundamental no projeto, não há necessidade de fazer algo elaborado e robusto, basta fazer algo que rode.

              DSC02095.JPG

                                 Figura 11 - Chassi montado, simples e útil

     Por fim, usei um arame para juntar ao chassi a pistola, uma protoboard e as pilhas, e ficou assim


                               DSC02096.JPG

                                                Figura 12 - Robô montado

PARTE V

     Por fim o código para rodar a aplicação:

#include  

// Objetos para manipular os servo motores
Servo rodaDireita, rodaEsquerda, gatilhoDeBolha;

const int chaveDasBolhasPin = 8; // Pino que acionará o transistor
const int rodaDireitaPin = 3; // Pino da roda direita
const int rodaEsquerdaPin = 4; // Pino da roda esquerda
const int gatilhoPin = 5; // Pina do servo do gatilho

const byte VALOR_MIN_INDICE = 0; // Índice classificativo para indicar a menor velocidade de um determinado servo
const byte VALOR_ZERO_INDICE = 1; // Índice classificativo para indicar a velocidade nula de um determinado servo
const byte VALOR_MAX_INDICE = 2; // Índice classificativo para indicar a maior velocidade de um determinado servo
/*
Não confundam essas velocidades como as que são medidas por exemplo 5m/s
A velocidade mínima de um servo motor continuo (HAKEADO) significa que ele irá
rodar no máximo de sua velocidade angular no sentido anti-horário. A nula, ele ficará parado.
A máxima ele rodará no máximo de sua velocidade angular no sentido horário

Para um servo motor normal:
Velocidade mínima ele posicionara-se-a em -90 graus
Velocidade nula, ele posicionara-se-a em 0 graus
Velocidade máxima, ele posicionara-se-a em 90 graus
*/

// Como os dois da roda são HaKEADOS e eles são colocado no chassi invertidos, a lógica de velocidade de um
// é a inversa do outro
const int rodaDireitaVelocidades[3] = {0, 90, 180};
const int rodaEsquerdaVelocidades[3] = {180, 90, 0};

// Para o servo normal, do gatilho, são colocadas apenas as posições desejadas para ele executar o trabalho,
// como você pode ver no vídeo, pois não há necessidade de movimentos maiores
const int gatilhoPosicoes[3] = {90, 55, 20};

// guardara as velocidades das rodas
int velocidadeRodaDireita = rodaDireitaVelocidades[VALOR_ZERO_INDICE];
int velocidadeRodaEsquerda = rodaEsquerdaVelocidades[VALOR_ZERO_INDICE];

// Para fazer curvas vamos usar um esquema de proporção, cada roda tem a sua,
// vai -100% a 100%, é significam dobrar ao máximo para esquerda e direita
// e isso nas proporções intermediária (ex: 36%, -79%)
int porcentagemDobraRodaDireita, porcentagemDobraRodaEsquerda = 0;

// cada ação se repetira em um determinado ciclo no programa, para isso
// temos que guardar quando elas ocorreram
unsigned long tempoDeAcaoRodas, tempoDeAcaoBolhas, tempoDeAcaoGatilho;

// marca se determinada ação ocorreu
boolean bolhasLigadas, gatilhoDisparado;

// Função que desligará o motor DC, consequentemente o robô não fará bolhas
void ligarBolhas(){
digitalWrite(chaveDasBolhasPin, LOW);
bolhasLigadas = true;
}

// Função que ligar o motor DC, consequentemente o robô fará bolhas
void desligarBolhas(){
digitalWrite(chaveDasBolhasPin, HIGH);
bolhasLigadas = false;
}

// Função para acionar o servo do gatilho e posicionar na sua marca máxima
void dispararGatilho(){
gatilhoDeBolha.write(gatilhoPosicoes[VALOR_MAX_INDICE]);
gatilhoDisparado = true;
}

// Função para acionar o servo do gatilho e posicionar na sua marca mínima
void soltarGatilho(){
gatilhoDeBolha.write(gatilhoPosicoes[VALOR_MIN_INDICE]);
gatilhoDisparado = false;
}

// Função para fazer o robô andar, a velocidade vai de -100% (ré) a 100% (macha a frente)
void acionarMotores(int velocidade){
if(velocidade < -100 || velocidade > 100){
velocidade = 0;
}

// controlar os servos e mais simples desta forma, e quem faz a mágica é essa função matemática
// v = Vmin + ((Vmax - Vnula) * (velociddeDesejadaEmPorcentagem / 100))
// é bem simples é faz nada mais que uma média setorizada por porção
velocidadeRodaDireita = rodaDireitaVelocidades[VALOR_ZERO_INDICE] + ((rodaDireitaVelocidades[VALOR_MAX_INDICE] - rodaDireitaVelocidades[VALOR_ZERO_INDICE]) * ((float) velocidade / 100.0));
velocidadeRodaEsquerda = rodaEsquerdaVelocidades[VALOR_ZERO_INDICE] + ((rodaEsquerdaVelocidades[VALOR_MAX_INDICE] - rodaEsquerdaVelocidades[VALOR_ZERO_INDICE]) * ((float) velocidade / 100.0));

imprimirVelocidades(); // Explico em breve
}

// Função que faz o robô fazer curvas, a curva vai de -100% (tudo a esquerda) a 100% (tudo a direita)
void fazerCurva(int angulo){
if(angulo < -100 || angulo > 100){
angulo = 0;
}

if(angulo < 0){
// Se o angulo for menor que 0, basta modificar apenas a roda esquerda
angulo = angulo * -1; // Converter para um valor positivo e não atrapalhar a equação
// c = (Vmax - Vnula) * (1 - (anguloDesejado / 100))
porcentagemDobraRodaEsquerda = (rodaEsquerdaVelocidades[VALOR_MAX_INDICE] - rodaEsquerdaVelocidades[VALOR_ZERO_INDICE]) * (1- ((float) angulo / 100.0));
}else if(angulo > 0){
// Se o angulo for maior que 0, basta modificar apenas a roda direita
// mesma equação
porcentagemDobraRodaDireita = (rodaDireitaVelocidades[VALOR_MAX_INDICE] - rodaDireitaVelocidades[VALOR_ZERO_INDICE]) * (1- ((float) angulo / 100.0));
porcentagemDobraRodaEsquerda = 0;
}else{
// Se zero, significa seguir em frente
porcentagemDobraRodaDireita = 0;
porcentagemDobraRodaEsquerda = 0;
}

imprimirVelocidades(); // Explico em breve
}

// Está função agrega as duas variáveis que criamos, velocidade e porcentagem de curva para compor o movimento do robô
void imprimirVelocidades(){
rodaDireita.write(velocidadeRodaDireita + porcentagemDobraRodaDireita);
rodaEsquerda.write(velocidadeRodaEsquerda + porcentagemDobraRodaEsquerda)
}


void setup() {
pinMode(chaveDasBolhasPin, OUTPUT); // A chave que aciona o transistor como saída
desligarBolhas(); // Desligar o motor DC

rodaDireita.attach(rodaDireitaPin);
rodaEsquerda.attach(rodaEsquerdaPin);

gatilhoDeBolha.attach(gatilhoPin);
dispararGatilho(); // Iniciar o gatilho

randomSeed(analogRead(0)); // Essa função cria uma semente apropriada para geração de
// Números aleatórios realmente serem aleatórios, evitando que a cada execução
// tenham os mesmos conjuntos de números, a dica é pegar a semente de uma porta analógica sem uso, ex: a 0

delay(2000); // Tempo para ligar o robô e por ele no chão

tempoDeAcaoRodas, tempoDeAcaoBolhas, tempoDeAcaoGatilho = millis(); // Inicializar os tempos das tarefas
}

void loop() {
// A cada 3 segundos o robô fara uma nova composição de movimentos, todos aleatórios
if( (millis() - tempoDeAcaoRodas) > 3000 ){
int velocidadeRandomica = random(200) - 100;
acionarMotores(velocidadeRandomica);

int anguloRandomico = random(300) - 100;
fazerCurva(anguloRandomico);

tempoDeAcaoRodas = millis();
}

// Hora ou outra eu ligo e desligo o motor DC
// A cada 7 segundos eu desligo, e após 2 segundos
// ligo novamente
if(bolhasLigadas == true){
if( (millis() - tempoDeAcaoBolhas) > 7000 ){
desligarBolhas();
tempoDeAcaoBolhas = millis();
Serial.println("bolhas desligadas...");
}
}else{
if( (millis() - tempoDeAcaoBolhas) > 2000 ){
ligarBolhas();
tempoDeAcaoBolhas = millis();
Serial.println("bolhas ligadas...");
}
}

// Essa tarefa é muito importante, pois o gatilho é
// responsável por lubrificar o cilindro que gera as bolhas
// a cada 3s, eu solto o gatilho (apertei no setup) e após
// 1 segundo puxo novamente
if(gatilhoDisparado == false){
if( (millis() - tempoDeAcaoGatilho) > 1000 ){
dispararGatilho();
tempoDeAcaoGatilho = millis();
Serial.println("gatilho disparado...");
}
}else{
if( (millis() - tempoDeAcaoGatilho) > 3000 ){
soltarGatilho();
tempoDeAcaoGatilho = millis();
Serial.println("gatilho livre...");
}
}
}

     Isso é tudo que seu robô precisa para ficar rodando aleatoriamente e fazendo bolhas para suas crianças e seu cachorro brincar.

DSC03100.JPG


Atividades recentes