[code]//	*************************************************************************************************************************
//	Grid Tie Inverter Code voor de GTI300W.

//	Microchip PIC 16F716.
//	MPLAB IDE.
//	Complier: Hi-Tech C.
//	
//	*************************************************************************************************************************

#include <htc.h>

__CONFIG (FOSC_HS & WDTE_ON & BOREN_ON & BODENV_40 );			// Instellen PIC 16F716 Externe Oscillator. Kan ook met GUI -> Configure -> Configuration bits

#define _XTAL_FREQ 16000000  			// 16Mhz kristal op de PIC/GTI.
#define LaagVoltage 53  		// ACD = Binair 76543210. Max 255, min 0 (byte 0b00000000) Vref=5V / 53 = 1.05V = 10.5V  // 76.5 = 15V
#define HoogVoltage 153			// 153 = 2.95V = 28V
#define FanOpstartWaarde 63		// 63 = 1.24V Fan aan als deze onder deze waarde komt. (de originele firmware werkte zo)
#define MppVoltWaarde 86		// Mpp punt manueel ingeven van de 18V zonnepanelen (17V)
#define NetDetectieTimeOut 108	// Netdetectie elke 9kHz. 
#define MppVertraging 1			// Vertraging die nodig is om de mpp tracker uit te voeren: 0.05 * 1 = 0.05 sec.
#define MppVertragingsOptrek 16  // 16  * 0.05 = +- 0.8s voor op te trekken. Dit wil zeggen: elke 0.8sec de pulsbreedte verhogen, indien alle omstandigheden het toelaten.
#define FanVertraging 10		// Vertraging die nodig is om de ventilator check uit te voeren 0.05 * 100 = 5 sec.
#define DraaiFanVertraging 1	// Vertraging die nodig is om de ventilator draai code uit te voeren. (1 Fanschakeltijd) 0.05 * 2 = 0.10 sec.
#define FanSchakelTijd	100		// Het aantal keer dat we de ventilator snel aan- en uit willen schakelen (pseudo, software) PWM. Dit voordat we de Fan full-on aanschakelen.
#define WerkVertraging 60		// Opstartvertraging als alle voorwaarden om te werken voldaan zijn 0.05 * 60 = 3 sec.

// Waarden voor de optionele laadregelaar mpp tracker. Naargelang de kabelverliezen, mag je dit lichtjes omhoog of omlaag doen.
#define BoostVoltage 73			// 14,4V is het boostvoltage van de laadregelaar
#define BoostVoltageOndergrens 72 //14.2V de absolute ondergrens van het boostvoltage, onder deze grens snel terugschakelen.
#define FloatVoltage 70			// 13.8V floatvoltage van de laadregelaar
#define ReconnectVoltage 68     // 13.3V reconnectvoltage van de laadregelaar
#define AutomaticPowerLock	10	//De Tijd om APL te doen als het optimale vermogen gevonden is.

// Functies

void CheckVolt(void);
void CheckFan(void);
void DraaiFan(void);
void DoeMPP(void);
void DoeLaadRegelaarMPP(void);
void StartOp(void);
void ADCInit(void);
void Timer0Initialisatie(void);
void Timer1Initialisatie(void);
void Timer2Initialisatie(void);
void Controle(void);
unsigned char ADCLees(unsigned char ch);
void GeenNetUitschakelen(void);
void GeenVoltUitschakelen(void);
void Inschakelen(void);

// Variabelen
unsigned char LeesVolt;
unsigned char VoltOk;
unsigned char LeesGrid;
unsigned char LeesAmp;
unsigned char LeesAmp1;
unsigned char LeesAmp2;
unsigned char LeesTemp;
unsigned char GridOk;
unsigned char WerkModeOk;
unsigned char PwmAan;
unsigned char PwmPeriode;
unsigned char PwmPeriode1;
unsigned char PwmPeriode2;
unsigned char PulsBreedte;			
unsigned char GridVorigeWaarde;
unsigned char AmpVorigeWaarde;
unsigned char GridPeriodeTeller;
unsigned char GridPeriodeTellerVorigeWaarde;
unsigned char SineCyclusVoltooid;
unsigned int MppVermogenVorigeWaarde;
unsigned int MppVermogen;
unsigned int MppOptrekVermogen;
unsigned char MpptGevonden;
unsigned char ZoekRichtingHoger;
unsigned char ZoekRichtingLager;
unsigned char MppVertragingTeller;
unsigned char MppVertragingsOptrekTeller;
unsigned char Vertraging1;
unsigned char WerkVertragingTeller;
unsigned char FanVertragingTeller;
unsigned char DraaiFanVertragingTeller;
unsigned char StartFan;
unsigned char FanStatus;
unsigned char FanSchakelen;
unsigned char FanSchakelTeller;
unsigned char LeesVoltVertragingTeller;
unsigned char SinusKeuze;
unsigned char SineIndex = 0; 		// sine table index, 0..90 
unsigned char VolladingBereikt;
unsigned char PulsBreedteVorigeWaarde;
unsigned char AutomaticPowerLockVertragingTeller;

