10 bit ADC in 16f676 to 8 bit

Status
Not open for further replies.
There are 3 things. Solar Panel, battery and Load that is light or LED. Now requirement is when solar panel ADC value is near about 0, i.e at evening or night at that time battery charging should be OFF and LOAD should be ON. Now once load is ON, so it should remain ON till panel ADC value is near about 10, assuming that its a day time. Now when Solar panel value is above 9V battery charging will be OFF but if battery is fully charged i.e battery ADC value is near about 462, battery charging should be OFF. Now what happens as you know as battery volt gets down so intensity of LOAD or light reduces so here we have to implement PWM for battery voltage of 13V to atleast 10.50V so that intensity should remain somewhat constant. LOAD is getting ON/OFF only because of Solar panel value and nothing else.

- - - Updated - - -

For this code also, LOAD gets dim near about 9.20V of battery voltage and gets completely OFF at 7V. Now while increasing battery voltage same condition, initially its dim at near about 8V and then intensity goes on increasing. Still LOAD not getting switch OFF at Solar Panel voltage of 9V and above.

- - - Updated - - -

Hi venky, this also not working same LOAD ON/OFF issue at undesired voltage.
 


Let's try this code==>
It satisfys all the conditions you have mentioned as I understood...
Update the status...

Code:
//#fuses INTRC_IO, NOWDT, NOPROTECT, BROWNOUT, PUT

#define ON 0
#define OFF 1
#define timer_val 0
#define BATTERY_CHARGE PORTC.B5
#define LOAD PORTC.B4

unsigned int Panel_Value, Battery_Value,FLAG_1=0,FLAG_2=0,FLAG_3,FLAG_4,FLAG_5,FLAG_6,FLAG_7,FLAG_8;
unsigned int count_on,count_off;

//int OnPulse = 217;
//int OffPulse = 38;
//char TOG = 0;
unsigned int i = 305,j=1, factor = 0,divide_val=0,k=14,l=3;

void panel_check();
void battery_check();

void interrupt timer0_ISR()
	{
     if(INTCON.T0IF)
       T0IF_bit = 0;
     
     if(FLAG_1 == 1)
	{
	TMR0 = 255-divide_val;
	LOAD = OFF;
	FLAG_1 = 0;
	}
     else
	{
	TMR0 = divide_val;
	LOAD = ON;
	FLAG_1 = 1;
	}
     }
}

void main() 
{
     TRISA = 0xff;      //port A as input
     TRISC = 0x00;      //port C as output
     PORTC = 0x00;      //INITIAL VALUE ON PORTC

     ADCON0 = 0b00000000;         //Left Justified
     ADCON1 = 0b00110000;         //Clock derived from internal RC oscilator
     ANSEL  = 0b00000011;         //channel AN0 and AN1 as analog input

//     INTCON = 0b10100000;
     INTCON.T0IF = 0;

     T0CS_bit = 0;
     PSA_bit = 0;  //Prescaler is assigned to Timer0 module
     PS0_bit = 0;  //TMR0 rate 1:1
     PS1_bit = 0;
     PS2_bit = 0;

     while(1)
		{
		Panel_Value = ADC_Read(0);
		Battery_Value = ADC_Read(1);
		panel_check();
		}
}

void panel_check()
	{
	/**Batterry charge condition**/
	if(Panel_value >= 122 && Battery_Value <= 430)		//AD Value for 3 volt
		BATTERY_CHARGE = ON;
	else if(Panel_Value <= 30 || Battery_Value > 430)	//Panel AD value for 1v <=40
		BATTERY_CHARGE = OFF;

	/**LOAD ON/OFF condition**/                                   
	if(Panel_Value > 321)    				//Panel Voltage 9 v
		{
		LOAD = OFF;
		INTCON = 0;
		}
	else
		battery_check();		
	}

void battery_check()
	{
	/**Condition for LED brightness adjustment Between 13V and 10.5V battery voltages**/
	if(Battery_Value > 310)
		{
		INTCON = 0b10100000;
		divide_val = (Battery_Value-310)*255/425;
		if(FLAG_1 == 1)
			
		}                        
	else
	/**Battery voltage below 10.5V condition**/
		{
		LOAD = OFF;
		INTCON = 0;		
		}
	}
 
