E10_com_protocoder

Bem-vindo!

Nesta publicação vamos aprender a programar e a controlar um PrintBot a partir de um terminal com a ajuda do Protocoder. Protocoder é uma  ferramenta de prototipagem de aplicações móveis, que permite criar interfaces e programas rapidamente. Protocoder foi desenvolvido por Victor Díaz e podes encontrar informações ou descarregar o Protocoder aqui.

Utilizaremos o Protocoder como o interface que utilizaremos para comunicar com a placa ZUM BT-328 através do Bluetooth, e assim podermos mover o PrintBot Evolution  livremente ou utilizar cada um dos modos automáticos: segue-linhas, segue-luz e esquiva-obstáculos.

Para controlar o PrintBot Evolution utilizaremos dois programas:

  1.  Código Protocoder: armazenará a interface gráfica e as funções encarregadas de enviar os dados para a placa Zum através do Bluetooth do terminal.
  2.  Código Zum BT-328: armazenará a programação do PrintBot Evolution, como por exemplo, os modos de funcionamento ou a comunicação Bluetooth.

Podes descarregar ambos os códigos no final desta entrada. Lembra-te que para executar o código do Protocoder, deverás ter instalado, o Protocoder no teu terminal (podes descarrega-lo aqui).

Código Protocoder

Para ver e modificar o código do Protocoder, em primeiro lugar, acede à aplicação Protocoder a partir do teu terminal e introduz o endereço IP que aparece na parte inferior da janela do navegador web do teu computador. ip_protocoderDescarrega o código no final desta entrada e passa o arquivo printbot_evolution_protocoder.proto para o teu terminal. No teu terminal, com um explorador de arquivos, abre a pasta onde guardaste o arquivo (normalmente está em downloads), clica sobre o código do Protocoder e aparecerá um diálogo. Selecciona open with Protocoder (abrir com Protocoder). Vai abrir-se uma janela. Selecciona a opção Install (instalar). Agora já podes utilizar e modificar o código.

