Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Float to String Function Use to display values on LCD

Status
Not open for further replies.

hassanakhtar91

Newbie level 5
Joined
Jan 31, 2014
Messages
8
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
71
I'm using PIC 16F877A microcontroller for my project in which I need to display current and voltage values on LCD using ADC of PIC. When I display float values on LCD using floattostr function, LCD doesen't show anything. I suspect this function takes a lots of memory of PIC and microcontroller can't operate. Is there any alternative code that I can replace instead of floattostr function so the microcontroller doesent take a lot of space and display is perfectly shown on LCD.

My code is given below. The problem is in current_Read(void) function.


Code:
sbit LCD_RS at RB2_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;


sbit LCD_RS_Direction at TRISB2_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;

float v;


char txt[5];
char txt1[5];
void voltage_READ(void)
      {
           float max;
           int i;
           int t[40];
           ADCON0.ADON=1;
           for(i=0; i<=39; i++)
           {
           v= ADC_Read(0);
           v =v*(10.0/1023.0);
           v=(v-5.0);
           t[i]=v*110.1909091;
           }

           ADCON0.ADON=0;
           max=t[0];
           for(i=0; i<=39; i++)
           {
           if(max<t[i])
            max=t[i];
           }
           max=max*.707106781*18.33;
           intToStr(max, txt);
           Lcd_out(1,9,txt);
           delay_ms(200);
      }
      void current_READ(void)
      {
           float max;
           int i,current;
           int t[40];
           ADCON0.ADON=1;
           for(i=0; i<=39; i++)
           {
           v= ADC_Read(1);
           v =v*(10.0/1023.0);
           v=(v-5.0);
           t[i]=v*10;
           }

           ADCON0.ADON=0;
           max=t[0];
           for(i=0; i<=39; i++)
           {
           if(max<t[i])
            max=t[i];
           }
           max=max*.707106781;
           intToStr(max, txt1);
           Lcd_out(2,8,txt1);
           delay_ms(1000);
      }




void main()
{
          Lcd_Init();                        // Initialize LCD
          ADCON0.ADCS1=1;
          ADCON0.ADCS1=0;
          ADCON0.ADON=0;
          
          while(1)
         {

            Lcd_out(1,1, "voltage:");
            Lcd_out(2,1, "Current:");
            voltage_READ();
            current_READ();
          }
}
 
Last edited by a moderator:

hello,


Can you catch the windows "messages" , result of compiling
copy all as text and post it ..

Code:
t[i]=v*110.1909091;

wher is the declaration of table t ?
and other variables as max...

try also to reduce the number of intermediate calculus
example

Code:
 v =v*(10.0/1023.0);  -->   v=v*0.00977517;

Code:
 max=max*.707106781*18.33; -> max=max*12,9612673;
 

hello,


Can you catch the windows "messages" , result of compiling
copy all as text and post it ..

Code:
t[i]=v*110.1909091;

wher is the declaration of table t ?
and other variables as max...

try also to reduce the number of intermediate calculus
example

Code:
 v =v*(10.0/1023.0);  -->   v=v*0.00977517;

Code:
 max=max*.707106781*18.33; -> max=max*12,9612673;
