Vous êtes sur la page 1sur 8

Code://Task getInput takes input of time and eco/$$ mode //Task PV monitor uses ADC to get read the

voltages at the PV, Home, and Battery //Task algorithm uses our algorithm to select which relays are to be turned on //Task updateClk keeps the clock updated to within minutes #include "trtSettings.h" #include "trtkernel644.c" #include <avr/sleep.h> #include <inttypes.h> #include <avr/io.h> #include <avr/interrupt.h> #include <stdio.h> #include <avr/pgmspace.h> #include <stdlib.h> #include <string.h> #include <util/delay.h> #include <math.h> // Don't mess with the semaphores #define SEM_RX_ISR_SIGNAL 1 #define SEM_STRING_DONE 2 // user hit <enter> #include "trtUart.h" #include "trtUart.c" #define SEM_RX_WAIT 3 // semaphore to protect shared variable #define SEM_SHARED 4 #define SEM_WAIT 5 #define SEM_WAIT_ALG 6 #define SEM_DR 7 #define SEM_POWER 8 #define SEM_COLLECT 9 // UART file descriptor // putchar and getchar are in uart.c FILE uart_str = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW); #define begin { #define end } // input arguments to each thread int args[5] ; uint32_t DRend; float PVpower, PowerDemand, battCharg, duration, MaxPower, battVolt, GridPower; double percent; int flagDR; uint16_t h, m,s; //monitor the power and current from the PV, battery, Home Demand, Grid // --- define task 1 ---------------------------------------void PVmonitor(void* args) begin uint32_t rel, dead; int counter; counter=0; Counter for 10 minute power check unsigned char savedPortD; double V1,V2,V3,V4,V5, V7, Ain, Vref, halfVref;


float PVcurrent, Homecurrent, Gridcurrent,current, PVpow,PowerDem,gridP; //Set up ADC ADCSRA = (1<<ADEN) + 7 ; DDRA=0x00; Vref=4.94; halfVref=2.47; trtWait(SEM_RX_WAIT); //Wait for input while(1) begin //Every 10 minutes, turn PV on to charge battery in order to get power //(only between 8am and 8pm) if (counter == 0) begin if ((8 < h) && (h<20)) begin savedPortD=PORTD; PORTD=0x28; fprintf(stdout, "Check P V and Batt\n"); end end

//***********PV READINGS********************** //first conversion ADMUX = (1<<ADLAR); ADCSRA |= (1<<ADSC) ; while(!(ADCSRA & (1<<ADIF) ) ) ; Ain=ADCH; V1=Ain/51.0; //second conversion ADMUX=(1<<ADLAR)| (1<<MUX0); ADCSRA |= (1<<ADSC) ; while(!(ADCSRA & (1<<ADIF) ) ) ; Ain=ADCH; V2=Ain/51.0*11.26*1.0355; //100.4/9.8 exact resistances PVcurrent=512/(Vref*2.0)*(V1-halfVref); //254/154*0.512* 1000 current in mA PVpow=PVcurrent*V2; //mW //************BATTERY READINGS****************** //3rd Conversion (Port A2) ADMUX=(1<<ADLAR)| (1<<MUX1); ADCSRA |= (1<<ADSC) ; while(!(ADCSRA & (1<<ADIF) ) ) ; Ain=ADCH; V3=Ain/51.0; //4th Conversion (Port A3) ADMUX=(1<<ADLAR)| (1<<MUX1)|(1<<MUX0); ADCSRA |= (1<<ADSC) ; while(!(ADCSRA & (1<<ADIF) ) ) ; Ain=ADCH; V4=Ain/51.0*11.26*1.0355; //101.9/9.9 exact resistances current=6.95*811.8/709.9*512.0/(Vref*2.0)*(V3-halfVref); battCharg=V4/13.20; //Voltage ratio to get charge

