Reputation: 11
I am trying to make a solar panel that tracks the sun by comparing the resistance of 4 photoresistors. I have coded the part that determines the resistance of the photoresistors (I am currently only testing with 2) but I am struggling to get the servo movement part right.
I do not know the exact location of the sun in the sky, I only know what direction the servos need to move to make the solar panel face the sun. I need to tell the servo to move in a certain direction until the resistances of the photoresistors are within a certain margin (I have created this already). Does anyone know how to do this?
Here is what I have:
const int sensorPin = A0;
const int sensorPin1 = A1;
int sensorValue = 0;
int sensorValue1 = 0;
float Vin = 5;
float Vout = 0;
float Vout1 = 0;
float Rref = 2180;
float R = 0;
float R1 = 0;
#include <Servo.h>
Servo myservo;
int pos = 0;
void setup() {
Serial.begin(9600);
myservo.attach(9);
}
void loop() {
sensorValue = analogRead(sensorPin);
Vout = (Vin * sensorValue) / 1023;
R = Rref * (1 / ((Vin / Vout) - 1));
Serial.print("R: ");
Serial.println(R);
delay(500);
sensorValue1 = analogRead(sensorPin1);
Vout1 = (Vin * sensorValue1) / 1023;
R1 = Rref * (1 / ((Vin / Vout1) -1));
Serial.print("R1: ");
Serial.println(R1);
delay(500);
if ((R1 > R) && ((R1 -R) > 1000)){
for (pos = 0; pos <= 180; pos += 1) {
myservo.write(pos);
delay(15);
}
}
if ((R > R1) && ((R -R1) > 1000)) {
for (pos = 180; pos >= 0; pos -= 1) {
myservo.write(pos);
delay(15);
}
}
}
I also saw a video by GreatScott! (link: https://www.youtube.com/watch?v=_6QIutZfsFs) where he did this. His design is different from mine but I wanted to see his code. He didn't show all of it but this is what I managed to copy. I don't have much knowledge of C++ so I don't really know what he is doing. Can someone explain it to me?
int topleft = 0;
int topright = 0;
int bottomleft = 0;
int bottomright = 0;
void setup() {
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
TCCR1A = 0;
TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << WGM11);
TCCR1B = 0;
TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11);
ICR1 = 40000;
OCR1A = 3000;
OCR1B = 3600;
}
void loop() {
topleft = analogRead(A0);
topright = analogRead(A1);
bottomleft = analogRead(A2);
bottomright = analogRead(A3);
if (topleft > topright) {
OCR1A = OCR1A + 1;
delay(15);
}
if (bottomleft > bottomright) {
OCR1A = OCR1A + 1;
delay(15);
}
if (topleft < topright) {
OCR1A = OCR1A - 1;
delay(15);
}
if (bottomleft < bottomright) {
OCR1A = OCR1A - 1;
delay(15);
}
if (OCR1A > 4000) {
OCR1A = 4000;
}
if (OCR1A < 2000) {
OCR1A = 2000;
}
}
Upvotes: 1
Views: 272
Reputation: 2183
You don't need to know (or find out) the pos
of the servo in one go; you can simply move it closer and closer to where it needs to be in every loop until the solar panel is aligned properly.
You could try something like this, which is also a rough translation of the bottom bit of code you quote into the terms of your program.
Note: very rough code, not all details are taken care of, and it is untested, but you get the idea.
const int sensorPin0 = A0;
const int sensorPin1 = A1;
int pos = 90; // Start with centered servo
void setup() {
Serial.begin(9600);
myservo.attach(9);
}
void loop() {
analogRead(sensorPin0); // Do measurements twice and use second one
sensorValue0 = analogRead(sensorPin0); // No need to calculate R values;
analogRead(sensorPin1); // the raw values can also be used.
sensorValue1 = analogRead(sensorPin1);
if (sensorValue0 > sensorValue1) { // If value 0 > value 1, then
pos++; // move one degree towards 180 degrees
if (pos > 180) pos = 180; // Limit pos to 0 - 180
}
if (sensorValue0 < sensorValue1) { // If value 0 < value 1, then
pos--; // move one degree towards 0 degrees
if (pos < 0) pos = 0; // Limit pos to 0 - 180
}
myservo.write(pos); // Let servo go to pos
delay(200); // Wait a bit and do it all again
}
I every loop, the servo will move one degree closer to a properly aligned solar panel. It will stay there as long as both LDRs show the same value.
Note that LDRs are slow, and also that to get good differentiation, you may need to put small shields or tubes on them to prevent them from always getting about the same amount of sun.
Upvotes: 1
Reputation: 96
You could move the Servo in the calculated direction a little bit, check again if the light is getting stronger in that direction, then move again... until the light get darker, then move back.
Upvotes: 0