Two point calibration; 8/16 bit MCU; complex operation

Discussion in 'Embedded Systems and Microcontrollers' started by aamirali, Sep 8, 2014.

  1. aamirali

    Thread Starter Member

    Feb 2, 2012
    415
    1
    1. I have to measure voltage in 8/16 bit MCU & have to do its calibration also.
    I have selected 2 point calibration as it corrects both gain & offset error.

    2. Voltage to measure = 0-5V.
    Let measured at two pint: Vm1 & Vm2
    Let actual volatge at those point = Vo1 & Vo2

    Gain error = (Vm2-Vm1)/ (Vo1-Vo2)
    offset error = Vm1 - (gain_error * Vo1)

    reading = (Vm - offset_error)/gain_error;

    3. Problem is this involves complex math & generally goes to float. Now using float operation on 8/16 bit MCU is very intensive.

    Queries:
    1. Is there any better method for which I don't have to do such float calculation. If yes any example code?

    2. If no to 1, can above method be made less operation intensive like by fixed point math. If yes any example code
     
  2. NorthGuy

    Active Member

    Jun 28, 2014
    604
    121
    Is it self-calibrating, or you're doing the calibration once, do calculation outside MCU, and then program MCU to only do "reading = ..."?
     
  3. MrChips

    Moderator

    Oct 2, 2009
    12,440
    3,361
    I never use floating-point for such simple calculations.

    For example, I can convert from degrees C to F and F to C to two decimal places without having to resort to floating point.
     
  4. aamirali

    Thread Starter Member

    Feb 2, 2012
    415
    1
    @NorthGuy : I have to do calibartion whenever user want t. So have to store values in MCU

    @MrChips : Can you give one example
     
  5. NorthGuy

    Active Member

    Jun 28, 2014
    604
    121
    For the calibration, you must do division, but even if done in MCU it is not done very often. "User" cannot want it at 10kHz, right? No need to optimize that part.

    For your main fomula, you pre-calculate:

    k = 65536/gain_error;

    Then you do

    reading = (Vm - offset_error)*k>>16;

    (>>16 is the same as /65536 but is really fast)

    Multiplication is way faster than division, so it'll be efficient.

    Measure voltage in mV. Integers will give you enough resolution.

    You will need to find a correct sze for your varibales so that it doesn't overflow.
     
  6. MrChips

    Moderator

    Oct 2, 2009
    12,440
    3,361
    Give me your two calibration points and I will show you how to do it.
     
  7. aamirali

    Thread Starter Member

    Feb 2, 2012
    415
    1
    @MrChips :

    Done calibration at two pints 0.5V & 4.5V

    Vm = 0.41V , 4.7V
    Vo = .5V , 4.5V


    So offset error = -0.12625
    gain error = 1.0725


    Edit: adc is 10 bit. Vref = 5V. Measurable range = 0-5V
     
    Last edited: Sep 9, 2014
  8. MrChips

    Moderator

    Oct 2, 2009
    12,440
    3,361
    What are you actually trying to do?
    Analog input voltages are digitzed to binary values, 0-1023 for 10-bit ADC.
    Is your software doing a floating point conversion and then displaying voltage as in a digital voltmeter?
     
  9. aamirali

    Thread Starter Member

    Feb 2, 2012
    415
    1
    @MrChips :

    1. actually I wanted to show how much voltage value I get when I apply 0.5v & 4.5V. It code i have only 10 bit adc data
    2. Below are actual digital values which i get
    3. V0 = 0.5V , digital data I get = 84
    4. V0= 4.5V , digital data I get = 962

      Now I have to apply offset error & gain error.
     
  10. MrChips

    Moderator

    Oct 2, 2009
    12,440
    3,361
    I still do not understand what you are doing.
    Forget about gain and offset error for now. I understand that and how to calculate the correct results.
    What are you using to show the result?
    What numbers do you want to display?
     
  11. aamirali

    Thread Starter Member

    Feb 2, 2012
    415
    1
    1. I have measured the voltage 0-5V.
    2. Since adc have offset & gain errors, I have to adjust them, before sending the final data over uart to PC.
    I cannot put the error data to PC. Since user may connect the board I made to any PC. So have to calculate & store error correction values in MCU only.
    3. As shown in previous post, calculating these errors, include float.
     
  12. MrChips

    Moderator

    Oct 2, 2009
    12,440
    3,361
    There is no need to do floating point arithmetic or to transmit fractional decimals to a PC.
    You can simplify the data transmission by sending data scaled to 0-500 or 0-1023.

    I will assume that your calibration points are fixed at 0.5V and 4.5V.

    Suppose the ADC recorded value at 0.5V input is x1.
    Suppose the ADC recoded value at 4.5V input is x2.

    We will scale the voltages by 100.

    Then the slope m = (450 - 50)/(x2-x1) = 400/(x2 - x1)
    Don't perform the calculation yet. Simply record the difference dx = x2 - x1
    Hence the slope m = 400/dx

    The intercept c = 50 - m*x1

    Hence any ADC value x is corrected to value y given by

    y = m*x + c

    y = m*x + 50 - m*x1

    y = m*(x - x1) + 50

    y = (x-x1)*400/dx + 50

    This reduces to one multiplication and one division using integer arithmetic.
     
Loading...