10 bit ADC in 16f676 to 8 bit

Status
Not open for further replies.
Plz look at the revised code, umcommented
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,FLAG_2=0,FLAG_3,FLAG_4,FLAG_5,FLAG_6,FLAG_7,FLAG_8;

//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 interrupt(){
     if(INTCON.T0IF){
     T0IF_bit = 0;
     TMR0 = timer_val;
     }
     if(FLAG_1 == 1){
     LOAD = ON;
     //FLAG_2 = 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;
     //CMCON0 = 0x07;               //Disable the comparators
     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;

     //TMR0 = timer_val;

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

                                  if(Panel_value>=122){       //AD Value for 3 volt
                                   BATTERY_CHARGE = ON;
                                          if(Battery_Value>=430){  //AD Value for 12v
                                           BATTERY_CHARGE = OFF;
                                          }
                                  }

                                  if(Battery_Value > 430){
                                  BATTERY_CHARGE = OFF;
                                  }

                                  if(Panel_Value <= 30 ){   //Panel AD value for 1v <=40
                                   BATTERY_CHARGE = OFF;
                                  LOAD = ON;                                             
                                  }

                                  if(Panel_Value > 321){    //Panel Voltage 9 v
                                   LOAD = OFF;
                                  }

                                  
                                  if(Battery_Value <=425 && Battery_Value > 310){ /////////////LOOP ------(1)
                                  FLAG_1 = 1;
                                  FLAG_2 = 1;
                                                  
                                                  divide_val = ((Battery_Value/4) + k);   
                                                            if(divide_val>=200){
                                                                     divide_val = divide_val + l;
                                                                     l=l+3;
                                                                      if(l==42){
                                                                         l = 3;
                                                                     }
                                                            }
                                                     if(TMR0 >= divide_val){
                                                               LOAD = OFF;
                                                      k++;
                                                      //FLAG_1=0;
                                                      }
                                                          if(k>=134){
                                                           k=14;
                                                           FLAG_1 = 0;
                                                          }                                 

                                }

                                

                                   

                                   if(Battery_Value <= 310 ){        //Battery ADC value for 9v 310,309
                                     while(Battery_Value<=400){
                                     Battery_Value = ADC_Read(1);
                                     LOAD = OFF;
                                     }
                                     LOAD = ON;
                                  }                                  
                                  

                              }

}

In the loop named LOOP---1, I am first dividing the 10 bit ADC value by 4 and adding two constants k and l to it to get the PWM width value. Such that if ADC value for battery is 462 which is a value for 13v, then 425/4 = 106+(Initial value of K i.e 14)=120, which will be minimum pulse width at 13 v battery voltage to maintain 9v across load. But here issue is constant K and l will not vary according to ADC value so constant value will not be added accordingly. Timer 0 is loaded in interrupt routine.. Hardwae is fixed can't change anything.
 

this whole thing is really confusing, a simple schematic would help us help you. I've seen people using filter capacitors on adc pins for filtering, you might want to check if that helps.
If i got that right: you want to keep the luminosity of a led constant, regardless of the voltage applied?

pityu
 

Yes now u got it right, luminosity of LED should be constant at least up to 10.15v from 13v. What to do for that? And how to refer Timer1 as Timer0 is referred as TMR0 how to refer timer 1.
 

if(Battery_Value <=425 && Battery_Value > 310)

to

if((Battery_Value <=425) && (Battery_Value > 310))


Do you want to modify l ? l=l+3;


