A montagem que descrevo neste artigo mostra de uma forma simples, como adicionar uma lógica que se parece com sentimentos humanos, aplicados em sistemas robóticos. Conforme visto no artigo desta mesma edição - “Parte Homem, parte Máquina” - temos o fator Silva em que se calcula o grau que uma máquina está entre a total falta de sentimentos humanos e a total semelhança que ela tem com o ser humano.
Para criarmos um robô que se assemelhe aos sentimentos humanos, precisamos de uma lógica de programação, um poder de processamento e uma quantidade de sensores muito grande, mas independentemente da quantidade de recursos, cada sentimento que será implementado numa máquina deverá ser criado e testado separadamente. Por este motivo passo neste artigo a inserção de um único sentimento, ou seja, de um único sensor, e as atualizações e “up grade” ficam a cargo do projetista.
A ideia é tampar os olhos do robô e ele ficar “nervoso”, acendendo um LED RGB no tom vermelho, e caso os olhos do robô fiquem destampados, ele mudará para o azul. É possível imaginar a quantidade de respostas sensitivas que podemos aplicar utilizando um LED RGB.
O que faz o reconhecimento dos olhos do robô serem tampados é um LDR (sensor de luz), aplicado entre os dois olhos falsos no robô (rodinhas). Veja a figura 1.
A parte mecânica
Utilizei neste projeto um motor que vem no kit, de onde retirei a rodinha, pois este motor é mais forte.
Este motor gira um conjunto de engrenagens que servem para redução ou aumento de torque. Além de usar o recurso de engrenagens para aumentar o torque, utilizei o recurso PWM no controle de alimentação do motor.
A montagem das engrenagens está disposta numa estrutura quadrada para que tenha a aparência de uma pequena coruja, que possa ser colocada sobre a mesa ou computador. Caso o leitor prefira, poderá colocar sobre rodas, como foi apresentado no projeto do Robô-Garra. Observe a figura 2.
Notem que os olhos estão presos na última engrenagem, eles ficam girando de um lado para o outro como se estivessem vigiando o local, porém eles giram somente quando o robô tem “vontade” de fazê-lo.
A parte eletrônica
O kit possui o Modelixino, que é composto por uma matriz de contatos unida com um Arduíno (veja nas edições anteriores mais detalhes sobre este equipamento).
Conforme é possível ver na figura 3, temos o circuito eletrônico do nosso robô. Note que o circuito é composto de três etapas. A primeira é o sistema que movimenta os olhos do robô, onde um relé comuta a direção de giro através dos sinais recebidos do pino 13 do Arduíno. O pino 6, que é ligado ao TIP122 (Darlingthon de potência) que amplifica os sinais PWM vindos do Arduíno, mantém a alimentação constante.
A segunda parte é o sensor LDR que fica entre os olhos do robô. Como este sensor já vem montado em uma placa do próprio kit, o utilizamos ligado diretamente ao pino 3 do Arduíno.
A terceira parte deste circuito é a alimentação do LED RGB, e alimentar este dispositivo merece um detalhe importante, pois este componente possui 4 terminais, sendo um o catodo e 3 anodos. Cada um dos anodos corresponde a uma cor (RED, GREEN, BLUE);
Para acendermos o vermelho no LED, aplicamos uma tensão variável no pino que corresponde o vermelho, o mesmo acontece para as demais cores. Podemos efetuar uma mistura de cores e, assim, obter uma gama maior de cores, onde podemos mesclar o vermelho com o azul e criar um roxo, e assim por diante. Vale a pena o leitor perder um tempo testando somente as cores que o LED RGB pode produzir.
O motor é alimentado por um conjunto de 6 V, quatro pilhas de 1,5 V tamanho AA. Os demais componentes são alimentados diretamente dos pinos do Arduíno.
Aconselho o leitor a montar os módulos, um por um, para entender o funcionamento do sistema, e também modificar as linhas do programa para ver o que acontece quando mudamos os valores de algumas variáveis ou da lógica em si. No sensor LDR, é possível ainda adicionar um potenciômetro para regular a sensibilidade do mesmo, pois dependendo do ambiente poderá ser necessário diminuir a sensibilidade, ou de aumentá-la ligando-se um transistor na saída.
O programa
O programa completo é fornecido na nota abaixo. Nele, é possível observar logo nas primeiras linhas as variáveis que adotamos para monitorar e fazer funcionar todas as saídas que utilizaremos no projeto, onde temos o pino 13 como sinal de saída para dar direção ao motor, ele faz isso armando ou desarmando o relé. Temos também a variável out PWM para o pino 6, uma saída PWM para ativarmos o funcionamento do motor, não importando o lado para o qual ele gire.
CODIGO FONTE int outPin = 13;
int outPWM = 6; int direcao = 0; int greenPin = 9; // Conectado ao led verde no pino 09 int bluePin = 10; // Conectado ao led azul no pino 10 int redPin = 11; // Conectado ao led vermelho no pino 11 int inPin = 2; long randNumber; void setup() { pinMode(outPin, OUTPUT); pinMode(outPWM, OUTPUT); pinMode(redPin, OUTPUT); pinMode(greenPin, OUTPUT); pinMode(bluePin, OUTPUT); pinMode(inPin, INPUT); }
void loop() { randNumber = random(20); // Gera um número randomicamente if (randNumber < 3){ if (direcao == 1) { digitalWrite(outPin, HIGH); // Arma o relé direcao = 0; } else { digitalWrite(outPin, LOW); // Desarma o relé direcao = 1; } for (int i=0; i<=20; i++) { digitalWrite(outPWM, HIGH); delay(50); digitalWrite(outPWM, LOW); delay(50); leLDR(); } } leLDR(); // o estado do sensor LDR delay(500); // Pausa no programa. }
void ativaRgb(int redVal,int greenVal, int blueVal) { analogWrite(redPin, redVal); // Escreve o valor do PWM do led vermelho analogWrite(greenPin, greenVal); // Escreve o valor do PWM do led verde analogWrite(bluePin, blueVal); // Escreve o valor do PWM do led azul }
void leLDR() { if(digitalRead(inPin) == LOW) { ativaRgb(0,255,0) ; // Chama a função que acende o led } else { ativaRgb(255,0,0) ; // Chama a função que acende o led } }
Criamos uma variável chamada “direcao”, que tem como finalidade setar no programa a atual direção que o motor está girando.
Para alimentar o LED RGB criamos 3 variáveis: o greenPIN, o bluePin e o redPin, cada um deles conectado à sua porta ligada aos terminais do LED. Criamos uma variável inPin que setamos como pino de entrada para a plaquinha do LDR. E, finalmente, criamos uma variável tipo “Long” chamada rand Number, que tem por finalidade armazenar valores gerados randomicamente pela função random(), onde colocamos o número 20 para que o sistema gere números aleatórios de 0 a 20. Este número pode mudar, dependendo do projeto.
O motivo de criar números randômicos é pelo fato de termos uma va- riável em constante mudança. Para que o sistema fique monitorando esta variável até que ela tenha um valor determinado, neste caso na condição if (randNumber <3), de modo a colocar o motor para funcionar. Quanto maior a diferença entre os números gerados, menores serão as possibilidades da cláusula if (se) acontecer. Este recurso é aplicado para que os olhos girem quando ele gerar números inferiores a 3, o que faz parecer que o robô somente gira os olhos quando ele quer, uma vez que não sabemos quais os números randômicos gerados no momento.
Na segunda parte do programa temos a função setup(), onde configuramos todas as saídas e entradas utilizando a função pinMode().
Conforme o programa entra em execução, ele fica chamando a função “leLDR()”, função esta que está fora da função “loop()”, porém sendo chamada dentro dela. A função “leLDR()” faz uma checagem do pino 3, onde está conectado o LDR, notem que se o pino 3 estiver no estado “High” ele chama a função “ativaRgb()” que acende o LED conforme as variáveis aplicadas nas saídas dos pinos correspondentes, se estiver em LOW acende o vermelho. O estado LOW ocorre quando tampamos a luz que incide no LDR.
Reparem que dentro da condição if, quando o motor começa a girar, temos uma outra chamada da função “leLDR()”, isso porque quando o mo- tor está sendo acionado, o programa que é habilitado (linha a linha), sofre um atraso, e se o LDR for obstruído e levar o pino 3 a LOW, o motor teria que executar o seu movimento, ou seja, os 20 pulsos necessários para virar para depois, acionar a leitura do LDR. Isto seria suficiente para alterar o estado do LDR e o LED não mudar de cor. Por isso, a cada pulso que o motor recebe é feita uma leitura no LDR.
Só na questão de manter a leitura do LDR sempre constante num sistema de leitura do programa, linha a linha, o leitor irá notar a necessidade de processamento destas máquinas robóticas. Em muitos casos, multiprocessadores se fazem necessários como também circuitos dedicados para determinado tipos de sensores, onde estes circuitos passam a informação pronta para o sistema de processamento formular uma ação.
Outro fator é a capacidade de armazenamento de um programa, dependendo do microcontrolador aplicado o máximo pode chegar a pouco mais de 7000 bytes. Para o nosso exemplo há espaço de sobra, pois utilizamos algo em torno de 1200 bytes, mas quando aumentamos os números de variáveis e de condições e controles que o microcontrolador deverá armazenar e controlar, esse espaço é pouco.
A variável “direcao” é uma variável que não liga ou lê porta nenhuma, ela é uma variável interna que controla o estado de direção do motor. Esta variável começa com o valor 0; e quando a condição if for verdadeira ela aciona outra condição if, só que desta vez analisa a condição da própria variável “direcao”, que neste caso é 0, corta a corrente do relé e muda o seu próprio valor para 1, para que, depois, na próxima volta a condição if lerá o seu valor, armará o relé e voltará com o seu valor para 0.
Conclusão
A possibilidade de programar sentimentos em uma máquina, ou pelo menos simular algo parecido a sentimentos pode ser feito, porém há a necessidade de recursos tais como processamento, velocidade deste processamento que está vinculado ao “clock” do sistema, e também de memória ou espaço de armazenamento dos programas e dados.
Programar algo complexo com recursos limitados é uma arte, e somente montando e programando um exemplo como este, o leitor notará as dificuldades de manipulação destes itens que compõem a lógica de funcionamento, e com isso ficará admirado quando se deparar com projetos robóticos avançados como o Asimo (e outros) que muito se parecem ao ser humano.