This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

how to display a float value to the lcd

Other Parts Discussed in Thread: MSP430G2231

hi all am using msp430g2231 and am using code composer studio..
i and am trying to display a adc value to my lcd.. my input voltage is 1.85v for that am getting a digital value like 532..
and i tried to show this digital value and i did that successfully.. now i need to show the float value to my lcd by converting the digital value in to analog by this following calculation


analog value =(532/1023)*3.57 = 1.856
now i need to display that float value to my lcd please suggest me a code for this ?????

  • Simply you muliply your analog value want to see how many digits after the comma.

    For example : your analog vale = 1.856

    analog value *= 1000 => analog value = 1856

    and after this you need to send  this value character by character in a LCD

     

    lcd_putch(volt/1000+48); // '1'

    lcd_putch('.'); // '.'

    lcd_putch((volt/100)%10+48); //'8'

    lcd_putch((volt/10)%10+48); //'5'

    lcd_putch(volt%10+48); // '6'

     

    this post maybe helps you : http://e2e.ti.com/support/microcontrollers/msp43016-bit_ultra-low_power_mcus/f/166/t/126338.aspx

     

  • thanks for your suggestion and i successfully shown the float value to my lcd now the problem is if i varied the input analog voltage  the lcd displaying value is not getting varied instantly.. its updating the varied input voltage  after switch off and on  the microcontroller.. now i need to show the lcd value instantly while i changing the input analog voltage??..

    what i have to do for this????

  • We don't know your ADC initialization code.

    • Which clock source you use for ADC10 ? (ADC10CLK/MCLK/SMCLK/ACLK)
    • Did you use frequency divider ?
    • Sample and Hold value (SHS_?) (4x / 16x / 64x) ?

    if you answer this question. Maybe this problem will solve.

  • below its my source code have a look and suggest me???

     

     

     

    void main(void)
    {
       
        unsigned int res[1];
        unsigned int volt,volt1,volt2;
         unsigned int i,x=0;
        WDTCTL = WDTPW + WDTHOLD;  // Stop watchdog timer
        BCSCTL1 = CALBC1_1MHZ;    // Set range
          DCOCTL = CALDCO_1MHZ;   
           
         
        ADC10CTL1 = INCH_1 + CONSEQ_3;
        ADC10CTL0 |= ADC10SHT_2 + ADC10ON + MSC+ADC10IE;; //sample and hold time, adc on, cont. sample
        ADC10AE0 |= 0x03; // select channel A0
        ADC10DTC1 = 0x02;
       
        //ADC10CTL0 &= ~ENC;
      //  while (ADC10CTL1 & BUSY);               // Wait if ADC10 core is active
      //  ADC10SA = (int)res;
       
        //ADC10CTL0 |= ADC10SC + ENC; // start conversions
           InitializeLcm();
        ClearLcmScreen();
       
        LcmSetCursorPosition(0x00,0x00);
        PrintStr("Analog volt1:");
        LcmSetCursorPosition(0x40,0x40);
        PrintStr("Analog volt2:");
        LcmSetCursorPosition(0x54,0x54);
        PrintStr("Avg volt:");
       
       
       
     while(1)
      {
          //ClearLcmScreen();
         
        ADC10CTL0 &= ~ENC;
      while (ADC10CTL0 & BUSY);
      ADC10SA = (int)res;                            // define data buffer start
      // start ADC10 conversion
      ADC10CTL0 |= ENC + ADC10SC;
     
        for(i=0;i<2;i++)                     //code from reading from res and adding the 5 analog inputs
        {
            x=x+res[i];
        }
      
        volt1=(float)((res[0]*0.0034897) * 1000);
         __delay_cycles(200);
        volt2=(float)((res[1]*0.0034897) * 1000);
         __delay_cycles(200);
       
         x= x/2;
        volt=(float)((x*0.0034897) * 1000);
         __delay_cycles(200);
        
       
        LcmSetCursorPosition(0x0d,0x0d);
        LCD_output_result(volt1);
        __delay_cycles(200000);
       
       
        LcmSetCursorPosition(0x4d,0x4d);
        LCD_output_result(volt2);
        __delay_cycles(200000);
       
        
        LcmSetCursorPosition(0x60,0x60);
        LCD_output_result(volt);
       
        __delay_cycles(100000);
        __delay_cycles(100000);
        __delay_cycles(100000);
       x=0;
      
      }    
    }

     

  •  __delay_cycles(200000);

     __delay_cycles(200000);

     __delay_cycles(100000);

     __delay_cycles(100000);

     __delay_cycles(100000);

    total = 700.000 uS = 0.7 Sec + some folating point calculations = ~1second

    You could try reduce delays. And check your lcd library. Maybe some long delays may include...

    And try reduce sample and hold time. You use ADC10SHT_2. This means 16x ADC10CLK.

    If you use ADC10SHT_0 your A/D conversion will speed up for before.

     

    For floating point calculations this is a good way.Thanks Jens.

    Jens-Michael Gross said:

    Ex : ADC10MEM  = 512
    volt = (float) (512*0.0034799) = 1.781733...
    volt = volt * 1000 => volt = 1781

    A much, much faster (yet not as accurate, at least with these values)  version is

    volt = (ADC10MEM*56)>>16; 
    Gives 1792 for ADC10MEM=512 and is by several magnitudes faster and does not nead any floating point operation (and not the float multiplicaiton function).
    What have I done? I have multiplied the factor by 16000 and then divided the result by 16 with a shift operation (takes only 4 clock cycles).
    Since 56 is a 6 bit value and ADC10MEM is 10 bit at max, the intermediate multiplication result still fits into 16 bit.

    A little bit slower (as it requires 32 bit multiplication) but more accurate is the following:

    volt = (ADCMEM*228058L)>>16;  // now I multiplied the factor with 65536000, the multiplication result fits into a long (28 bit size max) and the shift just takes the upper word as result.
    This gives teh expected 1781. (1781.703125, to be exact, the fraction in the lower word of the multiplication result) If you want rounding, simply add 32768 before applying the shift.

    [/quote]

  • M.Fatih INANC said:
    __delay_cycles(200000);

    YOu should really set up a timer for such long delays. That what timers are made for.
    The first thing I did for every new MSP I worked with (well, tehre are not too many) was setting up a timebase, with an ISR that counts up a global variable every millisecond.

    This way, i only have to wait until this variable has increased by 1000 for a 1s delay.
    And if my system clock ever changes, all I have to do is to adjust the timer interrupt, while with __delay_cycles, every single statement of this kind needs to be properly adjusted.

    M.Fatih INANC said:
    try reduce sample and hold time. You use ADC10SHT_2. This means 16x ADC10CLK.

    A reduces S&H time migh talso influence the quality of the conversion.

    The S&H time acts as a low pass filter for spikes and noice on the signal. It also relaxes the (relatively) high inrush current to the conversion buffer capacitor during sample time. If the signal source has a high impedance, it is important to give this capacitor enough time to fill (see datasheet). On ADC12, I noticed that a S&H time of 4 ADC12CLK cycles signigicantly decreases the conversion quality on higher input signal frequencies or noise levels.
    Well, it depends on the situation. If there were a general solution, no engineers were needed for doing the development. (and in this case, there were no need for any SHTx choice in the ADC10 config at all)

    Jens-Michael Gross said:
    volt = (ADC10MEM*56)>>16

    Of course it must be >>4 (/16) and not >>16 (/65536) :)

  • Jens-Michael Gross said:
    try reduce sample and hold time. You use ADC10SHT_2. This means 16x ADC10CLK.

    A reduces S&H time migh talso influence the quality of the conversion.[/quote]

     

    Jens,

    Which Sample and Hold value is optimized for general ADC applications ?

    Due to this influence, we must always use the ADC10SHT_3 (64x ADCCLK) ?

    Or this parameter may change to our application ?

     

    Thanks.

    Regards.

  • M.Fatih INANC said:
    hich Sample and Hold value is optimized for general ADC applications

    There is no general advice. It depends on the applicaiton. Signal source impedance vs ADC input impedance (the dynamic one, formed by input series resistance and input buffer capacitor value), input noise and expected input signal frequency etc.
    Usually, the best case is to make it as large as possible for the required sampling frequency. Gives best conversion results. However, if you want peak snapshots, a shorter S&H time is better. And if you control the S&H buffer using a tiemr (whcih is the best for low-power operations), then you probably don't use the SHTx bits at all. and let the timer open and close the sampling buffer.

**Attention** This is a public forum