Reactions: djc

    djc

    Points: 2
    Helpful Answer Positive Rating
In battery_check condition do we have to make FLAG_ =0 again? I did that, still not working. Still LOAD getting ON/OFF at undesired voltages but intensity getting manage satisfactorily up to 10.50V.After that it gets dimmer and dimmer and ultimately OFF. Reverse process is there when battery voltage increases. And load not getting OFF when Panel voltage increases. What to do now?
 


check the ADC values properly...

1) Panel_Value = 321 for 9V;
2) Panel_value = 122 for 3V;
3) Battery_Value = 430 for 13V;
4) Battery_Value > 310 for 10.5V;

If these are proper then the LED 'll not dim...
And for panel voltage greater than 9V only the LED gets OFF....
 

Hi mathsbe, thanx a lot dud, code is finally working, i will post it soon. There are little modifications made to switch off the load at9V and turn back On at 12.4V. Sorry for late rply. Anyways tell me how did u get the idea of PWM values i.e formula u derived and switch ON and OFF the load in interrupt itself, I was in the impression that eitherON the load in interrupt and OFF it in main with varying values from 70 for 9V to nearly 255, but it wasnt making any sense. How did u do that can u tell me?
 

Hi djc, this is actually an ISR handling execution. For that we need to look on the Interrupt triggerring. That's was I did to turn ON and OFF the LEDs... It's good to see the program working...
Update the latest code...
 

Code:
#define ON 0 
#define OFF 1
#define timer_val 0
#define BATTERY_CHARGE PORTC.B5
#define LOAD PORTC.B4

unsigned int Panel_Value, Battery_Value,FLAG_1=0,FLAG_2=0,FLAG_3,FLAG_4,FLAG_5,FLAG_6,FLAG_7,FLAG_8;
unsigned int count_on,count_off;

//int OnPulse = 217;
//int OffPulse = 38;
//char TOG = 0;
unsigned int i = 305,j=1, factor = 0,divide_val=0,k=14,l=3;

void panel_check();
void battery_check();

void interrupt ()
{
     if(INTCON.T0IF)
       T0IF_bit = 0;

     if(FLAG_1 == 1)
	{
	TMR0 = 255-divide_val;
	LOAD = OFF;
	FLAG_1 = 0;
	}
     else
	{
	TMR0 = divide_val;
	LOAD = ON;
	FLAG_1 = 1;
	}
}

void main()
{
     TRISA = 0xff;      //port A as input
     TRISC = 0x00;      //port C as output
     PORTC = 0x00;      //INITIAL VALUE ON PORTC

     ADCON0 = 0b00000000;         //Left Justified
     ADCON1 = 0b00110000;         //Clock derived from internal RC oscilator
     ANSEL  = 0b00000011;         //channel AN0 and AN1 as analog input

//     INTCON = 0b10100000;
     INTCON.T0IF = 0;

     T0CS_bit = 0;
     PSA_bit = 0;  //Prescaler is assigned to Timer0 module
     PS0_bit = 0;  //TMR0 rate 1:1
     PS1_bit = 0;
     PS2_bit = 0;

     while(1)
		{
		Panel_Value = ADC_Read(0);
		Battery_Value = ADC_Read(1);
		panel_check();
		}
}

void panel_check()
	{
	/**Batterry charge condition**/
	if(Panel_value >= 122 && Battery_Value <= 430)		//AD Value for 3 volt
		BATTERY_CHARGE = ON;
	else if(Panel_Value <= 30 || Battery_Value > 430)	//Panel AD value for 1v <=40
		BATTERY_CHARGE = OFF;

	/**LOAD ON/OFF condition**/
	if(Panel_Value > 321)    				//Panel Voltage 9 v
		{
		LOAD = OFF;
		INTCON = 0;
		}
	else
		battery_check();
	}

void battery_check()
{
	/**Condition for LED brightness adjustment Between 13V and 10.5V battery voltages**/
	if(Battery_Value > 321)
		{
		INTCON = 0b10100000;
		divide_val = (Battery_Value-321)*255/462;
                   if(FLAG_1 == 1){
                      FLAG_1 = 0;
                    }
		}
	else if(Battery_Value < 321){
	/**Battery voltage below 10.5V condition**/
                INTCON = 0;
	   while(Battery_Value <= 440){
		LOAD = OFF;
	        Battery_Value = ADC_Read(1);
	   }
	}
}
Can you PM me ur contact details, atleast FB acount. I wud like to stay in touch.
 