Code C - [expand]
1
2
3
l=l+3;
if(l==42){
l = 3;



explain the above code. why k and l is used.
 

Yes now u got it right, luminosity of LED should be constant at least up to 10.15v from 13v. What to do for that? And how to refer Timer1 as Timer0 is referred as TMR0 how to refer timer 1.

What's the panel_value and battery_value refers to? And what's the clock frequency you are using? And what 'll be the PWM frequency you need?
 

k and l are constants to be added each time to reach the maximum pulse width of 255 for PWM. To each ADC value divided by 4, k+1 will be added, when divide_val will reach 200 one more constant ' l ' , will be added which is incrementing by 3.

- - - Updated - - -

Panel_Value is ADC value for Solar Panel and Battery_Value is ADC value for battery. Clock frequency is internal clock of 4Mhz. Not sure about the PWM frequency. Frequency should be such that flicker should not appear. Right now timer0 is running at prescalar of 1:1.
 

Can you plz tell me how set particular frequency of 4 Khz. knowing that PWM frequency depends upon Timer value, i have tried different timer values too. But not working.
 
Last edited:

Try this code...
and post the response...
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,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 interrupt timer0_ISR()
	{
     if(INTCON.T0IF)
       T0IF_bit = 0;
     
     if(FLAG_1 == 1)
	{
     	LOAD = OFF;
	TMR0 = 255-divide_val;
	}
     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;
     //CMCON0 = 0x07;               //Disable the comparators
     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;

     //TMR0 = timer_val;

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

                                  if(Panel_value>=122){       //AD Value for 3 volt
                                   BATTERY_CHARGE = ON;

                                          if(Battery_Value>=430){  //AD Value for 12v
                                           BATTERY_CHARGE = OFF;
                                          }
                                  }

                                  if(Battery_Value > 430){
                                  BATTERY_CHARGE = OFF;
                                  }

                                  if(Panel_Value <= 30 ){   //Panel AD value for 1v <=40
                                   BATTERY_CHARGE = OFF;
                                  LOAD = ON;                                             
                                  }

                                  if(Panel_Value > 321){    //Panel Voltage 9 v
                                   LOAD = OFF;
                                  }

                                  
                                  if(Battery_Value <=425 && Battery_Value > 310)
					{ /////////////LOOP ------(1)
                                  	
					divide_val = (Battery_Value-310)*255/425;

					if(FLAG_1 == 1)
					FLAG_1 = 0;
					}                                 

                                }

                              

                                   if(Battery_Value <= 310 ){        //Battery ADC value for 9v 310,309
                                     while(Battery_Value<=400){
                                     Battery_Value = ADC_Read(1);
                                     LOAD = OFF;
                                     }
                                     LOAD = ON;
                                  }                                  
                                  

                              }

}
 

hello,

Where is the validation for global interrupt (as GIE or periipheral ) for using timer0 interrupt ?
does interrupt works with this code ?
 

INTCON = 0b10100000;
INTCON.T0IF = 0;

Yes interrupt is working fine for the code.

- - - Updated - - -

Hey mathespbe your code is working much better, thanx a lot. Only one issue remaining is LOAD is not getting OFF in last if(), condition that is below 9 v. Below 9 v it gets very dim, that is ok but then it flickers a lot and LOAD should not get ON until 12.4 v. But its not getin OFF completely and getting ON on even before 9 v. Means voltage at which it gets OFF, it gets ON at same voltage. Why its happening? I tried sevral if conditions, but not working? What must be the reason? I changed FLAG_1 condition, a little, is that correct?
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,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 interrupt ()
{
     if(INTCON.T0IF){
        T0IF_bit = 0;

              if(FLAG_1 == 1){

             	LOAD = OFF;
        	TMR0 = 255-divide_val;
        	FLAG_1 = 0;
        	}
             else
        	{
        	TMR0 = divide_val;
        	LOAD = ON;
        	FLAG_1 = 0;
        	}
      }
}

        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;
             //CMCON0 = 0x07;               //Disable the comparators
             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;

             //TMR0 = timer_val;

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

                                          if(Panel_value>=122){       //AD Value for 3 volt
                                           BATTERY_CHARGE = ON;

                                                  if(Battery_Value>=430){  //AD Value for 12v
                                                   BATTERY_CHARGE = OFF;
                                                  }
                                          }

                                          if(Battery_Value > 430){
                                          BATTERY_CHARGE = OFF;
                                          }

                                          if(Panel_Value <= 30 ){   //Panel AD value for 1v <=40
                                           BATTERY_CHARGE = OFF;
                                          LOAD = ON;
                                          }

                                          if(Panel_Value > 321){    //Panel Voltage 9 v
                                           LOAD = OFF;
                                          }


                                          if(Battery_Value <=425 && Battery_Value > 310){ /////////////LOOP ------(1)
                                             FLAG_1 = 1;
        					divide_val = (Battery_Value-310)*255/425;

        			
        					//if(FLAG_1 == 1){
        					//FLAG_1 = 0;
        					//}

                                        }


                                           if(Battery_Value <= 310 ){        //Battery ADC value for 9v 310,309
                                             while(Battery_Value<=400){
                                             Battery_Value = ADC_Read(1);
                                             LOAD = OFF;
                                             }
                                             LOAD = ON;
                                          }


                                      }

        }
 
