Real time serial data acquisition

Status
Not open for further replies.

ambilys

New Member
Hi

I wish to take the samples from pic16f877a,4Mhz HS( if it is given a sine wave input) and plot the same.I am giving 230vp sine wave 50hz as input and transformed it into 5v range and level shifted it into positive voltages.

This is my code

Code:
                              // Loop variable


      float val,val1;//Declare the adcvalue stored variables
      char uart_rd[50],uart_rd1[50];

      void main()
      {
          TRISA=0XFF;//porta as input
      ADCON1 = 0x82; // AN0->AN4 selected as analog input
        ADCON0 = 0b11000001; // Configue analog mode

           UART1_Init(9600);               // Initialize UART module at 9600 bps


          while(1)
          {
          val=ADC_Read(0);
          val1=(val*325.0)/1023.0;
          FloatToStr(val1,uart_rd1);
             strncpy(uart_rd,uart_rd1,3);
             UART1_Write(val1);

             //UART1_Write(10);
            UART1_Write(13);
            delay_us(1);

       }
       }

I have checked the values in hyperterminal and see that the controller not even sample the peak voltage.I wish to have the samples correctly so that I can able to plot the waveform correctly.
 
Can't find anything else wrong with your code other than you are wasting time for unnecessary calculations and string manipulations. And your baudrate is really low.
Just send the raw ADC result through the uart if you need maximum speed.

int val;
char uart_rd[10];

while(1)
{
val=ADC_Read(0);
itoa(val,uart_rd, 10);
UART1_Write(uart_rd);
delay_us(1);
}
 
Last edited:
First of all, you got the formula wrong.

It is AC, so it'll go from -325V to +325V. You probably need to give it some margin, so that the range is actually -400V to +400V (or similar). For it to spread beween 0 and 5V you need to attenuate it 800/5 = 160 times (or so) and shift 2.5V. Let's suppose you did this correctly. After the attenuation and the shift, 0V corresponds to -400V, 2.5V to 0V and 5V to +400V. Or, in ADC readings 0 is -400V, 512 is 0V and 1023 is +400V. The correct formula to reflect this relationship would be:

V = 800*(val-512)/1023;

A magic of copy and paste.
 
How wrong you have to go that it matters?

You cannot improve the accuracy of the signal that you measure. So, if the accuracy is 1% (as if you used 1% resistors for a voltage divider, ignoring other errors), then you can only have 100 meaninful counts. Everything else is a noise. If you use 300-400 counts, your rounding error (0.3%) will not matter - the combined error will be sqrt(1^2 + 0.3^2) = 1.05%.

If you somehow got into a situation where every ADC count matters, you need a better ADC.
 
 
itoa is an undeclared identifier in mikroc
 
You can improve the accuracy of your measurements. Add a little bit of noise and oversample.

Adding a noise will only increase the error.

Taking an average of multiple samples does decrease the error by sqrt(N). But it has nothing to do with single measurements. When you take an average, the resolution increases too. Say, you average 100 integers. The average will have 0.01 resolution. Note that resolution increases N times, while accuracy increases sqrt(N) times, which means that the gain in accuracy will be less than the gain in resolution. It is, therefore, no reason to get extra resoltion for individual samples.

It's not applicable to OP who wants to get the shape of the curve and therefore cannot oversample. The important thing is that he missed by a factor of two in his formula.
 
factor of 2 means?
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…