Hi mathsbe

I am again facing some issue in this program. Requirement is LOAD should get OFF above 3v of panel voltage. I wrote that and its working. Now LOAD should get ON below 1V of panel voltage. In present code LOAD is getting ON at 2.50V of panel voltage. I tried to do that but not working. Here is the code
Code:
#define ON 0
#define OFF 1
#define timer_val 0
#define BATTERY_CHARGE PORTC.B5
#define LOAD PORTC.B4

unsigned int Panel_Value, Battery_Value,FLAG_1=0,FLAG_2=0,FLAG_3,FLAG_4,FLAG_5,FLAG_6,FLAG_7,FLAG_8;
unsigned int count_on,count_off;

//int OnPulse = 217;
//int OffPulse = 38;
//char TOG = 0;
unsigned int i = 305,j=1, factor = 0,divide_val=0,k=14,l=3;

void panel_check();
void battery_check();

void interrupt ()
{
     if(INTCON.T0IF)
       T0IF_bit = 0;

     if(FLAG_1 == 1)
	{
	TMR0 = 255-divide_val;
	LOAD = OFF;
	FLAG_1 = 0;
	}
     else
	{
	TMR0 = divide_val;
	LOAD = ON;
	FLAG_1 = 1;
	}
}

void main()
{
     TRISA = 0xff;      //port A as input
     TRISC = 0x00;      //port C as output
     PORTC = 0x00;      //INITIAL VALUE ON PORTC

     ADCON0 = 0b00000000;         //Left Justified
     ADCON1 = 0b00110000;         //Clock derived from internal RC oscilator
     ANSEL  = 0b00000011;         //channel AN0 and AN1 as analog input

//     INTCON = 0b10100000;
     INTCON.T0IF = 0;

     T0CS_bit = 0;
     PSA_bit = 0;  //Prescaler is assigned to Timer0 module
     PS0_bit = 0;  //TMR0 rate 1:1
     PS1_bit = 0;
     PS2_bit = 0;

     while(1)
		{
		Panel_Value = ADC_Read(0);
		Battery_Value = ADC_Read(1);
		panel_check();
		}
}

void panel_check()
	{
	/**Batterry charge condition**/
	if(Panel_value >= 122 && Battery_Value <= 430)		//AD Value for 3 volt
		BATTERY_CHARGE = ON;
	else if(Panel_Value <= 30 || Battery_Value > 430)	//Panel AD value for 1v <=40
		BATTERY_CHARGE = OFF;

	/**LOAD ON/OFF condition**/
	if(Panel_Value > 122)    				//Panel Voltage 3 v
		{
		LOAD = OFF;
                INTCON = 0;
                }
	if(Panel_Value < 35)            /*********LOAD should ON below 1V of panel Volt************/
                {
                LOAD = ON;
                INTCON = 0;
                }
	else
            battery_check();
	}

void battery_check()
{
	/**Condition for LED brightness adjustment Between 13V and 10.5V battery voltages**/
	if(Battery_Value > 321)
		{
		INTCON = 0b10100000;
		divide_val = (Battery_Value-321)*255/462;
                   if(FLAG_1 == 1){
                      FLAG_1 = 0;
                    }
		}
	else if(Battery_Value < 321){
	/**Battery voltage below 10.5V condition**/
                INTCON = 0;
	   while(Battery_Value <= 440){
		LOAD = OFF;
	        Battery_Value = ADC_Read(1);
	   }
	}
}

Plz guide me on this.
 

Hi jayanth,
35 is correct value for 1v. It doesnt matter what value i put there to get LOAD ON, if i write that condition LOAD remains ON forever, whether Panel Value crosses threshold value for ON or OFF. At present whatever condition i put for LOAD to get OFF, it switches ON back at same value. Thats the issue. I am unable to put separate condition for LOAD to get ON.
 

Zip and post your project files + Proteus file. I will fix it.

- - - Updated - - -

