View previous topic :: View next topic |
Author |
Message |
newpic
Joined: 09 Aug 2005 Posts: 32
|
printf floating |
Posted: Fri May 13, 2011 2:57 pm |
|
|
My printf long shown either 0.00 or 5.00,
if pot set to max --> read 5.00, anything less then max --> 0.00
Can anybody tell me what is wrong?
Code: | #include <mechatronic.h>
long result;
float volt;
#INT_EXT
void ext_isr(void)
{
output_toggle(LED);
delay_ms(10);
clear_interrupt(INT_EXT);
}
void main(void)
{
output_low(LED);
setup_adc( ADC_CLOCK_INTERNAL );
setup_adc_ports(1);
setup_ccp2(CCP_PWM); // Configure CCP1 as a PWM
setup_timer_2(T2_DIV_BY_1, 0x3F, 1);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
while(1)
{
delay_ms(10);
result = read_adc();
delay_ms(10);
volt = (result / 1023);
volt = (float)volt * 5;
// printf(" %lu \n\r",result);
printf(" %1.2f \n\r",volt);
}
} |
mechatronic.h
Code: | //File name mechatronic.h
#include <16F917.H>
#device ADC=10 // choose 10 bit AD instead of 8
#fuses INTRC_IO, NOWDT, NOPROTECT, NOBROWNOUT, PUT
#use delay(clock=8000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#define LED PIN_D6 |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri May 13, 2011 4:12 pm |
|
|
Quote: | setup_adc( ADC_CLOCK_INTERNAL );
|
Use the correct ADC divisor. For an 8 MHz oscillator, you should use:
Code: | setup_adc(ADC_CLOCK_DIV_16); |
Quote: | setup_adc_ports(1); |
What is this ? You should use the correct constant, not a magic number.
If you want to use the AN0 pin, you should use
Code: | setup_adc_ports(sAN0); |
The main problem is that you are not setting the ADC channel.
You need to do this:
Code: |
set_adc_channel(0); |
|
|
|
newpic
Joined: 09 Aug 2005 Posts: 32
|
|
Posted: Fri May 13, 2011 8:51 pm |
|
|
per pic16f917.h
see below
Quote: | // Constants used in SETUP_ADC_PORTS() are:
#define sAN0 1 //| A0 |
Either sAN0 or 1 is same right?
Code: |
volt = (result / 1023);
volt = (float)volt * 5;
// printf(" %lu \n\r",result);
printf(" %1.2f %lu\n\r",volt,result); |
the ADC result is right, I can get the adc from 0 - 1023 while turning pot1 clockwise, but the volt is 0.00 if result 0-1022 and volt is 5.00 if result = 1023.
I think my either my variable is not right, but I couldn't not trace the problem. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri May 13, 2011 8:58 pm |
|
|
Add a decimal point and a 0 to the end of the 1023, to make it be a float:
Quote: | volt = (result / 1023.0); |
Read this page for reasons why it's bad to use "magic numbers" in your
program:
http://c2.com/cgi/wiki?MagicNumber |
|
|
newpic
Joined: 09 Aug 2005 Posts: 32
|
|
Posted: Fri May 13, 2011 9:14 pm |
|
|
Code: | volt = (result / 1023.0); |
work!!
Thanks. |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Fri May 13, 2011 9:18 pm |
|
|
This line Code: | volt = (result / 1023); | will return 0.0 unless result is 1023 or more in which case it returns 1.0. Result/1023 is done with integer math to produce an integer which is then assigned to a float. If you change 1023 to 1023.0 as PCM programmer says it will force a floating point division. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Sat May 14, 2011 2:39 am |
|
|
The point about using the defines rather than just a number, is twofold:
First, the _current_ define is '1', but CCS _will_ change things at times in what their functions use. So if they add a new feature to the ADC configuration, the required value may well become something different, like '32'. If you use the defines, the supplied .h file will change when this happens, and your code will still work. If you use '1', it won't.
The second, is that '1' says nothing, while the defines are to some extent 'documenting'. So sAN0, says you are selecting the AN0 pin, and in a few years time, if either yourself, or someone else, has to look at the code, this will make reading it a lot easier....
Best Wishes |
|
|
|