Robô movido a energia solar controlado por lanterna usando Arduino

Solar Powered Robot Controlled by Flashlight Using Arduino

This project is a robot sensitive to light gradient with solar charging capacity, that is, it seeks light to charge itself. It accomplishes this behavior with a set of four light-sensitive photoresistors in voltage divider circuits, the Arduino unit reads the four values ​​that correspond to the intensity of light received by the sensors through their analog readout pins. It then applies a high voltage through a reed switch that completes a circuit between a 9V battery and two toy motors, resulting in a spin or movement toward the light.

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

Figure 1: Solar-powered light-controlled robotic tank prototype based on Arduino

These motors could not be activated directly with Arduino, if you can get small enough motors the switching part of this project can be omitted without loss of functionality. If any of the four photodiodes is registering much louder than the others, it detects which photodiode is receiving the boosted signal and rotates or moves in that direction while the boosted signal is being received. This light tracking algorithm can be used to program solar panels to track the sun or to control the robot via flashlight, as demonstrated here. For this project the reader needs knowledge of starting with Arduino .

Pictures and diagrams of the complete circuit board would be a bit confusing in this case, so I put in the box the main components that are repeated 4 and 2 times respectively in the real project. The first subsystem of the circuit is the voltage divider based on a photoresistor that repeats four times, with each photoresistor placed on a different side of your robot. The photoresistor varies resistance based on the light signal received through the photoconductivity of the receiving semiconductor material. The variable resistance produces a variable current in the circuit according to Ohm's law, V=iR where the voltage V is constant (5V). Be careful not to make the wires leading to any photodiodes excessively long, as you may lose signal due to the wire's internal resistance and solder connections. Voltage is supplied to this part of the circuit directly from the 5V/Gnd pins of the Arduino UNO. The 5V line passes through a 10k Ohm resistor, passes through the photodiode and returns to ground. An analog signal is read between the resistor and the photodiode via the Arduino's analog pins. An optional addition is the LED indicator shown going from the other side of the resistor (positive) to ground (negative), this LED will change intensity based on the signal received by the photodiode. If these LEDs are too close to one of the photodiodes, your machine can go into a sort of analog feedback loop in that direction, where it rotates in the direction of its own LEDs. I believe I coded against this possibility, but if you are seeing this behavior, try removing the LEDs as they are only useful when debugging this part of the circuit. Four analog pins must be connected to four iterations of this circuit block. In principle, you can increase the number of iterations to increase directional sensitivity, but this is not necessary for this application. The sketch accompanying this project is sensitive to a difference in the intensity of the light received; if all incoming signals are very similar, the robot will continue to sample its environment but remain stationary. As soon as any of the signals are greater than the others by a threshold value, the program enters its motion loop. It determines which photoresistor is receiving the maximum signal and then applies current to the motor that moves the robot in the corresponding correct direction. This action continues as long as the photoresistor is receiving maximum intensity and there is a large enough difference between the values ​​read.

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

Figure 2: Image showing the photo resistor circuit connections in the robotic tank for flashlight detection

The second blocked part of the circuit is only necessary if you need more power for the motors than the Arduino can supply directly from its PWM output pins. My chassis/tracks/motor is from a Chinese toy, the Arduino was having trouble driving the motors with the tracks turned on, so I built a switching block into the circuit that allows the PWM output to turn a reed relay that completes a circuit for a 9V battery. The reed relay works using an electromagnet which, when activated by the lowest current (Arduino), causes the contact points inside the switch to become magnetized and close the circuit. In principle, you can drive very large electric motors with this concept by selecting the right reed relay. I didn't need much more power so a 9V battery was enough, the key I used is in the parts section for no. As this component is operated via an electromagnetic field, a transient protection diode is necessary, as the collapse of the magnetic field (when the switch is turned off) can cause a current spike that will return to the Arduino, as predicted by Maxwell's equations. . A good discussion on how to implement this specific reed relay switch without causing damage to your board can be found here.

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

Figure 3: Image showing the battery wire circuit connections on the robotic tank

This part of the circuit is repeated twice corresponding to two motors, and as stated, if you can power your motors directly with the Arduino, you can omit this part of the project without loss of functionality.

Circuit diagrams and components used

Circuit Diagram

Voltage Divider

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

Figure 4: Circuit diagram of voltage divider network used for flashlight detection

switching circuit

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

Figure 5: Circuit diagram of DC motor controller used for light-guided navigation of robotic car

Refer to the circuit diagram guide for the complete circuit used in the project

Components used

Arduino UNO

4x resistor, 10 K Ohms

4x Photo Light Sensitive Resistor Photo Resistor, Opto Resistor 5mm GL5516 5516

4x LED

RadioShack® 1.5W 9V Solar Panel

Toy tracks/platforms/motors (2)

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

Project source code

###

 constintfrontPin = A0;
 constintleftPin = A1;
 constrightPin = A2;
 constantbackPin = 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)
 {
 of
 {
 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
 {
 of
 {
 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.
 {
 of
 {
 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.
 {
 of
 {
 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);
 }

 }

###

Circuit diagrams

Circuit-Diagram-Based-Arduino-Solar-Powered-Flash-Light-Controlled-Robotic-Tank

Project video

Back to blog

Leave a comment

Please note, comments need to be approved before they are published.