Cérebro


A ideia é de um robô que estabeleça uma relação com ambiente e com as pessoas mostrando que ele consegue extrair desse contexto uma experiência sensorial e a partir disso gerar uma resposta visual. Na prática, o robô tem quatro áreas luminosas na sua estrutura de cérebro, cada área corresponde a um sentido diferente (no caso: visão, audição, tato e olfato). A partir do momento que cada sentido é estimulado, uma luz uniforme ou dispersada acende na área correspondente (cada área com sua respectiva cor). Quão maior a intensidade do estímulo, mais luminosa a área correspondente vai ser.


PROJETO ORIGINAL -

Requisitos funcionais:
  • Sensor de proximidade: Corresponde ao sentido do tato. Serão dois sensores de ultrassom.
  • Sensor de intensidade luminosa: Corresponde ao sentido da visão. Serão vários LDRs.
  • Sensor de frequência sonora: Corresponde ao sentido da audição. Falta definir como esse sensor será especificamente.
  • Sensor de gás analógico: Corresponde ao sentido do olfato. Será um único sensor de gás.
  • LEDs: Serão LEDs RGB, cada cor correspondendo a um sentido. 

Requisitos não funcionais: 
  • Estrutura interna: provavelmente produzida em náilon ou acrílico, servirá de apoio aos sensores e LEDs.
  • Estrutura externa: servirá de revestimento protetor do robô e definirá o formato de cérebro planejado. Os possíveis matérias para a estrutura externa ainda serão testados. 

Processamento:
Conteúdo criado na rede antiga por Alexandre Andrade, Raquel Pontes, Victor Uchôa, Lucas Sampaio e Juan Henrique.


"DIÁRIO DE BORDO" -

03 de Outubro de 2012

VISÃO

Na parte da visão nós testamos o LDR em função do fade, neste caso quanto mais luz captada pelo LDR, maior o brilho dos LEDs. Nós usamos cinco LDRs e um LED, e programamos de forma que apenas o LDR que captasse a maior luminosidade controlasse o fade do LED.

Código Utilizado  

// Iniciamos declarando as variáveis do código
int ldr0=A0, ldr1=A1, ldr2=A2, ldr3=A3, ldr4=A4, ldrVal;
int LDRled = 11;

void setup(){
// Em setup declaramos que o LDRled é OUTPUT, o arduino está enviando o sinal a ele, Serial.begin inicia a comunicação do sensor com
//arduino
Serial.begin(9600);
pinMode(LDRled, OUTPUT);
}

