No sprintf for PIC16F88 ?

General discussion on mikroC PRO for PIC.
Post Reply
Author
Message
CVMichael
Posts: 239
Joined: 30 Apr 2009 02:36
Location: Canada, Toronto

No sprintf for PIC16F88 ?

#1 Post by CVMichael » 20 Apr 2010 03:04

I am using PIC16F88, and all I see in the library manager sprinti and sprintl, where is sprintf :?: I need to print on the LCD float numbers, so I can't use the other sprint functions.

basicbasic111
Posts: 127
Joined: 26 Jan 2010 17:01

Re: No sprintf for PIC16F88 ?

#2 Post by basicbasic111 » 20 Apr 2010 06:09

as i know

that function is for 18f .......

here is a post for you

http://www.mikroe.com/forum/viewtopic.p ... tf#p119978

User avatar
tihomir.losic
mikroElektronika team
Posts: 2138
Joined: 02 Dec 2009 14:16
Location: Serbia
Contact:

Re: No sprintf for PIC16F88 ?

#3 Post by tihomir.losic » 20 Apr 2010 08:19

Hello,

unfortunately sprintf function is not supported for p12 and p16 PIC MCU families, and for
PIC16F88 you can use following libraries:

- sprintl: The function returns the number of characters actually written to destination string.
The same as sprintf, except it doesn't support float-type numbers.

- sprinti: The same as sprintf, except it doesn't support long integers and float-type numbers.

Best regards,

Losic Tihomir
mikroElektronika [Support team]

CVMichael
Posts: 239
Joined: 30 Apr 2009 02:36
Location: Canada, Toronto

Re: No sprintf for PIC16F88 ?

#4 Post by CVMichael » 20 Apr 2010 13:50

The reason why I needed to use sprintf is because I need to print float type.

I made my own function to convert float to string in the mean time.