E10_com_protocoder Uma vez que tenhas importado o arquivo .proto, verás o projecto na aba do navegador MY PROJECTS. Clica sobre o ícone e verás o código. Dentro do código podemos distinguir varias partes:

  1. Criar botão de texto: cria um botão com texto dentro dele. É útil para dar mais informação sobre o uso que se tem do botão. Para cria-los, utilizamos um código como este:

    Dentro do código, com var btnSiguelinas estamos a declarar o botão. Teremos que dar um nome distinto a cada botão para que não hajam conflitos. Depois, com ui.addButton dizemos que a variável btnSiguelineas será um botão. Entre parêntesis escrevemos, por ordem, o texto que aparecerá no botão, a posição em X e Y, a largura e a altura do botão. Depois indicamos a função que se activará ao pressionar o botão. Neste caso, envia por Bluetooth a palavra “siguelinas”. (segue-linhas)
  2. Criar botão com imagem

    Com var btn180 estamos a declarar o botão, mas não como no anterior. Neste caso, utilizamos uma imagem em vez de um texto. Depois, com ui.addImageButton dizemos que a variável btn180 será um botão de imagem. Entre parêntesis escrevemos, por ordem, a posição em X e em Y, a largura e a altura do botão e o nome da imagem que queremos que apareça no botão. Depois indicamos a função que se accionará ao pressionarmos o botão (neste caso, envia por Bluetooth a palavra 180). Para adicionar uma imagem ou qualquer outro arquivo, basta arrastar o ficheiro do explorador de ficheiros do teu computador até ao quadro inferior direito. Lembra-te que quanto mais simples for o nome, mais fácil será introduzi-lo no código sem erros. archivos
  3. Criar botões para o Dashboard: Para inclui-los, fazemos do mesmo modo que os botões para o dispositivo, mas em vez de utilizar o prefixo ui, utilizamos o prefixo dashboard. Por defeito, o Dashboard não aparecerá, mas se quiseres que apareça, modifica a línha dashboard.show(false) para dashboard.show(true);.
  4. Funcões para conexão e desconexão do Bluetooth: Estas são as funções incluídas dentro das variables btnConectar e btnDesconectar. Vamos também, criar uma variável com o nome btClient, que utilizaremos para “interagir” através do Bluetooth.
    1. Conectar: Para conectar, em primeiro lugar criamos um botão com o texto “Conectar Bluetooth” e dentro da função que se activará ao pressionarmos o botão, incluímos a conexão para Bluetooth.

      Dentro desta função, além de conectarmos o Bluetooth, dizemos que a variável bluetoothOn (que utilizamos como “sinal” de conexão/desconexão para o bluetooth) tem o valor 1 e alteramos a transparência do botão para 0, que significa, completamente transparente. Vamos também incluir algumas animações, como jump e fazemos com que o dispositivo vibre quando se conectar.
    2. Desconectar: Para desconectar, em primeiro lugar, criamos um botão com o texto Desconectar e dentro da função que se activará ao pressionarmos o botão, incluímos a desconexão para o Bluetooth.

      Dentro desta função, além de desconectarmos o Bluetooth, dizemos que a variable bluetoothOn (que utilizamos como “sinal” de conexão/desconexão do Bluetooth) terá o valor 0 e alteramos a transparência do botão para 255, que significa, opaco.
  5. Função para enviar e receber dados por Bluetooth: A função para a transmissão de dados por Bluetooth é a seguinte:

    Esta função não possui nenhum botão, já que se chamará esta função cada vez que um botão for pressionado (excepto para conectar e desconectar o Bluetooth). Para enviar dados por Bluetooth, utilizamos o comando btClient.send(“=”+str+”+”). Esta função envia, por exemplo, um comando para mover o carro para a frente: =avanzar+ (avançar). Neste caso, realizámos a codificação desta maneira, mas podes experimentar com outro tipo de código. Utilizam-se os caracteres = e + como delimitadores do inicio e do final das transmissões.

    1. Envio de dados por Bluetooth: Para enviar dados através do Bluetooth utilizamos a função send() com um texto entre aspas (por exemplo, se queremos enviar a palavra retroceder utilizaríamos: send(“retroceder”);

Código Arduino

Para ver e modificar o código do Arduino, descarrega o pacote no final desta entrada e pressiona sobre o arquivo printbot_evolution_arduino.ino. Se não tiveres instalado o IDE do Arduino ou outro IDE com o qual possas ler o arquivo, podes descarrega-lo visitando o Curso de programação para makers com Arduino e Protocoder, para veres diferentes IDEs e descarregares o teu preferido. Além disso, poderás aprender mais sobre o Arduino e o Protocoder. Uma vez o ficheiro aberto, é possível distinguir as várias partes do código dentro dele.

  1. Declaração de variáveis e inclusão de arquivos: Declaramos as diferentes variáveis que utilizaremos durante o programa:

    Dentro destas variáveis, utilizaremos algumas para dizer ao Arduino , por exemplo, em que pinos estão conectados as fichas, ou outras coisas como os delays, para modificar a execução do programa. Se os movimentos de rotação não se realizarem correctamente ou quiseres modifica-los para que girem noutros ângulos, podes modificar as variáveis giro_180, giro_90, giro_45 y giro_30.
  2. Setup: Na função setup, uma das que somos obrigados a utilizar no Arduino (tal como a função loop) vamos iniciar o programa e os componentes que o compõem. O código da função setup é:

    Dentro desta função, iniciamos a porta série a uma velocidade de 19200 bauds/s, que corresponde à velocidade a que funciona o módulo Bluetooth da placa ZUM BT-328.
    A seguir, precisamos de: dizer onde está conectado cada servo, parar os servos e colocar o servo com o sensor Bat (sensor de ultrassons) na sua posição central. Por último, com o comando pinMode(pin,mode), definimos os diferentes pinos como entradas (INPUT) ou saídas (OUTPUT) conforme necessário.
  3. Loop: Dentro da função loop (a outra função do Arduino que somos obrigados a utilizar), lidamos com a recepção de dados:

    Dentro desta função, vemos o comando if (Serial.available() >0) que traduzido para linguagem “humana” seria: Se existirem dados na porta série, então prossegue com os seguintes comandos. Neste caso, as ordenes são chamar a función readFromAndroid().. Esta função encarrega-se de ler os dados enviados  pela aplicação Protocoder. O outro comando que aparece no loop é writeData().. Esta função encarrega-se de activar os diferentes modos de controlo (tanto os manuais, como os externos), assim que os dados da função anterior tenham sido lidos.
  4. readFromAndroid();:

    Em vez desta função, poderíamos ter utilizado a função readString(), mas a leitura seria feita mais lentamente, causando que os comandos enviados do Protocoder (no nosso terminal) até ao PrintBot Evolution, chegassem com atraso..
  5. writeData();: Esta função está encarregue de controlar o fluxo do programa, lê os dados que foram recebidos na função readFromAndroid() e realiza um comando ou outro, conforme esses dados recebidos.
  6. Funções de movimento: Estas funções estão encarregues de mover o PrintBot Evolution. Estas funções são: avançar, recuar, parar, esquerda, direita, girar_180_graus, esquerdaLinhas e direitaLinhas. Podemos utilizar estas funções em qualquer momento: apenas temos que chama-las. Por exemplo, para utilizar a função girar_180_graus utilizamos o comando:
  7. Funções de modos: Estas funções usam-se para que o PrintBot Evolution entre nos modos automáticos.
    1. Segue linhas: Neste modo automático, utilizam-se os sensores infravermelhos para detectar se o sensor está em cima de uma linha. Neste modo utilizam-se as funções especiais de movimento, esquerdaLinhas e direitaLinhas que movem apenas uma roda, em vez das duas em direcções contrárias, para realizar o movimento.
    2. Esquiva obstáculos: Neste modo automático, utiliza-se o sensor de ultrassons para detectar objetos e evitar chocar contra eles. O código desta função é:

      Dentro desta função, em primeiro lugar, encontramos as variables izq (esquerda),drch (direita) e cent (centro), que determinam a posição do miniservo que move o sensor de ultrassons. As posições têm que apontar à esquerda, direita e centro respectivamente, mas podes ajustar as posições a outras diferentes ou criar novas posições. A seguir, confirmamos se existem obstáculos na direcção em que aponta o servo, utilizando a função buscaObstaculos() para todas as posições, transmitindo o ângulo que o servo deve apontar, como informação. O código desta função é:

      Dentro desta função podes modificar a distância máxima que utilizaremos para detectar obstáculos, ou seja, qual a distância a partir da qual se encontrarmos um objeto, se considera um obstáculo ou não. Para calcular a distância, utilizam-se as funções auxiliares Distance e TP_init que se encarregam de activar o sensor Bat, enviar um sinal de ultrassons, calcular o tempo que demora a ler o sinal, depois de ter refletido num obstáculo, e depois, de acordo com esse tempo, calcular a distância a que este obstáculo se encontra. Assim que soubermos se temos ou não um obstáculo à nossa frente em cada uma das três posições, podemos mover o PrintBot para uma zona livre.
    3. Segue luz: Este modo automático utiliza-se para mover o PrintBot até uma zona onde a intensidade da luz, seja maior. Para isso, lemos o valor de cada um dos pinos onde estão conectados os módulos LDR (Light-Dependant Resistors, ou em português, Fotoresistência), comparamos os valores, giramos para o lado onde a intensidade da luz seja maior, e movemos o PrintBot em linha recta durante 1 segundo.

Podes ver esta entrada em execução, no seguinte vídeo:

Lembra-te que podes modificar cada um dos parâmetros utilizados, para ajustar o funcionamento do teu PrintBot Evolution ao teu gosto. Propomos-te como exercício:

  • Modifica os ícones da aplicação Protocoder para incluir imagens em vez de texto nos botões.
  • Utiliza os sensores de infravermelhos para detectar precipícios. Podes ver um exemplo de como fazê-lo aqui.
  • Podes criar um botão para que o teu PrintBot mova a cabeça e emita um som.

Se quiseres aprender mais sobre o Arduino, o Protocoder e robótica, podes espreitar o Curso de programação para makers com Arduino e Protocoder