How does MCU display text on screen

Thread Starter

King2

Joined Jul 17, 2022
163
Computer works on binary numbers, so how do we see text messages on computer screen, As a programmer I don't understand the concept behind it

I did an experiment in which I'm just storing ascii numbers so I got a text message.
C:
#include<stdio.h>

int main(void) {

    int Name[] = {75, 73, 78, 71, 50};

    for (int i = 0; i < 5; i++)
    {
        printf("%c", Name[i]);
    }
    return 0;
}
Output

Code:
KING2
I tried to find the reason on internet then I found that binary string gets converted to ASCII value.

I think I need to learn different type conversions binary to ascii, hexadecimal to ascii, and decimal to ascii

Edit : I have changed my thread title my question is related to microcontroller.
 
Last edited:

MrSalts

Joined Apr 2, 2020
2,767
Computer works on binary numbers, so how do we see text messages on computer screen, As a programmer I don't understand the concept behind it

I did an experiment in which I'm just storing ascii numbers so I got a text message.
C:
#include<stdio.h>

int main(void) {

    int Name[] = {75, 73, 78, 71, 50};

    for (int i = 0; i < 5; i++)
    {
        printf("%c", Name[i]);
    }
    return 0;
}
Output

Code:
KING2
I tried to find the reason on internet then I found that binary string gets converted to ASCII value.

I think I need to learn different type conversions binary to ascii, hexadecimal to ascii, and decimal to ascii
Once converted to ASCI, the ASCI value is converted to a bitmap or TrueType font, the bitmap is displayed as pixels directly. A TrueType font has to be calculated for scaling before it is converted to a bitmap and displayed.
 

BobTPH

Joined Jun 5, 2013
8,813
There is no conversion from binary to ASCII. All data in the computer is binary, always. Everything else is just the interpretation of the binary data. ASCII is just a standard interpretation of binary patterns as alphanumeric characters. Other interpretations of the binary data could be signed or unsigned integer, IEEE floating point, or binary coded decimal. If you were to look at a random byte in memory, there is no way to determine which interpretation is correct. You would need knowledge of the program and it’s data allocation to interpret it.
 

MrChips

Joined Oct 2, 2009
30,712
This is a lot more complex than any one can imagine.
Where does one begin?

Start with looking up 5x7 dot matrix text font.
 

WBahn

Joined Mar 31, 2012
29,978
Computer works on binary numbers, so how do we see text messages on computer screen, As a programmer I don't understand the concept behind it
I would strongly encourage you to work through the Nand2Tetris project. It is a sequence of twelve projects (each one nominally a week's effort) in which you first design and build (in emulation) a complete computer using nothing by two-input NAND gates and D-type flip flops. That's roughly the first half of the course. Then you write an assembler for the CPU's instruction set. Then you write a translator that implements a stack-based virtual machine. Then you write a compiler for an object-oriented language. Then you write the operating system (which is really a set of library routines). Since you are doing everything, there is no magic involved (there's a bit of magic in terms of how the peripherals, the screen and the keyboard, interact with memory, but that's a separate issue) which means that you have to start from a position where a bit stored in RAM at a certain address turns on or turns off a single pixel on the screen, to drawing lines and circles and characters. You have to implement the routines to get user input from the keyboard starting from a position where a single address in RAM merely has the keycode for whatever key happens to be pressed at the moment you read it. You have to implement dynamic memory allocation. You have to implement a String class. You have to implement math routines to perform multiplication, division, and square root.

It is an amazingly well put together course and, while it sounds overwhelming, is very tractable. You can either do the course on your own by following the text, or you can enroll in a Coursera course. The website I linked above also has videos for each project.
 

Thread Starter

King2

Joined Jul 17, 2022
163
We have a number in a different format like binary, hexadecimal, octal, decimal ASCII.

Suppose a micro controller displays the values of temperature and humidity on the screen.

Do we have to convert binary numbers to ASCII format to display temperature and humidity on screen?
 

MrSalts

Joined Apr 2, 2020
2,767
Lets say you have the 8-bit binary value in a variable that you named "temp" from your °F temp sensor B01001001.
This is meaningless quantity to most people on initial look and some people can look at if for a few seconds and let you know that this is equal to 73 in decimal.
If you want to show that number as "73" in a normal, human readable form on a display, you're going to have to convert it a few times.

First,
let's assume your sensor uses 8-bit unsigned values so the possible,values can be 0-255 in decimal form. If your sens does something else, you can work out the details after I cover the basics.

Second
You'll need a variable called hundreds, once called tens and one called ones for each place value possible from your "temp" variable.

Then you need to check which value to set "hundreds".
Code:
hundreds = temp % 100; // I used modulo divide (look it up if your not sure).
Hundreds should equal zero in this case).

