wwfeldman
Advanced Member level 4
I am using VDAC8 and ADC_SAR to convert analog to digital and back, in KIT059, PSoC5LP.
A for loop assigns the digital value to the DtoA, whose output is buffered by an op amp follower.
The output is fed back into another buffering opamp and then to an A to D converter, ADC_SAR.
the program:
the pinouts for the op-amps were assigned by PSoC Creator
the input range of the SAR AtoD is Vssa to Vdda (single ended)
the reference is thus forced to internal and the reference is 2.5 V
This is the observed results - - left column is the d to a theoretical value, which agrees with meter measurement thereof,
the right column is a to d output as seen on the LCD:
this is the graph of the data, without the the SAR produced 0s
the question is - what happened to the SAT output when it went above about 2.5 V?
why did it go to zero?
what did i miss/do wrong?
A for loop assigns the digital value to the DtoA, whose output is buffered by an op amp follower.
The output is fed back into another buffering opamp and then to an A to D converter, ADC_SAR.
the program:
Code:
#include "project.h"
#include "stdio.h"
#include "string.h"
#include "math.h"
uint8 i, ii, j, jj, k, kk; //index variables
uint8 temp = 0, startflag = 0; //0 = wait 1 = start
//declare linear regression varibles
uint8 n = 0;
double x, y = 0;
double xsum, ysum = 0;
double xy, xysum = 0;
double x2, x2sum = 0;
double num, den, slope, intercept;
double zero = 0;
double kkk;
char8 res[16u];
double value, fracpart, intpart ; //value is real, frac is fractional part, decim is whole number part
uint8 intfrac, intdecim, decim, frac;
// function:
void lma_clear_display(void)
{
//clear dispaly
for(j = 0; j<=3; j++)
{
LCD_Position(j,0);
LCD_PrintString(" ");
}
} //end clear display for(j = 0; j<=3; j++)
// function:
void lma_print_real(double value)
{
intpart = (int) value;
fracpart = (value - intpart)*1000;
LCD_PrintNumber(intpart);
LCD_PrintString(".");
if(fracpart < 10) LCD_PrintString("0");
if(fracpart < 100) LCD_PrintString("0");
//if(fracpart < 1000) LCD_PrintString("0");
//if(fracpart < 10000) LCD_PrintString("0");
LCD_PrintNumber(fracpart);
} //end lma_print_real
int main(void)
{
//initialize display
LCD_Start();
CyGlobalIntEnable; /* Enable global interrupts. */
lma_clear_display();
LCD_Position(0,0);
LCD_PrintString("initialize ");
CyDelay(500);
//initialize variables
n = 0;
x = 0;
y = 0;
xy = 0;
x2 = 0;
xsum = 0;
ysum = 0;
xysum = 0;
x2sum = 0;
zero = 0;
//set op amps, A2D, and D2A
OpAmp_grn_in_Start();
OpAmp_wht_out_Start();
D2A_Vout_Start();
D2A_Vout_SetSpeed(D2A_Vout_HIGHSPEED);
D2A_Vout_SetRange(D2A_Vout_RANGE_4V);
lma_clear_display();
LCD_Position(0,0);
LCD_PrintString("D to A started ");
CyDelay(500);
A2D_wht_pot_Start();
A2D_wht_pot_SetPower(A2D_wht_pot__MEDPOWER);
A2D_wht_pot_SetResolution(A2D_wht_pot__BITS_8);
A2D_wht_pot_StartConvert();
A2D_grn_snsr_Start();
A2D_grn_snsr_SetPower(A2D_grn_snsr__MEDPOWER);
A2D_grn_snsr_SetResolution(A2D_grn_snsr__BITS_8);
A2D_grn_snsr_StartConvert();
//step through output voltages from 0.75 to 3.23 V
//digital range 47 to 202 or 0.75 V to 3.32 V
//increment +1 yields 156 data points
//increment +5 yields 32 data points
lma_clear_display();
LCD_Position(0,0);
LCD_PrintString("for loop ");
CyDelay(500);
for(k = 47; k<=202; k = k + 5)
{
D2A_Vout_SetValue(k);
CyDelay(500);
//get pot value
A2D_wht_pot_StartConvert();
//wait for end of conversion
do
{temp = A2D_wht_pot_IsEndConversion(A2D_wht_pot_RETURN_STATUS);}
while (temp == 0);
CyDelay(200);
x = A2D_wht_pot_CountsTo_Volts(A2D_wht_pot_GetResult8());
//get sensor value
A2D_grn_snsr_StartConvert();
//CyDelay(200);
//wait for end of conversion
do
{temp = A2D_grn_snsr_IsEndConversion(A2D_grn_snsr_RETURN_STATUS);}
while (temp == 0);
CyDelay(200);
lma_clear_display();
LCD_Position(0,0);
LCD_PrintString("convert finished ");
CyDelay(500);
y = A2D_grn_snsr_CountsTo_Volts(A2D_grn_snsr_GetResult8());
//linear regression calculations
n = n + 1;
xsum = xsum + x;
ysum = ysum + y;
xysum = xysum + (x * y);
x2sum = x2sum + (x * x);
lma_clear_display();
LCD_Position(0,0);
LCD_PrintString("k = ");
LCD_PrintNumber(k);
LCD_PrintString(" ");
lma_print_real((double) (k * 4.08/255.0));
LCD_Position(1,0);
LCD_PrintString("x = ");
lma_print_real((double) x);;
LCD_Position(2,0);
LCD_PrintString("y = ");
lma_print_real((double) y);
CyDelay(10000);
} //end for(k = 47; k<=202; k = k + 5)
//find slope and intercept
num = n * xysum - xsum * ysum;
den = n * x2sum - (xsum * xsum);
slope = num/den;
num = ysum * x2sum - xsum * xysum;
intercept = num/den;
zero = (-1 * intercept / slope) - 2.5 ;
//display results
lma_clear_display();
LCD_Position(0,0);
LCD_PrintString("sensor data ");
LCD_Position(1,0);
LCD_PrintString("slope = ");
lma_print_real(slope);
LCD_Position(2,0);
LCD_PrintString("int = ");
lma_print_real(intercept);
LCD_Position(3,0);
LCD_PrintString("zero = ");
lma_print_real(zero);
CyDelay(5000); //5 second pause
} //end of main
/* END OF FILE */
the pinouts for the op-amps were assigned by PSoC Creator
the input range of the SAR AtoD is Vssa to Vdda (single ended)
the reference is thus forced to internal and the reference is 2.5 V
This is the observed results - - left column is the d to a theoretical value, which agrees with meter measurement thereof,
the right column is a to d output as seen on the LCD:
0.752 0.840
0.832 0.938
0.912 1.016
0.992 1.113
1.072 1.191
1.152 1.289
1.232 1.387
1.312 1.465
1.392 1.543
1.472 1.641
1.552 1.719
1.632 1.816
1.712 1.895
1.792 1.992
1.872 2.070
1.952 2.168
2.032 2.246
2.112 2.344
2.192 2.422
2.272 0
2.352 0
2.432 0
2.512 0
2.592 0
2.672 0
2.752 0
2.832 0
2.912 0
2.992 0
3.072 0
3.152 0
3.232 0
this is the graph of the data, without the the SAR produced 0s
the question is - what happened to the SAT output when it went above about 2.5 V?
why did it go to zero?
what did i miss/do wrong?
Last edited by a moderator: