View previous topic :: View next topic |
Author |
Message |
William Meade Guest
|
ADC Averaging Problem.... |
Posted: Fri May 09, 2003 2:39 pm |
|
|
<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
|
Re: ADC Averaging Problem.... |
Posted: Fri May 09, 2003 3:09 pm |
|
|
<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
|
Re: ADC Averaging Problem.... |
Posted: Fri May 09, 2003 3:22 pm |
|
|
:=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.... |
Posted: Fri May 09, 2003 3:37 pm |
|
|
:=:=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
|
Re: ADC Averaging Problem.... |
Posted: Fri May 09, 2003 4:02 pm |
|
|
:=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 |
|
|
|