| 
	
	|  |  |  
	
		| View previous topic :: View next topic |  
		| Author | Message |  
		| jdasari Guest
 
 
 
 
 
 
 
			
			
			
			
			
			
			
			
			
 
 | 
			
				| ADC on PIC16F877 |  
				|  Posted: Wed Apr 02, 2003 10:58 pm |   |  
				| 
 |  
				| I'm trying to read the voltage feed into channel 4 of the ADC on port A and then print it to the LCD screen. For some reason the program seems to get stuck in the while loop and does not print the readings from the ADC onto the screen. I have the code below. Any help will be greatly appreciated. 
 int flag=0;
 float bat_voltage;
 lcd_init();
 setup_adc_ports(ALL_ANALOG);
 setup_adc(ADC_CLOCK_DIV_2);
 set_tris_a(0xFF);
 
 while (flag == 0)
 {
 set_adc_channel(4);
 delay_us(100);
 lcd_putc (" \f In the while loop \n");
 delay_ms(10000);
 bat_voltage=read_adc();
 printf(lcd_putc,"bat_voltage=\%f", bat_voltage);
 //lcd_putc(bat_voltage);
 if(bat_voltage ==  3)
 {
 lcd_putc (" \f Full Charge \n");
 flag=1;
 }
 }
 
 lcd_putc("\f Exiting \n");
 }
 ___________________________
 This message was ported from CCS's old forum
 Original Post ID: 13335
 |  |  
		|  |  
		| PCM programmer 
 
 
 Joined: 06 Sep 2003
 Posts: 21708
 
 
 
			    
 
 | 
			
				| Re:  ADC on PIC16F877 |  
				|  Posted: Thu Apr 03, 2003 1:15 am |   |  
				| 
 |  
				| :=I'm trying to read the voltage feed into channel 4 of the ADC on port A and then print it to the LCD screen. For some reason the program seems to get stuck in the while loop and does not print the readings from the ADC onto the screen. I have the code below. Any help will be greatly appreciated. ---------------------------------------------------
 I'm not at the company, so I can't test anything, but I can
 make a few comments on your code.
 
 :=
 :=           int flag=0;
 
 The A/D converter returns an integer value.  There's no reason
 to make this next variable be a float.  If you're using the
 A/D in 8 bit mode, then make it be an int8.   If you're using
 the A/D in 10 bit mode (#device adc=10) then declare it to be
 an int16.
 :=	   float bat_voltage;
 :=	   lcd_init();
 :=           setup_adc_ports(ALL_ANALOG);
 :=           setup_adc(ADC_CLOCK_DIV_2);
 
 I would put this next line before the ADC setup lines above.
 It would look cleaner that way (to me).
 :=           set_tris_a(0xFF);
 :=
 :=       while (flag == 0)
 :=	{
 :=		set_adc_channel(4);
 :=		delay_us(100);
 :=		lcd_putc (" \f In the while loop \n");
 
 This is a 10 second delay.  That alone, could make the code
 appear to be "locked up".
 :=		delay_ms(10000);
 
 Here, you're putting the adc value, which will be either 8 or
 16 bits, into a float.  As I said, I'm not at the company, so
 I can't confirm this, but I wouldn't do something like this.
 It would not surprise me if the code crashed, with CCS, if
 you did this.  If you really want to return a float, you should
 specifically cast the function so it returns a float.
 ie.:  bat_voltage = (float)read_adc();
 But, the best thing to do, as I said above is to declare
 bat_voltage as an int8 or int16.  That's because read_adc()
 only returns an 8 or 10 bit value.
 :=		bat_voltage=read_adc();
 
 Then, you should change this next line so it displays an 8
 or 16 bit integer. Ie., use \%u or \%lu instead of \%f.
 :=		printf(lcd_putc,"bat_voltage=\%f", bat_voltage);
 :=		//lcd_putc(bat_voltage);
 
 This next line is very bad.  You're testing for an exact value
 which may never occur.  You should test for "greater than or
 equal to".
 Also, are you assuming that the value read from the A/D is in
 volts ?   So you're trying to test for at least 3 volts ?
 It doesn't return volts.  If you're running the A/D in 8-bit
 mode, it returns a value from 0 to 255.  Assuming that your
 reference voltage is +5v (Vdd), then 255 corresponds to +5v,
 and 153 would be approximately 3.0 volts.  So I think you
 need to think about this some more.
 :=		if(bat_voltage ==  3)
 
 I think you probably want to do this:
 <PRE>
 if(bat_voltage >=  153)
 
 or better yet, do this:
 
 #define _3_VOLTS  153   // Put this line above main()
 
 if(bat_voltage >= _3_VOLTS)
 
 </PRE>
 
 :=		{
 :=			lcd_putc (" \f Full Charge \n");
 :=				flag=1;
 :=		}
 :=	}
 :=
 :=	lcd_putc("\f Exiting \n");
 
 Is this brace here, at the end of main() ?  If so, you should
 put a while(1); statement here, so the PIC does not go to sleep.
 :=}
 ___________________________
 This message was ported from CCS's old forum
 Original Post ID: 13340
 |  |  
		|  |  
		| jdasari Guest
 
 
 
 
 
 
 
			
			
			
			
			
			
			
			
			
 
 | 
			
				| Re:  ADC on PIC16F877 |  
				|  Posted: Fri Apr 04, 2003 1:09 pm |   |  
				| 
 |  
				| Thanks much PCM. One quick question. When I set the Vref using the set_vref(vrefhHigh | Value) function, how should I factor in the value which seems to be an intiger value from 0 - 15?
 
 Regards
 -dj
 ___________________________
 This message was ported from CCS's old forum
 Original Post ID: 13410
 |  |  
		|  |  
		| PCM programmer 
 
 
 Joined: 06 Sep 2003
 Posts: 21708
 
 
 
			    
 
 | 
			
				| Re:  ADC on PIC16F877 |  
				|  Posted: Fri Apr 04, 2003 1:18 pm |   |  
				| 
 |  
				| :=Thanks much PCM. One quick question. :=When I set the Vref using the set_vref(vrefhHigh | Value) function, how should I factor in the value which seems to be an integer value from 0 - 15?
 :=
 ----------------------------------------------------
 
 I'm not sure what you mean by "factor in".
 
 The 16F877 does not have a Vref module.  So you can't use
 that CCS function with the 16F877.
 
 The 16F877A has one.  But it's only for use with the Comparator
 module in that chip.  It's not used with the A/D.
 
 With either of these two chips, if you want to use a Vref
 other than Vdd, you have to supply it with an external circuit
 and apply it to the appropriate Vref pin.
 ___________________________
 This message was ported from CCS's old forum
 Original Post ID: 13411
 |  |  
		|  |  
		| jdasari Guest
 
 
 
 
 
 
 
			
			
			
			
			
			
			
			
			
 
 | 
			
				| Re:  ADC on PIC16F877 |  
				|  Posted: Tue Apr 08, 2003 11:36 pm |   |  
				| 
 |  
				| Please bear with my beginners ignorance here. 
 Once I get the voltage reading using the read_adc( ) how can I convert that into the actual decimal voltage. i.e For e.x if I read 153 how can display that as 3 volts on the LCD? I have my code pasted below. Thanks much in advance.
 
 #include <lcd.c>
 #include <keybd.c>
 
 void main()
 {
 
 int choice=1; int flag=0;
 int8 bat_voltage;
 float dig_voltage= 0;
 lcd_init();
 set_tris_a(0xFF);
 setup_adc_ports(ALL_ANALOG);
 setup_adc(ADC_CLOCK_DIV_32);
 
 
 while (flag == 0)
 {
 set_adc_channel(1);
 delay_us(100);
 bat_voltage=read_adc();
 printf(lcd_putc,"\f bat_voltage=\%u", bat_voltage);
 if(bat_voltage  >= 255)
 {
 lcd_putc (" \f Full Charge \n");
 flag=1;
 }
 dig_voltage = (bat_voltage*5)/255;
 printf(lcd_putc,"\n \%f", dig_voltage);
 delay_ms(1000);
 }
 
 lcd_putc("\f Exiting \n");
 while(1);
 
 }
 ___________________________
 This message was ported from CCS's old forum
 Original Post ID: 13521
 |  |  
		|  |  
		|  |  
  
	| 
 
 | You cannot post new topics in this forum You cannot reply to topics in this forum
 You cannot edit your posts in this forum
 You cannot delete your posts in this forum
 You cannot vote in polls in this forum
 
 |  
 Powered by phpBB © 2001, 2005 phpBB Group
 
 |