1V is = 40 raw adc value. RA0, RA1, RA2 has comparator. You have to disable it otherwise you will get wrong adc value.

Add

Code C - [expand]
1
CMCON = 0x07;



This will solve your problem. If Panel_Voltage is less than or equal to 35 the LOAD will be ON. Once it is switched ON then it will turn OFF only when Panel_Voltage is greater than 122 (3V). So, it will be ON from < 1V to 3V once it is ON. If yu want to turn it OFF if when Panel_Voltage is between 1V and 3V then you should use - Turn OFF if Panel_Voltage is greater than 40.
 


change it ...

Code:
if(Panel_Value < 35)            /*********LOAD should ON below 1V of panel Volt************/
                {
                LOAD = ON;
                INTCON = 0b10100000;
                }
 
Last edited by a moderator:

Thanx jayanth. But i have no Proteus simulation. What i have is only readymade hardware and code i posted. For CMCON = 0x07, do i have to give same condition "if(panel_Value<35){
LOAD = ON;
}
or directly only CMCON = 0x07; condition.

- - - Updated - - -

hi mathsbe,

i tried that too, but not working. Actually whenever LOAD = ON condition is put in main or subroutine, LOAD keeps in ON condition even Panel Value is above 3V. Any other solution?
 

Zip and post your mikroC project files. I will debug and test it. I don't have time to create a new project and paste the code and test it. Just add CMCON settings after ANSELx register settings in your code.

LOAD is turning ON in this ISR also. Why you are using ISR?


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void interrupt ()
{
     if(INTCON.T0IF)
       T0IF_bit = 0;
 
     if(FLAG_1 == 1)
    {
    TMR0 = 255-divide_val;
    LOAD = OFF;
    FLAG_1 = 0;
    }
     else
    {
    TMR0 = divide_val;
    LOAD = ON;
    FLAG_1 = 1;
    }
}



ISR is toggling your LOAD.
 

Right now i am unable to put different conditions for ON and OFF. LOAD will be ON for the same condition as for OFF. Thats the issue.

- - - Updated - - -

Yes ISR is used to create software PWM, so that wheb battery voltage is less than 13V or so, intensity of lights or LOAD should be same atleast till 11 or 10.50 v .

- - - Updated - - -

Yes ISR is used to create software PWM, so that wheb battery voltage is less than 13V or so, intensity of lights or LOAD should be same atleast till 11 or 10.50 v .
Here i am posting PCB design software and my PCB design so u vl have rough idea of circuit. PCB design have all basic connection. In this Solar.Pa is the file.
 

Attachments

  • Solar_Panel_18.rar
    19.7 KB · Views: 95
  • Protel Advanced PCB 2.71.rar
    2.4 MB · Views: 98
  • Protel_Project.rar
    27.1 KB · Views: 91
Last edited:

Your interrupt service routine is like this


If FLAG is 1 then LOAR is turned OFF and flag is set to 0 on interrupt say first. Then again on next interrupt if falg is 0 then it will set falg to 1 and LOAD to 1. This will continuously toggle the flag and load. This is wrong. You don't need to use interrupt to create PWM pulses. mikroC has PWM library which can be used for getting PWM pulses. Another thing is I don't see any code which starts the Timer0 interrupt.

So, explain step by step how the system should work then only a solution can be provided.

Should LOAD be ON when Panel_Value is less than 1V and should it be ON if Panel_Voltage is greater then 3V?

What is the condition for starting PWM and to what is PWM is fed?


Answer the above and I will fix the code.
 

Initially i tried switching LOAD ON in interrupt and then OFF in main. But it was not working a all. So i tried ON and OFF in interrupt itself. So it's working a bit. Timer0 interrupt is starting in battery check loop.Load should be ON when Panel_Value is less than 1V and should be OFF when Panel_Value is greater than 3V.
Condition for starting PWM is when battery value or battery voltage is below 13V upto 9V so that intensity of LOAD which are LED lights should be constant somewhat because intensity is not 100% as at 13V of battery volt. So intensity should constant atlest upto 10.5V.
I am again posting the code.
Code:
#define ON 0
#define OFF 1
#define timer_val 0
#define BATTERY_CHARGE PORTC.B5
#define LOAD PORTC.B4

