View previous topic :: View next topic |
Author |
Message |
irmanao
Joined: 08 Apr 2015 Posts: 77
|
ADC test code |
Posted: Wed Jul 08, 2015 7:23 am |
|
|
(dspic33e usb starter kit)
I wanted to do a test for adc with the following code
Code: | #include <33EP512MU810.h>
#use delay(clock=8000000)
#byte PORTD=0xF81
#byte PORTE=0xF83
void init_all (void);
long ad;
void main()
{
init_all();
output_high(PIN_D0);
delay_ms(2000);
output_low(PIN_D0);
while(TRUE)
{
ad=read_adc();
if (ad>200)
{
output_high(PIN_D1);
delay_ms(500);
output_low(PIN_D1);
}
}
}
void init_all(void){
set_tris_e(0xff);
set_tris_d(0x00);
setup_adc_ports( sAN30 | VSS_VDD );
setup_adc ( ADC_CLOCK_INTERNAL );
set_adc_channel ( 0 );
} |
I connect AN30 to 0-2V but the led on D1 doesn't turn on.
(I'm new to programming)
Any suggestions?
thanks
Last edited by irmanao on Mon Jul 13, 2015 5:08 pm; edited 1 time in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19561
|
|
Posted: Wed Jul 08, 2015 7:51 am |
|
|
It wouldn't....
AN30, requires set_adc_channel(30).
The channel number is the multiplexer input pin to use. Just because you are only enabling AN30, the multiplexer still has connections for 0 to 29....
Don't get confused by the internal ADC selection channels. These are distinct from the multiplexer selection, which set_adc_channel controls. By default the CCS code, runs the ADC in one channel mode. The set_adc_channel code, sets the CH0SA bits, selecting which actual ADC input is to be read. |
|
|
irmanao
Joined: 08 Apr 2015 Posts: 77
|
|
Posted: Wed Jul 08, 2015 9:11 am |
|
|
thanks for the reply.
Now D1 stays on WITHOUT even feeding it analog voltage when
Code: | if (ad>400){
output_high(PIN_D1);
delay_ms(1000);
output_low(PIN_D1);
}
|
but stays off when i change the code
Code: | if (ad<400){
output_high(PIN_D1);
delay_ms(1000);
output_low(PIN_D1);
}
|
what am i doing wrong? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19561
|
|
Posted: Wed Jul 08, 2015 12:21 pm |
|
|
Not feeding it an analog voltage does not mean it is at 0.
It'll float, and could read almost anything.
However also add #device adc=12 (just above the clock setting). As it stands you are not telling the compiler how to configure the ADC result, and it may well be left justifying the result. |
|
|
705150
Joined: 25 Apr 2013 Posts: 14
|
|
Posted: Wed Jul 08, 2015 12:45 pm |
|
|
You need to provide some time off, turn on led, wait 500, turn off led, wait again 500, the led does turn off but is turned back on too fast for you to notice it was off. _________________ if it doesn't work, don't force it, try a bigger hammer... |
|
|
irmanao
Joined: 08 Apr 2015 Posts: 77
|
|
Posted: Thu Jul 09, 2015 5:50 am |
|
|
I added #device adc=12 but the only thing that changed was that the led was flashing either way (<400,>400). When i connected the voltage there was no difference.
Code: | if (ad>400){
output_high(PIN_D1);
delay_ms(1000);
output_low(PIN_D1);
}
delay_ms(50);
}} |
Last edited by irmanao on Fri Jul 10, 2015 5:33 am; edited 1 time in total |
|
|
guy
Joined: 21 Oct 2005 Posts: 297
|
|
Posted: Fri Jul 10, 2015 1:59 am |
|
|
You're in the right track....
Change to Debug mode, put a breakpoint after the line ad=read_adc(); and run the code in Debug mode. When the program execution stops in the breakpoint, move the cursor over the variable ad to show its value. That way you know if the problem is in the A/D conversion or in the if/flash logic.
A few things to consider: the 12-bit A/D can sometimes give a slightly negative result for voltages around 0 volts. If the variable ad is defined as long (instead of signed int16) may get a value of about 65535.
Your threshold (400) is approximately 1/10 of the total 12-bit range (0..4095) so it will represent a voltage of 0.1Vdd (0.33V for 3.3V supply). |
|
|
irmanao
Joined: 08 Apr 2015 Posts: 77
|
|
Posted: Fri Jul 10, 2015 5:32 am |
|
|
The values i get are all under 2000. The led also flashes when i put
if (ad<2000)
However when i connect voltage nothing changes.(voltage goes to AN30(pin4) and VSS (pin 15))
what am i doing wrong?
- thanks for the help- |
|
|
guy
Joined: 21 Oct 2005 Posts: 297
|
|
Posted: Fri Jul 10, 2015 6:16 am |
|
|
I looked at the data sheet, errata, USB starter kit... Haven't found anything yet.
Can you repost your current code? (after the changes)
BTW, get rid of the set_tris statements. The CCS compiler takes care of this automatically when you write output_high(PIN_D1) and the default power-up for I/O pins is input.
will cause PIN_E8, PIN_E9 to become outputs (probably not what you wanted. These are 16-bit registers). |
|
|
irmanao
Joined: 08 Apr 2015 Posts: 77
|
|
Posted: Fri Jul 10, 2015 6:23 am |
|
|
Code: | #include <33EP512MU810.h>
#device adc=12;
#use delay(clock=8000000)
#byte PORTD=0xF81
#byte PORTE =0xF83
void init_all (void);
int16 ad;
void main() {
init_all();
output_high(PIN_D0);
delay_ms(2000);
output_low(PIN_D0);
while(TRUE){
ad=read_adc();
if (ad>2000){
output_high(PIN_D1);
delay_ms(1000);
output_low(PIN_D1);
}
delay_ms(50);
}}
void init_all(void){
setup_adc_ports( sAN30 | VSS_VDD );
setup_adc ( ADC_CLOCK_INTERNAL );
set_adc_channel ( 30 );
} |
|
|
|
guy
Joined: 21 Oct 2005 Posts: 297
|
|
Posted: Fri Jul 10, 2015 6:32 am |
|
|
it's a minor thing but try to delete the ; (semicolon) from the line #device adc=12;
Otherwise to me the code looks ok. Maybe re-check that you're connecting to the right pin (pin 4 of the dsPIC, not the PIC24 which is also on the board) etc.
It could also be a bug in the compiler etc. which requires to check all the setup of the registers. Let's see if someone else has any ideas... |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19561
|
|
Posted: Fri Jul 10, 2015 1:26 pm |
|
|
Also, try with ADC=10.
This chip has the ADC configurable for 10bit or 12bit operation. It's possible there is a problem with the 12bit code, so try in 10bit mode. |
|
|
irmanao
Joined: 08 Apr 2015 Posts: 77
|
|
Posted: Fri Jul 10, 2015 5:12 pm |
|
|
I already did. Same results.. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9253 Location: Greensville,Ontario
|
|
Posted: Fri Jul 10, 2015 6:18 pm |
|
|
I'd go back to basics..
remove the 'test condition/LED portion and
...cut code to just read the ADC and then send the result to a PC terminal program say at a 1Hz rate. Using a pot on the ADC input you should see the result on the PC.
Do whatever you need to get this step working 100% then add your 'test and turn on LED' section of code.
Jay |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jul 10, 2015 6:39 pm |
|
|
I wonder if you are doing something that you are not showing us.
Because these are not the correct addresses for these ports:
Quote: | #include <33EP512MU810.h>
#device adc=12;
#use delay(clock=8000000)
#byte PORTD=0xF81
#byte PORTE =0xF83 |
Also, your program has no #fuses, which is suspicious. |
|
|
|