[/QUO

I've reduced the calculus but still the problem is there.
The message is:
Used RAM (bytes):152 (43%) Free RAM (bytes) : 200 (57&)
Used ROM (program words):2349 (29%) Free ROM (program words) :5838 (71%)
Project Linked successfully
Linked in 359ms
 

Your messages windows is too short
did you mark(coche) the options Errors, Warnings and Hints..
often the problem is describe inside...



where are the declaration of table t ?
and other variables as max...
 

Your messages windows is too short
did you mark(coche) the options Errors, Warnings and Hints..
often the problem is describe inside...



where are the declaration of table t ?
and other variables as max...

Take a look at the code again. I have declared max as float max and table t as int t[40].
The code is not showing any error but when I simulate this code in proteus, it doesn't show any display on the LCD.
This code works fine and simulation gives the desired results if my input is an integer and to display it I used to Int to str function but unfortunately my input is in float and it neither works either I use in int to str or float to str. So Is there any alternative C code that I can replace instead of float to str function?
 

you can declare t[] and max as global
because you use it in other functions
to reduce consumption of RAM.

another function to transfor float to ascii

Code:
 unsigned char *Float2Ascii (float x, unsigned char *str,char precision)
{
 /* converts a floating point number to an ascii string */
 /* x is stored into str, which should be at least 30 chars long */
 unsigned char *adpt;
 int ie, i, k, ndig;
 double y;
 adpt=str;
 ndig = ( precision<=0) ? 7 : (precision > 22 ? 23 : precision+1);
 ie = 0;
 /* if x negative, write minus and reverse */
 if ( x < 0)
 {
   *str++ = '-';
   x = -x;
 }
 /* put x in range 1 <= x < 10 */
 if (x > 0.0) while (x < 1.0)
 {
   x *= 10.0;                // a la place de =*
   ie--;
 }
 while (x >= 10.0)
 {
   x = x/10.0;
   ie++;
 }
 // in f format, number of digits is related to size
 ndig += ie;                                // a la place de =+
 //round. x is between 1 and 10 and ndig will be printed to
 // right of decimal point so rounding is ...
 for (y = i = 1; i < ndig; i++)
 y = y/10.;
 x += y/2.;
 if (x >= 10.0) {x = 1.0; ie++;}
 if (ie<0)
 {
   *str++ = '0'; *str++ = '.';
   if (ndig < 0) ie = ie-ndig;
   for (i = -1; i > ie; i--)  *str++ = '0';
 }
 for (i=0; i < ndig; i++)
 {
   k = x;
   *str++ = k + '0';
   if (i ==  ie ) *str++ = '.';
   x -= (y=k);
   x *= 10.0;
  }
 *str = '\0';
return (adpt);
}



char CRam1[26];
....
  Float2Ascii (F1, CRam1,3);  // my function .. keep same width
  UART1_Write(9);
  UART1_Write_Text(CRam1);
.....
 
Last edited:

hello,

the main problem is RAM memory...to handle
Normally, you must get somme warning
concerning Variable and IRP bit... and even compiling is successfull
your program will not work as expected..


you can get problem if you want to put float value into integer array t[] !


in fact PIC16F877 has not enough RAM memory to handle an array of 40 float = 40x4=160 bytes
maximum Ram Bank is 96 or 80 bytes..
if you split the array
float t[20]; => 20x4=80 bytes and use absolute adresse with IRP_bit as bank switch ,it is possible

i put txt[] and max in global variables area to deduce RAM comsumption
because never used in same time.. so don't need multiple copies.
Check the result ...
it works for only 20 floating values in t[20] !
you can see also difference of behavior with FloattoStr and Flot2Ascii wich gives constante width of car as result.

Maybe you can get the max value only with integer ADC value
so use
int t[40];
and after use float to convert to physical value of measurment..

With evoluate PIC as PIC18F46K22, no problemo with RAM
> 3Ko de RAM


Code:
float v;
char txt[15];
float t[20]  absolute 0x1A0;  // bank3  
float max;


 unsigned char *Float2Ascii (float x, unsigned char *str,char precision)
{
 /* converts a floating point number to an ascii string */
 /* x is stored into str, which should be at least 30 chars long */
 unsigned char *adpt;
 int ie, i, k, ndig;
 double y;
 adpt=str;
 ndig = ( precision<=0) ? 7 : (precision > 22 ? 23 : precision+1);
 ie = 0;
 /* if x negative, write minus and reverse */
 if ( x < 0)
 {
   *str++ = '-';
   x = -x;
 }
 /* put x in range 1 <= x < 10 */
 if (x > 0.0) while (x < 1.0)
 {
   x *= 10.0;                // a la place de =*
   ie--;
 }
 while (x >= 10.0)
 {
   x = x/10.0;
   ie++;
 }
 // in f format, number of digits is related to size
 ndig += ie;                                // a la place de =+
 //round. x is between 1 and 10 and ndig will be printed to
 // right of decimal point so rounding is ...
 for (y = i = 1; i < ndig; i++)
 y = y/10.;
 x += y/2.;
 if (x >= 10.0) {x = 1.0; ie++;}
 if (ie<0)
 {
   *str++ = '0'; *str++ = '.';
   if (ndig < 0) ie = ie-ndig;
   for (i = -1; i > ie; i--)  *str++ = '0';
 }
 for (i=0; i < ndig; i++)
 {
   k = x;
   *str++ = k + '0';
   if (i ==  ie ) *str++ = '.';
   x -= (y=k);
   x *= 10.0;
  }
 *str = '\0';
return (adpt);
}

void voltage_READ(void)
      {
          
           int i;
           
           ADCON0 = 0x81;  // ADON = 1, Channel A.0 select, Fosc/32 select
           ADCON1 = 0x8E;  // 0x8E,0xC0 port a as analog, right justified output
        
           ADCON0.ADON=1;
           for(i=0; i<=19; i++)
           {
           v= ADC_Read(0);
           v =v*(10.0/1023.0);
           v=(v-5.0);
             IRP_bit=1;
             t[i]=v*110.1909091;
               IRP_bit=0;
           }

           ADCON0.ADON=0;
           max=t[0];
           for(i=0; i<=19; i++)
           {
           if(max<t[i])
            max=t[i];
           }
           max=max*12,9612673;
          // FloatToStr(max, txt);
           i=Float2Ascii (max,txt,3);   // 3 decimales
           Lcd_Out(1,9,txt);
           Delay_ms(200);
      }
      void current_READ(void)
      {
           int i,current;
           ADCON0.ADON=1;
           for(i=0; i<=19; i++)
           {
           v= ADC_Read(0);     // <- i only have RA0 as analog !!
           v =v*(10.0/1023.0);
           v=(v-5.0);
           IRP_bit=1;
           t[i]=v*10;
           IRP_bit=0;
           }

           ADCON0.ADON=0;
           max=t[0];
           for(i=0; i<=19; i++)
           {
           if(max<t[i])
            max=t[i];
           }
           max=max*.707106781;
           i=Float2Ascii (max,txt,3);   // 3 decimales
           Lcd_Out(2,10,txt);
          // FloatToStr(max, txt);
          // Lcd_Out(2,8,txt);
           Delay_ms(1000);
      }





//==============================

void main() 
{
  Init_Hardware();
  
  ADC_Init();
  ADCON0 = 0x81;  // ADON = 1, Channel A.0 select, Fosc/32 select
  ADCON1 = 0x8E;  // 0x8E,0xC0 port a as analog, right justified output
 
  LCD_PWR=1;   // RD5 =LCD_PWR voir schema 103-00032 en C2
  Lcd_Init();
  Delay_ms(2000);
 

    
          ADCON0.ADCS1=1;
          ADCON0.ADCS1=0;
          ADCON0.ADON=0;
          
          while(1)
         {

            Lcd_Out(1,1, "voltage:");
            Lcd_Out(2,1, "Current:");
            voltage_READ();
            current_READ();
          }
}


for 5V 1023 points on both measures
i get on my LCD :
voltage 6611.452
current : 35.355
 
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top