Measuring ADC samples and store in digital - how to calculate?

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • tvnaidu
    Contributor
    • Oct 2009
    • 365

    Measuring ADC samples and store in digital - how to calculate?

    I am reading an ADC Input by Microcontroller form AC realy, I have to store them to represent sign wave. when I read peak value, which is active High, I am reading 12 bit ADC value is 4090 (actually 4096, but some drop is there), sometimes I get 4086. the low I gets zero and middle I gets 2044 or 2040. Here

    active high: 4094
    middle: 2048.
    active low : 0

    I have make middle as centre point and I have to store 2048 as zero and active low as negative 1 and active high as 4094. how can I do in C language to store them, do I have to divide or modulus?. I am taking 1000 samples per Second, using all these samples, these samples I have to store between -1 and +1, can somebody through how can I store (when I read I get svalues between 0 and 4094 and I have to store them between -1 and +1). appreciated.
  • mac11
    Contributor
    • Apr 2007
    • 256

    #2
    Are you just trying to figure out how to map the values (0 ... 4095) to (-1 ... +1)?

    When converting ADC readings I like to think of it as chopping the measured range into pieces. The number of pieces is defined by the number of bits in your ADC. So here, you have 12 bits, which is 4096 small steps.

    The thing you're chopping is the input voltage. You say you want your numbers to range from -1 to +1, so that means you're dividing 2 by 4096 (the 2 comes from -1 - 1).

    So, each of the bits in the ADC number (svalue) represents 2/4096 volts (a tiny little step in voltage). Thinking about it this way should make more sense.

    ADC reading of 1 (I mean svalue = 1) equates to 1 * (2 / 4096) = some tiny voltage (one little step in voltage)
    ADC reading of 2 gives you 2 *(2 / 4096), which is double what the above value is (two steps in voltage)
    ADC reading of N = N * 2 / 4096

    But these aren't really the right range, these values go from 0 to 2 not -1 to +1 like you wanted. So you have to offset the result by subtracting one. So you end up with;

    result to store = (svalue * 2 / 4096) - 1

    This whole thing assumes your input scales linearly. And it's actually not really telling you voltage, just splitting your ADC svalue equally between -1 and +1.

    If you wanted to interpret your ADC svalue as an actual voltage (which you didn't ask for, but I'm writing here...) you'd have to factor in your reference voltage and resistor divider factor on the ADC input line.

    If you're just measuring some arbitrary sine wave and just want to store values as -1 to +1 it should be fine. If you're measuring the output of some device and trying to equate that to some real world measurement (speed, temperature, distance, etc) it might not be accurate.

    Comment

    • tvnaidu
      Contributor
      • Oct 2009
      • 365

      #3
      Thanks for the e-mail.

      This is to measure arbitrary since wave only, I think I have to declare all those variables as float instead integer since integer gets truncated and I will get zero when I do (svalue * 2 / 4096), if I declare variable "adc_samp1" below as float and then I can have a value between -1 and +1.

      int svalue;
      float adc_samp1;

      svalue = read ADC Input //this value is between 0 and 4096

      adc_samp1 = (svalue * 2 / 4096) -1; //this should be between -1 and +1.

      that wy I can store all those sampled values in an float array to my final sinusoidal curve.

      Comment

      • tvnaidu
        Contributor
        • Oct 2009
        • 365

        #4
        I am reading 24 ADC inputs with 1ms Timer, but it is taking more time to read, anybody have idea about ADC?

        Comment

        • tvnaidu
          Contributor
          • Oct 2009
          • 365

          #5
          I have all are floating point vars. it take 8.3us for each FP (+,*)?. I have 48 of those plus 8 more total additions in addition to select GPIO for each LED and reading each sample (56 * 8.3us = 464.8 us, almost half of 1ms). if I comment this below code, I have print for half-second at the end, I can see my print coming very faster, if I enable below code, print is very very slow. this is my separate task, the first flag (get_curr_read_ flag = TRUE) set by PIT 1ms timer, here it loks for that flag TRUE, then it reset to FALSE, then read one set of ADC samples and do math and store them in accumulators, then I have local counter here for 500 for Half-sec (measure_power_ factor), when this reaches 500 (SAMPLES/2), I reset this to zero and do power calculations. this is my code. I have print all the way below for half-sec, if I comment all these FP (+,*), I get that orint very quickly, if I enable these, it is very slow, I gets print for every 5 Seconds.

          Code:
           
          
          #define SAMPLES 1000
          
          TK_ENTRY(tk_adc_readings)
          {
           int err;
           int temp;
          int i;
          
          float curr_buf1 =0;
          float curr_buf2 =0;
          float curr_buf3 =0;
          float curr_buf4 =0;
          float curr_buf5 =0;
          float curr_buf6 =0;
          float curr_buf7 =0;
          float curr_buf8 =0;
          float curr_buf9 =0;
          float curr_buf10 =0;
          float curr_buf11 =0;
          float curr_buf12 =0;
          float curr_buf13 =0;
          float curr_buf14 =0;
          float curr_buf15 =0;
          float curr_buf16 =0;
          float curr_buf17 =0;
          float curr_buf18 =0;
          float curr_buf19 =0;
          float curr_buf20 =0;
          float curr_buf21 =0;
          float curr_buf22 =0;
          float curr_buf23 =0;
          float curr_buf24 =0;
          float Board_Total =0;
          
          
           
           while (!net_ready)
            TK_SLEEP(1);
          
           
          
          
           err = eg_init();
          
           if( err == SUCCESS )
           {
            exit_hook(eg_cleanup);
           }
           else
           {
            dtrap();         // eg_init()  shouldn't ever fail
           }
          
           for (;;)
           {
          
             //this get_curr_read_flag seyt by PIT 1ms timer, reset here  
          
          if (get_curr_read_flag == TRUE) {
             get_curr_read_flag = FALSE;
             
             //comment this temporarily - added this function code below
             //get_readings();
             
             VOLT_READ1;
             for(i=0; i < 0x22; i++)
             volt_buf1 = (int)((((MCF_ADC_ADRSLT7&0x7FF8)>>3) - 2048) * 407 ) / 2048;
             volt1_accu += volt_buf1 * volt_buf1;
          
             
          
             CURR_READ1;
             for(i=0; i < 0x22; i++)
             curr_buf1 = (int) ((((MCF_ADC_ADRSLT7&0x7FF8)>>3) - 2048) * 100) / 2048;   
             curr1_accu += curr_buf1 * curr_buf1;
             power1_accu += volt_buf1 * curr_buf1;
          
             
          
             CURR_READ2;
             for(i=0; i < 0x22; i++)
             curr_buf2 = (int) ((((MCF_ADC_ADRSLT7&0x7FF8)>>3) - 2048) * 100) / 2048;   
              curr2_accu += curr_buf2 * curr_buf2;
             power2_accu += volt_buf1 * curr_buf2;
          
             
          
              CURR_READ3;
             for(i=0; i < 0x22; i++)
             curr_buf3 = (int) ((((MCF_ADC_ADRSLT7&0x7FF8)>>3) - 2048) * 100) / 2048;   
              curr3_accu += curr_buf3 * curr_buf3;
             power3_accu += volt_buf1 * curr_buf3;
          
           
          
               CURR_READ4;
             for(i=0; i < 0x22; i++)
             curr_buf4 = (int) ((((MCF_ADC_ADRSLT7&0x7FF8)>>3) - 2048) * 100) / 2048;   
                curr4_accu += curr_buf4 * curr_buf4;
             power4_accu += volt_buf1 * curr_buf4;
          
           
          
                 CURR_READ5;
             for(i=0; i < 0x22; i++)
             curr_buf5 = (int) ((((MCF_ADC_ADRSLT7&0x7FF8)>>3) - 2048) * 100) / 2048;   
                 curr5_accu += curr_buf5 * curr_buf5;
             power5_accu += volt_buf1 * curr_buf5;
          
           
          
                 CURR_READ6;
             for(i=0; i < 0x22; i++)
             curr_buf6 = (int) ((((MCF_ADC_ADRSLT7&0x7FF8)>>3) - 2048) * 100) / 2048;   
                 curr6_accu += curr_buf6 * curr_buf6;
             power6_accu += volt_buf1 * curr_buf6;
          
           
          
                 CURR_READ7;
             for(i=0; i < 0x22; i++)
             curr_buf7 = (int) ((((MCF_ADC_ADRSLT7&0x7FF8)>>3) - 2048) * 100) / 2048;   
                 curr7_accu += curr_buf7 * curr_buf7;
             power7_accu += volt_buf1 * curr_buf7;
          
           
          
                 CURR_READ8;
             for(i=0; i < 0x22; i++)
             curr_buf8 = (int) ((((MCF_ADC_ADRSLT7&0x7FF8)>>3) - 2048) * 100) / 2048;   
                 curr8_accu += curr_buf8 * curr_buf8;
             power8_accu += volt_buf1 * curr_buf8;
          
           
          
             curr_18_BT = curr_buf1+curr_buf2 +curr_buf3+ curr_buf4 + curr_buf5 + curr_buf6 + curr_buf7  + curr_buf8;
             curr_18_AT += curr_18_BT * curr_18_BT;
          
          
             VOLT_READ2;
             for(i=0; i < 0x22; i++)
             volt_buf2 = (int)((((MCF_ADC_ADRSLT7&0x7FF8)>>3) - 2048) * 407 ) / 2048;
                 volt2_accu += volt_buf2 * volt_buf2;
          
           
          
                 CURR_READ9;
             for(i=0; i < 0x22; i++)
             curr_buf9 = (int) ((((MCF_ADC_ADRSLT7&0x7FF8)>>3) - 2048) * 100) / 2048;   
                 curr9_accu += curr_buf9 * curr_buf9;
             power9_accu += volt_buf2 * curr_buf9;
          
           
          
                 CURR_READ10;
             for(i=0; i < 0x22; i++)
             curr_buf10 = (int) ((((MCF_ADC_ADRSLT7&0x7FF8)>>3) - 2048) * 100) / 2048;   
                 curr10_accu += curr_buf10 * curr_buf10;
             power10_accu += volt_buf2 * curr_buf10;
          
             
          
              CURR_READ11;
             for(i=0; i < 0x22; i++)
             curr_buf11 = (int) ((((MCF_ADC_ADRSLT7&0x7FF8)>>3) - 2048) * 100) / 2048;   
                 curr11_accu += curr_buf11 * curr_buf11;
             power11_accu += volt_buf2 * curr_buf11;
          
           
          
                 CURR_READ12;
             for(i=0; i < 0x22; i++)
             curr_buf12 = (int) ((((MCF_ADC_ADRSLT7&0x7FF8)>>3) - 2048) * 100) / 2048;   
                 curr12_accu += curr_buf12 * curr_buf12;
             power12_accu += volt_buf2 * curr_buf12;
           
                 CURR_READ13;
             for(i=0; i < 0x22; i++)
             curr_buf13 = (int) ((((MCF_ADC_ADRSLT7&0x7FF8)>>3) - 2048) * 100) / 2048;   
                 curr13_accu += curr_buf13 * curr_buf13;
             power13_accu += volt_buf2 * curr_buf13;
          
           
          
                 CURR_READ14;
             for(i=0; i < 0x22; i++)
             curr_buf14 = (int) ((((MCF_ADC_ADRSLT7&0x7FF8)>>3) - 2048) * 100) / 2048;   
                 curr14_accu += curr_buf14 * curr_buf14;
             power14_accu += volt_buf2 * curr_buf14;
          
           
          
                 CURR_READ15;
             for(i=0; i < 0x22; i++)
             curr_buf15 = (int) ((((MCF_ADC_ADRSLT7&0x7FF8)>>3) - 2048) * 100) / 2048;   
                 curr15_accu += curr_buf15 * curr_buf15;
             power15_accu += volt_buf2 * curr_buf15;
          
           
          
                 CURR_READ16;
             for(i=0; i < 0x22; i++)
             curr_buf16 = (int) ((((MCF_ADC_ADRSLT7&0x7FF8)>>3) - 2048) * 100) / 2048;   
                 curr16_accu += curr_buf16 * curr_buf16;
             power16_accu += volt_buf2 * curr_buf16;
          
           
          
             curr_9_16_BT = curr_buf9+curr_buf10 +curr_buf11+ curr_buf12 + curr_buf13 + curr_buf14 + curr_buf15  + curr_buf16;
             curr_9_16_AT += curr_9_16_BT * curr_9_16_BT;
          
          
             VOLT_READ3;
             for(i=0; i < 0x22; i++)
             volt_buf3 =(int) ((((MCF_ADC_ADRSLT7&0x7FF8)>>3) - 2048) * 407 ) / 2048;
                volt3_accu += volt_buf3 * volt_buf3;
          
           
          
                CURR_READ17;
             for(i=0; i < 0x22; i++)
             curr_buf17 = (int) ((((MCF_ADC_ADRSLT7&0x7FF8)>>3) - 2048) * 100) / 2048;   
                curr17_accu += curr_buf17 * curr_buf17;
             power17_accu += volt_buf3 * curr_buf17;
          
           
          
                CURR_READ18;
             for(i=0; i < 0x22; i++)
             curr_buf18 = (int) ((((MCF_ADC_ADRSLT7&0x7FF8)>>3) - 2048) * 100) / 2048;   
                curr18_accu += curr_buf18 * curr_buf18;
             power18_accu += volt_buf3 * curr_buf18;
          
           
          
                CURR_READ19;
             for(i=0; i < 0x22; i++)
             curr_buf19 = (int) ((((MCF_ADC_ADRSLT7&0x7FF8)>>3) - 2048) * 100) / 2048;   
                curr19_accu += curr_buf19 * curr_buf19;
             power19_accu += volt_buf3 * curr_buf19;
          
           
          
                CURR_READ20;
             for(i=0; i < 0x22; i++)
             curr_buf20 = (int) ((((MCF_ADC_ADRSLT7&0x7FF8)>>3) - 2048) * 100) / 2048;   
                 curr20_accu += curr_buf20 * curr_buf20;
             power20_accu += volt_buf3 * curr_buf20;
          
           
          
                CURR_READ21;
             for(i=0; i < 0x22; i++)
             curr_buf21 = (int) ((((MCF_ADC_ADRSLT7&0x7FF8)>>3) - 2048) * 100) / 2048;   
                curr21_accu += curr_buf21 * curr_buf21;
             power21_accu += volt_buf3 * curr_buf21;
          
           
          
                CURR_READ22;
             for(i=0; i < 0x22; i++)
             curr_buf22 = (int) ((((MCF_ADC_ADRSLT7&0x7FF8)>>3) - 2048) * 100) / 2048;   
                curr22_accu += curr_buf22 * curr_buf22;
             power22_accu += volt_buf3 * curr_buf22;
          
           
          
                CURR_READ23;
             for(i=0; i < 0x22; i++)
             curr_buf23 = (int) ((((MCF_ADC_ADRSLT7&0x7FF8)>>3) - 2048) * 100) / 2048;   
                curr23_accu += curr_buf23 * curr_buf23;
             power23_accu += volt_buf3 * curr_buf23;
          
           
          
                CURR_READ24;
             for(i=0; i < 0x22; i++)
             curr_buf24 = (int) ((((MCF_ADC_ADRSLT7&0x7FF8)>>3) - 2048) * 100) / 2048;   
                curr24_accu += curr_buf24 * curr_buf24;
             power24_accu += volt_buf3 * curr_buf24;
          
           
          
             curr_17_24_BT = curr_buf17+curr_buf18+curr_buf19+curr_buf20+curr_buf21+curr_buf22+curr_buf23+curr_buf24;
             Board_Total = curr_18_BT + curr_9_16_BT + curr_17_24_BT;
             Board_Total_AT += Board_Total * Board_Total;
             curr_17_24_AT += curr_17_24_BT * curr_17_24_BT;
          
             
                        measure_power_factor ++;
            }
            
           
          
             //for every Half-second calculate powers and reset this flag
          
          
                   if (measure_power_factor == (SAMPLES/2))  {
                   //calculate RMS currents and voltages and powers
            //calc_powers();
                       measure_power_factor = 0;
                   printf("********* Half-second-print ****************************\n");
          
                
                  }
                 
          
             
          
            //eg_loop();             // will block if anything needs to be done
          
            tk_yield();             // give up CPU in case it didn't block
          
            eg_wakes++;
          
            if (net_system_exit)
             break;
           }
          
           
          
           TK_RETURN_OK();
          }
          Last edited by tvnaidu; Nov 14 '09, 01:47 PM. Reason: added code tag

          Comment

          • tvnaidu
            Contributor
            • Oct 2009
            • 365

            #6
            floating point variable here slowing down my CPU, since my CPU clock is running at 60MHz. I changed all float variables to integer, I can see lot of difference.

            Comment

            • tvnaidu
              Contributor
              • Oct 2009
              • 365

              #7
              I found the issue, it is in for loop. sorry for posting this. I don't know may be I can remove that code?.

              Comment

              Working...