Hi all,
Not sure if this is the best category to post this project as I'm not really looking for guidance, more so just sharing with the community. If there is somewhere more appropriate please let me know so I can delete this one and repost under the correct category.
Anyway... I've been plucking away at this for some time and have it all working pretty well.
It uses LDR's to track the sun, it has manual control mode, it uses POT's to monitor and limit travel on the axii (linear actuators), it has an RGB LED as an indicator to the current status the tracker is in and at the moment it has a POT to simulate wind strength. This wind potentiometer would need to be replaced with a proper wind speed monitor (anemometer) if one was to build a full size tracker. For now the wind pot is merely there for testing of safety features. If the wind is to strong the tracker will move into what I've called "lie flat mode" to minimize surface area against strong wind.
During low light or night time the tracker will also move into lie flat mode.
Although my test rig is crudely made, it has been tested and seems to preform as desired.
I currently have the code in different tabs on the arduino IDE so it shouldn't matter what order it's pieced together in as long as you have the main code first.
Main Sketch
/* Dual axis solar tracker using 12v DC motor linier actuators,
4 LDR's, 4 limit switches, a wind sensor and manual control
joystick */
//LDR
const int LeftTopLDR = A0;
const int RightTopLDR = A1;
const int LeftBottomLDR = A2;
const int RightBottomLDR = A3;
int lt = 0;
int rt = 0;
int lb = 0;
int rb = 0;
int avt = 0;
int avb = 0;
int avl = 0;
int avr = 0;
int dvert = 0;
int dhoriz = 0;
int tolerance = 1;
const int minLight = 500;
boolean isLightOK = true;
//MOTOR DRIVER
const int AIN1 = 4;
const int AIN2 = 5;
const int APWM = 6;
const int BIN1 = 7;
const int BIN2 = 8;
const int BPWM = 9;
const int StandBy = 10;
boolean motorAstate = true;
boolean motorBstate = true;
//LED
const int redLEDpin = 3;
const int greenLEDpin = 12;
const int blueLEDpin = 11;
int slowFlash = 3000;
int displace = 500;
int value;
long time = 0;
//WIND SENSOR
boolean isWindOK = true;
const int windSensorPin = A6;
const int maxWind = 600;
const int numReadings = 20;
int windReadings[numReadings];
int windIndex = 0;
int windTotal = 0;
int windAverage = 0;
unsigned long startWindMillis = 0;
unsigned long prevWindMillis = 0;
unsigned long windInterval = 1000;
//POTENTIOMETERS
const int vertPotPin = A4;
const int horizPotPin = A5;
const int vertPotMax = 510;
const int vertPotMin = 300;
const int horizPotMax = 750;
const int horizPotMin = 300;
const int horizPotMid = 510;
const int deadBand = 10;
int vertPotVal = 0;
int horizPotVal = 0;
//ALIGNMENT VARIABLES
unsigned long startAlignMillis = 0;
unsigned long prevAlignMillis = 0;
unsigned long alignedInterval = 5000;
boolean isAlignFirstLoop = true;
//LIE FLAT VARIABLES
unsigned long startLieFlatMillis = 0;
unsigned long prevLieFlatMillis = 0;
unsigned long lieFlatInterval = 5000;
boolean lieFlatTrigger = false;
boolean isLieFlatFirstLoop = true;
boolean comingFromAligned = true;
//MANUAL CONTROL VARIABLES
boolean manualControlSwitch;
const int buttonPin = 22; // the number of the pushbutton pin
int buttonState; // the current reading from the input pin
int lastButtonState = LOW; // the previous reading from the input pin
unsigned long startDebounceTime = 0;
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 30; // the debounce time; increase if the output flickers
const int ledPin = 13;
int ledState = LOW;
const int joyVertPin = A8;
const int joyHorizPin = A9;
int joyVertVal = 0;
int joyHorizVal = 0;
int joyVertMidPoint = 127;
int joyHorizMidPoint = 113;
int joyDeadZone = 10;
int buttonReading = 0;
void setup()
{
Serial.begin(9600);
// INITIALIZE WIND SENSOR TO 0:
for (int thisReading = 0; thisReading < numReadings; thisReading++)
windReadings[thisReading] = 0;
// SET PIN MODES FOR MANUAL CONTROL.
pinMode(buttonPin, INPUT_PULLUP);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, ledState);
// SET PIN MODES FOR LEDS
pinMode(redLEDpin, OUTPUT);
pinMode(greenLEDpin, OUTPUT);
pinMode(blueLEDpin, OUTPUT);
digitalWrite(blueLEDpin, HIGH);
digitalWrite(greenLEDpin, HIGH);
digitalWrite(redLEDpin, LOW);
delay(4000);
digitalWrite(redLEDpin, HIGH);
// SET PIN MODES FOR MOTOR DRIVER
pinMode(AIN1, OUTPUT);
pinMode(AIN2, OUTPUT);
pinMode(BIN1, OUTPUT);
pinMode(BIN2, OUTPUT);
pinMode(APWM, OUTPUT);
pinMode(BPWM, OUTPUT);
pinMode(StandBy, OUTPUT);
digitalWrite(AIN1, LOW);
digitalWrite(AIN2, LOW);
digitalWrite(BIN1, LOW);
digitalWrite(BIN2, LOW);
digitalWrite(APWM, LOW);
digitalWrite(BPWM, LOW);
digitalWrite(StandBy, LOW);
}
void loop(){
CheckPots();
// CHECK BOTTON STATE FOR MANUAL CONTROL AND SWITCH ACCORDINGLY
startDebounceTime = millis();
buttonReading = digitalRead(buttonPin);
if(buttonReading != lastButtonState) {
lastDebounceTime = startDebounceTime;
}
if((unsigned long)startDebounceTime - lastDebounceTime >= debounceDelay) {
if(buttonReading != buttonState) {
buttonState = buttonReading;
if(buttonState == LOW) {
manualControlSwitch = !manualControlSwitch;
}
}
}
digitalWrite(ledPin, ledState);
lastButtonState = buttonReading;
if(manualControlSwitch == true){
digitalWrite(greenLEDpin, HIGH); // FADE BLUE LED OFF AND ON.
digitalWrite(redLEDpin, HIGH);
time = millis();
value = 128+127*cos(2*PI/slowFlash*time);
analogWrite(blueLEDpin, value);
ManualControl();
// Serial.println(" ManualControl ");
}
//else{
CheckLight(); //IF MANUAL CONTROL NOT ACTIVE CHECK WIND AND LIGHT CONDITIONS:
CheckWind();
//}
if((lieFlatTrigger == true) && (manualControlSwitch == false)){
LieFlat(); //MOVE PANELS SO THEY ARE FLAT AND LEVEL FOR
// Serial.println(" Lie Flat "); //ETHER HIGH WINDS OR LOW LIGHT (NIGHT TIME).
}
else if((isLightOK == true) && (isWindOK == true) && (lieFlatTrigger == false) && (manualControlSwitch == false)){
UpdatePosition(); //ONLY WHEN ALL CONDITIONS ARE
// Serial.println(" UpdatePosition "); //MET IS IT OK TO UPDATE POSITION.
}
}
Checklight
void CheckLight(){
lt = analogRead(LeftTopLDR); // READ AND CALCULATE LIGHT SENSORS
rt = analogRead(RightTopLDR);
lb = analogRead(LeftBottomLDR);
rb = analogRead(RightBottomLDR);
avt = (lt + rt) / 2; // average value top
avb = (lb + rb) / 2; // average value bottom
avl = (lt + lb) / 2; // average value left
avr = (rt + rb) / 2; // average value right
dvert = avt - avb; // calculate the diffirence between the top and bottom
dhoriz = avl - avr;// calculate the diffirence between the left and rigt
int aveLight = (lt + rt + lb + rb) / 4;//GET THE AVERAGE LIGHT READING FROM THE LDR's
Serial.print(" Average Light ");
Serial.println(aveLight);
if(aveLight >= minLight){ // IF THERE IS ENOUGH LIGHT
isLightOK = true;
}
else{
isLightOK = false;
lieFlatTrigger = true; // SETS THE CONDITION FOR THE LIE FLAT FUNCTION
}
}