Go Down

Topic: Printf in Arduino Due (Read 4170 times) previous topic - next topic

malbahri


Hi,

I am using Arduino Due in the embedxcode 4.6.3. I would like to use printf to present my  program output. Printf is working  fine if it is included in the  void loop function an example of that as per the below program :

#include" Arduino.h"

void setup ()
{
Serial.begin(9600);
}
void loop ()
{
printf("Test");

}

but when I tried to use printf inside the void setup function as the below, the printf function does not report the output
#include" Arduino.h"

void setup ()
{
Serial.begin(9600);
printf("Test");}
void loop ()
{
}

I hope I can get your kind support and advice


m_lab85

hi,

try to use Serial.print("Test"); instead of printf("Test");

regards,

M,

malbahri

Actually I need to use the printf because as I am targetting to include similar the below
printf("Result Point is %Zd,%Zd",R.x,R.y);

to be honest I don't know how can I do it in the Serial.print

You can use 'sprintf' which has the same syntax as 'printf' but the output is directed to a char array which is given as the first parameter.
e.g.
char cAry[128];
sprintf(cAry, "This is a test for printing %04d (decimal) and 0x%04X (Hex)\nNext Line.\n", 767, 767);
Serial.print(cAry);

stimmer

It may be that printf is buffering until it gets a newline, like it does on Linux. Try printf("Test\n"); instead.
Due VGA library - http://arduino.cc/forum/index.php/topic,150517.0.html

bperrybap

malbahri,
I just updated the Arduino Printf playground page to show how to add printf() support
to the Print class.
You may be interested in this.
It does require modifying the Arduino supplied Print.h header but once done, it allows
any device that uses the Print class to have printf() support by simply referencing printf()
from the device object.
i.e.
Serial.printf("Hello World");
Here is a link to the Printf playground page:
http://playground.arduino.cc//Main/Printf

--- bill

ghlawrence2000


Actually I need to use the printf because as I am targetting to include similar the below
printf("Result Point is %Zd,%Zd",R.x,R.y);

to be honest I don't know how can I do it in the Serial.print


Out of interest, does %Zd format work on Arduino?

Regards,

Graham

Paul Stoffregen

I recently added this on Teensy 3.0, which uses a similar ARM chip.  Here's the code (in Print.cpp), if anyone interested in trying on Arduino Due.

Code: [Select]

extern "C" {
__attribute__((weak))
int _write(int file, char *ptr, int len)
{
        ((class Print *)file)->write((uint8_t *)ptr, len);
        return 0;
}
}

int Print::printf(const char *format, ...)
{
        va_list ap;
        va_start(ap, format);
        return vdprintf((int)this, format, ap);
}

int Print::printf(const __FlashStringHelper *format, ...)
{
        va_list ap;
        va_start(ap, format);
        return vdprintf((int)this, (const char *)format, ap);
}

bperrybap

Paul,
I replied back to the email you sent me about adding printf support into the Print class for the AVR.
Maybe you didn't get it?
Here is a summary:

It has to take into consideration line endings.
foo.printf("Hello World\n");
should work the same as
foo.println("Hello World");

I ended up having to put a check in the putchar/write routine
to check for a new line and force out a carriage routine just
before sending out the new line to make line wrappings work properly
for serial terminals.
(You can see on the Printf page I updated)


BTW, I hadn't seen vdprintf() before, that will be better than the static
buffer I was using for non AVR processors. It is too bad that the AVR doesn't
include this function, it would have made things much simpler and portable.

--- bill

Paul Stoffregen

For now, I'm not really concerned that println() sends CR & LF, but printf("\n") sends on LF.

On Linux, the Arduino Serial Monitor seems to handle LF only pretty well.  I haven't tested what it does on Windows and Mac, but if those 2 systems don't treat LF only as a line break, perhaps the best solution is to update the IDE.

bperrybap

I've been wrestling with line ending issues on serial ports for over 30 years.
Most of it because of the way that CPM, Windows, and MAC did things. (vs unix)
The non unix platforms don't have the simple concept of "newlines" or
concept of raw vs cooked modes.
As a result they tend to always send/need both and often screw things up.

You have made the assumption that the only consumer of the character output is the Arduino IDE.
This is not always the case.
Try using using some serial device other than the IDE to monitor the serial port.
maybe putty? or an actual terminal.
Also, there are some embedded devices out there with serial ports that parse serial data, and not all of them
look for <LF> to parse the lines.
Some embedded devices only look for the <CR> and toss the <LF>
since they were designed to be connected to a real teminal which sends a <CR>
when user presses the <CR>/ENTER button on the keyboard.

There is no one be all answer for this since in order to make it work for
all situations you really need to have both raw and cooked modes.
However, what I've found is that cooked mode, where carriage routines
are inserted, tends to offer the greatest compability.

Just some things to think about.


--- bill

Paul Stoffregen

I might still add yet another layer to translate LF to CR & LF.  But on my (incredibly long) list of features to develop, this is a pretty low priority.

For now (Teensyduino 1.17), I'm going to leave it as-is without any translation.  If someone is using a terminal emulator that can't be configured to deal with only LF, they'll just have to use printf("\r\n"), or stick with the Arduino println() function.

bperrybap


I might still add yet another layer to translate LF to CR & LF.  But on my (incredibly long) list of features to develop, this is a pretty low priority.

You already have at least one translation routine already.
It is in serial1.cpp in the serial_print() routine in the teensy3 core.
It translates LF to CR, LF.
I'm curious why you chose to put it in there but not in the printf() for the Print class.

For now (Teensyduino 1.17), I'm going to leave it as-is without any translation.  If someone is using a terminal emulator that can't be configured to deal with only LF, they'll just have to use printf("\r\n"), or stick with the Arduino println() function.

I admire your *nix purity.
I'm a unix guy too (for 30+ years now) and also believe that all the others that came along later got it wrong.
In my case, 4 years ago, I had to go in and modify the GLCDdiag sketch serial output to do the
translation as it didn't work for a few folks without the added <CR>.

Maybe in the last 4 years the non *nix s/w people have awakend up to better newline handling
and do it better now, so it is less of problem.


Paul Stoffregen

In serial1.c, serial_print() and those other functions at the end are leftover debugging stuff.  They were mostly used while I was developing the USB stack.  I'm planning to remove them eventually.

bperrybap


In serial1.c, serial_print() and those other functions at the end are leftover debugging stuff.  They were mostly used while I was developing the USB stack.  I'm planning to remove them eventually.

I saw that. I was just curious why the translation was thought to be important enough to put in that code
but now it is not in the new printf() for the Print class.
Change of thinking?

--- bill

Go Up