//*************HOME READINGS************************ //5th Conversion (Port A4) ADMUX=(1<<ADLAR)| (1<<MUX2); float biggestValue; biggestValue=0; //Sample current for 1000 samples to find max value for (int i=0; i<1000; i++) begin ADCSRA |= (1<<ADSC) ; while(!(ADCSRA & (1<<ADIF) ) ) ; Ain=ADCH; V5=Ain/51.0;//*0.67273; if (V5>biggestValue) biggestValue=V5; end Homecurrent=13.467*(512.0/(Vref*2.0))*(biggestValue-half Vref); //Divide current by square root of 2 PowerDem=Homecurrent*13.6; //mW //*************GRID READINGS************************ //5th Conversion (Port A6) float biggestValue2; biggestValue2=0; ADMUX=(1<<ADLAR)| (1<<MUX2)| (1<<MUX1); ADCSRA |= (1<<ADSC) ; //Find peak current for (int i=0; i<1000; i++) begin ADCSRA |= (1<<ADSC) ; while(!(ADCSRA & (1<<ADIF) ) ) ; Ain=ADCH; V7=Ain/51.0; if (V7>biggestValue2) biggestValue2=V7; end //6th Conversion (Port A7) Gridcurrent=13.467*512.0/(Vref*2.0)*(biggestValue2-halfV ref); gridP=Gridcurrent*13.6; //*************Done With Conversions***************** //Load local variables into Global trtWait(SEM_SHARED); PowerDemand=PowerDem; GridPower=gridP; PVpower=PVpow; percent=battCharg; trtSignal(SEM_SHARED); if(h<10) fprintf(stdout, "DATA: 0%d:", h) ; else fprintf(stdout, "DATA: %d:", h) ; if(m<10) fprintf(stdout, "0%d:", m) ; else fprintf(stdout, "%d:", m) ; if(s<10) fprintf(stdout, "0%d ", s) ; else fprintf(stdout, "%d ", s) ; fprintf(stdout, "%2.3f ", PVcurrent); if(V2<10) fprintf(stdout, "0%.3f %.3f %.3f ", V2, percen

t, Homecurrent); else fprintf(stdout, "%.3f %.3f %.3f ", V2, percent, Hom ecurrent); fprintf(stdout, "%.3f ", PowerDemand); fprintf(stdout, "%3.3f\n", GridPower) if (counter == 0) begin counter=60; if ((8 < h) && (h<20)) begin PORTD=savedPortD; fprintf(stdout, "Done Ch ecking PV and Batt\n"); end end counter--; // Sleep rel = trtCurrentTime()+ SECONDS2TICKS(10.0); dead = trtCurrentTime() + SECONDS2TICKS(10.0); trtSleepUntil(rel, dead); end end

// --- define task 2 ---------------------------------------//Get Clock and Demand Response Inputs from User void getInput(void* args) begin uint16_t hour, min, sec, Power, Time; fprintf(stdout, ">") ; fscanf(stdin, "%d%d%d",&hour,&min, &sec ) ; trtWait(SEM_STRING_DONE); h=hour; m=min; s=sec; flagDR=0; trtSignal(SEM_RX_WAIT); trtSignal(SEM_WAIT); trtSignal(SEM_SHARED); trtSignal(SEM_WAIT_ALG); trtSignal(SEM_COLLECT); //Signal other tasks that they can start while(1) begin fprintf(stdout, ">") ; fscanf(stdin, "%d %d",&Power,&Time) ; trtWait(SEM_STRING_DONE); trtWait(SEM_SHARED); duration=Time; MaxPower=Power; trtSignal(SEM_SHARED); DRend=trtCurrentTime()+SECONDS2TICKS(duration*60.0); flagDR=1; fprintf(stdout, "FlagDR: %d Power %d Time %d\n", flagDR,

Power, Time); end end //---------Task 3, Update clock void updateClk(void* args) begin int add, addmin, addhour; uint32_t rel, dead ; add=0; addmin=0; addhour=0; trtWait(SEM_WAIT); while(1) begin trtWait(SEM_SHARED) ; if(s<59) s=s+add; else {s=0; addmin=1; } if(m<59) {m=m+addmin; addmin=0;} else if(m==59 && addmin) {m=0; addhour=1; addmi n=0;} if(h<23 && addhour==1) {h=h+1; addhour=0;} else if (h==23 && addhour==1) {h=0; addhour=0;} trtSignal(SEM_SHARED); add=1; rel = trtCurrentTime()+ SECONDS2TICKS(1.0); dead = trtCurrentTime() + SECONDS2TICKS(1.0); trtSleepUntil(rel, dead); end end //---------------------------------------------------------------------void algorithm(void* args) begin uint32_t rel, dead ; float PVsupply,powerDem,battpercent; uint8_t price[24]={12, 12 ,12, 12, 12, 12, 18, 18, 12, 12, 12, 12, 20, 2 0, 20, 20, 20, 20, 30, 30, 30, 30, 12, 12}; int canCharge, EmergencyChrg, LocflagDR; uint16_t MAXCHARGE; //for 11 batteries MAXCHARGE=35640; //mAHrs // EmergencyChrg=0; canCharge=1; //When we're allowed to charge - 0:no charge 1:Charge DDRD=(1<<DDD2) |(1<<DDD3)|(1<<DDD4)|(1<<DDD5)|(1<<DDD6); //Signals DR from Power Grid //PortD2 - PV Relay to home Relay 1 //PortD3 - PV to Battery Relay 2 //PortD4 - Battery Relay to Home Relay 3 //PortD5 - Grid Relay to Home Relay 5 //PortD6 - Relay 4 trtWait(SEM_WAIT_ALG); PORTD=0xfc; //Set the Grid on initially while(1) begin //Load Global Variables into Local trtWait(SEM_SHARED) ;

