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 support@ccsinfo.com

ADC Averaging Problem....

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







ADC Averaging Problem....
PostPosted: Fri May 09, 2003 2:39 pm     Reply with quote

<font face="Courier New" size=-1><html>
<body>
<pre>

Below is a driver that I wrote for the CS5516 A/D chip. This
actually works great except for the averaging code that I
tried to incorporate. The variable (value) that I return from
the driver is correct, but when I try to average it and return
the variable (avalue) from the driver function it give me the
following number "16711935". The number that I get back from
the (value) variable is 5963 which is correct. Can anyone
advise me on what I am doing wrong?

// Driver routines for the CS5516 A/D chip
//
// The following need to be set at the beginning of the
// main program prior to calling this driver function.
//

// output_float(ADC_DI) Set ADC Data In pin as input
// output_low(ADC_DO) Set ADC data out pin low
// output_low(ADC_CLK) Set ADC clock pin low

#define MEAN_FILTER_WIDTH 10 // Added for averaging

// DEFINE CONNECTIONS TO PIC
#define ADC_RESET PIN_B3
#define ADC_DI PIN_C0
#define ADC_DO PIN_C2
#define ADC_CLK PIN_C3

// DEFINE DRIVER VARIABLES
int32 value; // define value variable

int32 mean; // Added for averaging
int32 avalue; // Added for averaging
int16 input_buffer[MEAN_FILTER_WIDTH]; // Added for averaging
static char inbuf_index = 0; // Added for averaging
static char num_elements = 0; // Added for averaging

// WRITE TO ADC
void write_adc_byte(byte data) {
byte i; // define counter variable

for(i=1;i<=8;++i) { // count from 1 to 8
output_bit(ADC_DO,shift_left(&data,1,0)); // output 0 or 1 to data out pin
output_high(ADC_CLK); // set adc clock pin high
output_low(ADC_CLK); // set adc clock pin low
} // end 'for' loop
}

// READ ADC
int16 read_adc_value() {

byte i;

While (!input(ADC_DI)); // WAIT FOR ADC_DI TO GO HIGH
while (input(ADC_DI)); // WAIT FOR ADC_DI TO GO LOW

// Clear Ready Flag
for(i=1;i<=8;++i) { // repeat 8 times
output_high(ADC_CLK); // set adc clock pin high
output_low(ADC_CLK); // set adc clock pin low
}
// Read ADC Value
for(i=1;i<=16;++i) { // repeat 16 times
shift_left(&value,2,input(ADC_DI)); // shift in value (16 bit number)
output_high(ADC_CLK); // set adc clock pin high
output_low(ADC_CLK); // set adc clock pin low
}
// Read ADC Error Flags
for(i=1;i<=8;++i) { // repeat 8 times
output_high(ADC_CLK); // set adc clock pin high
output_low(ADC_CLK); // set adc clock pin low
}

return value; // Return (value) to calling Function

//------------------------------AVERAGING SECTION---------------------------------------

// Insert ADC reading into circular input buffer.
input_buffer[inbuf_index] = value; // Added for averaging
inbuf_index++; // Added for averaging
if(inbuf_index >= MEAN_FILTER_WIDTH) // Added for averaging
inbuf_index = 0; // Added for averaging

if(num_elements < MEAN_FILTER_WIDTH) // Added for averaging
num_elements++; // Added for averaging

// Calculate the mean. This is done by summing up the
// values and dividing by the number of elements.
mean = 0; // Added for averaging
for(i = 0; i < num_elements; i++) // Added for averaging
mean = mean + input_buffer[i]; // Added for averaging

avalue = mean / num_elements; // Added for averaging

return avalue; // Added for averaging

//---------------------------------------------------------------------------------------

}

// INITIALIZE ADC
adc_init() {
output_low(ADC_RESET); // Set reset pin low
delay_ms(150); // Delay 150 mili-seconds for A/D to reset
output_high(ADC_RESET); // Set reset pin high
}

// START AUTOMATIC ADC CONVERSION
adc_start() {

write_adc_byte(0x88); // Start automatic conversion (10001000)
}

// SET ADC GAIN 8(X25) 24 Bits MSB First
set_adc_gain() {
read_adc_value(); // Goto read adc value sub-routine
write_adc_byte( 0x90 ); // 10010000 - Command Register
write_adc_byte( 0x00 ); // 00000000 - Configuration Register (Bits 17 - 24)
write_adc_byte( 0xC0 ); // 11000000 - Configuration Register (Bits 9 - 16)
write_adc_byte( 0x00 ); // 00000000 - Configuration Register (Bits 0 - 8)
write_adc_byte( 0x88 ); // 10001000 (Start automatic conversion)
}