Then subtract out the amount in hundreds 0, 100 or 200 from your temp variable

Code:
temp = temp - (hundreds * 100);
Now we need to do the same for tens and assign any left over to ones placeholder variables

tens = temp % 10;
temp = temp - (tens * 10);
ones = temp;

now, you have the three digits that can be possible values of your temp sensor.

but these are just three variables that again are holding a binary value. The good news, each binary value is a single-digit value that can be expressed as one base ten digit.

third,
most bitmap libraries are in ascii, so you should convert the value to ASCII.
luckily, the ascii value of digits 0-9 are just the value plus 48. Don't ask why, it's just how they were assigned. To be clear, 48 is the ascii value of the character "0". 49 is the ascii value of a "1" ... and 57 is the ascii value for a "9".
You could skip the ascii conversion if you write your own bitmaps but it's easier to steal one and it will likely be in ascii.

forth
bitmaps. Now, you need three new variables, hundredsBM, tensBM, onesBM where the BM stands for bitmap

Here is a function that will help you with each row being an ascii character.
Each character in this bitmap will be five columns by 8 rows. The hex values represent a pixel pattern ( 1= black and 0=white).
this is from an old NOKIA display if you look at the binary for a zero (turn your head 90° to see the zero hidden in there).
Code:
B00111000,
B01000100,
B10000010,
B01000100,
B00111000,
B00000000,
The library is written out a bit more efficiently in hex instead of binary.
Code:
static const byte ASCII[5] =
{
{0x00, 0x00, 0x00, 0x00, 0x00} // 20
,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 !
,{0x00, 0x07, 0x00, 0x07, 0x00} // 22 "
,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 #
,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 24 $
,{0x23, 0x13, 0x08, 0x64, 0x62} // 25 %
,{0x36, 0x49, 0x55, 0x22, 0x50} // 26 &
,{0x00, 0x05, 0x03, 0x00, 0x00} // 27 ’
,{0x00, 0x1c, 0x22, 0x41, 0x00} // 28 (
,{0x00, 0x41, 0x22, 0x1c, 0x00} // 29 )
,{0x14, 0x08, 0x3e, 0x08, 0x14} // 2a *
,{0x08, 0x08, 0x3e, 0x08, 0x08} // 2b +
,{0x00, 0x50, 0x30, 0x00, 0x00} // 2c ,
,{0x08, 0x08, 0x08, 0x08, 0x08} // 2d -
,{0x00, 0x60, 0x60, 0x00, 0x00} // 2e .
,{0x20, 0x10, 0x08, 0x04, 0x02} // 2f /
,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 30 0
,{0x00, 0x42, 0x7f, 0x40, 0x00} // 31 1
,{0x42, 0x61, 0x51, 0x49, 0x46} // 32 2
,{0x21, 0x41, 0x45, 0x4b, 0x31} // 33 3
,{0x18, 0x14, 0x12, 0x7f, 0x10} // 34 4
,{0x27, 0x45, 0x45, 0x45, 0x39} // 35 5
,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 36 6
,{0x01, 0x71, 0x09, 0x05, 0x03} // 37 7
,{0x36, 0x49, 0x49, 0x49, 0x36} // 38 8
,{0x06, 0x49, 0x49, 0x29, 0x1e} // 39 9
,{0x00, 0x36, 0x36, 0x00, 0x00} // 3a :
,{0x00, 0x56, 0x36, 0x00, 0x00} // 3b ;
,{0x08, 0x14, 0x22, 0x41, 0x00} // 3c <
,{0x11, 0x11, 0x11, 0x11, 0x11} // 3d =
,{0x00, 0x41, 0x22, 0x14, 0x08} // 3e >
,{0x02, 0x01, 0x51, 0x09, 0x06} // 3f ?
,{0x32, 0x49, 0x79, 0x41, 0x3e} // 40 @
,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 41 A
,{0x7f, 0x49, 0x49, 0x49, 0x36} // 42 B
,{0x3e, 0x41, 0x41, 0x41, 0x22} // 43 C
,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 44 D
,{0x7f, 0x49, 0x49, 0x49, 0x41} // 45 E
,{0x7f, 0x09, 0x09, 0x09, 0x01} // 46 F
,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 47 G
,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 48 H
,{0x00, 0x41, 0x7f, 0x41, 0x00} // 49 I
,{0x20, 0x40, 0x41, 0x3f, 0x01} // 4a J
,{0x7f, 0x08, 0x14, 0x22, 0x41} // 4b K
,{0x7f, 0x40, 0x40, 0x40, 0x40} // 4c L
,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 4d M
,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 4e N
,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 4f O
,{0x7f, 0x09, 0x09, 0x09, 0x06} // 50 P
,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 51 Q
,{0x7f, 0x09, 0x19, 0x29, 0x46} // 52 R
,{0x46, 0x49, 0x49, 0x49, 0x31} // 53 S
,{0x01, 0x01, 0x7f, 0x01, 0x01} // 54 T
,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 55 U
,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 56 V
,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 57 W
,{0x63, 0x14, 0x08, 0x14, 0x63} // 58 X
,{0x07, 0x08, 0x70, 0x08, 0x07} // 59 Y
,{0x61, 0x51, 0x49, 0x45, 0x43} // 5a Z
,{0x00, 0x7f, 0x41, 0x41, 0x00} // 5b [
,{0x02, 0x04, 0x08, 0x10, 0x20} // 5c ¥
,{0x00, 0x41, 0x41, 0x7f, 0x00} // 5d ]
,{0x04, 0x02, 0x01, 0x02, 0x04} // 5e ^
,{0x40, 0x40, 0x40, 0x40, 0x40} // 5f _
,{0x00, 0x01, 0x02, 0x04, 0x00} // 60 `
,{0x20, 0x54, 0x54, 0x54, 0x78} // 61 a
,{0x7f, 0x48, 0x44, 0x44, 0x38} // 62 b
,{0x38, 0x44, 0x44, 0x44, 0x20} // 63 c
,{0x38, 0x44, 0x44, 0x48, 0x7f} // 64 d
,{0x38, 0x54, 0x54, 0x54, 0x18} // 65 e
,{0x08, 0x7e, 0x09, 0x01, 0x02} // 66 f
,{0x0c, 0x52, 0x52, 0x52, 0x3e} // 67 g
,{0x7f, 0x08, 0x04, 0x04, 0x78} // 68 h
,{0x00, 0x44, 0x7d, 0x40, 0x00} // 69 i
,{0x20, 0x40, 0x44, 0x3d, 0x00} // 6a j
,{0x7f, 0x10, 0x28, 0x44, 0x00} // 6b k
,{0x00, 0x41, 0x7f, 0x40, 0x00} // 6c l
,{0x7c, 0x04, 0x18, 0x04, 0x78} // 6d m
,{0x7c, 0x08, 0x04, 0x04, 0x78} // 6e n
,{0x38, 0x44, 0x44, 0x44, 0x38} // 6f o
,{0x7c, 0x14, 0x14, 0x14, 0x08} // 70 p
,{0x08, 0x14, 0x14, 0x18, 0x7c} // 71 q
,{0x7c, 0x08, 0x04, 0x04, 0x08} // 72 r
,{0x48, 0x54, 0x54, 0x54, 0x20} // 73 s
,{0x04, 0x3f, 0x44, 0x40, 0x20} // 74 t
,{0x3c, 0x40, 0x40, 0x20, 0x7c} // 75 u
,{0x1c, 0x20, 0x40, 0x20, 0x1c} // 76 v
,{0x3c, 0x40, 0x30, 0x40, 0x3c} // 77 w
,{0x44, 0x28, 0x10, 0x28, 0x44} // 78 x
,{0x0c, 0x50, 0x50, 0x50, 0x3c} // 79 y
,{0x44, 0x64, 0x54, 0x4c, 0x44} // 7a z
,{0x00, 0x08, 0x36, 0x41, 0x00} // 7b {
,{0x00, 0x00, 0x7f, 0x00, 0x00} // 7c |
,{0x00, 0x41, 0x36, 0x08, 0x00} // 7d }
,{0x10, 0x08, 0x08, 0x10, 0x08} // 7e ←
,{0x78, 0x46, 0x41, 0x46, 0x78} // 7f →
};
this can then be used to call each asciii value to a group of 5 bytes (8-bits each) to assign all the pixels in a character for this super-simple font.