Last edited:

it is very simple

v = (v/1023.00)*255.00

It will convert to 8 bit vaue now you can do type casting v=(int)v to convert to 8 bit int
 


in your code,, while(1) loop ends with the LED blink condition itself... The code for your 9v condition doesn't get execute here... just check the program flow... Check that and update...
 

hey mathespbe, plz guide more on LOAD ON/OFF issue below 9v, i tried several conditions but not working. Sory to bother you, but I need some more guidance. The last if() condition is not a blink condition Load is off till battery vale doesn't reach 400 value. If it reached 400 then only it will be ON. If i remove PWM loop then it works fine else doesn't work.
 
Last edited:

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,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 interrupt timer0_ISR()
	{
     if(INTCON.T0IF)
       T0IF_bit = 0;
     
     if(FLAG_1 == 1)
	{
     	LOAD = OFF;
	TMR0 = 255-divide_val;
	}
     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;
     //CMCON0 = 0x07;               //Disable the comparators
     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;

     //TMR0 = timer_val;

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

                                  if(Panel_value>=122)
                                      {       
                                           //AD Value for 3 volt
                                           BATTERY_CHARGE = ON;

                                          if(Battery_Value>=430)  //AD Value for 12v
                                           BATTERY_CHARGE = OFF;
                                      }

                                  if(Battery_Value > 430)
                                          BATTERY_CHARGE = OFF;
                                  

                                  if(Panel_Value <= 30 )
                                        {   //Panel AD value for 1v <=40
                                            BATTERY_CHARGE = OFF;
                                            LOAD = ON;                                             
                                        }

                                  if(Panel_Value > 321)    //Panel Voltage 9 v
                                   LOAD = OFF;
                                  
                                  if(Battery_Value <=425 && Battery_Value > 310)
					{ /////////////LOOP ------(1)
                                  	
					divide_val = (Battery_Value-310)*255/425;

					if(FLAG_1 == 1)
					FLAG_1 = 0;
					}
                              

                                   if(Battery_Value <= 310 )
                                           {        //Battery ADC value for 9v 310,309
                                                     while(Battery_Value<=400)
                                                     {
                                                           Battery_Value = ADC_Read(1);
                                                           LOAD = OFF;
                                                      }
                                                    LOAD = ON;
                                          }                                  
                                  

                              }

Now check the condition for 9V...
Your 9V condition is not proper... Just check it or update me what should happen for 9v condition...

And update the response...
 

Hi mathespbe, this code also making no effect. Conditions are still same. Same ON/ OFF issue on undesired voltages. Below 9 v of battery volt, LOAD should get completely OFF and should not get turned ON until battery voltge of 12.4v. Plz tell me what is not proper in 9V condition? One more thing plz tell me that where should FLAG_1 specifically be 1 and 0, because with conditions in code LOAD is continuously OFF.
 
Last edited:

hi try this

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
//#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,FLAG_2=0,FLAG_3,FLAG_4,FLAG_5,FLAG_6,FLAG_7,FLAG_8,status;
unsigned int count_on,count_off;
 
unsigned int i = 305,j=1, factor = 0,divide_val=0,k=14,l=3;
 
 
 