If anyone wants to see the code, let me know, and I will post it when I get home (at this moment I'm at work), though I'm sure other people already posted float to string code, right ?

p.erasmus
Posts: 3391
Joined: 05 Mar 2009 10:28

Re: No sprintf for PIC16F88 ?

#5 Post by p.erasmus » 20 Apr 2010 13:53

Please post the code it is usefull information in the Forum :D
P.Erasmus
Saratov,Russia
--------------------------------------------------------------

CVMichael
Posts: 239
Joined: 30 Apr 2009 02:36
Location: Canada, Toronto

Re: No sprintf for PIC16F88 ?

#6 Post by CVMichael » 20 Apr 2010 14:07

OK, I will post the code when I get home (in about 10 hours from now).

Is there a section on this forum for posting code ? for example on vbforums.com they have a section "Code Bank" ?

p.erasmus
Posts: 3391
Joined: 05 Mar 2009 10:28

Re: No sprintf for PIC16F88 ?

#7 Post by p.erasmus » 20 Apr 2010 14:15

unfortunately not but add it to this post or as a .mbas file attached and the people can down load it
thank for your support
P.Erasmus
Saratov,Russia
--------------------------------------------------------------

CVMichael
Posts: 239
Joined: 30 Apr 2009 02:36
Location: Canada, Toronto

Re: No sprintf for PIC16F88 ?

#8 Post by CVMichael » 20 Apr 2010 23:12

OK, Here is the code for "float to char" and "long to char".

Note that both functions don't write NULL at the end of the string.
The functions take a starting position to write the number from, and it returns the position it finished writing the number.

Here is an example how to use the functions:

Code: Select all

char str[20];
float pos_x = 11.223344;
float pos_y = 4.5678912;
int pos = 0;

str[pos++] = 'X';
pos = float_to_char(str, pos, pos_x, 3);
str[pos++] = ' ';

str[pos++] = 'Y';
pos = float_to_char(str, pos, pos_y, 3);
str[pos++] = ' ';
str[pos] = 0; // NULL

Lcd_Out(1, 1, str);  // display the text
So, that should display: "X11.223 Y4.567 "

Let me know if you make any improvements to the code.

Code: Select all

int float_to_char(char *buff, int start_pos, float fnum, short dec)
{
    long i;
    int pos, k;
    
    if(fnum < 0) {
        buff[start_pos++] = '-';
        fnum *= -1;
    }
    
    i = fnum;
    
    pos = long_to_char(buff, start_pos, i);
    buff[pos++] = '.';

    fnum -= i;
    fnum *= pow10l(dec);
    i = fnum;

    pos += dec;
    for(k = dec; k > 0; k--){
        buff[--pos] = 48 + (i % 10);
        
        i /= 10;
    }

    return pos + dec;
}

int long_to_char(char *buff, int start_pos, long inum)
{
    char n, k;
    long div = 1000000000;

    if(inum < 0) {
        buff[start_pos++] = '-';
        inum *= -1;
    }

    for(k = 0; k < 10; k++)
    {
        n = (inum / div) % 10;

        if(n > 0) break;

        div /= 10;
    }

    buff[start_pos++] = 48 + n;
    k++;
    div /= 10;

    for(; k < 10; k++)
    {
        n = (inum / div) % 10;
        buff[start_pos++] = 48 + n;

        div /= 10;
    }

    return start_pos;
}

long pow10l(short p)
{
    switch(p)
    {
        case 1: return 10l;
        case 2: return 100l;
        case 3: return 1000l;
        case 4: return 10000l;
        case 5: return 100000l;
        case 6: return 1000000l;
        case 7: return 10000000l;
        case 8: return 100000000l;
        case 9: return 1000000000l;
        default: return 1;
    }
}

CVMichael
Posts: 239
Joined: 30 Apr 2009 02:36
Location: Canada, Toronto

Re: No sprintf for PIC16F88 ?

#9 Post by CVMichael » 22 Apr 2010 01:59

I added 2 lines of code to round the last digit

Code: Select all

int float_to_char(char *buff, int start_pos, float fnum, short dec)
{
    long i;
    int pos, k;
    
    if(fnum < 0) {
        buff[start_pos++] = '-';
        fnum *= -1;
    }
    
    i = fnum;
    
    pos = long_to_char(buff, start_pos, i);
    buff[pos++] = '.';

    fnum -= i;
    fnum *= pow10l(dec);
    i = fnum;
    fnum -= i;                     // The 2 new lines to round last digit
    if(fnum >= 0.5) i++;

    pos += dec;
    for(k = dec; k > 0; k--){
        buff[--pos] = 48 + (i % 10);
        
        i /= 10;
    }

    return pos + dec;
}

ponchorcg
Posts: 11
Joined: 04 May 2011 18:05
Location: México

Re: No sprintf for PIC16F88 ?

#10 Post by ponchorcg » 19 Jun 2011 20:06

Hi CVMichael, firts I wants to say thanks you for have posted your float to string conversion rutine. I was having the same problem like you (floattostring don´s work very well). I want to share the code that i used in mikroc pro for pic 4.6. (Is the same that you posted, but in order =P).

Code: Select all

// Conexiones del Modulo LCD
sbit LCD_RS at RB7_bit;
sbit LCD_EN at RB6_bit;
sbit LCD_D4 at RB5_bit;
sbit LCD_D5 at RB4_bit;
sbit LCD_D6 at RB3_bit;
sbit LCD_D7 at RB2_bit;
sbit LCD_RS_Direction at TRISB7_bit;
sbit LCD_EN_Direction at TRISB6_bit;
sbit LCD_D4_Direction at TRISB5_bit;
sbit LCD_D5_Direction at TRISB4_bit;
sbit LCD_D6_Direction at TRISB3_bit;
sbit LCD_D7_Direction at TRISB2_bit;
int long_to_char(char *buff, int start_pos, long inum)
{
    char n, k;
    long div = 1000000000;

    if(inum < 0) {
        buff[start_pos++] = '-';
        inum *= -1;
    }

    for(k = 0; k < 10; k++)
    {
        n = (inum / div) % 10;

        if(n > 0) break;

        div /= 10;
    }

    buff[start_pos++] = 48 + n;
    k++;
    div /= 10;

    for(; k < 10; k++)
    {
        n = (inum / div) % 10;
        buff[start_pos++] = 48 + n;

        div /= 10;
    }

    return start_pos;
}

long pow10l(short p)
{
    switch(p)
    {
        case 1: return 10l;
        case 2: return 100l;
        case 3: return 1000l;
        case 4: return 10000l;
        case 5: return 100000l;
        case 6: return 1000000l;
        case 7: return 10000000l;
        case 8: return 100000000l;
        case 9: return 1000000000l;
        default: return 1;
    }
}
int float_to_char(char *buff, int start_pos, float fnum, short dec)
{
    long i;
    int pos, k;

    if(fnum < 0) {
        buff[start_pos++] = '-';
        fnum *= -1;
    }

    i = fnum;

    pos = long_to_char(buff, start_pos, i);
    buff[pos++] = '.';

    fnum -= i;
    fnum *= pow10l(dec);
    i = fnum;
    fnum -= i;                     // The 2 new lines to round last digit
    if(fnum >= 0.5) i++;

    pos += dec;
    for(k = dec; k > 0; k--){
        buff[--pos] = 48 + (i % 10);

        i /= 10;
    }

    return pos + dec;
}
float pos_x = 11.50;
float pos_y = 4.25;
int pos = 0;
char str[20];
void main() {
str[pos++] = 'X';
pos = float_to_char(str, pos, pos_x, 2);
str[pos++] = ' ';

str[pos++] = 'Y';
pos = float_to_char(str, pos, pos_y, 2);
str[pos++] = ' ';
str[pos] = 0; // NULL
LCD_INIT();
Delay_ms(1000);
LCD_CMD(_LCD_CLEAR);
Lcd_Out(1, 1, str);  // display the text
}

I have one question, can you post an explanaton about what is happening inside your rutine ? haha =P, again, thanks man, regards.

CVMichael
Posts: 239
Joined: 30 Apr 2009 02:36
Location: Canada, Toronto

Re: No sprintf for PIC16F88 ?

#11 Post by CVMichael » 20 Jun 2011 05:33

I commented the code, I hope it helps:

Code: Select all

// let's say our number is 123.456789, and we want 2 decimals

int float_to_char(char *buff, int start_pos, float fnum, short dec)
{
    long i;
    int pos, k;

    if(fnum < 0) {                   // if it's a negative number
        buff[start_pos++] = '-';     // put '-' in the string
        fnum *= -1;                  // make the number a positive
    }

    i = fnum;  // convert to integer (removes the decimals), i = 123

    pos = long_to_char(buff, start_pos, i); // print the integer, 123
    buff[pos++] = '.';                      // print decimal point

    fnum -= i;            // this removes the integer part of the float, leaving only the decimals (so fnum will be 0.456789)
    fnum *= pow10l(dec);  // multiply the float (decimals) by 100 (for 2 decimals), fnum = 45.6789
    i = fnum;             // i = 45
    fnum -= i;            // substract from fnum = 45.6789 only the integer part, leaving fnum = 0.6789
    if(fnum >= 0.5) i++;  // if greater than 0.5, then increment i by 1 (so it will be 46)

    pos += dec;
    for(k = dec; k > 0; k--){
        buff[--pos] = 48 + (i % 10); // convert to ASCII the decimals (46) in descending order, print 6 then 4

        i /= 10;
    }

    return pos + dec; // return the position it finished writing the number
}

ponchorcg
Posts: 11
Joined: 04 May 2011 18:05
Location: México

Re: No sprintf for PIC16F88 ?

#12 Post by ponchorcg » 20 Jun 2011 16:58

OOk man, thanks, I will check your example after work =P.

Post Reply

Return to “mikroC PRO for PIC General”