powerDem=PowerDemand; PVsupply=PVpower; battpercent=percent; LocflagDR=flagDR; trtSignal(SEM_SHARED); LocflagDR=flagDR; if (!LocflagDR) begin if (battpercent<0.2) EmergencyChrg=1; if (EmergencyChrg) begin PORTD=0x60;//Charge Batt ery from Grid fprintf(stdout, "EMERGEN CY\n"); fprintf(stdout, "PERCENT : ergencyChrg=0; end else if ((PVsupply>powerDem) && (!(battp ercent>0.8 && price[h]>18)) && !(h<=12 && price[h]<=18 && battpercent<0.95)){ PO RTD=0x04;} //connect PV to home! %.1f\n", (double)battpercent); if (battpercent>0.75) Em

else if (battpercent>.5 && PVsupply>(.5* powerDem)&& (!(battpercent>0.8 && price[h]>18)) && !(h<=12 && price[h]<=18 && ba ttpercent<0.95) ) {PORTD=0x14;} // bat and pv else if (PVsupply>powerDem && battpercen t>0.8 && price[h]>18) {PORTD=0x24;}//sell , use PV else if (PVsupply> (.7*powerDem) && h<=1 2 && price[h]<=18 && battpercent<0.95) {PORTD=0x28;} // grid powers house and pv charge batt else {PORTD=0x20; fprintf(stdout, "RELAY 5\n");}//grid end //A Demand Response has been signaled else if(LocflagDR) begin //Send Warning to Home fprintf(stdout, "DR RESPONSE!\n"); if (battpercent>.5)//if ((PVsupply+Batts upply)>powerDem) begin //Do dummy check //assume that PV can sup ply the house for the duration

if(battpercent>.5) begin if (PVsu pply>powerDem) {PORTD=0x24 ;}//Sell Power else POR TD=0X28;//Turn on Battery and House end else {PORTD=0x28;}//Use Grid, Charge Battery from PV end else PORTD=0x28; //Check to see if demand response is don e if(trtCurrentTime()>=DRend) flagDR=0; end //Sleep rel = trtCurrentTime()+ SECONDS2TICKS(12.0); dead = trtCurrentTime() + SECONDS2TICKS(15.0); trtSleepUntil(rel, dead); end end

// --- Main Program ---------------------------------int main(void) { //Init Uart trt_uart_init(); stdout = stdin = stderr = &uart_str; fprintf(stdout,"\n\r TRT 9feb2009\n\r\n\r"); // start TRT trtInitKernel(80); // 80 bytes for the idle task stack // --- create semaphores ---------trtCreateSemaphore(SEM_RX_ISR_SIGNAL, 0) ; // uart receive ISR semaphore trtCreateSemaphore(SEM_STRING_DONE,0) ; // user typed <enter> // variable protection trtCreateSemaphore(SEM_SHARED, 1) ; // protect shared variables // --- create tasks ---------------trtCreateTask(PVmonitor, 500, SECONDS2TICKS(1.05), SECONDS2TICKS(1.05), &(args [0])); trtCreateTask(getInput, 300, SECONDS2TICKS(1.1), SECONDS2TICKS(1.1), &(args[1] )); trtCreateTask(updateClk, 300, SECONDS2TICKS(1.12), SECONDS2TICKS(1.15), &(args [2])); trtCreateTask(algorithm, 300, SECONDS2TICKS(1.15), SECONDS2TICKS(1.2), &(args[ 3])); // --- Idle task -------------------------------------// just sleeps the cpu to save power // every time it executes set_sleep_mode(SLEEP_MODE_IDLE);

sleep_enable(); while (1) begin sleep_cpu(); end } // main