Reply by Rick Collins December 3, 20002000-12-03
I did not wade through your code to see if I could spot a problem, but I
may be able to help you understand better what is going on. I will put
comments in your posting. At 05:35 PM 11/13/00, you wrote:
>I have two sine waves (@2Khz & ranging from 0-1 Volt Amplitude) going
>into the Primary and Secondary inputs of the C31. My program below is
>supposed to measure a position ratio between the two voltages and the
>result will range from 0 to 1 (0 corresponds to the case when the two
>signals overlap each other and 1 to the case where they are furthest
>apart) using the following formula:
> Ratio=(Va-Vb)/(Va+Vb). Va and Vb are first converted to
>DC by means of the following formula:
>
> Va=Sqrt[(2/N)*sum(data(n)^2)-2avg^2], where N is # of samples.

I am not clear about what these equations mean. It looks like you are
taking some sort of least squares calculation. Then you use that to
determine the "ratio" of overlap. Is this a way to find the phase of the
two signals?

In any case, this will only work well if the two AC signal components have
the same range or max value. If you want to compare them, you first have to
scale them to similar ranges. >The program is first reading the input from the primary channel and
>storing a 100 samples into a buffer then uses the formula above to
>calculate the DC voltage. Then it reads the input from Auxiliary
>channel and stores 100 samples in the same buffer and does the same
>calculation. Finally, it uses the Ratio formula to calculate the
>output. The resulting value is then outputted throug the C31 output.
>However, since the resulting number is less than one.. it is first
>scaled beofore it is outputted. The problem i am having comes here: I
>can scale it by up to 300 and it gives me no more than 60 mV out! if i
>keep increasing the scaling factore I get the same number. I need to
>scale it to a bigger output (about 3 Volts) so I can get a better
>reading and thus a better accuracy.

I don't see any mention of the ADC or DAC coponents or the analog scaling
factors being used. The first thing I would check is to see what range of
output from the DAC you can get. You may be looking at a problem with the
hardware. So just write some simple code that outputs a sine wave at
maximum range from the DAC. See what you get on the scope. Do you know how
many bits of resolution the DAC has? This will affect your code too.

Then once you have the DAC working the way you want, you can loop the input
ADC to the output DAC in real time and apply a sine wave to the input and
see it on the output. Your code can apply whatever scale factor is
appropriate. But keep in mind that the ADC and DAC have limited dynamic
ranges. >I dont understand how the C31 reads and outputs voltages. What i mean
>is: how does it read 50 mV for example? does it read it as 50000 for
>instance? Also, why weren't I able to output more than 60 mV? I would
>really apprecaite the help since this is making me go crazy.

This depends entirely on your hardware. The C31 does not have a built in
ADC or DAC. Your board has these devices. What the C31 reads will depend on
the analog scale factor, the ADC resolution and how the value is justified
in the C31 32 bit word.
Rick Collins
Arius - A Signal Processing Solutions Company
Specializing in DSP and FPGA design

Arius http://www.arius.com
4 King Ave 301-682-7772 Voice
Frederick, MD 21701-3110 301-682-7666 FAX


Reply by Crazybaby November 13, 20002000-11-13
I have two sine waves (@2Khz & ranging from 0-1 Volt Amplitude) going
into the Primary and Secondary inputs of the C31. My program below is
supposed to measure a position ratio between the two voltages and the
result will range from 0 to 1 (0 corresponds to the case when the two
signals overlap each other and 1 to the case where they are furthest
apart) using the following formula:
Ratio=(Va-Vb)/(Va+Vb). Va and Vb are first converted to
DC by means of the following formula:

Va=Sqrt[(2/N)*sum(data(n)^2)-2avg^2], where N is # of samples.

The program is first reading the input from the primary channel and
storing a 100 samples into a buffer then uses the formula above to
calculate the DC voltage. Then it reads the input from Auxiliary
channel and stores 100 samples in the same buffer and does the same
calculation. Finally, it uses the Ratio formula to calculate the
output. The resulting value is then outputted throug the C31 output.
However, since the resulting number is less than one.. it is first
scaled beofore it is outputted. The problem i am having comes here: I
can scale it by up to 300 and it gives me no more than 60 mV out! if i
keep increasing the scaling factore I get the same number. I need to
scale it to a bigger output (about 3 Volts) so I can get a better
reading and thus a better accuracy.

