View previous topic :: View next topic |
Author |
Message |
irmanao
Joined: 08 Apr 2015 Posts: 77
|
Simultaneous ADC sampling (dspic33) |
Posted: Tue Jan 26, 2016 11:50 am |
|
|
dsPIC33EP512MU810 (dspic33e usb starter kit)
ccs version 5.008
I would like to sample two analog inputs simultaneously (both are 0-3V at 50 Hz) and then add them. (I have successfully sampled one)
The datasheet states that it is possible but doesn't go any further. I also couldn't find any code in the ccs manual.
Do i just have to add a second channel and read from that or is there something specific i need to do for simultaneous sampling?
Can anyone point me to the right direction?
Thanks |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Tue Jan 26, 2016 12:03 pm |
|
|
I just had a QUICK read of the datasheet and didn't see a way to 'sync' the two ADC peripherals to read at the same time.
Have to ask why ? At 50HZ that PIC can easily read 2 ADC channels,have a LOT of time left over for 'things'. I doubt you could see any problems.
Maybe explain what and why you need 'at the same time' ?
Just because a PIC has a feature doen't mean you have to use it.
Jay |
|
|
irmanao
Joined: 08 Apr 2015 Posts: 77
|
|
Posted: Tue Jan 26, 2016 12:45 pm |
|
|
Thanks for the reply,
I have been assigned to do this with this particular feature.
I need to make calculations with the two converted channels.
such as: adc1-adc2 which needs to be 0
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Tue Jan 26, 2016 1:02 pm |
|
|
Well you'll have to read the datasheet real carefully, as it may be possible....
Also V5.008 is very 'young' and may not have the code required to do that operation though, if the hardware will do it nothing to stop you from creating your own.
jay |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Tue Jan 26, 2016 2:05 pm |
|
|
Search the Microchip web site for application notes related to the A/D on dsPICs. Can't remember exactly what search terms I used, but they have many application notes regarding all the "exotic" features of the dsPICs. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Tue Jan 26, 2016 3:06 pm |
|
|
This can only be done in 10bit mode.
You have to set the SIMSAM bit yourself, set AD12B to 0, and set the CHPS bits to 01. Then configure the required inputs. Trigger a conversion, then directly read the ADCBUFF registers. |
|
|
irmanao
Joined: 08 Apr 2015 Posts: 77
|
|
Posted: Wed Jan 27, 2016 11:04 am |
|
|
Ok guys thanks for the replies...
So i need to add to my main program as Ttelmah (and the datasheet) suggested this?:
Code: | AD12B = 0; // 10 Bits
CHPS=01; // convert CH0 and CH1 |
Then sample both channels like so?:
Code: | set_adc_channel( 0 );
delay_us(4);
ad0=read_adc() ;
set_adc_channel( 1 );
delay_us(4);
ad1=read_adc() ;
|
And also, how do i directly read from the ADCBUFF registers? Have never done anything similar, any pointers?
Thanks again |
|
|
alan
Joined: 12 Nov 2012 Posts: 357 Location: South Africa
|
|
Posted: Wed Jan 27, 2016 11:16 am |
|
|
That PIC has 2 ADC's
Code: | set_adc_channel(Analog1);
set_adc_channel2(Analog2);
V1 = read_adc();
V2 = read_adc2();
|
if you want the S&H time smaller
Code: | read_adc(ADC_START_ONLY);
V2 = read_adc2();
V1 = read_adc(ADC_READ_ONLY);
|
V1 & V2 will differ only a few instructions as opposed to the whole conversion time.
Regards |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Wed Jan 27, 2016 11:24 am |
|
|
Yes. Alan has showed the correct way.
The single read shown in the second part is the correct way.
With this the first read_adc, triggers _both_ conversions because of the simultaneous setting, then the second just returns the actual result of the second ADC.
Beware that the adc channels used must be the standard ones, not the relocatable ones. Again the simultaneous sampling is not supported on the latter. |
|
|
irmanao
Joined: 08 Apr 2015 Posts: 77
|
|
Posted: Wed Jan 27, 2016 11:43 am |
|
|
Ok, so this takes care of the simultaneous setting -->>
Code: | AD12B = 0; // 10 Bits
CHPS=01; // convert CH0 and CH1 |
and i just need to add this code from alan
Code: | read_adc(ADC_START_ONLY);
V1 = read_adc1();
V0 = read_adc(ADC_READ_ONLY); | ?
Correct??
I will test this code and get back to you asap.
_thanks for your time_ |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Wed Jan 27, 2016 12:31 pm |
|
|
Almost.
Except you need the channel selection as well. The CHPS bits say to sample both AD1 & AD1, but the multiplexers need to be connected.
Code: |
set_adc_channel(Analog1);
set_adc_channel2(Analog2); //set the multiplexers
AD12B = 0; // 10 Bits
CHPS=01; // convert both CH0 and CH1
SIMSAM=1; //simultaneous sampling
//these need to be #bit defined, and the CHPS bits will have to be done
//individually or as a structure
//Then whenever you want to read
V0 = read_adc(); //This does a start and read on AD1
V1 = read_adc2(ADC_READ_ONLY); //Just read the value from AD2
//These must be this way round.
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Wed Jan 27, 2016 3:46 pm |
|
|
Thinking about it, in all honesty the simplest way to do this, is to keep it simple. Use the standard functions, and just overlap the reads.
Code: |
set_adc_channel(Analog1);
set_adc_channel2(Analog2); //set the multiplexers
//This and the clock setup - not shown, only needs to be done once
//Then read with:
read_adc(ADC_START_ONLY);
read_adc2(ADC_START_ONLY);
while(!adc_done())
;//wait for adc's to read
vol0=read_adc(ADC_READ_ONLY);
val1=read_adc2(ADC_READ_ONLY); //second adc data available one
//instruction later.
|
This will perform the two reads at the same time, with just one
instruction cycle between them,
Unless using DMA, this will be as fast as trying to perform the
automated read, and simpler.... |
|
|
irmanao
Joined: 08 Apr 2015 Posts: 77
|
|
Posted: Sun Jan 31, 2016 7:27 am |
|
|
I'll be checking the results tomorrow with the simpler way that ttelmah and alan kindly suggested. In the meantime, i can't build the program with simultaneous sampling. When i add to the code the following: Code: | AD12B = 0; // 10 Bits
CHPS=01; // convert both CH0 and CH1
SIMSAM=1; //simultaneous sampling
| i get this: Code: | *** Error 12 "dual-3-.c" Line 22(1,6): Undefined identifier AD12B
*** Error 12 "dual-3-.c" Line 23(1,5): Undefined identifier CHPS
*** Error 12 "dual-3-.c" Line 24(1,7): Undefined identifier SIMSAM
|
If you could, please elaborate on this: Code: | //these need to be #bit defined, and the CHPS bits will have to be done
//individually or as a structure
|
_thanks _ |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Sun Jan 31, 2016 9:05 am |
|
|
You need to define these bits. So (for instance):
#bit AD12B=getenv("BIT:AD12B")
Because CHPS is two bits in the register, these will either have to be defined separately (as two single bits), or you will have to define a structure containing the pair of bits as a bit field.
However read the post about just using the standard functions.
The point is that unless you are using DMA, you have to physically read the two results one after the other, so just start one ADC, then the other, wait for the first one to complete, then read it's result followed by the other. The two converters will run in parallel, just one instruction time apart, and the total time needed will be exactly the same as using simultaneous sampling. |
|
|
irmanao
Joined: 08 Apr 2015 Posts: 77
|
|
Posted: Mon Feb 01, 2016 9:44 am |
|
|
OK
I successfully compiled this code which just abstracts the two inputs and outputs when the result is 0: Code: | #include <33EP512MU810.h>
#device adc=10
#fuses PR_PLL,NOWDT,NOPROTECT
#use delay(clock=80000000)
#pin_select INT1=PIN_D6
#pin_select INT2=PIN_D7
void init_all (void);
int16 dms=9;
int16 ad1;
int16 ad2;
int16 awd;
int16 awdp=0;
int16 count=0;
void main()
{output_high(PIN_D1);
delay_ms(100);
output_low(PIN_D1);
delay_ms(100);
init_all();
WHILE(TRUE)
{
read_adc(ADC_START_ONLY);
read_adc2(ADC_START_ONLY);
while(!adc_done());
ad1=read_adc(ADC_READ_ONLY);
ad2=read_adc2(ADC_READ_ONLY);
awd=(ad1-ad2);
if ( awd=0 && awd>awdp ){
count=count+1;
if (count==5){
delay_ms(dms);
output_high(PIN_F13);
delay_us(60);
output_low(PIN_F13);
count=0;
}
}
awdp=awd;
}
}
#INT_EXT1
void ext_int1(void)
{
dms-=1;
if(dms<1){dms=9;}
}
#INT_EXT2
void ext_int2(void)
{
dms+=1;
if(dms>9){dms=1;}
}
void init_all (void){
ext_int_edge(1, H_TO_L);
ext_int_edge(2, H_TO_L);
enable_interrupts(GLOBAL);
enable_interrupts(INT_EXT1);
enable_interrupts(INT_EXT2);
setup_adc_ports( sAN0 | VSS_VDD );
setup_adc_ports( sAN3 | VSS_VDD );
setup_adc ( ADC_CLOCK_INTERNAL );
set_adc_channel ( 0 );
set_adc_channel2 ( 3 );
} |
When i try to run the program (after i program the dspic with the starter kit) i get this Code: | PK3Err0040: The target device is not ready for debugging.
Please check your configuration bit settings and program
the device before proceeding.
|
and it doesn't run.
Other programs work fine and run smoothly (blinking LEDs). What am i doing wrong? |
|
|
|