void loop(){
// A função Serial.print vai imprimir os valores dos LDRs
Serial.println(analogRead(ldr0));
Serial.println(analogRead(ldr1));
Serial.println(analogRead(ldr2));
Serial.println(analogRead(ldr3));
Serial.println(analogRead(ldr4));
// A função max compara dois valores e retorna apenas o maior, desta forma apenas o maior LDR vai controlar o fade do LED
ldrVal = max(analogRead(ldr0), analogRead(ldr1));
ldrVal = max(ldrVal, analogRead(ldr2));
ldrVal = max(ldrVal, analogRead(ldr3));
ldrVal = max(ldrVal, analogRead(ldr4));
Serial.println(ldrVal);
// Em constrain reestabelecemos o valor mínimo e máximo de LdrVAL, agora é de 200 a 900
ldrVal = constrain(ldrVal, 200, 900);
// Map cria uma proporção entre os limites iniciais(200, 900) e os limites futuros(0, 255), logo o resultado desta função será
//um valor entre 0 e 255 em relação aos limites iniciais 200 e 900.
ldrVal = map (ldrVal, 200, 900, 0, 255);
// Escreve o valor de ldrVal em LDRled e imprime na tela
analogWrite(LDRled, ldrVal);
Serial.print(ldrVal);
Serial.println("modified");
analogWrite(LDRled, ldrVal);
delay(100);

TATO

Na parte do tato realizamos o fade em função do sensor ultrassom, neste caso quanto menor a distância medida pelo ultrassom maior o brilho dos LEDs. Utilizamos dois Ultrassons e um LED, o fade do LED será controlado pelos dois ultrassons a partir de uma média entre os dois.  

Código utilizado

int ledultra = 9;  //Iniciamos declarando as variáveis do programa        
const int ultra1 = 7, ultra2 = 8;

void setup() {
// Serial.begin inicia a comunicação do sensor com o arduino e em pinMode declaramos que ledultra é OUTPUT, ele irá receber informaçã
do arduino
Serial.begin(9600);
pinMode(ledultra, OUTPUT);
}

void loop(){
long duration1, duration2, media, cm;
//Calcula a distância captada de ultra1
pinMode(ultra1, OUTPUT);
digitalWrite(ultra1, LOW);
delayMicroseconds(2);
digitalWrite(ultra1, HIGH);
delayMicroseconds(5);
digitalWrite(ultra1, LOW);
pinMode(ultra1, INPUT);
duration1 = pulseIn(ultra1, HIGH);
// Calcula a distância captada de ultra2
pinMode(ultra2, OUTPUT);
digitalWrite(ultra2, LOW);
delayMicroseconds(2);
digitalWrite(ultra2, HIGH);
delayMicroseconds(5);
digitalWrite(ultra2, LOW);
pinMode(ultra2, INPUT);
duration2 = pulseIn(ultra2, HIGH);
// Declara o valor de media
media = (duration1+duration2)/2;
cm = microsecondsToCentimeters(media); // Converte tempo em distância
Serial.print(cm); // Imprime o valor de cm
Serial.print("cm");
Serial.println();
cm = constrain(cm, 0, 200);
// Em constrain restabelecemos os limites de cm agora de 0 a 200
cm = map(cm, 0, 200, 255, 0);
//Em map criamos uma proporção entres os limites iniciais de cm(0, 200) e os novos limites(255, 0)
// Isto é feito em função do fade do LED que varia entre 0 e 255 desta forma quando um objeto estiver a dois metros do ultrassom o LED se manterá apagado, e quando a distância entre um objeto e o ultrassom for de 0 cm o LED brilhará o máximo.
// Imprime os valores calculados em cm
analogWrite(ledultra, cm);
Serial.print(cm);
Serial.print("modified");
Serial.println();
delay(100);
}

// 29 microssegundos equivale a 1 cm, dividindo o valor captado pelo ultrassom por 29 estaremos convertendo em centímetros e no final
dividimos por 2 porque queremos apenas a distância captada pelo sensor
long microsecondsToCentimeters(long microseconds)
{
return microseconds / 29 / 2;
}

10 de Outubro de 2012

Para aprimorar o cerébro, nós buscamos juntar os códigos (que acabou não sendo possível), testar os LDRs (resistor que depende de luz, e funciona como um sensor de luz) com todos os leds ligados apenas na fonte (já que ao final do projeto, o arduino só irá transmitir e receber informações) e os ultrassons (sonares) também com os leds e ligados na fonte.

Durante o processo houveram poucos problemas e foram apenas de mal contato.

Para ligar todos os LDRs e transmitir o sinal ao leds, decidimos usar o comando max, que consiste em pegar o maior valor entre dois números. Como foram utilizados 5 LDRs, fizemos em forma de série, Ex: Max entre LDR1 e  LDR2, MAX entre maior valor  de LDR1 e LDR2 por LDR3 e etc.

Para os ultrassons foi usada a média, que nada mais é que somar os valores de ULTRA1 e ULTRA2 e dividi-los por 2.

Como não conseguimos nada para encaixar o microfone na protoboard nesse dia, apenas melhoramos o que foi feito no encontro anterior.


24 de Outubro de 2012

Nesse encontro finalmente passamos ao "sentido da audição". Tivemos diversos problemas nessa etapa. Primeiramente, para conectar o sensor [modelo SEN12945P] precisamos soldar fios às suas saídas a fim de ligá-lo ao arduino.

O sensor tem 4 pinos: Ground, Vcc, Signal e NC.

Os dois primeiros são para alimentação enquanto que o signal serve para mandar o sinal ao arduino, porém não identificamos a função do NC.

Em seguida, problemas de circuito e mal contato na protoboard que foram solucionados com alguns testes. Por fim, uma má regulação do sensor e uma sala bastante ruidosa atrapalharam testar definitivamente a programação e o fading do led.


31 de Outubro de 2012

 

Continuamos trabalhando no microfone nesse encontro. Dessa vez conseguimos escrever um programa que conseguiu controlar o brilho do LED a partir da leitura do sensor. Contudo esbarramos em dois problemas.

O primeiro foi que ao emitir um som de intensidade constante, o LED deveria se manter aceso. O que realmente acontecia era que o LED ficava piscando. Quando observamos os valores que o sensor estava lendo no serial monitor, vimos que mesmo com um som constante, alguns zeros (aparentemente aleatórios) apareciam. Nossa solução foi eliminar esses zeros na programação, impedindo que eles fossem passados pro LED. Isso não funcionou totalmente, mas o LED passou a piscar menos. O código utilizado foi esse:

const int ledPin = 11;
int quantz=0, limitez=5;

void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}