you'll then need to find the right starting point on a screen to position each character.

this is essentially how to display a value on an LCD display or OLED display from an Arduino or similar microcontroller. Things are a bit different if you have Python and the PIL or PILLOW library and displaying to a monitor.

or, you can use something like .imageMagic in Linux command line if you have a raspberry pi or other Linux box.

lots of possible ways to get to your end goal, you just have to define what you want.
 
Last edited:

nsaspook

Joined Aug 27, 2009
13,084
We have a number in a different format like binary, hexadecimal, octal, decimal ASCII.

Suppose a micro controller displays the values of temperature and humidity on the screen.

Do we have to convert binary numbers to ASCII format to display temperature and humidity on screen?
Sure, there are an almost infinite number of ways you might need to convert data for presentation or computation.

Temperature data conversion from a SCL3300-D01-1 INCLINOMETER sensor in C code fragments.
C:
#define TEMPERATURE_RES        18.9
#define TEMPERATURE_OFFSET    -273.0
// part of the accel structure
double sensortemp;

accel->sensortemp = TEMPERATURE_OFFSET + (sdata.scan.channels[SCA3300_TEMP] / TEMPERATURE_RES);
1664076412727.png1664076435112.png

We convert that binary data from the SPI device interface into floating point for display (to a ascii string and then to a display buffer) and computation.

