View previous topic :: View next topic |
Author |
Message |
art
Joined: 21 May 2015 Posts: 181
|
Print ADC data problem |
Posted: Thu Dec 10, 2015 1:05 am |
|
|
Hai, i would like to know how to modify my code so it will only print after I get all 256 data from ADC. Please help me....
Code: |
#include <18F4550.h>
#DEVICE ADC=10
#fuses HS,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#include <string.h>
#include <input.c>
#include <stdio.h>
#include <stdlib.h>
main()
{
char ch;
int i;
unsigned char key;
float value, min;
while(true)
{
ch=getc();
if(ch=='Z')
{
while (key!=32)
{
setup_port_a( ALL_ANALOG );
setup_adc( ADC_CLOCK_DIV_16 );
set_adc_channel( 0 );
delay_us(5);
if(kbhit())
{key=getch();}
for(i=0;i<=255;i++)
{
value = Read_ADC();
min=value*5/1023 ;
printf("%2.3f ",min);
}
printf("\n");
} key=0;
}
}
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19549
|
|
Posted: Thu Dec 10, 2015 2:05 am |
|
|
The key thing is what happens to 'i' when it goes past 255?.
'i' is an 8bit integer. It can only hold values from 0 to 255. When you increment it past 255, it overflows and goes back to 0.... Hence the loop can never exit. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Dec 10, 2015 2:09 am |
|
|
Quote: |
i would like to know how to modify my code so it will only print after I get
all 256 data from ADC. |
Create a 256 element array. Do a loop and save the ADC readings in the
array. Then when done reading, loop through the array and print the
array elements.
Also, I don't know what compiler version you have, but vs. 5.051 gives
the following warnings:
Quote: |
>>> Warning 203 "PCH_Test.c" Line 36(1,1): Condition always TRUE
>>> Warning 208 "PCH_Test.c" Line 11(1,5): Function not void and does not return a value MAIN |
The first one is about your for() loop. It's going to run forever.
That's because you have declared 'i' as an 8-bit integer, which means it
can be from 0 to 255. Your test says if 'i' is less than or equal to 255
it will stay in the loop. But 'i' will always be only from 0 to 255.
That's what an 8-bit integer does. You need to fix this.
Quote: | int i;
for(i=0;i<=255;i++)
{
.
.
.
} |
The 2nd warning is about the line below. You need to put 'void' in front
of main():
|
|
|
art
Joined: 21 May 2015 Posts: 181
|
|
Posted: Thu Dec 10, 2015 2:40 am |
|
|
Dear pcm,
Do you have any example to create 256 array, save it and print all the array element as you mention? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Dec 10, 2015 3:12 am |
|
|
There is a test program in the post in the link below that does that.
It has a read loop and a separate printf loop:
http://www.ccsinfo.com/forum/viewtopic.php?t=44201&start=6
Just ignore the testing portion of it. Delete these lines from the first loop:
Code: | delay_us(1);
output_toggle(PIN_B0); |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19549
|
|
Posted: Thu Dec 10, 2015 4:51 am |
|
|
and as a comment. An ADC value is an integer, not a float. Requires only half the memory to store 256 integers versus 256 floats. I'm sure the example PCM_programmer points to, will use integers not floats, and you should always think when 'tempted' to use floats "Is this really necessary or a good idea". 99.99% of the time, the answer to this will be 'no'. |
|
|
art
Joined: 21 May 2015 Posts: 181
|
|
Posted: Thu Dec 10, 2015 5:04 pm |
|
|
Hai,
Thank you for the test code. I will test it and inform the result later.
Regarding 'float' for the calculation result :
Code: |
min=value*5/1023 ;
printf("%2.3f ",min); |
where should i put it? As you mention it will use a lot of memory, but i still need those calculation...Do you have any suggestion? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19549
|
|
Posted: Fri Dec 11, 2015 2:32 am |
|
|
The point is that you don't have to _store_ a float. You can still do float calculations. Do a search here for (cast).
However beware also that your calculation is wrong. 1023, is _not_ the correct division factor for the PIC ADC.
The PIC ADC behaves as if it returned values from 0 to 1024, but reaches 1023, 1.5 'steps' below the Vref voltage, and never goes any higher. Do a search here on this. This is not true for the very oldest PIC ADC's, but for all the ones after the first couple of years, it is.
Have a look here:
<http://www.electro-tech-online.com/threads/why-adc-1024-is-correct-and-adc-1023-is-just-plain-wrong.132570/>
Your conversion could be done more accurately, completely in integer:
Code: |
//with 'value' as an int16
int32 min;
min = (((int32)value*5000)+2500)/1024
printf("%5.3LW ",min);
|
The post I point to, explains the addition.
Your '2' in front of the decimal point is also wrong. In C, for number scaling, the digit in front of the decimal, is the 'total field width' (so how many characters to output), not the digits in front of the decimal. So you are saying 'output a result just 2 character wide, but then include a decimal point, and 3 digits after this' - four characters..... Ugh. It'll work, because the compiler handles overflowing, but is not how to output a value with a proper size.... |
|
|
art
Joined: 21 May 2015 Posts: 181
|
|
Posted: Mon Dec 14, 2015 1:25 am |
|
|
Hai,
Thank you. It works |
|
|
|