void loop() {
int sensorValue = analogRead(A0);
//A leitura do Sensor é feita.
Serial.println(sensorValue);
//Para efeito de controle, o valor lido é impresso no serial monitor.
sensorValue = constrain(sensorValue, 350, 700);
//A função constrain modifica os limites dos valores lidos. Todos os valores abaixo de 350 viram 350 e os acima de 700 viram 700.
sensorValue = map(sensorValue, 350, 700, 0, 255);
//A função map modifica o intervalo de 350 a 700 para 0 a 255, para poder imprimir esses valores no LED.
Serial.print(sensorValue);
Serial.println("mod");
if(sensorValue > 0) {
//Essa condicional impede que os zeros aleatórios passem pro LED, eliminando parte das piscadas do LED.
analogWrite(ledPin, sensorValue);
quantz=0;
} else {
quantz++;
//Essa variável vai armazenando quantos zeros seguidos aparecem.
}
if(quantz>=limitez) {
//Se o número de zeros seguido supera 5, o LED é apagado. Sem essa condicional o LED não apagaria quando houvesse silêncio, já que todos os zeros seriam eliminados.
quantz = 0;
analogWrite(ledPin, 0);
}
}


O segundo problema está relacionado ao efeito fading. Nos sensores relativos à visão e tato, conseguimos um fading bem interessante, mas com o microfone esse efeito não funcionou tão bem. É notável que o LED brilha mais ou menos com sons mais fortes ou mais fracos, mas a transição de uma intensidade de brilho pra outra é tão rápida, que não obtivemos o efeito que queríamos. Portanto, no próximo encontro vamos tentar algumas ideias pra melhorar o efeito fading a partir da programação.


7 e  14 de Novembro de 2012

Nos dois últimos encontros continuamos trabalhando no microfone. Após testar várias ideias, conseguimos chegar a um código bem simples que consegue realizar o fading. Decidimos fazer um código que só fizesse o fading pra apagar os leds, ou seja, quando algum som chegar no microfone os leds vão acender de vez e apagar gradualmente. O único problema que o novo código não resolve é o de um som contínuo. Como dito antes, o ideal era que os leds ficassem acesos enquanto algum som contínuo estivesse chegando ao microfone, mas ainda não encontramos uma forma de fazer isso. O código novo é esse:

const int ledMicrofone = 11;

void setup() {
pinMode(ledMicrofone, OUTPUT);
Serial.begin(9600);
}

void loop() {
int sinalMicrofone;
sinalMicrofone = analogRead(A0);
//A leitura do Sensor é feita.
sinalMicrofone = constrain(sinalMicrofone, 400, 1000);
//A função constrain modifica os limites dos valores lidos. Todos os valores abaixo de 400 viram 400 e osacima de 1000 viram 100.
sinalMicrofone = map(sinalMicrofone, 400, 1000, 0, 255);
//A função map modifica o intervalo de 350 a 700 para 0 a 255, para poder imprimir esses valores no LED.
analogWrite(ledMicrofone, sinalMicrofone);
//O Led é aceso de acordo com a intensidade do som que chegou no microfone.
for(int i = 0; i < sinalMicrofone; ++i) {
analogWrite(ledMicrofone, sinalMicrofone-i);
delay(20);
//Esse laço faz com o Led vá apagando gradualmente.
}
}


No próximo encontro vamos começar a pensar em como juntar todos os sentidos em um único código utilizando uma máquina de estados.