C:
            sprintf(buffer, "%6.2f,%6.2f,%6.2f,%5.1f", accel.xa, accel.ya, accel.za, accel.sensortemp);
            eaDogM_WriteStringAtPos(1, 0, buffer);
30.3C was the reading.
1664076840301.png
 

k1ng 1337

Joined Sep 11, 2020
940
I would strongly encourage you to work through the Nand2Tetris project. It is a sequence of twelve projects (each one nominally a week's effort) in which you first design and build (in emulation) a complete computer using nothing by two-input NAND gates and D-type flip flops. That's roughly the first half of the course. Then you write an assembler for the CPU's instruction set. Then you write a translator that implements a stack-based virtual machine. Then you write a compiler for an object-oriented language. Then you write the operating system (which is really a set of library routines). Since you are doing everything, there is no magic involved (there's a bit of magic in terms of how the peripherals, the screen and the keyboard, interact with memory, but that's a separate issue) which means that you have to start from a position where a bit stored in RAM at a certain address turns on or turns off a single pixel on the screen, to drawing lines and circles and characters. You have to implement the routines to get user input from the keyboard starting from a position where a single address in RAM merely has the keycode for whatever key happens to be pressed at the moment you read it. You have to implement dynamic memory allocation. You have to implement a String class. You have to implement math routines to perform multiplication, division, and square root.

It is an amazingly well put together course and, while it sounds overwhelming, is very tractable. You can either do the course on your own by following the text, or you can enroll in a Coursera course. The website I linked above also has videos for each project.
1ocrfs.jpg
 

WBahn

Joined Mar 31, 2012
29,978
We have a number in a different format like binary, hexadecimal, octal, decimal ASCII.

Suppose a micro controller displays the values of temperature and humidity on the screen.

Do we have to convert binary numbers to ASCII format to display temperature and humidity on screen?
Those different formats apply to how humans write them down in order to better interpret the underlying pattern of 1s and 0s. In all but very rare instances, a computer just sees a bunch of 1s and 0s (or, rather, the physical manifestation of them, such as a voltage or a degree of optical reflectivity, or the polarity of a magnetic field). The hardware and software works only with the bit patterns according to rules we impose in order to process them in a fashion that makes sense for how we want them to be interpreted.

Work through the Nand2Tetris course and you will see exactly how all of this happens.
 

MrChips

Joined Oct 2, 2009
30,712
This has always been a difficult concept for beginners to grasp. You are not alone. Let us take one step at a time. It is very important that you understand this if you want to become an expert in programming computers.

Firstly, you need to wrap your head around this reality.

Computers store information in binary!

There is no such thing as hex, decimal, floating point, ASCII, text, etc. as far as the computer is concerned. It is all binary, a collection of zeros and ones. These abstract concepts are fabrications of humans because they allow humans to work with objects with which they are familiar.

Let us take a diversion for a minute. An 8-bit piece of data has 256 possible combinations from 00000000 to 11111111.
We can use these to represent anything we wish, for example, 256 colours, 256 types of flowers, 256 numbers.
For example, we can represent 256 integers from 0 to 255 or -128 to 127.
Thus everytime we use a pattern such as 01000001, it can mean a million different things at the same time. It is whatever it means at that specific instance of usage. You the programmer get to decide what it means to you in that specific programming context.

Back on track, let us establish that our 8-bit data represents values from 0 to 255.
We establish that the binary sequence 01000001 represents 65 decimal.
Now, we would like 65 to appear on a computer screen. It would be just as easy or complex to request the computer to display 65 on a 1x16 or 2x16 alphanumeric LCD module.

Next Step
How do we go from 01000001 to 65 on an LCD module?
This is the complicated part. Stay tuned.

65 is two separate pictograms [6] and [5].
To be able to display all decimal values we need ten pictograms [0] to [9]. Think of a pictogram as an icon or flash card. There is one flash card for each numeral. Each flash card is unique and is given a unique code. This code has nothing to do with the numeral on the card. The card could be different colour cards, for example.

Our first programming step is to take the 01000001 binary sequence and deconstruct it into two binary sequences, 0110 and 0101. This is a classic programming exercise in its own right.

Now that we have two entities, we need to convert this to the ID code of each flash card.
This is another programming step. If the ID codes are randomly assigned the simplest method is to use a look-up table.

Now that we have our flash card ID codes, we can send them one at a time in the correct order to the display device such as an LCD module.

To understand how the flash card pictogram becomes visible look up 5x7 character font.
 

Thread Starter

King2

Joined Jul 17, 2022
163
This has always been a difficult concept for beginners to grasp. You are not alone. Let us take one step at a time. It is very important that you understand this if you want to become an expert in programming computers.
Decimal to ASCII
0 = 48;
1 = 49;
2 = 50;
3 = 51;
4 = 52;
5 = 53;
6 = 54;
7 = 55;
8 = 56;
9 = 57;

Binary to decimal
48 = 00110000
49 = 00110001
50 = 00110010
51 = 00110011
52 = 00110100
53 = 00110101
54 = 00110110
55 = 00110111
56 = 00111000
57 = 00111001

Binary to ASCII
00110000 binary string display ASCII 0
00110001binary string display ASCII 1
00110010 binary string display ASCII 2
00110011 binary string display ASCII 3
00110100 binary string display ASCII 4
00110101binary string display ASCII 5
00110110 binary string display ASCII 6
00110111 binary string display ASCII 7
0011100 binary string display ASCII 8
00111001 binary string display ASCII 9

If I send all these binary strings will I get message 0123456789 displayed on the screen
 

MrChips

Joined Oct 2, 2009
30,712
No. Only the first chart is correct.

A decimal value is N = Ax100 + Bx10 + Cx1.
Your job is to determine A, B, and C given N.
There are different ways to do this.
The most obvious method is
A = N/100
B = (N - A*100)/10
C = (N - A*100 - B*10)

Have you read and followed post #9?

There are more efficient ways to do this.
 

WBahn

Joined Mar 31, 2012
29,978
Decimal to ASCII
0 = 48;
1 = 49;
2 = 50;
3 = 51;
4 = 52;
5 = 53;
6 = 54;
7 = 55;
8 = 56;
9 = 57;
This should be
'0' = 48;

The decimal value 0 is NOT equal to 48 in ASCII. In ASCII, the binary pattern 0011 0000 (what we would say has the value 48 in decimal) is the CODE (that's what the 'C' in ASCII stands for) for a character that, when printed, looks like what we humans interpret as the digit '0'. This is NOT different than other codes that represent the character 'A' or the character '$'.

In fact, in C and many other languages, the single apostrophe surrounding a character is an operator that evaluates to the character code (usually ASCII) that represents that character.
 
Top