Robin Chávez
Published

Solar Panel Tracking System

Dual-Axis Panel Tracking System that uses two servo motors and LDRs to simulate the sun's tracking depending on its position

AdvancedShowcase (no instructions)390
Solar Panel Tracking System

Things used in this project

Hardware components

MSP-EXP430G2 MSP430 LaunchPad
Texas Instruments MSP-EXP430G2 MSP430 LaunchPad
×1
SG90 Micro-servo motor
SG90 Micro-servo motor
×2
LDR, 5 Mohm
LDR, 5 Mohm
×1
Female/Female Jumper Wires
Female/Female Jumper Wires
×1
Male/Female Jumper Wires
Male/Female Jumper Wires
×1
Jumper wires (generic)
Jumper wires (generic)
×1
9V battery (generic)
9V battery (generic)
×1
Anycubic i3 Mega 3D printer
Anycubic i3 Mega 3D printer
×1

Software apps and online services

Code Composer Studio
Texas Instruments Code Composer Studio
Fritzing

Hand tools and fabrication machines

3D Printer (generic)
3D Printer (generic)
Wood Base

Story

Read more

Schematics

Circuit Diagram

Code

SolarPanelTracking

C Header File
#include "msp430.h"
//Defining each of the LDR sensors and their inputs into the board
//The pins are required to connect the LDR and create the
//connection with the rest of the components
#define LEFT_SENSOR  BIT0
#define RIGHT_SENSOR BIT1
#define UP_SENSOR    BIT2
#define DOWN_SENSOR  BIT3

#define MCU_CLOCK           1000000 //Defines the micro-controller clock signal
#define PWM_FREQUENCY       46      //Frequency of the Servo Motors
#define SERVOS         60      //How long each of the servos will move in degrees

unsigned int conversion[4];       //conversion to determine what servo to move
unsigned int PWM_Period     = (MCU_CLOCK / PWM_FREQUENCY);  // PWM Period

int i;
int COUNTER;
int COUNTER2;

void Analog_to_Digital(void){ //Configuring the Analog_to_Digital conversion
                              //adapted from https://www.ti.com/product/MSP430G2553
    ADC10CTL1 = INCH_3 | ADC10DIV_0 | CONSEQ_3 | SHS_0; //Functions given the msp430 library
    ADC10CTL0 = SREF_0 | ADC10SHT_2 | MSC | ADC10ON | ADC10IE;
    ADC10AE0 = LEFT_SENSOR + RIGHT_SENSOR + UP_SENSOR + DOWN_SENSOR ;
    ADC10DTC1 = 4;

}

void main(void) {

    WDTCTL = WDTPW | WDTHOLD;
    TA1CCTL1  = OUTMOD_7 ;          //Generates the PWM outputs with different cycle
    TA0CCTL1  = OUTMOD_7  ;
    TA1CTL  = TASSEL_2 + MC_1 ;
    TA0CTL  = TASSEL_2 + MC_1 ;
    TA1CCR0 = PWM_Period-1;         // PWM Period
    TA0CCR0 = PWM_Period-1 ;
    TA1CCR1 = 0 ;
    TA0CCR1 = 0 ;

    P1DIR = 0;                      //Setting as Inputs ADC
    P1SEL = 0;                      //Digital Inputs
    P1OUT = 0;                      //resistors as pull-down
    P1REN |= (LEFT_SENSOR|RIGHT_SENSOR|DOWN_SENSOR|UP_SENSOR);
    //Setting outputs for the System and being able to control it
    P1DIR   |= BIT6  ;
    P2DIR   |= BIT2 ;
    P1SEL   |= BIT6  ;
    P2SEL   |= BIT2  ;
    Analog_to_Digital(); //Calling the ADC

    __enable_interrupt();
    while (1) {

        __delay_cycles(1000);
        ADC10CTL0 &= ~ENC;                  //Enabling the conversion of the ADC, this time set to 0 to start
        while (ADC10CTL1 & BUSY);           //Busy charges the LDR and shows if it is ready or not to use
        ADC10SA = (unsigned int)conversion; //Casting the conversion to ADC10 Address Pointer
        ADC10CTL0 |= ENC + ADC10SC;

        __bis_SR_register(CPUOFF + GIE);

        for (i = 0; i < SERVOS; i++) {      //Creating the movement of the servos
            TA1CCR1 = COUNTER2 ;
            TA0CCR1 = COUNTER ;
            __delay_cycles(20000);
            TA1CCR1 = COUNTER2 ;
            TA0CCR1 = COUNTER ;
             __delay_cycles(20000);
            }
        }
}

#pragma vector = ADC10_VECTOR
__interrupt void ADC10_ISR (void){
//The conversion helps to determine where each of the servos
//will move according to the light the LDR is receiving
if (conversion[0] < conversion[1]){
    if(conversion[1]> 550){
        COUNTER = 850;
        }
    else {
        COUNTER = 1350;
            }
}
else if ((conversion[0] + conversion[1])/2 < 500) {
    COUNTER = 1350;
} else {
    if(conversion[0]>550){
        COUNTER = 1850;
    }
    else {
        COUNTER = 1350;
    }
}
if (conversion[2] < conversion[3]) {
    if(conversion[3]> 550){
        COUNTER2 =850;
    }
    else {
        COUNTER2 = 1150;
    }
} else if ((conversion[2] + conversion[3])/2 < 500) {
    COUNTER2 = 1150;
}
else {
    if(conversion[2]>550){
        COUNTER2 = 1850;
    }
    else {
        COUNTER2 = 1150;
    }
}

__bic_SR_register_on_exit(CPUOFF);  //Exiting and returning the value of the MSP430

}

Credits

Robin Chávez

Robin Chávez

1 project • 1 follower

Comments