Hello All,
My solar dual axis tracker works well under artificial light and follows torch light perfectly, BUT as soon as I put it outside in the sun( no clouds) ,it goes to it's start position and ignores the sun. I put opaque plastic caps (ex pir sensors) on the 4 LDR's, to soften the sun light, but it made no difference.
Can someone please suggest what is wrong with the below code? Many thanks..Use code tags to format code for the forum
pin assignment questionable ???
The numbers represent analog's eg A0,A1,A2,A3 for 0,1,2,3
please re-edit your first post to put your code into a so called code-section
It is very unlikely that your code is causing the malfunction, because it works with flashlight as inteneded.
For analysing if your LDRs are saturated or not by the much brighter sunlight you should add code that prints the values of the analogRead-functions to the serial monitor.
Even a pretty "strong" flashlight might have 500 Lumen of light intensity
Bright sunlight is 10000 Lumen. 20 times more.
Which means all four LDRs are reporting "uaaah is this bright ! Bring me the sunscreen and my sun-glasses!"
Or in ADC-numbers
All four LDRs report ADC-value 1023 (if your microcontroller is an arduino-Uno)
even in case your sensors look under an angle of 45 degrees to the sun.
StefanL38. -->Sorry, but I have no idea where the code section is. I put my code between a start and end code tag, apart from that I have no idea, sorry.
You simply click on this link below and then you can read a tutorial that shows it step by step
Use a local RTC to turn the solar tracker simply.
Hi, @amspen
Can you please post some images of your tracker, in particular the LDR sensor assembly.
Can you please post a copy of your circuit, a picture of a hand drawn circuit in jpg, png?
Hand drawn and photographed is perfectly acceptable.
Please include ALL hardware, power supplies, component names and pin labels.
Before you repost your code, press [ CTRL ] [ T ] , this will auto format your code and make it easier to follow.
Can I suggest some Serial.print statements in your code to display the sensor data on the IDE monitor.
Also change Serial.begin(9600) to Serial.begin(115200), then make sure you change the baud rate in the IDE monitor to 115200.
Thanks.. Tom...
Format your code using Tools/Auto Format in the future.
The sun is several orders of magnitude stronger than whatever you used, you will need to adjust sensitivity.
Hello Tom
I got the code from :https://www.instructables.com/Arduino-Solar-Tracker/
I set the Serial.begin to 115200 , as you suggest
I don't know how to put :Serial.print statements in the code.
#include <Servo.h> // include Servo library
Servo horizontal; // horizontal servo
int servoh = 90; // stand horizontal servo
Servo vertical; // vertical servo
int servov = 90; // stand vertical servo
int tol = 50; // Increase tolerance
int dtime = 10; // Reduce delay for faster response
// LDR pin connections
// name = analogpin;
int ldrlt = 0; //LDR top left
int ldrrt = 1; //LDR top right
int ldrld = 2; //LDR down left
int ldrrd = 3; //ldr down right
void setup()
{
Serial.begin(115200);
// servo connections
// name.attacht(pin);
horizontal.attach(9);
vertical.attach(10);
}
void loop()
{
int lt = analogRead(ldrlt); // left top
int rt = analogRead(ldrrt); // right top
int ld = analogRead(ldrld); // left down
int rd = analogRead(ldrrd); // right down
int dtime = analogRead(4) / 20; // read potentiometer
int tol = analogRead(5) / 4;
int avt = (lt + rt) / 2; // average value top
int avd = (ld + rd) / 2; // average value down
int avl = (lt + ld) / 2; // average value left
int avr = (rt + rd) / 2; // average value right
int dvert = avt - avd; // check the difference of top and down
int dhoriz = avl - avr;// check the difference of left and right
if (-1 * tol > dvert || dvert > tol) // check if the diffirence is in the tolerance else change vertical angle
{ // || means "OR"
if (avt > avd)
{
servov = ++servov;
if (servov > 180)
{
servov = 180;
}
}
else if (avt < avd)
{
servov = --servov;
if (servov < 0)
{
servov = 0;
}
}
vertical.write(servov);
}
if (-1 * tol > dhoriz || dhoriz > tol) // check if the difference is in the tolerance else
//change horizontal angle
{
if (avl > avr)
{
servoh = --servoh;
if (servoh < 0)
{
servoh = 0;
}
}
else if (avl < avr)
{
servoh = ++servoh;
if (servoh > 180)
{
servoh = 180;
}
}
else if (avl == avr)
{
// nothing
}
horizontal.write(servoh);
}
delay(dtime);
}
Hi, @amspen
I have edited your code to include a monitor display function.
When you try it, make sure the IDE monitor speed is set to 115200.
It will give you the raw data from each of the LDRs.
#include <Servo.h> // include Servo library
Servo horizontal; // horizontal servo
int servoh = 90; // stand horizontal servo
Servo vertical; // vertical servo
int servov = 90; // stand vertical servo
int tol = 50; // Increase tolerance
int dtime = 10; // Reduce delay for faster response
// LDR pin connections
// name = analogpin;
int ldrlt = 0; //LDR top left
int ldrrt = 1; //LDR top right
int ldrld = 2; //LDR down left
int ldrrd = 3; //ldr down right
int lt;
int rt;
int ld;
int rd;
void setup() {
Serial.begin(115200);
// servo connections
// name.attacht(pin);
horizontal.attach(9);
vertical.attach(10);
}
void loop() {
lt = analogRead(ldrlt); // left top
rt = analogRead(ldrrt); // right top
ld = analogRead(ldrld); // left down
rd = analogRead(ldrrd); // right down
serialout();
int dtime = analogRead(4) / 20; // read potentiometer
int tol = analogRead(5) / 4;
int avt = (lt + rt) / 2; // average value top
int avd = (ld + rd) / 2; // average value down
int avl = (lt + ld) / 2; // average value left
int avr = (rt + rd) / 2; // average value right
int dvert = avt - avd; // check the difference of top and down
int dhoriz = avl - avr; // check the difference of left and right
if (-1 * tol > dvert || dvert > tol) // check if the diffirence is in the tolerance else change vertical angle
{ // || means "OR"
if (avt > avd) {
servov = ++servov;
if (servov > 180) {
servov = 180;
}
} else if (avt < avd) {
servov = --servov;
if (servov < 0) {
servov = 0;
}
}
vertical.write(servov);
}
if (-1 * tol > dhoriz || dhoriz > tol) // check if the difference is in the tolerance else
//change horizontal angle
{
if (avl > avr) {
servoh = --servoh;
if (servoh < 0) {
servoh = 0;
}
} else if (avl < avr) {
servoh = ++servoh;
if (servoh > 180) {
servoh = 180;
}
} else if (avl == avr) {
// nothing
}
horizontal.write(servoh);
}
delay(dtime);
}
//==================================
void serialout() {
Serial.print("lefttop = ");
Serial.print(lt);
Serial.print("\t righttop = ");
Serial.print(rt);
Serial.print("\t leftdown = ");
Serial.print(ld);
Serial.print("\t rightdown = ");
Serial.println(rd);
}
You should see the values change as you cover each LDR.
You do have the X shaped visor on the LDR assembly?
Tom...
Hi,
I have edited it a bit more to allow the ADC to keep up with the multiplexed inputs.
#include <Servo.h> // include Servo library
Servo horizontal; // horizontal servo
int servoh = 90; // stand horizontal servo
Servo vertical; // vertical servo
int servov = 90; // stand vertical servo
int tol = 50; // Increase tolerance
int dtime = 10; // Reduce delay for faster response
// LDR pin connections
// name = analogpin;
int ldrlt = 0; //LDR top left
int ldrrt = 1; //LDR top right
int ldrld = 2; //LDR down left
int ldrrd = 3; //ldr down right
int lt;
int rt;
int ld;
int rd;
void setup() {
Serial.begin(115200);
// servo connections
// name.attacht(pin);
horizontal.attach(9);
vertical.attach(10);
}
void loop() {
lt = analogRead(ldrlt); // left top
lt = analogRead(ldrlt); // left top
rt = analogRead(ldrrt); // right top
rt = analogRead(ldrrt); // right top
ld = analogRead(ldrld); // left down
ld = analogRead(ldrld); // left down
rd = analogRead(ldrrd); // right down
rd = analogRead(ldrrd); // right down
serialout();
int dtime = analogRead(4) / 20; // read potentiometer
int tol = analogRead(5) / 4;
int avt = (lt + rt) / 2; // average value top
int avd = (ld + rd) / 2; // average value down
int avl = (lt + ld) / 2; // average value left
int avr = (rt + rd) / 2; // average value right
int dvert = avt - avd; // check the difference of top and down
int dhoriz = avl - avr; // check the difference of left and right
if (-1 * tol > dvert || dvert > tol) // check if the diffirence is in the tolerance else change vertical angle
{ // || means "OR"
if (avt > avd) {
servov = ++servov;
if (servov > 180) {
servov = 180;
}
} else if (avt < avd) {
servov = --servov;
if (servov < 0) {
servov = 0;
}
}
vertical.write(servov);
}
if (-1 * tol > dhoriz || dhoriz > tol) // check if the difference is in the tolerance else
//change horizontal angle
{
if (avl > avr) {
servoh = --servoh;
if (servoh < 0) {
servoh = 0;
}
} else if (avl < avr) {
servoh = ++servoh;
if (servoh > 180) {
servoh = 180;
}
} else if (avl == avr) {
// nothing
}
horizontal.write(servoh);
}
delay(dtime);
}
//==================================
void serialout() {
Serial.print("lefttop = ");
Serial.print(lt);
Serial.print("\t righttop = ");
Serial.print(rt);
Serial.print("\t leftdown = ");
Serial.print(ld);
Serial.print("\t rightdown = ");
Serial.println(rd);
}
Tom..
Hi Tom. All values show 1023 in the sun and the X shaped visor in the picture, is near identical to the one I made, which I painted matt black.
Sounds like a problem in the wiring or choice of components (the LDRs and associated resistors).
The wiring diagram in the original Instructables is nearly uninterpretable, and the 10K value for the resistors in the voltage dividers is probably much too large. Or, the ground connection is missing.
Something like this would probably work, with resistors of 1K or less:
What if you cover them up, or even just one LDR, can you see a difference?
You are running the code in post #15?
Tom..
I uploaded your last code:
Inside all show values around 600/800 , using a led torch all values go to 1023.
Outside all values also show 1023. Blocking light on each, decreases the value and instantly changes the orientation.
Hi,
Take @jremington advise in post #17, that should help.
The LDRs are saturated even in the shade of the sun.
Tom..
The diagram you are showing is the same as what I made.
The only difference is the resistor value, mine are 10K.
I will replace mine later with 330 Ohm, as you suggest .
As a matter of interest, What are the pot meters connected to A4 (tolerance ) & A5 (speed) for?