Nesses mesmos dois encontros dos dias 7 e 14, parte do grupo começou a planejar o shield para o arduíno que conterá todas as saídas de Signal, Vcc e Ground dos sensores e dos quatro drives de LEDs. Listamos todo o material que será necessário comprar: placa de ilha 10cmX10cm dupla face, barras de pino fêmea de 3 e 4 entradas, mais o material de experimentação do revestimento do robô. Posteriormente, foi analisado o tamanho adequado da placa, bem como a melhor disposição de todos os componentes, de forma a adequá-los aos "caminhos" na placa e a origem deles na própria estrutura do robô. O shield já está planejado com um esquema desenhado para nos orientar na hora de montá-lo.

21 de Novembro de 2012


Nesse encontro as atividades foram realizadas no Museu de Arte Contemporânea de Pernambuco (MAC-PE). Começamos a trabalhar no sentido do olfato com o sensor de gás mas avançamos pouco, visto que ainda não entendemos perfeitamente o funcionamento do sensor. O código que utilizamos para testar a leitura do sensor foi esse:

void setup() {
Serial.begin(9600);
}

void loop() {
int val;
val=analogRead(A0);
//Faz a leitura do sensor.
Serial.println(val);
//Imprime no serial monitor o valor lido.
delay(100);
}

28 de Novembro de 2012

 Nesse encontro não conseguimos avançar no trabalho com o sensor de gás, devido a falta de um cabo usb para ligar o arduino no computador. Portanto, nos limitamos a discutir possíveis métodos de unir os códigos de todos os sentidos em um único código sem prejudicar o efeito visual do fading. No próximo encontro esperamos avançar com o trabalho do sensor de gás e também começar a montar o shield que une os sensores e os drivers ao arduino.

05 de Dezembro de 2012


  Nesse encontro conseguimos escrever e testar alguns códigos para o sensor de gás. No final chegamos a um código similar ao do microfone. A única diferença está no tratamento dos valores do leitor, já que quando assopramos no sensor de gás, a leitura é "atrapalhada" fazendo o valor diminuir. Isso só acontece porque nosso sensor de gás detecta gases do tipo GLP, ou Gases liquefeitos de petróleo, e não gás carbônico, o produto de nossa respiração. Tendo em vista isso, quanto menor o valor lido pelo sensor, mais forte a pessoa está soprando e portanto, maior o brilho dos leds. O código utilizado foi:

int sensorGas;
int ledGas = 11;

void setup(){
pinMode(ledGas, OUTPUT);
Serial.begin(9600);
}

void loop(){
sensorGas = analogRead(A0);
//A leitura do Sensor é feita.
Serial.println(sensorGas);
sensorGas = constrain(sensorGas, 30, 80);
//A função constrain modifica os limites dos valores lidos. Todos os valores abaixo de 30 viram 30 e os acima de 80 viram 80.
sensorGas = map(sensorGas, 30, 80, 255, 0);
//A função map modifica o intervalo de 30 a 80 para 255 a 0, para poder imprimir esses valores no LED.
analogWrite(ledGas, sensorGas);
for(int i = 0; i < sensorGas; ++i)
{
analogWrite(ledGas, sensorGas-i);
delay(20);
//Esse laço faz com o Led vá apagando gradualmente.
}
}

  Também avançamos na construção do shield une os sensores e os drivers ao arduino e testamos algodão como um possível material para a estrutura externa do cérebro. Considerando que todos os códigos de todos os sentidos estão prontos, na próxima semana vamos trabalhar na união desses códigos


12 de Dezembro de 2012

 Nesse encontro começamos a juntar os sentidos em um único código e esbarramos em alguns problemas. Esses problemas estão relacionados ao fato de que faz parte do conceito do cérebro mostrar que os sentidos funcionam simultaneamente. Para obter essa simultaneidade é necessário que o código final seja sequencial sem delays e loops dentro da função principal. Daí vem nosso problema: o efeito fading que nós fizemos depende diretamente do uso das funções delay e for. Portanto, na parte da programação, a prioridade é reescrever todos os códigos dos sentidos sem utilizar delay e for.
  No âmbito da parte externa testamos o polímero PU (Poliuretano) como possível material. Esse material tem dezenas de aplicações e é rígido o suficiente para se sustentar, é fácil de moldar e também dispersar a luz da maneira que queríamos.


