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

18F2550 ADC Sampling Rate
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

Interrupts to regulate ADC sampling interval
PostPosted: Sun Mar 11, 2012 10:42 am     Reply with quote

Yes ADC=8 sets 8 bit ADC conversions.

The CCS manual gives several examples of how to do interrupts.

In your case, you want to sample the ADC at 2ms intervals.

Basically you set up a 2ms interrupt in your initialisation routine, and write an interrupt routine.

So the whole thing COULD be of the form:-

Code:

int8 data_store[2,x];

initialise()
{
  set_your_timer_of_choice_to_overflow_at_say_~2ms_intervals();
  set_your_timer_of_choice_interrupt_on;
  set_global_interrupts_on;
}

interrupt_routine_ISR()
{
 read_adc;
 start_next_conversion;
 save_adc_data_to_data_store;
}

main()
{
  initialise();
  while (true)
  {
    taska();
    taskb();
    .....
  }
}

Where taska, taskb, ...... are your other functions.
Because you are sending data via USB at the same time as collecting fresh data you may get a conflict.
The way round would be to have a two dimensional array, data_store[2,x], and work in two phases.

In phase_0; data goes to data_store[0,_], and data_store[1,_] is sent to USB, until empty.
When data_store[0,_] is full, you go to phase_1.
In phase_1; data goes to data_store[1,_], and data_store[0,_] is sent to USB, until empty.
When data_store[1,_] is full, you go back to phase_0.

Mike
Ttelmah



Joined: 11 Mar 2010
Posts: 19826

View user's profile Send private message

PostPosted: Sun Mar 11, 2012 11:54 am     Reply with quote

If you look at the thread I already pointed to:
<http://www.ccsinfo.com/forum/viewtopic.php?t=47494>

This shows 'how' to do ADC sampling at a timed interval.

You only need to change this line:

CCP_2=399;

to sample at a lower frequency (It is actually an instruction count-1, so at 48MHz - 12MIPS, to sample at 500Hz, a value of 23999, will work).

Then just expand the number of samples - as shown it takes 256, increase the array to 1024, and the count the same amount, and send these how you want.

The existing code uses CDC, and sends the data in hex, but will still send 1000 records of data in under 1/50th of a second, if your program at the other end accepts it this fast....

Seriously look at your PC code carefully, if things are taking too long.

Best Wishes
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Sun Mar 11, 2012 12:07 pm     Reply with quote

Quote:

In phase_0; data goes to data_store[0,_], and data_store[1,_] is sent to USB, until empty.
When data_store[0,_] is full, you go to phase_1.
In phase_1; data goes to data_store[1,_], and data_store[0,_] is sent to USB, until empty.
When data_store[1,_] is full, you go back to phase_0.


Forgot to say, I'm assuming the rest of your system allows the USB to empty one data store in LESS time than the PIC fills the other. If this does not happen, you're in trouble; you then need to sort out the USB etc.

Mike
hops-cc



Joined: 06 Mar 2012
Posts: 6

View user's profile Send private message

PostPosted: Wed Mar 14, 2012 3:58 pm     Reply with quote

Hi Everyone;

