Jeff Epler's blog

30 October 2021, 21:12 UTC

Use printf() in Arduino programs


Are you happiest with printf() debugging? Do circumstances lead to you writing "arduino code" because it's just about the easiest way to set up an embedded software project that's not to different from C(++)? I have something for you.

I've only tested it on a sample of 1 board (the Adafruit Feather M4 Express) but I suspect that it works on a wide variety of arm-based (or, actually, newlib-based) boards.

Long story short, put the following code in your .ino file, call Serial.begin() as usual, then use printf(...) and fprintf(stderr, ...) just like you would anywhere. The only caveat I've discovered so far is that printing floating-point numbers didn't work for me.

// This bridges from stdio output to Serial.write
#include <errno.h>
#undef errno
extern int errno;
extern "C" int _write(int file, char *ptr, int len);
int _write(int file, char *ptr, int len) {
    if (file < 1 || file > 3) {
        errno = EBADF;
        return -1;         
    }                
     
    if (file == 3) { // File 3 does not do \n -> \r\n transformation
        Serial.write(ptr, len);
        return len;
    }
     
    // color stderr
    static bool stderr_flag;    
    bool is_stderr = (file == 2);
    if (is_stderr != stderr_flag) {
        if (is_stderr) {
            Serial.write("\033[95m");
        } else {
            Serial.write("\033[0m");
        }
        stderr_flag = is_stderr;
    }

    int result = len;
    for (; len--; ptr++) {
        int c = *ptr;
        if (c == '\n')
            Serial.write('\r');
        Serial.write(c);
    }
    return result;
}

extern "C" int write(int file, char *ptr, int len);
int write(int file, char *ptr, int len) __attribute__((alias("_write")));

[permalink]

All older entries
Website Copyright © 2004-2024 Jeff Epler