// 'Sinustabelle' voor de modulatie van de pulsbreedte // Gebaseerd op GTI_LCD_EE.c // Based on GTI_LCD_EE.c
const unsigned char Sinus[90] = {
0,   0,   0, 
0,   0,   0,   0,   0,   0,    0,   0, 
7, 13, 20,  27, 33,  40,  46,  53,  59, 
65,  71,  77, 83, 88, 93, 99, 103, 108,
113, 117, 121, 125, 128, 131, 134, 137,
139, 142, 143, 145, 146, 147, 148, 148,
148, 148, 147, 146, 145, 143, 142, 139,
137, 134, 131, 128, 125, 121, 117, 113,
108, 103, 99, 93,  88,  83, 77, 71, 65,
59,  53,  46, 40, 33, 27,  20,  13,  7,
0,   0,   0,   0,   0,    0,    0,   0,  
0,   0,   0,
}; 

void main()
{

StartOp();
ADCInit();
Timer0Initialisatie();
Timer1Initialisatie();
Timer2Initialisatie();

 

for (;;)
	{
	CheckFan();
	DraaiFan();
	CheckVolt();
	DoeMPP();
	//DoeLaadRegelaarMPP();
	Controle();

	}
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////

void StartOp(){
	//    XX  XX  XX  RA4 RA3 RA2 RA1 RA0
	TRISA=0b11110111; // RA0, RA1, RA2 als INPUT. RA3 als output! Opto insertie regeling opamp/ucc
	//    RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0
	TRISB=0b00101000; // opgeven portb als output  RB0->RB2, RB4-RB7. RB5 input = NET. RB3 input omdat bij output de PWM start na de PWMInit().
	GIE=1; 	    //Enable Global Interrupt
	PEIE=1;		//Enable Peripal Interrupts   The PIR registers contain the interrupt flags for the “peripheral” interrupt sources, which include: The ADC, UART, CCP, USB, TMR3, TMR2, TMR1, and TMR0 modules.
	RB4=1;		// Shutdown UCC AAN.
	RB0=0;		// Fan AF.
	RA3=1;		// Opto insertieregelingstroom opamp/ucc AAN.
	nRBPU=0;	// 1 = PORTB pull-ups are disabled
				// 0 = PORTB pull-ups are enabled by individual PORT latch values
				// 5V Pull-up weerstand in de PIC aanzetten: dit is voor de invoer pin van de optocoupler nodig, 
				// om deze hoog te trekken naar +5V. De originele software werkt ook zo. Zie datasheet p12.
}

// Main Interrupt Service Routine (ISR)
void interrupt isr(void){

	if (TMR2IF == 1) {			// PWM.
		
		TMR2IF = 0;          	// Clear TMR2 interrupt flag  Om TMR2 interrupt vlag actief te zetten.	

		//*** PWM ***
		//----------------------------------------------------------------------------------------

			if (SineIndex < 90) {
				if (SinusKeuze == 1) {			// SinusKeuze == 1
						if ( SineIndex == 0 ) { 
						SineIndex  = 10;  			// Op positie 10 beginnen voor aanpassing aan de OptoCoupler.
 							}
   						CCPR1L = (PulsBreedte) * (Sinus[SineIndex++] ) >>8  ;  // Installeer de volgende pulsbreedte uit de sinus constante * PulsBreedte. 
				}															// Bit shiften om te kunnen varieëren. Anders is het resultaat te groot (255 stappen, 8 bits)

				else {							// SinusKeuze == 2
						if ( SineIndex == 0 ) { 
						SineIndex  = 3;  			// Op positie 2 beginnen voor aanpassing aan de OptoCoupler.
 							}
	   					CCPR1L = (PulsBreedte) * (Sinus[SineIndex++] ) >>8   ;  // Installeer de volgende pulsbreedte uit de sinus constante * PulsBreedte. 
			   															// Bit shiften om te kunnen varieëren. Anders is  het resultaat te groot (255 stappen, 8 bits)		
				}

			}

		// *** Netdetectie ***
		//----------------------------------------------------------------------------------------
		
 		GridVorigeWaarde = LeesGrid;
		LeesGrid = RB5;		 // Lees de huidige waarde van de netinvoer op RB5 (digitale puls) in.

		if (LeesGrid == 0){    	//LeesGrid == 0

			 if (GridVorigeWaarde == 0) { 
								// GridVorigeWaarde = 0 en LeesGrid = 0
								// 0 vs 0 ______ of 1 vs 1 ------
								// Tellen of het niet langer dan 10ms duurt, want anders hebben we geen grid (!) Dan onmiddelijk uitschakelen.
								// Anders Ok. 100µs / 10ms = 100. Tijdens het werken hoger belasting schijnbaar dan maar 77 de lus doorlopen. Anders inderdaad 100.
					GridPeriodeTeller++;		
					if (GridPeriodeTeller > NetDetectieTimeOut) {
						GridOk = 0;
						PulsBreedte = 0;
						WerkModeOk = 0;
						RB4 = 1; // UCC shutdown // Controle		
						GridPeriodeTeller = 0;
 					}
			}
			else {
								// GridVorigeWaarde = 1 en LeesGrid = 0
								// 1 vs 0  ---___

					if (GridPeriodeTellerVorigeWaarde > GridPeriodeTeller) {	//Als de vorige waarde van de hoge periode _---_ groter was...
						GridOk = 0;												//...dan de huidige waarde, dan is het net weggevallen!
						PulsBreedte = 0;
						WerkModeOk = 0;
						RB4 = 1; // UCC shutdown // Controle		
						GridPeriodeTeller = 0;
					}
					else {														// Als de vorige waarde van de hoge periode _---_ kleiner of gelijk was..
																				// ...dan de huidige waarde, dan is alles Ok. Kleiner is bvb 0, de eerste keer. GridOk = 1
						GridPeriodeTeller = 0;									// Begin van een nieuwe lage periode.
						GridPeriodeTellerVorigeWaarde = GridPeriodeTeller;	
					}

					SineIndex = 0;              // Reset de SinusIndex voor een nieuwe periode te beginnen. // Nuldoorgang = JA
					SinusKeuze = 2;				// De tweede sinus activeren.
					//RB4 = 1;   					// Controle
			}

		}

		else { // LeesGrid = 1

				if (GridVorigeWaarde == 0) {
								// GridVorigeWaarde = 0 en Leesgrid = 1
								// 0 vs 1  ___---
						GridOk = 1;
						GridPeriodeTeller = 0;		// Begin van een nieuwe hoge periode.
						SineIndex = 0;              // Reset de SinusIndex voor een nieuwe periode te beginnen. // Nuldoorgang = JA
						SinusKeuze = 1;				// De eerste sinus activeren.
						//RB4 = 0;					// Controle
					
				}
				else {
								// GridVorigeWaarde = 1 en Leesgrid = 1
								// 0 vs 0 ______ of 1 vs 1 ------
								// Tellen of het niet langer dan 10ms duurt, want anders hebben we geen grid (!) Dan onmiddelijk uitschakelen.
								// Anders Ok. 100µs / 10ms = 100. Tijdens het werken hoger belasting schijnbaar dan maar 77 de lus doorlopen. Anders inderdaad 100.
						GridPeriodeTeller++;		
							if (GridPeriodeTeller > NetDetectieTimeOut) {
								GridOk = 0;
								PulsBreedte = 0;
								WerkModeOk = 0;
								RB4 = 1; // UCC shutdown // Controle		
								GridPeriodeTeller = 0;
 							}

				}

		}	

}

	
	if (TMR1IF == 1) {			//De MPP tracker & Startvertraging & Fanvertraging aansturen per Timer1		 
		TMR1IF = 0;	

		TMR1L = 88; // preset for timer1 LSB register (16 bit teller, deel 2, 8 bit). Deze onthoud dit anders niet
		TMR1H = 158; //preset for timer1 MSB register (16 bit teller, deel 1, 8 bit). Deze onthoud dit anders niet.

		
		if( MppVertragingTeller<255 )								
			MppVertragingTeller++;	    			

		if( WerkVertragingTeller<255 )	
			WerkVertragingTeller++;

		if( FanVertragingTeller<255 )
			FanVertragingTeller++;	

		if( DraaiFanVertragingTeller<255 )
			DraaiFanVertragingTeller++;	

	}

	if ( TMR0IF == 1 ) {		
		TMR0IF = 0;				//Clear de Timer0 interrupt vlag.

	}

}

void Controle(){

	if (GridOk == 0) {		// GridOk = 0
			if (VoltOk == 0 ) {
					// GridOk = 0 en VoltOk = 0
					// Geen grid en geen volt.
					GeenNetUitschakelen();
			}
			else {	// VoltOk = 1
					// GridOk = 0 en VoltOk = 1
					// Geen grid en wel Volt.
					GeenNetUitschakelen();
			}
						
	}	

	else {						// GridOk = 1
			if (VoltOk == 0) {  // VoltOk == 0
					// GridOk = 1 en VoltOk = 0
					// Wel grid, maar geen volt.
					GeenVoltUitschakelen();
			}
			else {	// VoltOk == 1
					// GridOk = 1 en VoltOk = 1
					// Grid & Volt zijn in orde!

					if (WerkModeOk == 0 ) { 
														//Als dit de eerste keer starten is, even wachten.
							WerkModeOk = 1;				//De PWM en MPP tracker draaien alleen als deze variable "1" is.
							WerkVertragingTeller=0;
					}
					else {	// WerkModeOk == 1
							if (WerkVertragingTeller > WerkVertraging){	//Als de Teller groter is dan de ingestelde vertraging, dan mogen we inschakelen.
							Inschakelen();
							}	
					}
							
			}							

	}	
	
}

void DoeMPP() {

		if ( WerkModeOk == 1) {

			if (MppVertragingTeller > MppVertraging) {

			MppVertragingTeller = 0;				//Vertragingsteller terug op nul zetten.
		
			RB1=0;    // Groene LED UIT.

			if (PulsBreedte == 0){						//Niet meer nodig met nieuwe Sinus. Te testen.
				ZoekRichtingHoger = 1;					//Altijd starten in zoekrichting hoger. Pulsbreedte 0 doen
														//in verband met de CCPR1L formule niets...anders krijg je valse
														//meldingen bij het starten.
			}
			
			if( MppVertragingsOptrekTeller<255 )		//Suggestion by Jörg
				MppVertragingsOptrekTeller++;

	   		switch(ZoekRichtingHoger){

				case 0: 

				MppVermogenVorigeWaarde = MppVermogen;
				MppVermogen = (PulsBreedte * LeesVolt);

					switch (ZoekRichtingLager) {
						case 0:
							ZoekRichtingLager = 1;	//Wachten nieuwe meting.
						break;
						case 1:
							if (MppVermogen < MppVermogenVorigeWaarde) {	//Kleiner, terug naar nieuwe meting.
								if( PulsBreedte>0 )		//Suggestion by Jörg
								PulsBreedte--;
								ZoekRichtingLager = 0;
							
							}
							if (MppVermogen >= MppVermogenVorigeWaarde) {	//Groter. Volgende stap nemen.
								if( PulsBreedte>0 )		//Suggestion by Jörg
								PulsBreedte--;
								ZoekRichtingLager = 2;
						
							}
						break;
						case 2:
							if (MppVermogen >= MppVermogenVorigeWaarde) {	//Vermogen groter dan het vorige. Hier terugkeren tot het niet meer groter wordt.
								if( PulsBreedte>0 )		//Suggestion by Jörg
								PulsBreedte--;
							}
							if (MppVermogen < MppVermogenVorigeWaarde) {	//Vermogen kleiner dan de vorige waarde
								ZoekRichtingHoger = 1;
								ZoekRichtingLager = 0;
							}
						break;					
					}

				break;

				case 1: 

				MppVermogenVorigeWaarde = MppVermogen;
				MppVermogen = (PulsBreedte * LeesVolt);

				if (MppVertragingsOptrekTeller > MppVertragingsOptrek)
				{
					MppVertragingsOptrekTeller = 0;

					if (MppVermogen >= MppVermogenVorigeWaarde){	//Groter of gelijk.
						if( PulsBreedte<255 )		//Suggestion by Jörg
							PulsBreedte++;
						MppOptrekVermogen = MppVermogen;
					}
				}

				if (MppVermogen < MppOptrekVermogen) {   //Kleiner.

					if( PulsBreedte>0 )		//Suggestion by Jörg
						PulsBreedte--;
					ZoekRichtingHoger = 0;
					ZoekRichtingLager = 0;
				}

				break;
				
			}

		}

	}

}

void DoeLaadRegelaarMPP() {
	if ( WerkModeOk == 1) {

		if (MppVertragingTeller > MppVertraging) {
			MppVertragingTeller = 0;				//Vertragingsteller terug op nul zetten.

		if (LeesVolt <= ReconnectVoltage) {    		// Onder de 13V.  De laadregelaar zijn werk laten doen
		VolladingBereikt = 0;
		}
		if (LeesVolt >= BoostVoltage) {				// Boven de 14.4V. 14.5V tracker.
		VolladingBereikt = 1;
		}

		// !!Test!! Direct uitvoeren 13.7V tracker
		// if (LeesVolt == FloatVoltage) {
		// VolladingBereikt = 2;						// 13.8V én 14.4V reeds bereikt: 13.8V tracker.
		//}

		switch (VolladingBereikt) {
			case 0:
			//Doe niets, zet alles AF.
					if( PulsBreedte>0 )		//Suggestion by Jörg
					PulsBreedte--;

			break;
			case 1:

				//------------------ 14.5V TRACKER -------------------------------
				if( MppVertragingsOptrekTeller<255 )		//Suggestion by Jörg
		 			MppVertragingsOptrekTeller++;
				 	if (MppVertragingsOptrekTeller > MppVertragingsOptrek){
						MppVertragingsOptrekTeller = 0;
						if (LeesVolt >= BoostVoltage) {	//Groter of gelijk.
			 				if( PulsBreedte<255 )		//Suggestion by Jörg
							PulsBreedte++;
						}
						if (LeesVolt < BoostVoltage) {	//Kleiner.
							if( PulsBreedte>0 )		//Suggestion by Jörg
							PulsBreedte--;
						}

				}

				if (LeesVolt < BoostVoltageOndergrens) {	// Kleiner.
					if( PulsBreedte>0 )		//Suggestion by Jörg
					PulsBreedte--;
				}

				if (LeesVolt == FloatVoltage) {
					VolladingBereikt = 2;						// 13.8V én 14.4V reeds bereikt: 13.8V tracker.
				}

				//-----------------------------------------------------------------
			break;

			case 2:
				//------------------ 13.8V TRACKER -------------------------------
				if( MppVertragingsOptrekTeller<255 )		//Suggestion by Jörg
		 			MppVertragingsOptrekTeller++;
				 	if (MppVertragingsOptrekTeller > MppVertragingsOptrek){
						MppVertragingsOptrekTeller = 0;
						if (LeesVolt >= FloatVoltage) {	// Groter of gelijk.
						 	if( PulsBreedte<255 )		//Suggestion by Jörg
							PulsBreedte++;
						}
				}

				if (LeesVolt < FloatVoltage) {		// Kleiner.
					if( PulsBreedte>0 )		//Suggestion by Jörg
					PulsBreedte--;
				}
				//-----------------------------------------------------------------
			break;
		}		

		}
	}
}

void CheckVolt(){ 

//	if (LeesVoltVertragingTeller == 1){
//		LeesVoltVertragingTeller = 0;

		LeesVolt= ADCLees(1);	//RA1 Lezen.
	
		if (LeesVolt >= LaagVoltage & LeesVolt <= HoogVoltage )
			{
			VoltOk=1;	
			}
		else
		{
			VoltOk=0;
		}

//	}

}

void CheckFan(){

	if(FanVertragingTeller > FanVertraging){
	FanVertragingTeller = 0;

		LeesTemp = ADCLees(0); 	//RA0 Lezen.
		
		if (LeesTemp < FanOpstartWaarde)
			{
			StartFan=1;	//Fan aan.
			}
		else
			{
			StartFan=0;	//Fan uit.
			}
		}
}

void DraaiFan(){

	if(DraaiFanVertragingTeller > DraaiFanVertraging){
	DraaiFanVertragingTeller = 0;

	switch (StartFan) {
		case 0:
			RB0 = 0;	//Ventilator uit.
			FanStatus = 0; //Terug van in het begin beginnen met de software PWM (hieronder).
		break;
		
		case 1:
			switch (FanStatus) {
				case 0:		//1e stap: fan starten met PWM.
					switch(FanSchakelen) {
						case 0:
							RB0 = 0;	// Ventilator uit.
							FanSchakelen = 1;
							if( FanSchakelTeller<255 )		//Suggestion by Jörg
								FanSchakelTeller++;
						break;

						case 1:
							RB0 = 1;	// Ventilator aan.
							FanSchakelen = 0;

						break;
					}

				if (FanSchakelTeller > FanSchakelTijd ) {
					FanStatus = 1; 		// Neem de volgende stap, je hebt genoeg aan/uit cycli gedaan.
					FanSchakelTeller = 0;
				}

				break;

				case 1:		//2e stap: overschakelen naar FULL ON
					RB0 = 1;	//Ventilator full on.
				break;
			}
		break;
	}

	}

}

void Timer1Initialisatie() {			// Netcontrole

	//   **** Timer 1 ***, Aandrijven tellers mppvertraging, fanvertraging, werkvertraging.

   TMR1L = 88; // preset for timer1 LSB register (16 bit teller, deel 2, 8 bit)
   TMR1H = 158; //preset for timer1 MSB register (16 bit teller, deel 1, 8 bit) 

   TMR1CS = 0;				// Geen Teller mode. Interne klok.
   T1CKPS0 = 1;  // bit 4
   T1CKPS1 = 1;  // bits 5-4  Prescaler Rate Select bits // 1:1 = prescaler 1:8
   TMR1IF = 0;				// Timer1, op nul zetten. 
   TMR1ON = 1;				// Timer1 aan.
   TMR1IE = 1;				// Timer1 interrupt aan.

}

void Timer2Initialisatie(){

   // *** PWM *** periode op 20kHz / Timer2 Sinuskeuze (en netcontrole) op 10Khz.
   PR2 = 148;                // PWM periode 27kHz 
							 // MAAR Postscaler 1:3 staat aan, dit wil zeggen periode 27kz in hardware 
							 // en 9kHz in software. (installeren nieuwe sinusindex) Zie datasheet p. 36
	
   CCP1CON = 0b00001100;     // '00------' unimplemented bits
                             // '--00----'   DC1B1:DC1B0 duty cycle 10 bit resolutie. De andere 8 bits sttan in ccprl
                             // '----1100' active hi PWM mode P1A B C en D actief.
   TMR2IF = 0;                 // TMR2IF wissen, op nul zetten. Deze komt op 1 van zodra PR2 = TMR2. (één PWM puls)
   TMR2IE = 1;                 // Timer2 interrupt aan.
   T2CON = 0b000010000;       // '0-------' unimplemented bit
                             // '-0000---' TOUTPS<3:0>, Postscaler 0000 = 1:1 / 0001 = 1:2 / 0010 = 1:3
                             // '-----1--' TMR2ON, turn Timer 2 on
                             // '------01' T2CKPS<1:0>, 0:0 = Prescaler 1:1 / 0:1 = Prescaler 1:4
   TMR2ON = 1;

   PulsBreedte = 0; 
}

void Timer0Initialisatie(){

 	//Timer0.
	TMR0 = 56;				//Tijd van de teller0. Elke 100µS. Timer0 staat nu uit.
	
	T0CS = 0;				//Klok bron selecteer interne klok.

	PSA=0;					//PreScaler Assigment bit: de prescaler hieronder is van toepassing op de Timer0
							//Ofwel is ie bij timer0 ofwel bij de wdt. 1 = WDT, 0 = Timer0 (1:2) PIC Timer calculator heeft dit fout
							//In de datasheet staat het juist.
	PS0 = 0;				//Prescaler. 
	PS1 = 0;				//Prescaler.
	PS2 = 0;				//Prescaler.

	TMR0IF = 0;				// Interrupt vlag op nul.
	T0IE = 0;				// Timer0 interrupt 1 = AAN / 0 = UIT.

}

void ADCInit(){
	//		   76543210
	ADCON0 = 0b10000000; // P.43 van de datasheet. Fosc/32
	ADCON1 = 0b00000000; // P.44 van de datasheet: Referentievoltage van Vdd gebruiken (5V) RA0->RA3 allemaal analoog.
}

void GeenNetUitschakelen() {
		//Het verschil met GeenVoltUitschakelen zit hem in de UCC shutdown die we hier wel doen.

		WerkModeOk = 0;			// WerkMode 0, als Net & Volt niet Ok is. Globale AAN/UIT Schakelaar.
	    PulsBreedte = 0;  		// Pulsbreedte af.
   		TRISB3 = 1;  			// Zet RA3 als input (PWM volledig uit)
		RB4 = 1; 				// UCC Shutdown AAN. Dit is zo in de originele firmware.
		MppVertragingTeller = 0;// Tijd om de Mpptracker te draaien.

		RB2=1;	//Rode LED
		RB1=0;  // Groene LED 

}

void GeenVoltUitschakelen() {
		//Het verschil met GeenNetUitschakelen zit hem in de UCC shutdown die we hier niet doen.

		WerkModeOk = 0;			// WerkMode 0, als Net & Volt niet Ok is. Globale AAN/UIT Schakelaar.
        PulsBreedte = 0;  		// Pulsbreedte af.
   		TRISB3 = 1;  			// Zet RA3 als input (PWM volledig uit)
		RB4 = 0; 				// UCC Shutdown Niet AAN. Dit is zo in de originele firmware.
		MppVertragingTeller = 0;// Tijd om de Mpptracker te draaien.

		RB2=1;	//Rode LED
		RB1=0;  // Groene LED 

}

void Inschakelen() {
		//Alle voorwaarden zijn voldaan om te beginnen: Volt & Grid zijn Ok. Dus PWM aanzetten, en UCC shutdown afzetten.

		RB4 = 0; 		// UCC Shutdown AF
		TRISB3 = 0;  	// Zet RA3 als output (PWM aan)
		RB1=1;    		// Groene LED.	// LED AAN.
		RB2=0;   		// Rode LED.

}

unsigned char ADCLees(unsigned char ch)			//Fuctie om ADC te lezen: RA0-RA4 Zie datasheet voor CHS waarden
{
   if(ch>4) return 0;  // Ongeldige invoer: Tusssen 0 en 4

   	switch(ch){
		case 0: CHS2=0b0;CHS1=0b0;CHS0=0b0;	//RA0
			break;
		case 1: CHS2=0b0;CHS1=0b0;CHS0=0b1;	//RA1
			break;
		case 2: CHS2=0b0;CHS1=0b1;CHS0=0b0;	//RA2
			break;
		case 3: CHS2=0b0;CHS1=0b1;CHS0=0b1;	//RA3
			break;
		case 4: CHS2=0b1;CHS1=0b0;CHS0=0b0;	//RA4
			break;
	}

	ADON=1;  // ADC Module aanzetten
	__delay_us(5); // Wachten tot de condensator geladen is. P43 datasheet

	// HI-TECH C Compiler for PIC10/12/16 MCUs Version 9.81 Release Notes
	// Delays and the watchdog timer Note that if the _delay feature is used to insert a simple delay sequence or
	// loop, the CLRWDT instruction may be used in this sequence. If the watchdog timer is not being used, this
	// is of no concern. If the watchdog timer is enabled, then be aware that delays may reset its timer.
	// Deze delay_us doet een CLRWDT() ! Getest & werkende bevonden.

	GO_DONE=1;  //Start conversie
   		while(GO_DONE); // Wachten op de het meetresultaat. GO_DONE gaat terug op nul als de pic klaar is met meten.
   	
	ADON=0;  // ADC uitschakelen.

   return ADRES;
}

[/code]