</pre>
</body>
</html></font>
___________________________
This message was ported from CCS's old forum
Original Post ID: 14315
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

Re: ADC Averaging Problem....
PostPosted: Fri May 09, 2003 3:09 pm     Reply with quote

<font face="Courier New" size=-1>
This is really not an answer to your question but you can improve performance greatly if you specify a buffer width of either 8 or 16. This will allow division to be performed by a bit shifting operation that only takes a few instruction cycles.</font>
___________________________
This message was ported from CCS's old forum
Original Post ID: 14318
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

Re: ADC Averaging Problem....
PostPosted: Fri May 09, 2003 3:22 pm     Reply with quote

:=Below is a driver that I wrote for the CS5516 A/D chip. This
:=actually works great except for the averaging code that I
:=tried to incorporate. The variable (value) that I return from
:=the driver is correct, but when I try to average it and return
:=the variable (avalue) from the driver function it give me the
:=following number "16711935". The number that I get back from
:=the (value) variable is 5963 which is correct. Can anyone
:=advise me on what I am doing wrong?
-----------------------------------------------------------
Can you post the complete averaging routine, including all
variable declarations ? (You don't have to post any other
routines). If some variables used by that routine are declared
as globals, then post those lines too.
___________________________
This message was ported from CCS's old forum
Original Post ID: 14319
William Meade
Guest







Re: ADC Averaging Problem....
PostPosted: Fri May 09, 2003 3:37 pm     Reply with quote

:=:=Below is a driver that I wrote for the CS5516 A/D chip. This
:=:=actually works great except for the averaging code that I
:=:=tried to incorporate. The variable (value) that I return from
:=:=the driver is correct, but when I try to average it and return
:=:=the variable (avalue) from the driver function it give me the
:=:=following number "16711935". The number that I get back from
:=:=the (value) variable is 5963 which is correct. Can anyone
:=:=advise me on what I am doing wrong?
:=-----------------------------------------------------------
:=Can you post the complete averaging routine, including all
:=variable declarations ? (You don't have to post any other
:=routines). If some variables used by that routine are declared
:=as globals, then post those lines too.

<html>
<body>
<pre>

The following code is from the main program and it shows where
I call the function with - read_adc_value(); The averaging
code that I inserted actuall came from one of your files
called filters.c. What I tried to do is incorporate the
averaging into the ADC driver so I wouldn't need to include a
seperate file for compiling the program.


// DISPLAY WEIGHT ON LCD
If (state == 1) {

read_adc_value();

lcd_gotoxy(7,1); // goto position 7 on line 1
If (value < 0) value = 0; // Check to see if avalue less than 0
If (value > 32767) value = 0; // Check to see if avalue greater than 32767
printf(lcd_putc,"\%lu ",avalue); // display raw ADC value on line 1

If (value < value - scale_zero) // Check to see if avalue less than 0
weight = 0.0;
else
weight = ((value - scale_zero) / raw_per_pound);// Calculate weight on scale

ad_scale = weight * 655.35; // Calculate scale 4-20mA Output Value
write_AN_byte(ad_scale); // Update 4-20mA Signal

lcd_gotoxy(7,2); // goto position 7 on line 2

// CHECK TO SEE IF WEIGHT <= 0
If (weight <= 0) weight = 0; // If weight is < 0 display 0
printf(lcd_putc,"\%7.1f ",weight); // Display weight on LCD line 2 position 7

// CHECK TO SEE IF ENTER BUTTON IS PRESSED
if (!input(ENTER_BTN)) { // Check to see if ENTER button is pressed
while (!input(ENTER_BTN)); // Wait for ENTER button to be let up
Delay_us(500); // Delay 1/2 Second for Debounce
state = 2; // set state to 2 (Calibrate Scale)
}

</body>
</html>
___________________________
This message was ported from CCS's old forum
Original Post ID: 14320
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

Re: ADC Averaging Problem....
PostPosted: Fri May 09, 2003 4:02 pm     Reply with quote

:=What I tried to do is incorporate the
:=averaging into the ADC driver so I wouldn't need to include a
:=separate file for compiling the program.
--------------------------------------------------------
You can incorporate it without using a separate file.
Just copy and paste the entire function into your main source
file. Put it at the end of the file, and put a function prototype for it above main(). Then call it from within
your main program.

One purpose of using functions is to have a library of
re-usable, known-good, working code modules that you can just
drop in to your programs. If you cut them up, you defeat that
purpose.
___________________________
This message was ported from CCS's old forum
Original Post ID: 14322
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