A program to control a solar tracking platform to keep solar panels pointed at the sun. Details of the hardware can be found at mdpub.com.
main.cpp@0:c5d947408ea3, 2013-07-08 (annotated)
- Committer:
- omegageek64
- Date:
- Mon Jul 08 13:38:37 2013 +0000
- Revision:
- 0:c5d947408ea3
Tested in the field. Working.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
omegageek64 | 0:c5d947408ea3 | 1 | #include "mbed.h" |
omegageek64 | 0:c5d947408ea3 | 2 | |
omegageek64 | 0:c5d947408ea3 | 3 | //Program to control a sun tracking platform for solar panels. |
omegageek64 | 0:c5d947408ea3 | 4 | //Details of the hardware can be found at mdpub.com |
omegageek64 | 0:c5d947408ea3 | 5 | |
omegageek64 | 0:c5d947408ea3 | 6 | void stop(); |
omegageek64 | 0:c5d947408ea3 | 7 | void moveW(); |
omegageek64 | 0:c5d947408ea3 | 8 | void moveE(); |
omegageek64 | 0:c5d947408ea3 | 9 | void resetE(); |
omegageek64 | 0:c5d947408ea3 | 10 | void readcells(); |
omegageek64 | 0:c5d947408ea3 | 11 | |
omegageek64 | 0:c5d947408ea3 | 12 | Serial pc(USBTX, USBRX); |
omegageek64 | 0:c5d947408ea3 | 13 | AnalogIn Ecell(p19), Wcell(p20); |
omegageek64 | 0:c5d947408ea3 | 14 | DigitalIn ELimit(p5), WLimit(p6); |
omegageek64 | 0:c5d947408ea3 | 15 | InterruptIn EInt(p8), WInt(p9); |
omegageek64 | 0:c5d947408ea3 | 16 | DigitalOut MotorOn(p22), Direction(p21); |
omegageek64 | 0:c5d947408ea3 | 17 | DigitalOut MyLed1(LED1), MyLed2(LED2); |
omegageek64 | 0:c5d947408ea3 | 18 | int AtReset; |
omegageek64 | 0:c5d947408ea3 | 19 | float Sunup, Threshold, RunTime; |
omegageek64 | 0:c5d947408ea3 | 20 | float Eval, Wval, Ambval; |
omegageek64 | 0:c5d947408ea3 | 21 | |
omegageek64 | 0:c5d947408ea3 | 22 | void stop() { //Stop the drive motor. The interrupt calls this if either limit switch opens. |
omegageek64 | 0:c5d947408ea3 | 23 | pc.printf("Stop!\n\r"); //Print "Stop!" to the serial terminal for calibration/troubleshooting purposes. |
omegageek64 | 0:c5d947408ea3 | 24 | Direction = 0; //Open the direction and motor drive relays. |
omegageek64 | 0:c5d947408ea3 | 25 | MotorOn = 0; |
omegageek64 | 0:c5d947408ea3 | 26 | } |
omegageek64 | 0:c5d947408ea3 | 27 | |
omegageek64 | 0:c5d947408ea3 | 28 | void moveW() { //Move the panel W. |
omegageek64 | 0:c5d947408ea3 | 29 | Direction = 0; //Set direction to W. |
omegageek64 | 0:c5d947408ea3 | 30 | MotorOn = 1; //Run the motor. |
omegageek64 | 0:c5d947408ea3 | 31 | pc.printf("Motor on W!\n\r"); //Print "Motor on W!" to the serial terminal for calibration/troubleshooting purposes. |
omegageek64 | 0:c5d947408ea3 | 32 | wait(RunTime); //Run the motor for RunTime. |
omegageek64 | 0:c5d947408ea3 | 33 | MotorOn = 0; //Turn the motor off. |
omegageek64 | 0:c5d947408ea3 | 34 | AtReset = 0; //Set AtReset to 0 because we are not all the way E. |
omegageek64 | 0:c5d947408ea3 | 35 | } |
omegageek64 | 0:c5d947408ea3 | 36 | |
omegageek64 | 0:c5d947408ea3 | 37 | void moveE() { //Move the panel E. |
omegageek64 | 0:c5d947408ea3 | 38 | Direction = 1; //Set direction to E. |
omegageek64 | 0:c5d947408ea3 | 39 | wait(0.5); |
omegageek64 | 0:c5d947408ea3 | 40 | MotorOn = 1; //Run the motor. |
omegageek64 | 0:c5d947408ea3 | 41 | pc.printf("Motor on E!\n\r"); //Print "Motor on E!" to the serial terminal for calibration/troubleshooting purposes. |
omegageek64 | 0:c5d947408ea3 | 42 | wait(RunTime); //Run the motor for RunTime. |
omegageek64 | 0:c5d947408ea3 | 43 | MotorOn = 0; //Open the motor power and direction relays. |
omegageek64 | 0:c5d947408ea3 | 44 | Direction = 0; |
omegageek64 | 0:c5d947408ea3 | 45 | } |
omegageek64 | 0:c5d947408ea3 | 46 | |
omegageek64 | 0:c5d947408ea3 | 47 | void resetE() { //Move the panel all the way E after dark so that the sun will shine on it after sunrise. |
omegageek64 | 0:c5d947408ea3 | 48 | while (!ELimit) { //While the E limit switch is closed. |
omegageek64 | 0:c5d947408ea3 | 49 | moveE(); |
omegageek64 | 0:c5d947408ea3 | 50 | } |
omegageek64 | 0:c5d947408ea3 | 51 | AtReset = 1; //Set AtReset to 1 since we are now all the way E. |
omegageek64 | 0:c5d947408ea3 | 52 | } |
omegageek64 | 0:c5d947408ea3 | 53 | |
omegageek64 | 0:c5d947408ea3 | 54 | void readcells() { //Read the values of the E & W cells 5 times each and average the values. |
omegageek64 | 0:c5d947408ea3 | 55 | int i; |
omegageek64 | 0:c5d947408ea3 | 56 | for(i = 0; i < 5; i++){ //Loop 5 times |
omegageek64 | 0:c5d947408ea3 | 57 | Wval += Wcell.read(); //Read the values |
omegageek64 | 0:c5d947408ea3 | 58 | Eval += Ecell.read(); |
omegageek64 | 0:c5d947408ea3 | 59 | } |
omegageek64 | 0:c5d947408ea3 | 60 | Wval = Wval / 5; //Average the values |
omegageek64 | 0:c5d947408ea3 | 61 | Eval = Eval / 5; |
omegageek64 | 0:c5d947408ea3 | 62 | } |
omegageek64 | 0:c5d947408ea3 | 63 | |
omegageek64 | 0:c5d947408ea3 | 64 | int main() { |
omegageek64 | 0:c5d947408ea3 | 65 | pc.printf("Powered Up\n\r"); //Print "Powered Up" to the serial terminal for calibration/troubleshooting purposes. |
omegageek64 | 0:c5d947408ea3 | 66 | EInt.rise(&stop); //Call motor stop if either limit switch opens. |
omegageek64 | 0:c5d947408ea3 | 67 | WInt.rise(&stop); |
omegageek64 | 0:c5d947408ea3 | 68 | AtReset = 0; //1=at E limit. |
omegageek64 | 0:c5d947408ea3 | 69 | Sunup = 0.08; //Ambient light threshold at which sun is considered to be up. |
omegageek64 | 0:c5d947408ea3 | 70 | Threshold = 0.035; //Max allowed difference between E & W inputs. |
omegageek64 | 0:c5d947408ea3 | 71 | RunTime = 1.25; //How long the motor shold run on each move. (about 6 deg/sec after slight turn-on delay) |
omegageek64 | 0:c5d947408ea3 | 72 | while(1) { //Loop forever. |
omegageek64 | 0:c5d947408ea3 | 73 | readcells(); //Read the values of the E & W cells. |
omegageek64 | 0:c5d947408ea3 | 74 | Ambval = Wval + Eval; //Find the ambient light level |
omegageek64 | 0:c5d947408ea3 | 75 | MyLed1 = ELimit; MyLed2 = WLimit; |
omegageek64 | 0:c5d947408ea3 | 76 | pc.printf("%f %f %f\r\n", Wval, Eval, Ambval); //Print the west, east, and ambient values to the serial terminal for calibration purposes. |
omegageek64 | 0:c5d947408ea3 | 77 | if ((Ambval > (Sunup + 0.4)) ){ //If the sun is up ... |
omegageek64 | 0:c5d947408ea3 | 78 | if (((Wval-Eval) > Threshold) && !WLimit){ //If the W cell is illuminated by more than the threshhold and the W limit swich is closed... |
omegageek64 | 0:c5d947408ea3 | 79 | moveW(); //Move the panel W. |
omegageek64 | 0:c5d947408ea3 | 80 | } |
omegageek64 | 0:c5d947408ea3 | 81 | if (((Eval-Wval) > Threshold) && !ELimit){ //If the E cell is illuminated by more than the threshhold and the E limit swich is closed... |
omegageek64 | 0:c5d947408ea3 | 82 | moveE(); //Move the panel E. |
omegageek64 | 0:c5d947408ea3 | 83 | } |
omegageek64 | 0:c5d947408ea3 | 84 | } |
omegageek64 | 0:c5d947408ea3 | 85 | if ((Ambval < Sunup) && !AtReset) { //If the sun is down and the panel is not reset to the E... |
omegageek64 | 0:c5d947408ea3 | 86 | resetE(); //Move the panel to the E reset position. |
omegageek64 | 0:c5d947408ea3 | 87 | } |
omegageek64 | 0:c5d947408ea3 | 88 | wait(60); //Kill time. Set to 5 seconds during calibration/testing. |
omegageek64 | 0:c5d947408ea3 | 89 | } |
omegageek64 | 0:c5d947408ea3 | 90 | } |