# How to transmit ASCII over RS-232?

i want to display the voltage level through a Potentiometer over the serial comm line(RS-232) in pure ASCII. I am trying to do this using MC9S08AW60 on the Board-DEMO9S08AW60E. So, if the potentiometer is at 50% position, on Hterm it should show as following:

050%

Now for this(6 bytes) i need to be able to convert decimal to ASCII and transmit the same over RS232. I cant seem to find the logic behind conversion of decimal to ASCII.

questions:

1. logic for conversion of decimal to ASCII?

2. any better ideas?

3. if this question is outside the scope of this forum i am more than willing to change it to the appropriate forum.

Consider the following code:

if(TPM1SC_TOF == 1)
{

dummy = (bob*100)/255;
if((SCI1S1 & (1<<7)))
{
SCI1D = dummy;  // at this point i would like to send the percentage of the
//potentiometer value!
}
TPM1SC_TOF = 0;
}


Please take note of the attached block diagram!!

• you mean printf("\$03d%%\n", value)? – Eddy_Em Jan 28 '13 at 15:52
• @Eddy_Em - if the system doing the conversion has (or can afford to have) a printf, and if the output points at the serial port... Otherwise it would need to use a different function (fprintf or sprintf) or be done by hand. The big unanswered question right now is the nature/limitations of the system that will perform this operation. – Chris Stratton Jan 28 '13 at 15:55
• What is the platform / compiler you are using? AVR with Arduino? AVR with AVR-GCC? MSP430 with CCS? MSP430 with IAR? The idiomatic code for transmitting on the Serial port depends heavily on these factors. – vicatcu Jan 28 '13 at 15:58
• @Eddy_Em - on the contrary it's quite easy to understand what the question means. The problem is that we don't yet know the capabilities of the system. – Chris Stratton Jan 28 '13 at 16:01
• I'm curious. The question as was understood by @ChrisStratton, John U, and myself, and what a unprejudiced reading of the question in English combined with the clarity provided by the code snippet included in the question, making it clear he's got the registers and peripheral usage down pat, and subsequently the accepted answer, are all consistent. Why is this not a real question? – Chintalagiri Shashank Jan 29 '13 at 12:43

Here's part of a minimalistic printf implementation I've been using. It was originally written by Georges Menie of www.menie.org, according to the GPL notice at the top of the file. I have been modifying the implementation as a whole, and haven't really been keeping track of the changes, though, so you probably should use the original which seems to be available at http://www.menie.org/georges/embedded/#printf

The function listed below converts an int to its ascii string. You can try to follow the code and strip out the parts which you don't need. There are calls to prints in the function, which deals with padding and handling the width of the string. It also does the actual sending of chars via putchar. I haven't included that function here to reduce clutter. You should implement your own function to to do that here, which basically would send out each of the chars via your serial/rs232/uart peripheral until you encounter \0.

static int printi(char **out, int i, int b, int sg, int width, int pad, int letbase)
{
char print_buf[PRINT_BUF_LEN];
register char *s;
register int t, neg = 0, pc = 0;
register unsigned int u = i;

if (i == 0) {
print_buf[0] = '0';
print_buf[1] = '\0';
return prints (out, print_buf, width, pad);
}

if (sg && b == 10 && i < 0) {
neg = 1;
u = -i;
}

s = print_buf + PRINT_BUF_LEN-1;
*s = '\0';

while (u) {
t = u % b;
if( t >= 10 )
t += letbase - '0' - 10;
*--s = t + '0';
u /= b;
}

if (neg) {
printchar (out, '-');
++pc;
--width;
}
else {
*--s = '-';
}
return pc + prints (out, s, width, pad);
}

• mate is there an explanation of the variables being used?? i mean, which variable is refered to wat? – sheetansh Jan 29 '13 at 13:17
• I'd suggest you use the link in the answer and get the original source code and use the printf implementation (without stdarg). Strip it down if its heavier that what you need (which it is, and which is what I've been doing). The function listed above is simply the core of what you want to do. The 'logic'. 'i' is the integer you want to print, 'b' is the base (set to 16 to print in hex, for example), 'sg' is whether its signed. 'width' and 'pad' are used for string formatting (see the original printf for how) and 'letbase' is the base letter, usually 'a'. Thats used to construct the ascii. – Chintalagiri Shashank Jan 29 '13 at 13:26
• @sheetansh Also, to be clear, to send an ascii character with code, say, 68, you'd send the value 68 through the UART. You can look at the ascii tables for what various characters are represented by. – Chintalagiri Shashank Jan 29 '13 at 13:30
• thanks for the explanation regarding code. as for the ascii transmission, i have the table infront of me. i have tried certain manipulations to compensate for the difference between the numbers. but its not enough for all the values. I hope this wat you meant! – sheetansh Jan 29 '13 at 14:07
• mate i was just helped to precieve a simpler method.as the percentage value by the code can only exist from 0-100.so,if value is 069; a=069/100,b=069/10,c=069%10. now, as by ASCII chart '0'= 48(decimal). so new values are a=a+48,b=b+48,=c+48. these values over a transmisson stream. WHAT YOU THINK THIS WOULD? havent coded the transmission stream as yet, but i think it should. if any INSIGHTS, please let me know!! – sheetansh Jan 29 '13 at 15:21

