#include <TimeLib.h> //https://github.com/PaulStoffregen/Time #include <EEPROM.h> // Suntracker addon with actuator, for solarTrolley // open source suntracker project for higher performance solarpanels // Arduino IDE 1.18 This version is a standalone version of the webbased solartracker // You need to make some kind of data view mode trough serial/usb or embed some code for at display if you will used the polulo current chip data // Author: http://techmind.dk michael pedersen // Project home: http://techmind.dk/tag/suntracker/ // Start Date: 24. feb 2019 // License: coyright // Version: 08b // Update: 01 //*********************************************************************** //Define solartracker ports, valiables and static //Digital ports // 0 , 1 recerved for serial com //const byte interruptPin = 2; // interrupt Data pin from actuator position encoder const int motorController_IN3_OUT3 = 3; // HIGH = go WEST const int motorController_IN4_OUT4 = 4; // HIGH = go EAST //D in/out 5 NC/free const int dipSwitchWest = 6; const int ledAlive = 7; const int dipSwitchEast = 8; const int ledCheck = 9; //Analog ports int solarVoltSensor = 0; //int free = 1; int lightSensorEast = 2; //LDR int lightSensorWest = 3; //LDR int solarCurrentSensor = 4; int actuatorCurrentSensor = 5; //Variables long lowCounter = 0; int waitMinutesToNextTrackUpdate = 1; //This value is in minutes 1 equal one minut 5 eual 5 minuttes. In my application it is Set to 3 or 5 minutes bool testModeSet = 0; bool onWayHomeToWest = 0; bool east = 0; bool west = 1; bool acuatorCurrentExceeded; //1 = ok, 0 = overcurrent, Physical Limit, stop actuator bool dipSwitchWestState = 0; bool dipSwitchEastState = 0; int optoPositionTheValue = 0; int solarCurrentValue = 0; int actuatorCurrentSensorValue; // Stop actuator +-15 from 520 int lightSensorEastValue; int lightSensorWestValue; int addrE2 = 0; //eeprom start adress byte suntrackerPositionFromE2; //volatile int state = LOW; // The input state toggle //Declare metodes void goHomeWest(); //go all the way back to west start position void goHomeEast(); //go all the way back to west start position void goToWest(); void goToEast(); void stopActuator(); void testMode(); //******************** //Initialize and setup //******************** void setup(){ Serial.begin(9600); Serial.println("Hello world, i am suntracker and alive ;) "); //Initialize Solartracker ports and variables pinMode(ledAlive, OUTPUT); pinMode(ledCheck, OUTPUT); pinMode(dipSwitchWest, INPUT); pinMode(dipSwitchEast, INPUT); // Initialize Motor controller ports pinMode(motorController_IN3_OUT3, OUTPUT); // pinMode(motorController_IN4_OUT4, OUTPUT); // // Initialize, make sure actuator is stopped stopActuator(); digitalWrite(ledCheck, HIGH); //Attach the interrupt to the input pin and monitor for ANY Change //attachInterrupt(digitalPinToInterrupt(interruptPin), stateChange, CHANGE); //Set lowcounter time_t t = now(); // store the current time in time variable t minute(t); // returns the minute for the given time t lowCounter =minute(t); // set test mode testModeSet = LOW; //set to HIGH to enter test mode onWayHomeToWest = LOW; blinkGreenLEDFast(); digitalWrite(ledAlive, LOW); acuatorCurrentExceeded = HIGH; } //********************************** // The loop where everything happens //********************************** void loop(){ //Main state maschine Serial.println(optoPositionTheValue); if (!testModeSet) { // Run normal blinkGreenLEDSlow(); Serial.println("Run mode"); checkDualDipswitchPress(); // Enter testmode, press both endstop dipswitches at the same time checkSuntrackerCurrentPosition(); gotoNextSuntrackerPosition(); time_t t = now(); Serial.println(second(t)); } else { // Go into Testmode blinkRedLEDFast(); Serial.println("Test mode"); testMode(); digitalWrite(ledAlive, LOW); checkDualDipswitchPress(); // Leave testmode, press both endstop dipswitches at the same time } } void gotoNextSuntrackerPosition() { // *** Start test light level east / west lightSensorEastValue = analogRead(lightSensorEast); lightSensorWestValue = analogRead(lightSensorWest); Serial.print(lightSensorEastValue); Serial.print("....."); Serial.println(lightSensorWestValue); checkActuatorPhysicalLimit(); Serial.print(dipSwitchEastState); Serial.print("....."); Serial.println(dipSwitchWestState); //Check where to turn the suntracker to, to optain most light fotons if (lightSensorWestValue > lightSensorEastValue) { time_t t = now(); if ((lowCounter+waitMinutesToNextTrackUpdate) == (minute(t))) { goToWest(); Serial.println("Moving West"); } } else if (lightSensorWestValue < lightSensorEastValue) { time_t t = now(); if ((lowCounter+waitMinutesToNextTrackUpdate) == (minute(t))) { goToEast(); Serial.println("Moving east"); } } else if (lightSensorWestValue = lightSensorEastValue) { //LDR east and West equal, so stop actuator and copy minutes here and now til lowCounter, the wait offset data, not a counter, sorry stopActuator(); time_t t = now(); lowCounter =minute(t); } } void checkActuatorPhysicalLimit() { dipSwitchEastState = digitalRead(dipSwitchEast); // read dipswitch East 0 = pressed = end stop dipSwitchWestState = digitalRead(dipSwitchWest); // read dipswitch west 0 = pressed = end stop } void checkDualDipswitchPress() // Toggle testmode flag { // Both dipswitches pressed enter testmode dipSwitchEastState = digitalRead(dipSwitchEast); // read dipswitch west 0 = pressed = end stop if (!dipSwitchEastState) { dipSwitchWestState = digitalRead(dipSwitchWest); // read dipswitch west 0 = pressed = end stop if (!dipSwitchWestState) { testModeSet = !testModeSet; } } } void goToWest() { digitalWrite(ledCheck, HIGH); checkActuatorPhysicalLimit(); actuatorCurrentCheck(); if (acuatorCurrentExceeded) { if (dipSwitchWestState) { digitalWrite(motorController_IN3_OUT3, HIGH); digitalWrite(motorController_IN4_OUT4, LOW); } else { stopActuator(); } } else { stopActuator(); } } void goToEast() { checkActuatorPhysicalLimit(); actuatorCurrentCheck(); if (acuatorCurrentExceeded) { if (dipSwitchEastState) { digitalWrite(ledCheck, HIGH); digitalWrite(motorController_IN3_OUT3, LOW); digitalWrite(motorController_IN4_OUT4, HIGH); } else { stopActuator(); } } else { stopActuator(); } } void actuatorCurrentCheck() { actuatorCurrentSensorValue = analogRead(actuatorCurrentSensor); Serial.println(actuatorCurrentSensorValue); if (actuatorCurrentSensorValue > 540) { acuatorCurrentExceeded = LOW; Serial.println("acuator Current Exceeded!!"); } else if (actuatorCurrentSensorValue < 495) { acuatorCurrentExceeded = LOW; Serial.println("acuator Current Exceeded!!"); } } void stopActuator() { digitalWrite(motorController_IN3_OUT3, LOW); digitalWrite(motorController_IN4_OUT4, LOW); digitalWrite(ledCheck, LOW); } void checkSuntrackerCurrentPosition() { suntrackerPositionFromE2 = EEPROM.read(addrE2);//write EEPROM.write(addr, val); //optoPositionThePhotoTransistor interrupt data pin in //optoPositionTheValue } void testMode() { stopActuator(); acuatorCurrentExceeded = HIGH; } void blinkGreenLEDFast() { // Blink, Great solar tracker is alive digitalWrite(ledAlive, HIGH); delay(100); digitalWrite(ledAlive, LOW); delay(100); } void blinkGreenLEDSlow() { // Blink, Great solar tracker is alive digitalWrite(ledAlive, HIGH); delay(300); digitalWrite(ledAlive, LOW); delay(300); } void blinkRedLEDSlow() { // Blink, Great solar tracker is alive digitalWrite(ledCheck, HIGH); delay(300); digitalWrite(ledCheck, LOW); delay(300); } void blinkRedLEDFast() { // Blink, Great solar tracker is alive digitalWrite(ledCheck, HIGH); delay(100); digitalWrite(ledCheck, LOW); delay(100); }
Leave a comment