Robô movido a energia solar controlado por lanterna usando Arduino

Este projeto é um robô sensível ao gradiente de luz com capacidade de carregamento solar, ou seja, busca a luz para se carregar. Ele realiza esse comportamento com um conjunto de quatro fotorresistores sensíveis à luz em circuitos divisores de tensão, a unidade Arduino lê os quatro valores que correspondem à intensidade da luz recebida pelos sensores através de seus pinos de leitura analógicos. Em seguida, ele aplica uma alta tensão através de um interruptor reed que completa um circuito entre uma bateria de 9 V e dois motores de brinquedo, resultando em um giro ou movimento em direção à luz.

Protótipo de tanque robótico controlado por luz movido a energia solar baseado em Arduino

Figura 1: Protótipo de tanque robótico controlado por luz movido a energia solar baseado em Arduino

Esses motores não puderam ser ativados diretamente com o Arduino, se você conseguir motores pequenos o suficiente, a parte de comutação deste projeto pode ser omitida sem perda de funcionalidade. Se algum dos quatro fotodiodos estiver registrando muito mais alto que os outros, ele detecta qual fotodiodo está recebendo o sinal intensificado e gira ou se move nessa direção enquanto o sinal intensificado estiver sendo recebido. Este algoritmo de rastreamento de luz pode ser usado para programar painéis solares para rastrear o sol ou para controlar o robô via lanterna, como é demonstrado aqui. Para este projeto o leitor precisa de conhecimento de começando com arduino.

Imagens e diagramas da placa de circuito completa ficariam um pouco confusos neste caso, por isso coloquei na caixa os componentes principais que são repetidos 4 e 2 vezes respectivamente no projeto real. O primeiro subsistema do circuito é o divisor de tensão baseado em um fotorresistor que se repete quatro vezes, sendo cada fotorresistor colocado em um lado diferente do seu robô. O fotoresistor varia a resistência com base no sinal de luz recebido através da fotocondutividade do material semicondutor receptor. A resistência variável produz uma corrente variável no circuito de acordo com a lei de Ohm, V=iR onde a tensão V é constante (5V). Tenha cuidado para não deixar os fios que levam a qualquer fotodiodo excessivamente longos, pois você pode perder o sinal devido à resistência interna do fio e às conexões de solda. A tensão é fornecida a esta parte do circuito diretamente dos pinos 5V/Gnd do Arduino UNO. A linha de 5V passa por um resistor de 10k Ohms, passa pelo fotodiodo e volta ao terra. Um sinal analógico é lido entre o resistor e o fotodiodo por meio dos pinos analógicos do Arduino. Uma adição opcional é o LED indicador mostrado indo do outro lado do resistor (positivo) para o terra (negativo), este LED mudará de intensidade com base no sinal recebido pelo fotodiodo. Se esses LEDs estiverem muito próximos de um dos fotodiodos, sua máquina poderá entrar em uma espécie de loop de feedback analógico naquela direção, onde ela gira na direção de seus próprios LEDs. Acredito que codifiquei contra essa possibilidade, mas se você estiver vendo esse comportamento, tente retirar os LEDs, pois eles são úteis apenas durante a depuração desta parte do circuito. Quatro pinos analógicos devem ser conectados a quatro iterações deste bloco de circuito. Em princípio, você pode aumentar o número de iterações para aumentar a sensibilidade direcional, mas isso não é necessário para esta aplicação. O esboço que acompanha este projeto é sensível a uma diferença na intensidade da luz recebida; se todos os sinais recebidos forem muito semelhantes, o robô continuará a amostrar seu ambiente, mas permanecerá estacionário. Assim que qualquer um dos sinais for maior que os outros em um valor limite, o programa entra em seu loop de movimento. Ele determina qual fotorresistor está recebendo o sinal máximo e então aplica corrente ao motor que move o robô na direção correta correspondente. Esta ação continua enquanto o fotorresistor estiver recebendo intensidade máxima e houver uma diferença grande o suficiente entre os valores lidos.

Imagem mostrando as conexões do circuito do resistor fotográfico no tanque robótico para detecção de lanterna

Figura 2: Imagem mostrando as conexões do circuito do resistor fotográfico no tanque robótico para detecção de lanterna

