WebbotLib AVR library
WebbotLib It just does it
  C++ documentation  C documentation

rprintf.h

There are times when you need to create a formatted message that is made of a mixture of text and numbers. Normally this is used for logging purposes to log messages to a PC or LCD display.
This module provides various functions to allow you to do that - using the standard C 'printf' format. The specification is quite wide and includes the output of real numbers (ie numbers with something to the right of the decimal point).
When generating your code in Project Designer you can select from three different options for printf support. These give a trade off between functionality and the amount of program space required.
Since we don't have a screen, unlike a PC say, then we need to tell the rprintf module where the text output is to be sent by default - and this is done in the code generation dialogue box in Project Designer. Leaving the option blank will call all of the output to be discarded.
NOTE: these functions are retained for now - but you should consider using PRINTF(stream,format, args...) or the stream output commands like print instead.

 

Function

 


Writer rprintfInit(Writer writer)

Tells rprintf where to send its output to.
This has now been replaced by which is a much more forgiving way of making sure that the previous state is restored.
The parameter can specify the address of any function that takes a character as an argument. The most usual case is that characters are sent via a UART to the PC or a serial LCD. Note that if you are using a UART then you should have initialised it to the correct baud rate using uartInit(UART* uart, BAUD_RATE baud) before calling any of the rprintf functions.
To specify that data will be send to UART0 at 9600 you can use the following code:-
uartInit(UART0, 9600);
rprintfInit(&uart0SendByte);
If you want to use a different UART then just change the number in the line above. For example: if your controller has a UART2 then you can send info to it by using:
uartInit(UART2, 9600);
rprintfInit(&uart2SendByte);
If you want to write your code that will receive the output from rprintf functions rather than using a UART then you need to create a Writer. This can be done using the MAKE_WRITER macro which expects one parameter which is the name of your routine. The routine will receive the character in a variable called 'byte'. For example: lets say we want to create a Writer that converts everything to upper case before sending to UART1 then we could write:-
MAKE_WRITER(upperCaseWriter){
    // Convert the byte to upper case
    if( byte >= 'a' && byte <='z'){
        byte -='a';
        byte += 'A';
    }
    return uart1SendByte(byte);
}
You can then tell rprintf to use this routine by:
rprintfInit(&upperCaseWriter);
Note that if your program keeps changing where rprintf sends its output then it is good practise to make the start of your routine save the current rprintf destination, and then to restore it at the end of your routine. We can do this by saving the value returned by rprintfInit as this is the previous rprintf writer. So for example: say we have some code that will use our 'upper case' writer defined above - but during the rest of our application we want rprintf to go somewhere else. We should write the code as follows:-
// Change to our upper case writer and save the previous one
Writer old = rprintfInit(&upperCaseWriter);
... do stuff ....
... all rprintf output will be converted to upper case ...
... and sent out to UART1 ...
// Restore the previous writer
rprintfInit(old);
... Any rprintf output now goes to wherever it was going before ...

OUTPUT(Writer writer)

Brackets a piece of code whose rprintf output should be sent to a specific place.
Previously you would have temporarily changed the rprintf destination with code like this:-
// Change to our upper case writer and save the previous one
Writer old = rprintfInit(&upperCaseWriter);
... do stuff ....
... all rprintf output will be converted to upper case ...
... and sent out to UART1 ...
// Restore the previous writer
rprintfInit(old);
... Any rprintf output now goes to wherever it was going before ...
This can now be made simpler:-
// Change to our upper case writer and save the previous one
OUTPUT(&upperCaseWriter){
    ... do stuff ....
    ... all rprintf output will be converted to upper case ...
.   ... and sent out to UART1 ...
} // restores rprintf to where it was before
... Any rprintf output now goes to wherever it was going before ...
This new format is also safe in that the rprintf destination is automatically restored however you exit the loop. For example:-
// Change to our upper case writer and save the previous one
OUTPUT(&upperCaseWriter){
    return;    // EVEN THIS WILL RESTORE THE RPRINTF LOCATION !!
} // restores rprintf to where it was before
... Any rprintf output now goes to wherever it was going before ...

char hexchar(char x)

Convert binary to hexadecimal digit.
Convert the low four digits of the parameter into a hexadecimal character.

rprintfChar(unsigned char c)

Output a single character.
This will translate any 'linefeed' characters into 'carriage return' + 'line feed' sequences.

rprintfCharN(unsigned char c, size_t repeat)

