CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Print ADC data problem

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
art



Joined: 21 May 2015
Posts: 181

View user's profile Send private message

Print ADC data problem
PostPosted: Thu Dec 10, 2015 1:05 am     Reply with quote

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: 19550

View user's profile Send private message

PostPosted: Thu Dec 10, 2015 2:05 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Dec 10, 2015 2:09 am     Reply with quote

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():
Quote:
main()
art



Joined: 21 May 2015
Posts: 181

View user's profile Send private message

PostPosted: Thu Dec 10, 2015 2:40 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Dec 10, 2015 3:12 am     Reply with quote

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: 19550

View user's profile Send private message

PostPosted: Thu Dec 10, 2015 4:51 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Dec 10, 2015 5:04 pm     Reply with quote

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: 19550

View user's profile Send private message

PostPosted: Fri Dec 11, 2015 2:32 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Dec 14, 2015 1:25 am     Reply with quote

Hai,

Thank you. It works Very Happy
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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