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 |
|
C31 Output Problem
Started by ●November 13, 2000
Reply by ●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 |