unsigned int Panel_Value, Battery_Value,FLAG_1=0,FLAG_2=0,FLAG_3,FLAG_4,FLAG_5,FLAG_6,FLAG_7,FLAG_8;
unsigned int count_on,count_off;


unsigned int i = 305,j=1, factor = 0,divide_val=0,k=14,l=3;

void panel_check();
void battery_check();

void interrupt ()
{
     if(INTCON.T0IF)
       T0IF_bit = 0;


     if(FLAG_1 == 1)
        {
        TMR0 = 255-divide_val;
        LOAD = OFF;
        FLAG_1 = 0;
        }
    else
        {
        TMR0 = divide_val;
        LOAD = ON;
        FLAG_1 = 1;
        }

}

void main()
{
     TRISA = 0xff;      //port A as input
     TRISC = 0x00;      //port C as output
     PORTC = 0x00;      //INITIAL VALUE ON PORTC

     ADCON0 = 0b00000000;         //Left Justified
     ADCON1 = 0b00110000;         //Clock derived from internal RC oscilator
     ANSEL  = 0b00000011;         //channel AN0 and AN1 as analog input
     CMCON  = 0x07;
//     INTCON = 0b10100000;
     INTCON.T0IF = 0;

     T0CS_bit = 0;
     PSA_bit = 0;  //Prescaler is assigned to Timer0 module
     PS0_bit = 0;  //TMR0 rate 1:1
     PS1_bit = 0;
     PS2_bit = 0;

     while(1)
                {
                Panel_Value = ADC_Read(0);
                Battery_Value = ADC_Read(1);
                panel_check();
                }
}

void panel_check()
        {
        /**Batterry charge condition**/
        if(Panel_value >= 122 && Battery_Value <= 430)                //Panel AD Value for 3 volt
                BATTERY_CHARGE = ON;
        else if(Panel_Value <= 122 || Battery_Value > 430)        //Panel AD value for 3V
                BATTERY_CHARGE = OFF;


        /**LOAD ON/OFF condition**/
        if(Panel_Value > 122)                                    //Panel Voltage 3 v
                {
                LOAD = OFF;
                INTCON = 0;
                }
        /*if(Panel_Value < 35)
                {
                //LOAD = ON;
                INTCON = 0b10100000;
                }*/
        
        else
            battery_check();
        }

void battery_check()
{
        /**Condition for LED brightness adjustment Between 13V and 10.5V battery voltages**/
        if(Battery_Value > 321)
                {
                //FLAG_1 = 1;
                INTCON = 0b10100000;
                divide_val = (Battery_Value-321)*255/462;
                   //LOAD = ON;
                   if(FLAG_1 == 1){
                      FLAG_1 = 0;
                    }

                }
        else if(Battery_Value < 321){
        /**Battery voltage below 10.5V condition**/
                INTCON = 0;
           while(Battery_Value <= 440){
                LOAD = OFF;
                Battery_Value = ADC_Read(1);
           }
        }
}

In Panel check loop, conditions for charging the battery only is checked and if panel value is above 3V LOAD will be OFF.
Now when battery voltage is below 9V, LOAD will be OFF and will not get ON until battery voltage is above or equal to 12.4V
 

Show the one line code which starts the Timer0.

Once Panel_Voltage is < 1V LOAD turns ON and remain ON when Panel_Voltage is > 1V ot upto 3V. and turns OFF when Panel_Volt becomes > 3V. Once < 1V is detected and LOAD is turned ON then you don't have any code to turn it OFF until it becomes > 3V.
 

Code:
void battery_check()
{
        /**Condition for LED brightness adjustment Between 13V and 10.5V battery voltages**/
        if(Battery_Value > 321)
                {
                //FLAG_1 = 1;
                INTCON = 0b10100000;//////////////Timer0 interrupt starts/////////////////
                divide_val = (Battery_Value-321)*255/462;
                   //LOAD = ON;
                   if(FLAG_1 == 1){
                      FLAG_1 = 0;
                    }

                }

Yes load will turn ON once panel volt is less than 1V and will be OFF when Panel Volt is >3V. These two values i.e. 1V and 3V could be changed according to sunlight that's the only case no more complexity is there. Is Timer0 turning ON interrupt is incorrect??????
 
Last edited by a moderator:

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…