Printing ADC value to terminal

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am working with a Mega64 and I have the UART working. I can send my function a hex values and it writes the character equivalent to the terminal just fine.

void TransmitData( unsigned char data )
{
   /* Wait for empty buffer */
   while ( !( UCSR1A & (1<<UDRE)) );
   /* Put data into buffer, send the data */
   UDR1 = data;
}

This prints "ME" to the screen.

       TransmitData(0x4D);
       TransmitData(0x45);

Where I am getting lost is...how do I print the ADC value? For instance, when I get the ADC value, it is an integer between 0-1024. If I do :

TransmitData(200);

It does not print a 200 to my terminal. :cry:

Any help on how to deal with this?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

itoa() is your friend.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The simplest way is to use the itoa() function (integer-to-ascii). This is not a standard library function, so it's exact implementation varies between compilers, but most have a version of it.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You need to convert the binary value into a string. sprintf() can do this for you:

void WriteNum(uint8_t val)
{
  char buf[4]
  uint8_t t = 0;

  sprintf(buf, "%3u", val);

  while(buf[t] != '\0')
  {
    TransmitData(buf[t]);
    t++;
  }
}

This function works okay, but isn't great. Depending on what you are doing, the following may help, which is the full strength way to get stdio formatting working with your chosen IO route:

http://www.nongnu.org/avr-libc/user-manual/group__avr__stdio.html

Mike

Edit#1: Correct buffer size and format string.

Last Edited: Wed. Sep 12, 2007 - 11:00 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Mike,

But surely for a %u you don't want the "baggage" of printf() in an app when itoa() will do it in about 1/10th the code space? The only justification for printf() in a small embedded app is when you get into the real fancy formatting stuff (or, God forbid, floating point)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
  sprintf(buf, "%8u", val); 

use "%u" or "%3u" as format string. Numbers 0...255 do not need to use 8 characters, or you would need a larger buf[] to avoid an array overrun.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks everyone! That did the trick. Another success story. Michael, thanks for the code sample. That works great.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes but printf() is over-kill for this. As a comparison:

#include 
#include 

void TransmitData(char c) {
	UDR = c;
}

void WriteNum(uint8_t val) 
{ 
  char buf[8]; 
  uint8_t t = 0; 

  sprintf(buf, "%8u", val); 

  while(buf[t] != '\0') 
  { 
    TransmitData(buf[t]); 
    t++; 
  } 
}

int main(void) {
	WriteNum(ADCH);
	while(1);
}

gives:

AVR Memory Usage
----------------
Device: atmega16

Program:    2030 bytes (12.4% Full)
(.text + .data + .bootloader)

while:

#include 
#include 

void TransmitData(char c) {
	UDR = c;
}

void WriteNum(uint8_t val) 
{ 
  char buf[8]; 
  uint8_t t = 0; 

  itoa(val, buf, 10); 

  while(buf[t] != '\0') 
  { 
    TransmitData(buf[t]); 
    t++; 
  } 
}

int main(void) {
	WriteNum(ADCH);
	while(1);
}

gives:

AVR Memory Usage
----------------
Device: atmega16

Program:     386 bytes (2.4% Full)
(.text + .data + .bootloader)

So what is the point is wasting 1,644 of AVR code bytes needlessly ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

But surely for a %u you don't want the "baggage" of printf() in an app when itoa() will do it in about 1/10th the code space?

Given the original poster didn't seem to realise that vars need formatting, I think printf() is an okay answer. Hopefully they can now write arbitrary strings, which may be of use in debugging/logging their program too.

Of course itoa() is smaller (and you are correct, I've checked and it is almost 1/10th the size - kinda surprising) as it is more specific, but if you are using printf() elsewhere, you may get it and any fancy formatting for free. It's hard to tell without knowing the application, but all good information for the original poster :)

Mike

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Don't lose site of the fact that it's embedded controllers we are programming here. The smallest mega's are the 4K ones. 1,644 is quite a "hit" (40%!) in a controller of that size. If using tinys (well those that are C programmable) the problem can be even worse.

Sure, if you are up the other end of the scale putting a web server into an Ethernet/USB enabled 256K device complete with RTOS and all the trimmings then 1,644 bytes is a drop in the ocean (0.6%) but you'd almost be bound to be using printf() for something else in an app of that size.

In fact I'd even question the use of itoa(). If you ONLY want decimal I bet you could roll your own in less than the 116 bytes it "costs".

Cliff

PS 1644 is the "cost up" from itoa to printf. The actual "cost" of printf is 1644+116 = 1760 bytes

(other compilers may vary!)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

If you ONLY want decimal I bet you could roll your own in less than the 116 bytes it "costs".

My utoa() producing a right-justified output, leading-zero supressed, with powers of 10 in an EEPROM table is 64 words plus the EEPROM-read primitives (which are "free" since used elsewhere in the program). I suppose you can get it to 100 bytes, but 116 doesn't sound bad.

[Remember that the recursive solution (from a fairly recent thread) will probably be the smallest in code size at the expense of stack space.]

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.