16, 23 e 30 de Janeiro de 2013

    Com o prazo apertado pra finalizar o projeto tivemos que encontrar uma solução rápida para os problemas de programação. A melhor encontrada foi escrever dois códigos e consequentemente utilizar dois arduinos. O primeiro código une visão e tato e o segundo une audição e olfato.
Código 1 (visão e tato):

const int ultra = 7;
long duration;
long cm;
const int ledultra= 6;
const int LDRled = 5;
const int ldr0=A0, ldr1=A1, ldr2=A2, ldr3=A3;
int ldrVal;

void setup() {
Serial.begin(9600);
pinMode(ledultra, OUTPUT);
pinMode(LDRled, OUTPUT);
}

void loop()
{
duration = funcUltra(duration);
//funcUltra é a função que faz a leitura do ultrassom.
cm = microsecondsToCentimeters(duration);
//O tempo lido no ultrassom é convertido para centímetros.
cm = constrain(cm, 0, 30);
cm = map(cm, 0, 30, 255, 0); //constrain e map modificam os limites dos valores lidos. ldrVal = compara();
//compara é a função que lê os LDRs e retorna o maior valor lido.
ldrVal = constrain(ldrVal, 500, 900);
//constrain e map modificam os limites dos valores lidos.
ldrVal = map (ldrVal, 500, 900, 0, 255);
analogWrite(LDRled, ldrVal);
//O valor modificado dos LDRs é inscrito nos leds da visão.
analogWrite(ledultra, cm);
//O valor modificado do ultrassom é inscrito nos leds do tato.
delay(30);
}

long funcUltra(long duration)
//funcUltra é a função que faz a leitura do ultrassom.
{
pinMode(ultra, OUTPUT);
digitalWrite(ultra, LOW);
delayMicroseconds(2);
digitalWrite(ultra, HIGH);
delayMicroseconds(5);
digitalWrite(ultra, LOW);
pinMode(ultra, INPUT);
duration = pulseIn(ultra, HIGH);
return duration;
}

long microsecondsToCentimeters(long microseconds)
{
return microseconds / 29 / 2;
}

int compara()
//compara é a função que lê os LDRs e retorna o maior valor lido.
{
ldrVal = max(analogRead(ldr0), analogRead(ldr1));
//max retorna o maior entre dois valores.
ldrVal = max(ldrVal, analogRead(ldr2));
ldrVal = max(ldrVal, analogRead(ldr3));

return ldrVal;
}

Código 2 (audição e olfato):

/*
Esse código foi escrito como uma máquina de estados finitos.
Nele existem dois estados LEITURA e FADING.
Em LEITURA os valores dos sensores são lidos e modificados.
Em FADING esses valores são inscritos nos leds e um fade out é realizado.
*/
#define LEITURA 0
#define FADING 1

int sensorGas;
int sinalMicrofone;
int tempoAtual;
int tempoAnterior = 0;
int intervalo = 10;
int i = 0;
int j = 0;
const int ledGas = 9;
const int ledMicrofone = 10;
boolean estado = LEITURA;

void setup()
{
pinMode(ledGas, OUTPUT);
pinMode(ledMicrofone, OUTPUT);
Serial.begin(9600);
}

