small serial tx function

I wanted to add serial output to my project, but don't have much space to spare. Bringing in Serial costs over 1400 bytes just to transmit debug/logging data over the wire. So I came up with this function which adds only 66 bytes.

It only sends strings so that's part of why it's smaller and it only transmits/cant use it in conjunction with Serial (why would you?)/and would need tweaking to work on a atmega8 or a non 16mhz chip. But maybe someone has a need for it.

#define myubbr (16000000/16/9600-1)
void simpletx( char * string ){
  if (UCSR0B != (1<<TXEN0)){ //do we need to init the uart?
     UBRR0H = (unsigned char)(myubbr>>8);
     UBRR0L = (unsigned char)myubbr;
     UCSR0B = (1<<TXEN0);//Enable transmitter
     UCSR0C = (3<<UCSZ00);//N81
  }
  byte x = 0;      
  char c = string[x];      
  while(c != 0){  
    while ( !( UCSR0A & (1<<UDRE0)) );
    UDR0 = c; //send the data
    x++;      
    c = string[x];      
  }      
} 

void setup(){}

void loop(){
  simpletx("Hello\n");
  delay(500); 
}

Hey, dcb, that is indeed cool and potentially quite useful. Thanks for sharing! I gather it's hardcoded for 9600 baud, but that could easily be adjusted by changing the definition of myubbr?

Here's the same function trimmed down to 56 bytes: :slight_smile:

#define myubbr (16000000/16/9600-1)
void simpletx( char * string ){
if (UCSR0B != (1<<TXEN0)){ //do we need to init the uart?
UBRR0H = (unsigned char)(myubbr>>8);
UBRR0L = (unsigned char)myubbr;
UCSR0B = (1<<TXEN0);//Enable transmitter
UCSR0C = (3<<UCSZ00);//N81
}
while (*string)
{
while ( !( UCSR0A & (1<<UDRE0)) );
UDR0 = *string++; //send the data
}
}

Mikal

#define myubbr (16000000/16/9600-1)
void simpletx( char * string ){
if (UCSR0B != (1<<TXEN0)){ //do we need to init the uart?
UBRR0H = (unsigned char)(myubbr>>8);
UBRR0L = (unsigned char)myubbr;
UCSR0B = (1<<TXEN0);//Enable transmitter
UCSR0C = (3<<UCSZ00);//N81
}
while (*string)
{
while ( !( UCSR0A & (1<<UDRE0)) );
UDR0 = *string++; //send the data
}
}

Hi Mikal, it doesn't look like the while loop will terminate, I think *string is always true for any non null string

Hi mem,

Hi Mikal, it doesn't look like the while loop will terminate.

Hmm... I think it will. At least it worked for the one 5-second test I did. :smiley:

No seriously, the (outer) loop will always terminate because string is being incremented at every iteration, and so eventually *string, the while loop test condition, will attain a value of 0 when it gets to the end of the string.

Try dcb's test program:

void setup(){}
void loop()
{
  simpletx("Hello\n");
  delay(500);
}

It works great with both revisions of simpletx(). I like that tiny function! Thanks.

Mikal

PS: You often see this kind of technique in old C strcpy code, like:

void strcpy(char *to, char *from)
{
  while (*to++ = *from++); // !
}

M

Cute, That seems to work too :slight_smile: Except I count 56 bytes :wink:

56 bytes

Yup, that's right! Same here!

M