Now i take 64 samples at each time and send them to matlab. I write a delay (delay_ms(2)) in order to obtain a sampling frequency of 500Hz = 1/2ms. (I Know, This calculation is theorically and it's not exactly 500 Hz because of TAd and ADC settling times.)

In matlab i can see the fourier spektrum of the signal, BUT i saw it a little bit shifted in frequemcy domain when i wrote the sampling frequency=500 Hz. That's because matlab requires the exact sampling frequency of the signal and i dont know my PIC's sampling interrval exactly. How can i know the exact value of the sampling interval ?

Here's my codes. Can you help me with obtaining desired sampling frequency 500Hz ?

Code:

#include <18F2550.h>
#device ADC=8
#fuses HSPLL,USBDIV,PLL5,PUT,CPUDIV1,VREGEN,NOWDT,NOPROTECT,NOLVP,NODEBUG,NOMCLR
#use delay(clock=20000000)

#define USB_HID_DEVICE     FALSE             
#define USB_EP1_TX_ENABLE  USB_ENABLE_BULK    //Uçnokta1'de Yığın transferi aktif
#define USB_EP1_RX_ENABLE  USB_ENABLE_BULK   
#define USB_EP1_TX_SIZE    64                 //Uçnokta1 için maksimum alınacak ve gonderilecek
#define USB_EP1_RX_SIZE    64                 //veri boyutu (64 byte)

#include <pic18_usb.h>     
#include <USB_Konfigurasyon.h>                //USB konfigurasyon bilgileri bu dosyadadır.
#include <usb.c>         

#define UcNokta1       1
#define Komut          gelen_paket[0]

//Yazılım (Firmware) Sürüm no
#define surum_no1      0x00            //surum_no2.surum_no1 ornek: 1.0
#define surum_no2      0x01

//Komutlar
#define surum_oku      0x03
#define olcum_al       0x02

static unsigned int16 ADC_deger1 = 0;
static unsigned int16 ADC_deger2 = 0;
unsigned int8 i  ; 
void user_init(void)
{
   set_tris_a(0x01);                    //RA0,RA1 giriş
   set_tris_b(0xFF);
   setup_adc_ports(AN0);
   setup_adc(ADC_CLOCK_INTERNAL);
 
}
unsigned int16 ADC_Oku(byte kanal)
{
   unsigned int16 olcum=0;
   set_adc_channel(kanal);
   delay_us(20);
   olcum = read_adc();
   return olcum;
}

void main(void)
{
   byte sayac=0;
   byte gelen_paket[64];               //gelen paket
   byte gond_paket[64];                //gönderilecek paket
   byte surum1=surum_no1;
   byte surum2=surum_no2;

   user_init();                     
   usb_init();                     
   usb_task();                     

   usb_wait_for_enumeration();         //Cihaz, hazır olana kadar bekle
   if(usb_enumerated())
   output_high(Pin_A2);                //USB bağlantısı kurulduysa LED'i yak.

      while(usb_enumerated())
      {
                           for (i=1;i<=64;++i)
                           {
                           delay_ms(2);
                           ADC_deger1=ADC_Oku(0);
                           gond_paket[i] = (byte) ADC_deger1;
                           
                           }
                                                   
                           sayac = 0x40;

         if(sayac!=0)
         {
         usb_put_packet(UcNokta1, gond_paket, sayac, USB_DTS_TOGGLE);
         sayac = 0;
         Komut = 0;
         }
      }


}





Another problem is that; when i take 64 samples each time. The first byte of char, always equals to 75

(gond_paket[0]=75) why that fault occurs ?

The third thing it that; I want to make an isochronous transfer but i couldn't made it yet. There's not enough information on the web as far as i searched.
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

ADC timings etc.
PostPosted: Wed Mar 14, 2012 5:37 pm     Reply with quote

From your code
Code:

                         for (i=1;i<=64;++i)
                           {
                           delay_ms(2);
                           ADC_deger1=ADC_Oku(0);
                           gond_paket[i] = (byte) ADC_deger1;
                           
                           }
     

The inter-sample interval is just over 2ms (assuming that you actually have a 20MHz crystal).

Ttelmah and I have shown you two ways of getting well defined sample intervals, both take care of the set up times etc.

You are NOT taking a new sample gond_paket[0].

The 75 value you're complaining about is whatever default value happens to be in RAM.

Look at your code; the START value for i is 1, rather than the zero you seem to expect.

replace your code
Code:

                         for (i=1;i<=64;++i)

with
Code:

                         for (i=0;i<=63;++i)

Mike
hops-cc



Joined: 06 Mar 2012
Posts: 6

View user's profile Send private message

PostPosted: Thu Mar 15, 2012 9:40 am     Reply with quote

Thanks to everypost. You guys really helped me out. I've just seen all the replies. I will try all of them and write a feedback here. Thanks.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
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