A segunda parte bloqueada do circuito só é necessária se você precisar de mais energia para os motores do que o Arduino pode fornecer diretamente de seus pinos de saída PWM. Meu chassi/pistas/motor é de um brinquedo chinês, o Arduino estava tendo problemas para acionar os motores com as pistas ligadas, então construí um bloco de comutação no circuito que permite que a saída PWM gire um relé reed que completa um circuito para uma bateria de 9V. O relé reed funciona por meio de um eletroímã que quando ativado pela corrente mais baixa (Arduino) faz com que os pontos de contato dentro da chave fiquem magnetizados e fechem o circuito. Em princípio, você pode acionar motores elétricos muito grandes com este conceito selecionando o relé reed correto. Não precisei de muito mais energia, então uma bateria de 9V foi suficiente, a chave que usei está na seção de peças para não. Como este componente é operado via campo eletromagnético, um diodo de proteção contra transientes é necessário, uma vez que o colapso do campo magnético (quando a chave é desligada) pode causar um pico de corrente que retornará ao Arduino, conforme previsto pelas equações de Maxwell. Uma boa discussão sobre como implementar esta chave de relé reed específica sem causar danos à sua placa pode ser encontrada aqui.

Imagem mostrando as conexões do circuito dos fios da bateria no tanque robótico

Figura 3: Imagem mostrando as conexões do circuito dos fios da bateria no tanque robótico

Esta parte do circuito é repetida duas vezes correspondendo a dois motores, e conforme dito, se você conseguir alimentar seus motores diretamente com o Arduino, poderá omitir esta parte do projeto sem perda de funcionalidade.

Diagramas de circuito e componentes usados

Diagrama de circuito

Divisor de Tensão

Diagrama de circuito da rede divisora ​​de tensão usada para detecção de lanterna

Figura 4: Diagrama de circuito da rede divisora ​​de tensão usada para detecção de lanterna

Circuito de comutação

Diagrama de circuito do controlador de motor DC usado para navegação guiada por luz de carro robótico

Figura 5: Diagrama de circuito do controlador de motor DC usado para navegação guiada por luz de carro robótico

Consulte a guia do diagrama de circuito para obter o circuito completo usado no projeto

Componentes usados

Arduino UNO

4x resistor, 10 K Ohms

4x resistor sensível à luz fotográfica resistor fotográfico, resistor opto 5mm GL5516 5516

4x LED

Painel solar RadioShack® 1,5W 9V

Pistas / plataformas / motores para brinquedos (2)

2x interruptores reed (OMR-C-105H)

Código-fonte do projeto

###

constintfrontPin = A0;
constintleftPin = A1;
constintrightPin = A2;
constintbackPin = A3;
constintleftMotor = 9;
constintrightMotor = 10;
intthreshHold = 170;
int Direction;
int direction1;
int direction2;
int Delay = 25;
int Delay2 = 25;

void setup 
{

pinMode(frontPin, INPUT);
pinMode(leftPin, INPUT);
pinMode(rightPin, INPUT);
pinMode(backPin, INPUT);
pinMode(leftMotor, OUTPUT);
pinMode(rightMotor, OUTPUT);
digitalWrite(leftMotor, HIGH);
digitalWrite(rightMotor,HIGH);
delay(100);
digitalWrite(leftMotor, LOW);
digitalWrite(rightMotor, LOW);
delay(100);
digitalWrite(leftMotor, HIGH);
digitalWrite(rightMotor, HIGH);
delay(100);
digitalWrite(leftMotor, LOW);
digitalWrite(rightMotor, LOW);
delay(1500);
Serial.begin(9600);  
}