I dont understand how the C31 reads and outputs voltages. What i mean
is: how does it read 50 mV for example? does it read it as 50000 for
instance? Also, why weren't I able to output more than 60 mV? I would
really apprecaite the help since this is making me go crazy.

The program:

.start ".text",0X809900
.start ".data",0X809C00

.include "AICCOM31.ASM"
.data
AICSEC .word 0A14h,1h,3E7Eh,73h ;Fs KHz
CH_A_ADD .word CH_A+LENGTH-1
LENGTH .set 100
.brstart "CH_A_BUFF",128
CH_A .sect "CH_A_BUFF"
.loop LENGTH
.float 0
.endloop
.entry BEGIN
.text

BEGIN
LDP AICSEC
CALL AICSET
LDI LENGTH,BK
LDI @CH_A_ADD,AR0
LOOP LDI 63H,RC
RPTB LOOP_A
CALL IOPRI
FLOAT R6,R3
LOOP_A STF R3,*AR0++%
CALL RMS_CORR
LDF R0,R4 ;R4=Va

LDI 63H,RC
RPTB LOOP_B
CALL IOAUX
FLOAT R6,R3
LOOP_B STF R3,*AR0++%

CALL RMS_CORR
LDF R0,R5 ;R5=Vb
ADDF R4,R5,R1 ;Va+Vb
SUBF R5,R4,R0 ;Va-Vb
CALL FDIV ;R0=(Va-Vb)/(Vb+va)
MPYF 300,R0 ;SCALING FACTOR
FIX R0,R7
BR LOOP

;RMS_CORR ROUTINE
RMS_CORR CALL SUM
MPYF 0.01,R1
MPYF R1,R1
ADDF R1,R1
CALL DATA_SQR
MPYF 0.02,R3
SUBF R1,R3,R0
CALL SQRT
RETS

;SUM ROUTINE
SUM
LDF 0,R1
LDI 63H,RC
RPTB SUM_LOOP
LDF *AR0++%,R0
SUM_LOOP ADDF R0,R1
RETS

;DATA_SQR ROUTINE
DATA_SQR LDF 0,R3
LDI 63H,RC
RPTB DATA_LOOP
LDF *AR0++%,R0
MPYF R0,R0
DATA_LOOP ADDF R0,R3
RETS

;SQUARE ROOT ROUTINE
SQRT:
LDF R0,R3
RETSLE
PUSHF R0
POP R1
ASH -24,R1
ADDI 1,R1
ASH -1,R1

NEGI R1,R1
ASH 24,R1
PUSH R1
POPF R1

MPYF 0.5,R0

MPYF R1,R1,R2
MPYF R0,R2
SUBRF 1.5,R2

MPYF R2,R1

RND R1
MPYF R1,R1,R2
MPYF R0,R2
SUBRF 1.5,R2
MPYF R2,R1

RND R1
MPYF R1,R1,R2
MPYF R0,R2
SUBRF 1.5,R2
MPYF R2,R1

RND R1
MPYF R1,R1,R2
MPYF R0,R2
SUBRF 1.5,R2
MPYF R2,R1

RND R1
MPYF R1,R1,R2
MPYF R0,R2
SUBRF 1.5,R2
MPYF R2,R1

RND R1,R0
MPYF R3,R0
RETS

; start of fdiv program

FDIV:

RND R0,R4
LDF R1,R0
CALL FPINV
RND R0
MPYF R4,R0

RETS

; START OF FPINV SUBROUTINE

FPINV
LDF R0,R3
ABSF R0
PUSHF R0
POP R1
ASH -24,R1
NEGI R1,R1
SUBI 1,R1
ASH 24,R1
PUSH R1
POPF R1

MPYF R1,R0,R2
SUBRF 2.0,R2
MPYF R2,R1

MPYF R1,R0,R2
SUBRF 2.0,R2
MPYF R2,R1

MPYF R1,R0,R2
SUBRF 2.0,R2
MPYF R2,R1
MPYF R1,R0,R2
SUBRF 2.0,R2
MPYF R2,R1

RND R1

MPYF R1,R0,R2
SUBRF 1.0,R2
MPYF R1,R2
ADDF R2,R1

RND R1,R0

NEGF R0,R2
LDF R3,R3
LDFN R2,R0

RETS