Using Printf-style Output To Debug Arduino

First off, if you’re looking at that title and thinking it’s flame-bait, please hold off. What [Ihsan Kehribar] is working with is another way to get some feedback for what’s going on with your Arduino project. Or really any AVR project that uses an ISP connection. He’s added text output for AVR programs similar to the printf function used for a lot of non-embedded C development.

So, we’d bet you’re asking yourself why he’s not just using outright debugging? The AVR line supports many different types of it. But that can be complicated, and usually requires a proper programmer. If you just want to watch to see what values are changing, and when functions are being executed, this isn’t a bad solution. He uses the computer to continually poll the chip. Whenever the sketch calls the his print library it answers back with the payload to be displayed in the terminal. The overhead shouldn’t be too high, and if you’re smart about it this can be flagged as a debug option at the top of the program file.

21 thoughts on “Using Printf-style Output To Debug Arduino

  1. “if you’re looking at that title and thinking it’s flame-bait, please hold off.”

    Is this the hackaday equivilent of “INB4”? Why hold off? The summary is exactly what the title suggests.

    Is there anyone debugging arduino by aimlessly “guess & check” until the final product just miraculously works?

    I thought printf style was what everyone without proper debug did.

    1. no, the reader may think it’s talking about the basic of the basic use of programmer’s tty thing and serial.print and wonder if hackaday became Maker magazine or something.

    2. Sorry for the report, I hit the wrong button (again..)

      I do agree for the printf style debug. It’s used A LOT even when debug tools are available. It’s the best way to run your firmware in real conditions and having data feedback.
      Saved my ass quite a lot of times…

  2. Correct be if am wrong, but I believe you can define your own put_char function and use an avr-libc’s fdev_setup_stream (I think?) function to hook it up to avr-libc’s printf, which you can then use directly, making sprintf unnecessary.

    1. I was wrong, the function I meant was FILE* fdevopen (int(*)(char, FILE *) put,int(*)(FILE *)get). I believe ‘get’ can be null if you aren’t planning on reading from your communication line.

      1. Yep, I’ve used it recently to output from printf to character lcd. Maybe using uart instead of isp would be simpler here, you could connect it to serial port or usb through ftdi.

      2. I think the unique thing here is it’s using SPI rather than the USART, so if you were using the USART already for your app you could use this to send debugging messages elsewhere. However there’s already a couple of ‘soft serial’ libraries available that use bit-banging to implement serial IO, or you could just use something which has more than one USART, such as a mega.

        It’s fairly easy to plumb avr-libc’s stdio up to the USART so you can use printf/scanf etc, I’ve done this myself (partly in disgust at the state of the Arduino code) and I’ve implemented echoing, line buffering, backspace handling etc. That’s what I’m using for most of my debugging, as well as my OpenBench Logic Sniffer for more tricksy stuff.

  3. Now that I’ve moved wholesale to developing on ARM cortex-Mx chips I can truthfully say I am glad I will never again have to debug this way. GDB, I love you so, so much.

  4. I do deeply embedded systems and the first thing I do is get a CLI working on a serial port with printf().

    Using an SPI port is a bit harder – a pretty good hack!

    It’s not hard to write your own sprintf() – and printf() always calls sprintf().

  5. If you are in the Arduino IDE world to start, why not use the Serial class? It does have sprintf() but as pointed out, there are FOSS implementations of sprintf().

  6. lol! And getting your strings from flash is just a few more lines…

    //?? Printf-style to the serial
    void ps(const char *fmt, ... )
    char tmp[128]; // resulting string limited to 128 chars
    va_list args;
    va_start (args, fmt );
    vsnprintf(tmp, 128, fmt, args);
    va_end (args);

  7. Unless this can be somehow made to work with the AVR ISP programmer (or other programmers that work with avr studio) it is quite limited. True you don’t need a serial port, but most of the time it is used anyway.

    For debugging where no serial port is used i route the TX and RX singal near the 6pin ISP and for an 8 pin connector which connects with a Y cable to my programmer and serial port.
    At one point i even had a USB hub, AVR ISP II and USB-serial bridge taped together.

  8. Hi,

    I guess hackaday missed the main point of this hack.

    The main point is using SPI protocol to make debug interface, and also using the same cable for debug console and programming.

    Printf debugging isn’t novel as others tell.


  9. “….why he’s not just using outright debugging? The AVR line supports many different types of it. But that can be complicated, and usually requires a proper programmer.”

    can someone abbreviate on this please?
    i’m looking for a step-by-step debugger ever since i start using the arduino platform (AVR644 actually). is it really possible and what kind of programmer do i need?

    1. @rm: You’ll need a atmel dragon or a jtagice 3 for debugging any avr.

      Only if you are addicted to IDE’s. Try the teensy 2.0 (++) – you have a serial port, an LED, extra ports, and a free toolset (Atmel Studio && a downloader).

      I have debugged systems without the extra ports. I just needed the printf().

      I did a project with the extended 8051 – two serial ports, a compiler/loader, and an example driver for a polled serial port driver. Wrote my own sprintf(), interrupt-driven serial driver for the other port, then the full app.

      Don’t get me wrong – if you have a good IDE to look at registers, it can really help the productivity. However, I still use a CLI and printf()because they are very useful.

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.