So I dug a little bit for you. Take a look at Freescale's "HCS08 Peripheral Module Quick Reference"which is linked from the product page. There is a section titled "Using the Serial Communications Interface (SCI) for the HCS08 Family Microcontrollers." And Subsection 2 of that section is titled "Code Example and Explanation." Follow the bouncing ball and that should get you going. The Dev board already has the circuits needed to go from TTL UART to RS232. There's also code examples in there for the ADC. You'll then just need to manage converting your ADC readings into ASCII using "the usual methods" like, for example, sprintf from stdio.h.

Half the battle with acclimating yourself to a new controller/processor is figuring out where the examples and support ecosystem reside. Hope this helps. P.S. The code examples zip file referenced in the Quick Reference is here (not the easiest thing to find).

• what was your thought proces when looked up this reference!!? cause i guess i was just thinking wrong.thanks mate! – sheetansh Jan 28 '13 at 16:41
• @sheetansh google-fu is an art-form that is difficult to master, and takes years of patience and experience to master. The thought process starts with the knowledge that "such a thing must exist" and follows logically from there. – vicatcu Jan 28 '13 at 16:44
• mate i got the code and the simple method of using the SCI for the board! thanks for the input! – sheetansh Jan 29 '13 at 12:51
• @sheetansh no problem, glad I could help :-) – vicatcu Jan 29 '13 at 22:42

While you can probably do this with a printf-family function on that platform, it's informative to consider how you might write you own implementation. For example:

1. Find a power of ten larger than the maximum value - in this case your desire for leading zeros will simplify things.

2. Divide by decreasing powers of ten, to produce each output digit, retaining the remainder to feed the next calculation.

3. Convert each digit from a value to its ascii representation. For decimal, this is easy as you just add the ascii code of the character '0' (which is 0x30or 48 in decimal) to the decimal value. (For hex digits, you have to handle 0-9 and a-f in separate clauses)

4. Write the resulting bytes to the serial port, typically waiting until the UART transmit buffer is empty before writing each one.

The starting point code you've added seems to contemplate doing the conversion inside the transmit buffer check; that won't really work for multi-byte sending. Instead, your outer loop doing the ADC sampling would have the decimal-to-ascii conversion loop inside it, and inside that at the point where it's generated a single character would be a while looping waiting for the serial port to be ready for a character. (That is, assuming you don't need to do other things in the meantime - if you do, you'll need a software-managed transmit buffer and something such as an interrupt service routine to pull waiting characters out of the buffer and send them each time the serial port becomes able to accept one).

• while I can appreciate the "base principles" approach you've taken in this answer, I think the OP is hoping for some more platform-specific guidance... just my opinion – vicatcu Jan 28 '13 at 16:37
• thanks vicatcu for the insight but having a basic ppl apporach will help me to understadn the concept none the less! – sheetansh Jan 28 '13 at 16:40
• @vicatcu - There's not much "system specific" about this, it's all in the std libraries as it's only really "number-to-string" conversion which is quite well catered for. – John U Jan 28 '13 at 16:41
• Pretty much all of the platform specifics to implement this form of an answer are already in the OP's starting code - that would be the serial port flag check and output register write. The only other major thing to figure out is what the integer data type that would hold these values is called on this platform. Depending on the ADC output range and the order of operations, it may need to be a 16 bit type or even larger, thought the scaling conversion could be reshuffled to make it fit in something smaller, by not multiplying by 100 before dividing. – Chris Stratton Jan 28 '13 at 16:48
• @vicatcu - the question is "how to convert value to ascii & send over RS232" not "how to control the ADC". Once you have a value it's just a standard data conversion & shove it into the UART as people have said above that's usually pretty well documented & coded for already for any given micro. – John U Jan 28 '13 at 16:56