void loop 
{

int Direction;
int direction1;
int direction2;
intfrontSignal = 1023 - analogRead(frontPin);
intleftSignal = 1023 - analogRead(leftPin);
intrightSignal = 1023 - analogRead(rightPin);
intbackSignal = 1023 - analogRead(backPin);
Serial.println(frontSignal); 
Serial.println(leftSignal); 
Serial.println(rightSignal); 
Serial.println(backSignal);
// frontSignal + leftSignal + rightSignal + backSignal<= threshHold
if (abs(frontSignal-leftSignal)+abs(frontSignal-rightSignal)+abs(frontSignal-backSignal) >= threshHold )
{
Serial.println("motion loop");
                     direction1 = max(frontSignal, leftSignal);
                     direction2 = max(rightSignal, backSignal);
                      Direction = max(direction1, direction2);
//Loop here is entered only if the light received is not evenly distributed.
     if (frontSignal == Direction)
     {
                   do
                   {
                         digitalWrite(leftMotor, HIGH);
                         digitalWrite(rightMotor, HIGH);
                         delay(Delay2);
                         digitalWrite(leftMotor, LOW);
                         digitalWrite(rightMotor, LOW);
                         delay(Delay);
                         frontSignal = 1023 - analogRead(frontPin);
                         leftSignal = 1023 - analogRead(leftPin);
                         rightSignal = 1023 - analogRead(rightPin);
                         backSignal = 1023 - analogRead(backPin);
                         direction1 = max(frontSignal, leftSignal);
                         direction2 = max(rightSignal, backSignal);
                         Direction = max(direction1, direction2);
                         Serial.println("Forward");
          
                   } while(frontSignal == Direction && abs(frontSignal-leftSignal)+abs(frontSignal-rightSignal)+abs(frontSignal-backSignal) >= threshHold);
           digitalWrite(leftMotor, LOW);
           digitalWrite(rightMotor, LOW); 
     }
     else if (leftSignal == Direction)     //Signal is greatest on the left
     {
                             do
                 {
                       Serial.println("Left");
                       digitalWrite(rightMotor, HIGH);
                       delay(Delay2);
                       digitalWrite(rightMotor, LOW);
                       delay(Delay);
                       frontSignal = 1023 - analogRead(frontPin);
                       leftSignal = 1023 - analogRead(leftPin);
                       rightSignal = 1023 - analogRead(rightPin);
                       backSignal = 1023 - analogRead(backPin);
                       direction1 = max(frontSignal, leftSignal);
                       direction2 = max(rightSignal, backSignal);
                       Direction = max(direction1, direction2);
                 } while(leftSignal == Direction && abs(frontSignal-leftSignal)+abs(frontSignal-rightSignal)+abs(frontSignal-backSignal) >= threshHold);
          digitalWrite(rightMotor, LOW);
     }
     else if (rightSignal == Direction)        //Signal is greatest on the right.
     {
               do
               {
                     Serial.println("Right");
                     digitalWrite(leftMotor, HIGH);
                     delay(Delay2);
                     digitalWrite(leftMotor, LOW);
                     delay(Delay);             
                     frontSignal = 1023 - analogRead(frontPin);
                     leftSignal = 1023 - analogRead(leftPin);
                     rightSignal = 1023 - analogRead(rightPin);
                     backSignal = 1023 - analogRead(backPin);
                     direction1 = max(frontSignal, leftSignal);
                     direction2 = max(rightSignal, backSignal);
                     Direction = max(direction1, direction2);
                    
               } while(rightSignal == Direction && abs(frontSignal-leftSignal)+abs(frontSignal-rightSignal)+abs(frontSignal-backSignal) >= threshHold);
               digitalWrite(leftMotor, LOW);
     }
     else if (backSignal == Direction)      //Signal is greatest behind.
     {
               do
               {
                     Serial.println("Back");
                     digitalWrite(leftMotor, HIGH);
                     delay(Delay2);
                     digitalWrite(leftMotor, LOW);
                     delay(Delay);             
                     frontSignal = 1023 - analogRead(frontPin);
                     leftSignal = 1023 - analogRead(leftPin);
                     rightSignal = 1023 - analogRead(rightPin);
                     backSignal = 1023 - analogRead(backPin);
                     direction1 = max(frontSignal, leftSignal);
                     direction2 = max(rightSignal, backSignal);
                     Direction = max(direction1, direction2);
               } while(backSignal == Direction && abs(frontSignal-leftSignal)+abs(frontSignal-rightSignal)+abs(frontSignal-backSignal) >= threshHold);
               digitalWrite(leftMotor, LOW);
     }
}
else if(abs(frontSignal-leftSignal)+abs(frontSignal-rightSignal)+abs(frontSignal-backSignal) <= threshHold)
{
             int difference = abs(frontSignal-leftSignal)+abs(frontSignal-rightSignal)+abs(frontSignal-backSignal);
             Serial.println("Signal differential is equal to ");
             Serial.println(difference);
             digitalWrite(leftMotor, LOW);
             digitalWrite(rightMotor, LOW);
             delay(1000); // Else sample environment at a rate of 10 hz
}
else
{
             digitalWrite(leftMotor, LOW);
             digitalWrite(rightMotor, LOW);
}

} 

###

Diagramas de circuito

Diagrama de Circuito-Baseado-Arduino-Solar-Powered-Flash-Light-Controlled-Robotic-Tank

Vídeo do projeto

Conteúdo Relacionado

Voltar para o blog

Deixe um comentário

Os comentários precisam ser aprovados antes da publicação.