void loop(){
tempoAtual = millis();
if(estado == LEITURA){
sensorGas = analogRead(A4);
//O valor do sensor de gás é lido.
sensorGas = constrain(sensorGas, 30, 50);
sensorGas = map(sensorGas, 30, 50, 255, 0);
//constrain e map modificam os limites dos valores lidos.
analogWrite(ledGas, sensorGas);
//Esse valor é inscrito inicialmente nos leds.
sinalMicrofone = analogRead(A5);
//O valor do microfone é lido.
sinalMicrofone = constrain(sinalMicrofone, 200, 800);
sinalMicrofone = map(sinalMicrofone, 200, 800, 0, 255);
//constrain e map modificam os limites dos valores lidos.
analogWrite(ledMicrofone, sinalMicrofone);
//Esse valor é inscrito inicialmente nos leds.
estado = FADING;
//Fim do estado LEITURA.
}
else if (estado==FADING && (i if(i //Essa estrutura substitui o for e o delay.
{
if(tempoAtual - tempoAnterior > intervalo)
//Esse if substitui a utilização da função delay.
{
analogWrite(ledGas, sensorGas-i);
tempoAnterior = tempoAtual;
++i;
}
}
if(j //Essa estrutura substitui o for e o delay.
{
if(tempoAtual - tempoAnterior > intervalo)
//Esse if substitui a utilização da função delay.
{
analogWrite(ledMicrofone, sinalMicrofone-j);
tempoAnterior = tempoAtual;
++j;
}
}
}
else
{
estado = LEITURA;
i=0;
//Fim do estado FADING.
}
}

    A parte da montagem dos leds e sensores na estrutura do robô era a mais atrasada, e portanto, foi onde concentramos o trabalho. Novamente por causa do prazo apertado, tivemos que abandonar a montagem do shield, utilizando em seu lugar uma protoboard. Para montar encontramos grandes dificuldades em lidar com a quantidade de fios necessária para ligar os leds em paralelo e os sensores na protoboard. A imagem abaixo é da fase final da montagem e mostra a quantidade de fios utilizada.
GLSnwCT.jpg

Depois de montada a estrutura, fizemos os testes de funcionamento e todos os leds e sensores funcionaram da forma esperada. Nos próximos encontros só precisamos finalizar o robô com a parte externa que vai ser de arame e poliéster.


Conteúdos relacionados

Imagem Principal

No description for object of class

Descrição

AntigaNovaDiferenças
1 <h4>A ideia é de um robô que estabeleça uma relação com ambiente e com as pessoas mostrando que o robô consegue extrair desse contexto uma experiência sensorial e a partir disso gerar uma resposta visual. Na prática, o robô vai ter quatro áreas luminosas na sua estrutura de cérebro, cada área corresponde a um sentido diferente (no caso: visão, audição, tato e olfato). A partir do momento que cada sentido é estimulado, uma luz uniforme ou dispersada vai acender na área correspondente ao estímulo (cada área com sua respectiva cor). Maior a intensidade do estímulo, mais luminosa a área correspondente vai ser.</h4>
 1<h4>A ideia é de um robô que estabeleça uma relação com ambiente e com as pessoas mostrando que ele consegue extrair desse contexto uma experiência sensorial e a partir disso gerar uma resposta visual. Na prática, o robô tem quatro áreas luminosas na sua estrutura de cérebro, cada área corresponde a um sentido diferente (no caso: visão, audição, tato e olfato). A partir do momento que cada sentido é estimulado, uma luz uniforme ou dispersada acende na área correspondente (cada área com sua respectiva cor). Quão maior a intensidade do estímulo, mais luminosa a área correspondente vai ser.</h4>
22
33<p><br></p>
44
 
99
1010<h5></h5>
1111
 12<h5></h5> 
 13 
1214<ul><li>
1315Sensor de proximidade: Corresponde ao sentido do tato. Serão dois sensores de ultrassom. </li></ul>
1416
 17<h5></h5> 
 18 
1519<ul><li>Sensor de intensidade luminosa: Corresponde ao sentido da visão. Serão vários LDRs. </li></ul>
 20 
 21<h5></h5> 
1622
1723<ul><li>Sensor de frequência sonora: Corresponde ao sentido da audição. Falta definir como esse sensor será especificamente. </li></ul>
1824
 
2026
2127<ul><li>LEDs: Serão LEDs RGB, cada cor correspondendo a um sentido. </li></ul>
2228
23 <h5><br></h5><p>Requisitos não funcionais: </p>
 29
 30
 31
 32
 33<h5><br></h5>
 34
 35<h5>Requisitos não funcionais: </h5>
2436
2537<h5></h5>
2638
2739<ul><li>Estrutura interna: provavelmente produzida em náilon ou acrílico, servirá de apoio aos sensores e LEDs.</li></ul>
2840
 41<ul><li>Estrutura externa: servirá de revestimento protetor do robô e definirá o formato de cérebro planejado. Os possíveis matérias para a estrutura externa ainda serão testados. </li></ul> 
 42 
2943<h5></h5>
3044
31 <ul><li>Estrutura externa: servirá de revestimento protetor do robô e definirá o formato de cérebro planejado. Os possíveis matérias para a estrutura externa ainda serão testados. </li></ul>
 45
 46
 47<h5></h5>
 48
 49
3250
3351<h5><br></h5>
3452