//Power Rangers //Major Contributors: Anjola Ladenegan & Sarah Ritter //Other Contributors: Evan Syers & Meaghan Hannon //This file contains the reference curves in form of 3 dimensional arrays. //This file also contains the power point tracking algorithm #include #include #include "SDlib.h" #include "SDlib_LCD.h" #include "configbitsrev2014vSarah.h" #include #include "Array_File.h" #include #include /* * */ void A2D_init(void); int A2D_conv_voltage(void); int A2D_conv_current(void); int A2D_conv_battery(void); double PowerPoint(double, double); double DutyCycle (double, double); void PWM_Generator(double); int main(int argc, char** argv) { double voltage; double current1 = 4.75; double current2 = 4.75; double battery; double reqvoltage; double dutycycle_des; double dutycycle_act=0; double voltageread; double currentread1; double currentread2; double batteryread; double currentout; LCD_init(); serial_init(57600UL); set_output_device(2); A2D_init(); double counter1=0; double counter2=0; while (1){ /* dutycycle_des = 0; while(fabs(dutycycle_des-dutycycle_act)>0.001){ if (dutycycle_des>dutycycle_act){ dutycycle_act = dutycycle_act + 0.0005; } else if(dutycycle_des<=dutycycle_act){ dutycycle_act = dutycycle_act - 0.0005; } PWM_Generator(dutycycle_act); } PWM_Generator(dutycycle_des); batteryread = A2D_conv_battery(); //battery = (double) batteryread*((3.3/1023)*7); if(battery>12){ for (counter1=0; counter1<100; counter1++){ /*LCD_display_on(); LCD_clear(); LCD_setpos(0,0); printf("Battery Voltage > 12. Not Charging"); dutycycle_act = dutycycle_des; delay_ms(250); } }*/ //else{ //for(counter2=0; counter2<500; counter2++){ battery = 12; voltageread = A2D_conv_voltage(); voltage = (double) voltageread*((3.3/1023)*9.3); currentread1 = A2D_conv_current(); current1 = (double) currentread1*((3.3/1023)*(4.03)); currentread2 = A2D_conv_current(); current2 = (double) currentread2*((3.3/1023)*(4.03)); if (fabs(currentread1-currentread2)>.5){ if (currentread1>currentread2){ currentout = current1; } else if (currentread2>currentread1){ currentout = current2; } } else if(fabs(currentread1-currentread2)<.5){ currentout = current1; reqvoltage=PowerPoint(voltage, currentout); dutycycle_des=DutyCycle(reqvoltage,battery); if(dutycycle_act!=0){ while(fabs(dutycycle_des-dutycycle_act)>0.001){ if (dutycycle_des>dutycycle_act){ dutycycle_act = dutycycle_act + 0.0005; } else if(dutycycle_des<=dutycycle_act){ dutycycle_act = dutycycle_act - 0.0005; } PWM_Generator(dutycycle_act); } } //dutycycle_des = .5; PWM_Generator(dutycycle_des); dutycycle_act = dutycycle_des; LCD_display_on(); LCD_clear(); LCD_setpos(0,0); printf("Voltage : %.4f\r Current: %.4f\r Battery : %.4f\r DutyRatio: %.4f\r", voltage, currentout, battery, dutycycle_act); delay_ms(250); } } return (EXIT_SUCCESS); } void A2D_init(void){ // AD1PCFG = 0; // This statement was giving us errors AD1CON1 = 0; AD1CON1bits.FORM = 4; // 32-bit unsigned Integer AD1CON2 = 0; AD1CON3 = 0; AD1CON3bits.ADCS = 3; // Set for the clock source AD1CON1bits.ON = 1; } int A2D_conv_voltage(void){ int data; AD1CHSbits.CH0SA = 4; AD1CON1bits.SAMP = 1; // Start Acquisition delay_us(1); AD1CON1bits.SAMP = 0; // Start Conversion while(!AD1CON1bits.DONE); data = ADC1BUF0; // Return Samples return (data); } int A2D_conv_current(void){ int data; AD1CHSbits.CH0SA = 5; AD1CON1bits.SAMP = 1; // Start Acquisition delay_us(1); AD1CON1bits.SAMP = 0; // Start Conversion while(!AD1CON1bits.DONE); data = ADC1BUF0; // Return Samples return (data); } int A2D_conv_battery(void){ int data; AD1CHSbits.CH0SA = 6; AD1CON1bits.SAMP = 1; // Start Acquisition delay_us(1); AD1CON1bits.SAMP = 0; // Start Conversion while(!AD1CON1bits.DONE); data = ADC1BUF0; // Return Samples return (data); } /* double PowerPoint (double voltage, double current){ double incurr = current; //0.7; //INCOMING CURRENT double involt = voltage; //20.5; //INCOMING VOLTAGE double voltagerange = 0.5; double d=0; int c=0; int p=0; int m=0; int n=0; int row,column; double minimum_holder=1; double minimum=0; double max=0.0; double volt=0.0; int i = 0; int j = 0; for (i = 0; i < 5; i++) { for(j=0; j<20; j++) { d=sqrt(pow((Array1[i][j][0]-involt),2)+(pow((Array1[i][j][1]-incurr),2))); if (d<=minimum_holder) { minimum=d; } minimum_holder=d; if (d<=voltagerange) { m++; printf ("The distance to the curve is %f\n",d); printf("Interpolated Voltage is = %g \n", Array1[i][j][0]); printf("Interpolated Current is = %g \n", Array1[i][j][1]); printf("Interpolated Power is %f\n",Array1[i][j][2]); printf("This is on curve %d\n",i+1); p=i; } } } if (d==0) { //printf("This point is not close enough to any curve\n"); } else { for (c = 0; c < 20; c++) { if(Array1[p][c][2]>max) { max=Array1[p][c][2]; volt=Array1[p][c][0]; } } //printf("The Maximum Power on that curve is %f\n", max); //printf("The required voltage is %f\n",volt); } }*/ double PowerPoint (double voltage, double current) { double incurr = current; //0.7; //INCOMING CURRENT double involt = voltage; //20.5; //INCOMING VOLTAGE double max=0.0; double volt=0.0; double distarray[120]={0}; int count=0; int location; int w=0; int position; int c=0; int i; int j; for (i = 0; i < 6; i++) { for( j=0; j<20; j++) { distarray[count]=sqrt(pow((Array1[i][j][0]-involt),2)+(pow((Array1[i][j][1]-incurr),2))); //printf("distance is %f\n", distarray[count]); count=count+1; } } double min = distarray[0]; for ( w = 1 ; w < 120 ; w++ ) { if ( distarray[w] < min ) { min = distarray[w]; location = w+1; } } //printf("The closest is : %f\n",min ); //printf("located at %d\n",location); if (location<=20) { position=location-1; //printf("Interpolated Voltage is = %g \n", Array1[0][position][0]); //printf("Interpolated Current is = %g \n", Array1[0][position][1]); //printf("Interpolated Power is %f\n",Array1[0][position][2]); //printf("This is on curve 1\n"); for (c = 0; c < 20; c++) { if(Array1[0][c][2]>max) { max=Array1[0][c][2]; volt=Array1[0][c][0]; } } //printf("The Maximum Power on that curve is %f\n", max); //printf("The required voltage is %f\n",volt); } if(location>20 && location<=40) { position=(location-20)-1; //printf("Interpolated Voltage is = %g \n", Array1[1][position][0]); //printf("Interpolated Current is = %g \n", Array1[1][position][1]); //printf("Interpolated Power is %f\n",Array1[1][position][2]); //printf("This is on curve 2\n"); for (c = 0; c < 20; c++) { if(Array1[1][c][2]>max) { max=Array1[1][c][2]; volt=Array1[1][c][0]; } } //printf("The Maximum Power on that curve is %f\n", max); //printf("The required voltage is %f\n",volt); } if(location>40 && location<=60) { position=(location-40)-1; //printf("Interpolated Voltage is = %g \n", Array1[2][position][0]); //printf("Interpolated Current is = %g \n", Array1[2][position][1]); //printf("Interpolated Power is %f\n",Array1[2][position][2]); //printf("This is on curve 3\n"); for (c = 0; c < 20; c++) { if(Array1[2][c][2]>max) { max=Array1[2][c][2]; volt=Array1[2][c][0]; } } //printf("The Maximum Power on that curve is %f\n", max); //printf("The required voltage is %f\n",volt); } if(location>60 && location<=80) { position=(location-60)-1; //printf("Interpolated Voltage is = %g \n", Array1[3][position][0]); //printf("Interpolated Current is = %g \n", Array1[3][position][1]); //printf("Interpolated Power is %f\n",Array1[3][position][2]); //printf("This is on curve 4\n"); for (c = 0; c < 20; c++) { if(Array1[3][c][2]>max) { max=Array1[3][c][2]; volt=Array1[3][c][0]; } } //printf("The Maximum Power on that curve is %f\n", max); //printf("The required voltage is %f\n",volt); } if(location>80 && location<=100) { position=(location-80)-1; //printf("Interpolated Voltage is = %g \n", Array1[4][position][0]); //printf("Interpolated Current is = %g \n", Array1[4][position][1]); //printf("Interpolated Power is %f\n",Array1[4][position][2]); //printf("This is on curve 5\n"); for (c = 0; c < 20; c++) { if(Array1[4][c][2]>max) { max=Array1[4][c][2]; volt=Array1[4][c][0]; } } //printf("The Maximum Power on that curve is %f\n", max); //printf("The required voltage is %f\n",volt); } if(location>100 && location<=120) { position=(location-100)-1; //printf("Interpolated Voltage is = %g \n", Array1[5][position][0]); //printf("Interpolated Current is = %g \n", Array1[5][position][1]); //printf("Interpolated Power is %f\n",Array1[5][position][2]); //printf("This is on curve 6"); for (c = 0; c < 20; c++) { if(Array1[5][c][2]>max) { max=Array1[5][c][2]; volt=Array1[5][c][0]; } } //printf("The Maximum Power on that curve is %f\n", max); //printf("The required voltage is %f\n",volt); } if (min>=10) { //printf("This point is not close enough to any curve\n"); volt=0; } return volt; } double DutyCycle (double reqvoltage, double batteryvoltage) { double duty; /*if(batteryvoltage < 3.000 || reqvoltage < 10.00){ duty = 0; }*/ //else { duty = batteryvoltage/reqvoltage; //} return duty; } void PWM_Generator(double dutycycle) { //SYSTEMConfigPerformance(SYSCLK); // function that optimizes performance of PIC32 double systemclock = 80000000; double pwm_freq = 100000; OC1CON = 0x0000; // Turn off the OC1 when performing the setup OC1R = 0x0064; // Initialize primary Compare register OC1RS = 0x0064; // // Initialize secondary Compare register OC1CON = 0x0006; // Configure standard PWM mode for output compare module 1 // A write to PRy configures the PWM frequency // PR = [FPB / (PWM Frequency * TMR Prescale Value)] ? 1 // : note the TMR Prescaler is 1 and is thus ignored PR2 = (systemclock / pwm_freq) - 1; // A write to OCxRS configures the duty cycle // : OCxRS / PRy = duty cycle OC1RS = (PR2 + 1) * (dutycycle); T2CONSET = 0x8000; // Enable Timer2, prescaler 1:1 OC1CONSET = 0x8000; // Enable Output Compare Module 1 }