Print a character a given number of times.
For example to print a dashed line you could use:
rprintfCharN('-',60);

rprintfStr(char str[])

Print a string that is stored in RAM.
For example:
rprintfStr("Hello World");
This is not ideal since the fixed text 'Hello World' will actually eat into our valuable RAM space.

rprintfStrLen(char str[], size_t start, size_t len)

Print a section of string that is stored in RAM.
This will print out 'length' characters starting at the 'start' position of the string.
For example:
rprintfStrLen("Hello World",6,4);
will print out 'Worl'.

rprintfProgStr(const prog_char str[])

Output a constant string stored in program memory.
This function is normally only used when the text to be printed is not a fixed value. For example: you may have a function that takes a string as one of its arguments:
void myFunc(const char PROGMEM text[]){
    // .. do something ..
    rprintfProgStr(text); // output the text
}
Another common use is where there is a piece of text that you are outputting from lots of different places. For example you may be output "OK" in lots of places in your code. In this case we just want to define the text in one place and then reference it from all the places where we output the message. We could do that as follows:
const char PROGMEM msg[] = "OK";
and whenever we want to output the message we can just write:
rprintfProgStr(msg);
Also see: rprintfProgStrM

rprintfProgStrM(string)

Output a fixed string from program memory.
This will store the string in program memory and use rprintfProgStr(const prog_char str[]) to output it. For example:
rprintfProgStrM("OK");

rprintfCRLF()

Move the output to a new line.
Sends a carriage return and line feed to the output device.

rprintfu04(unsigned char data)

Output the low 4 bits of 'data' as one hexadecimal character

rprintfu08(unsigned char data)

Output the parameter as two hexadecimal characters.

rprintfu16(unsigned short data)

Output the parameter as 4 hexadecimal digits.

rprintfu32(unsigned long data)

Outputput the parameter as an 8 digit hexadecimal number.

rprintfNum(char base, char numDigits, boolean isSigned, char padchar, long n)

Allows you to print a number in any base using different padding characters.
base - The number base you want to use. eg 10 = decimal, 16=hexadecimal
numdigits - The number of digits you want to pad the number out to
isSigned - Set to TRUE if the number is a signed number, ele FALSE
padchar - The character to use on the left hand side to pad the number out to the appropriate number of digits. Normally a space ' '.
n - The value to be printed.

rprintfFloat(char numDigits, double x)

Prints a floating point number.
This is only available if you add the line:-
#define RPRINTF_FLOAT
prior to including this file.
This is necessary as it will bring in the floating point number library which, if not used by the rest of your code, will add quite a large payload.
This function will convert a floating point number into a string equivalent 'numDigits' long.

rprintf(format, args...)

Output a formatted string to the output.
The capability of this function is effected by the 'printf' option you have selected during code generation.
The 'minimal' option allows you to print whole numbers, characters and strings. 'double's and 'float's will be output as '?'.
The 'floating point' option enables the full functionality including floating point numbers.
Here are some examples:
#include "rprintf.h"
int16_t num1 = 1234; // a standard 'signed int'
int32_t num2 = 1234567; // a standard 'long int'
int16_t width = 5;
rprintf("num1=%d num2=%ld", num1, num2); // prints 'num1=1234 num2=1234567'
// If we want a 5 digit number with leading zeros...
rprintf("num1=%05d",num1); // prints 'num1=01234'
// Or if the field width needs to be variable then
rprintf("num1=%0*d", width, num1); // prints 'num1=01234'
When using this function the formatting string is automatically stored in program memory.
Note that due to the way C works then neither the compiler, nor the runtime, can verify that the % entries in the format string match the data type of the given parameters. Consequently: if you attempt to print out various variables in one go and there is a mismatch between the format string and the parameters that follow then C will print out what looks like garbage. If in doubt, or to debug a problem, then only output one value per call to rprintf.
Here is a list of the various '%' options available in the format string along with the data type which should be passed as a parameter:

rprintfMemoryDump(const void* data, size_t offset, size_t len)

Dumps an area of memory in tabular format showing both hexadecimal and ASCII values.
The first parameter specifies the memory address, the second is the byte offset starting at that address, and the last parameter specifies the number of bytes to dump out.
So if you have an array such as:
char buffer[50];
Then you can dump out its contents using:-
rprintfMemoryDump(buffer, 0, 50);

Valid XHTML 1.0 Transitional