void interrupt ()
{
     if(INTCON.T0IF && status){
        T0IF_bit = 0;
        
            if(FLAG_1 == 1){
            LOAD = OFF;
            TMR0 = 255-divide_val;
            FLAG_1 = 0;
            }
             else
            {
            TMR0 = divide_val;
            LOAD = ON;
            FLAG_1 = 0;
            }
      }
}
 
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);
        
        if(Panel_value>=122){       //AD Value for 3 volt
        BATTERY_CHARGE = ON;
        
        if(Battery_Value>=430){  //AD Value for 12v
        BATTERY_CHARGE = OFF;
        }
        }
        
        if(Battery_Value > 430){
        BATTERY_CHARGE = OFF;
        }
        
        if(Panel_Value <= 30 ){   //Panel AD value for 1v <=40
        BATTERY_CHARGE = OFF;
        status = 0;
        }
        
        if(Panel_Value > 321){    //Panel Voltage 9 v
        status = 1;
        }
        
        
        if(Battery_Value <=425 && Battery_Value > 310){ /////////////LOOP ------(1)
        FLAG_1 = 1;
        divide_val = (Battery_Value-310)*255/425;
        }
        
        if(Battery_Value <= 310 ){        //Battery ADC value for 9v 310,309
        while(Battery_Value<=400){
        Battery_Value = ADC_Read(1);
        status = 1;
        }
        else
        status = 0;
        }
        
    }
 
}

 


Instead of this code,

if(Battery_Value <= 310 )
{ //Battery ADC value for 9v 310,309
while(Battery_Value<=400)
{
Battery_Value = ADC_Read(1);
LOAD = OFF;
}
LOAD = ON;
}

use the following==>

if(Battery_Value <= 310 )
{ //Battery ADC value for 9v 310,309
while(Battery_Value <= 400)
{
Battery_Value = ADC_Read(1);
FLAG_1 = 1;
}
divide_val = (Battery_Value-310)*255/425;
}
When the LOAD gets OFF, FLAG_1 ==>1 and when LAOD gets ON, FLAG_1==> 0....
 

Now everything is going absurd n weird in code. In my initial code, LOAD used to get Switch OFF when Solar Panel voltage was going above 9V and switch ON when Solar Panel voltage is below 1V. Now it also has stopped working, guys plz wish me luck. Mathspbe aim is , PWM should work from 13V-9V of battery voltage and LOAD should be totaly OFF below 9V upto 12.4V. So will it do same thing with your suggestion? Because divide_val is getting changed in if(Battery_Value<=310) so wt will happen till 310 ? Or everything is same other than this?
 
Last edited:

Now everything is going absurd n weird in code. In my initial code, LOAD used to get Switch OFF when Solar Panel voltage was going above 9V and switch ON when Solar Panel voltage is below 1V. Now it also has stopped working, guys plz wish me luck.

I think this is what you required to wrk on... just try it...
And plz update what is the exact requirement...
Whether the load gets adjusted as per the battery voltage or the panel voltage???

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,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 interrupt timer0_ISR()
	{
     if(INTCON.T0IF)
       T0IF_bit = 0;
     
     if(FLAG_1 == 1)
	{
     	LOAD = OFF;
	TMR0 = 255-divide_val;
	}
     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;
     //CMCON0 = 0x07;               //Disable the comparators
     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;

     //TMR0 = timer_val;

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

                                  if(Panel_value>=122)
                                      {       
                                           //AD Value for 3 volt
                                           BATTERY_CHARGE = ON;

                                          if(Battery_Value>=430)  //AD Value for 12v
                                           BATTERY_CHARGE = OFF;
                                      }

                                  if(Battery_Value > 430)
                                          BATTERY_CHARGE = OFF;
                                  

                                  if(Panel_Value <= 30 )
                                        {   //Panel AD value for 1v <=40
                                            BATTERY_CHARGE = OFF;
                                                                       
                                        }

                                  if(Panel_Value > 321)    //Panel Voltage 9 v
                                   {
                                  
                                  if(Battery_Value <=425 && Battery_Value > 310)
					{ /////////////LOOP ------(1)
                                  	
					divide_val = (Battery_Value-310)*255/425;

					if(FLAG_1 == 1)
					FLAG_1 = 0;
					}
                              

if(Battery_Value <= 310 )
{ //Battery ADC value for 9v 310,309
while(Battery_Value <= 400)
{
Battery_Value = ADC_Read(1);
FLAG_1 = 1;
}
divide_val = (Battery_Value-310)*255/425;
}
}

                              }
 

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…