Thread: Send counter output to LCD

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    When you don't have access to snprintf() and other string functions, and you wish to build a fixed-size string, you may find that it is easiest to build the string from right to left.

    For example, if you have room for 16 characters, and you want it to have contents
    ±#.##A ###B ###C
    from variables avalue (signed integer multiplied by 100, so 100 = +1.00), bvalue (unsigned integer), and cvalue, with # signifying a decimal digit:
    Code:
    char buffer[17]; /* For testing; 16 should do on a microcontroller */
    unsigned int temp;
    
    buffer[16] = '\0'; /* For testing, so you can print this */
    buffer[15] = 'C';
    
    if (cvalue > 999) {
        buffer[12] = 'M';
        buffer[13] = 'A';
        buffer[14] = 'X';
    } else {
        buffer[14] = '0' + (cvalue % 10);
        buffer[13] = (cvalue > 9) ? '0' + ((cvalue / 10) % 10) : ' ';
        buffer[12] = (cvalue > 99) ? '0' + ((cvalue / 100) % 10) : ' ';
    }
    
    buffer[11] = ' ';
    buffer[10] = 'B';
    
    if (bvalue > 999) {
        buffer[7] = 'M';
        buffer[8] = 'A';
        buffer[9] = 'X';
    } else {
        buffer[9] = '0' + (bvalue % 10);
        buffer[8] = (bvalue > 9) ? '0' + ((bvalue / 10) % 10) : ' ';
        buffer[7] = (bvalue > 99) ? '0' + ((bvalue / 100) % 10) : ' ';
    }
    
    buffer[6] = ' ';
    buffer[5] = 'A';
    if (avalue < -999) {
        buffer[0] = '-';
        buffer[1] = 'M';
        buffer[2] = 'A';
        buffer[3] = 'X';
        buffer[4] = '!';
    } else
    if (avalue > 999) {
        buffer[0] = '+';
        buffer[1] = 'M';
        buffer[2] = 'A';
        buffer[3] = 'X';
        buffer[4] = '!';
    } else {
        if (avalue > 0) {
            temp = avalue;
            buffer[0] = '+';
        } else
        if (avalue < 0) {
            temp = -avalue;
            buffer[0] = '-';
        } else {
            temp = 0;
            buffer[0] = ' ';
        }
        buffer[4] = '0' + (temp % 10);
        buffer[3] = '0' + ((temp / 10) % 10);
        buffer[2] = '.';
        buffer[1] = '0' + ((temp / 100) % 10);
    }
    Extracting the rightmost digit is easy, so depending on your display formatting needs, you can often do it with a simple loop or two. For example, if you just want the first eight digits of buffer to show a number, you can do
    Code:
        char buffer[17];
        int number; /* Show this number */
    
        unsigned int temp;
        unsigned char i;
    
        if (number < -9999999) {
            temp = 9999999;
            buffer[0] = '-';
        } else
        if (number < 0) {
            temp = -number;
            buffer[0] = '-';
        } else
        if (number > 99999999) {
            temp = 99999999;
            buffer[0] = ' ';
        } else {
            temp = number;
            buffer[0] = ' ';
        }
    
        i = 8;
        do {
            buffer[--i] = '0' + (temp % 10);
            temp /= 10;
        } while (temp > 0);
    
        while (i-->1)
            buffer[i] = ' ';
    The do .. while loop constructs the unsigned number (which should not overflow the buffer, that's why the checks are needed). If there were fewer than seven digits, the last while snippet fills spaces leftwards, but keeps the initial character intact (which was already set in the range checking if clauses). Note that the do .. while loop can assign all 8 digits, in which case the last while snippet does nothing.

    In general, I recommend designing the output on paper, and testing it with a small C program (with different inputs). For example, now that I look at the above, I think you could use the two spaces in between for the negative sign, if B or C were negative. (That means that if you have two or more values, and one of them is never negative, it makes sense putting that to the left, because you can then use the separating spaces for the - sign for the others.)

  2. #2
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,787
    Quote Originally Posted by Nominal Animal View Post
    <snip>
    Is this a serious post? How is this better than what whiteflags posted (assuming the posted code checked for over-/under-flow)? I guess what's confusing is that you have two code snippets and it's not clear (probably) that the second is supposed to supersede the first.

    I'm sorry but I just don't understand the point of this post at all. Mr Nom, think back to when you were learning: would what you've written make even the slightest bit of sense? I'm not even sure what your point is, so I have serious doubts that somebody who could not write their own "atoi" function would see it.

  3. #3
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    Quote Originally Posted by Hodor View Post
    Is this a serious post? How is this better than what whiteflags posted (assuming the posted code checked for over-/under-flow)? I guess what's confusing is that you have two code snippets and it's not clear (probably) that the second is supposed to supersede the first.

    I'm sorry but I just don't understand the point of this post at all. Mr Nom, think back to when you were learning: would what you've written make even the slightest bit of sense? I'm not even sure what your point is, so I have serious doubts that somebody who could not write their own "atoi" function would see it.
    Whiteflags posted an example that is suited to the particular question asked by the OP.

    Nominal Animal posted a more generic solution, which has the added advantage of illustrating how to convert multiple values into a single string for a display (without the use of library functions). It is not uncommon to fit several different pieces of information on a single line of a display (I have to do this often). Since the OP is working with displays, it is quite possible that they might have to do such a thing as some point. Regardless, I hardly see such a lesson as pointless.

  4. #4
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    Quote Originally Posted by Hodor View Post
    Is this a serious post?
    It was.

    Quote Originally Posted by Hodor View Post
    How is this better than what whiteflags posted (assuming the posted code checked for over-/under-flow)?
    Better? Does it have to be better? It was supposed to be more in-depth.

    The code Whiteflags posted is excellent (aside from the buffer length or overflow checking). It, too, builds the contents from right to left; it just reverses the buffer at the end.

    I honestly thought I was talking about how you end up building rather complex digital readouts on very memory-constrained microcontrollers; the example code I posted typically uses registers only. In fact, when you realize the display is built from right to left, you can go on and skip having the buffer altogether (except for sign flags), pushing each digit (or character) to the device as they are generated.

    Quote Originally Posted by Hodor View Post
    Mr Nom, think back to when you were learning: would what you've written make even the slightest bit of sense?
    Mr Hod, I sure hope so. Granted, the machines I first learned to program had kilobytes of RAM, whereas an ATtiny85 (which you could easily use to drive an LCD via SPI) has only 512 bytes of RAM, and that includes your stack and all static variables.

    You might not have enough memory for any extra buffers to convert the numbers to, especially if you're doing windowed averaging or statistics on ADC input (it has four ADC inputs, each 10-bit, and can do about 15,000 samples per second).

    The kind of help a simple "build your display from right to left" statement may end up yielding should not be underestimated. I certainly hope someone had told it to me, when I first started trying to write my first games on C64/C128. Then again, there was no public internet, and even getting to a BBS was costly in my neck of the woods (no local BBSes).

    Perhaps the example code is distracting or useless, but the intent was good. Consider me disillusioned.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to Send programme output to a printer ??
    By Chandan2 in forum C Programming
    Replies: 6
    Last Post: 08-13-2013, 10:37 AM
  2. Selecting lowest counter and sending binary output
    By blueribbon33 in forum C++ Programming
    Replies: 1
    Last Post: 03-13-2012, 11:07 PM
  3. Replies: 1
    Last Post: 09-25-2011, 12:45 PM
  4. Trying to make this counter output something different
    By NinjaFish in forum C Programming
    Replies: 14
    Last Post: 02-16-2011, 05:13 AM
  5. Send output to keyboard buffer
    By DReynolds in forum C Programming
    Replies: 2
    Last Post: 06-06-2007, 03:44 PM