Solar Tracker Trolley C Sketch

#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);
    
  }

Join the Conversation

1 Comment

Leave a comment

Din e-mailadresse vil ikke blive publiceret.