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]

30 April 2014, 21:14 UTC

Towards fast I/O in Arduino for AVRs


So I've been working on something. I've only looked at assembler output so far, but it looks right and promising.

Basically, I'd like to let you name I/O pins via typedef, then efficiently read and write the pins. And I'd like to make Arduino's digitalWrite just as efficient when the pin argument is a constant.

All instruction counts are in Debian Wheezy's avr-gcc version 4.7.2 with -mmcu=atmega328p -Os specified on the commandline.

// You can declare ports (they use zero RAM)
typedef IOPIN<PORT_B, 0> iob0;
typedef IOPIN<PORT_B, 1> iob1;
typedef OCPIN<PORT_B, 1, true> ocb1; // emulate an open collector port

// .. and use them efficiently (instruction counts never include ret)
int en() { iob0::output(); }                // 1 instruction
int fn() { iob0::toggle(); }                // 1 instruction
int gn() { ocb1::set(); }                   // 2 instructions
int hn() { ocb1::clear(); }                 // 2 instructions
int jn(bool b) { iob0::write(b); }          // 5 instructions
int kn() { iob0::write(1); }                // 1 instruction

// you can use fastDigitalWrite just like digitalWrite (but faster and inline)
int c(int i) { fastDigitalWrite(1, i); }    // 5 instructions
int d() { fastDigitalWrite(1, 1); }         // 1 instruction

// these have a variable port so they still turn into calls to digitalWrite
int a(int i, int j) { fastDigitalWrite(i, j); }
int b(int i) { fastDigitalWrite(i, 1); }

Files currently attached to this page:

fast_io_prototype.cpp6.2kB

[permalink]

14 January 2013, 13:42 UTC

Hash saturation calculator


In the quest to "prove" the quality of the numbers output by my Arduino Random Number Generator, I've come across the concept of hash saturation while reading about the turbid random number generator which uses noise plus hash to give high quality random numbers. Implicitly I've relied on hash saturation all along, but now I have is a mathematical basis for this reliance.

read more…

22 June 2011, 20:19 UTC

Towards my GPS LED Light Clock


A few years ago, I made a CCFL light clock using an Arduino with a custom shield containing a transformer (to get a reliable 60Hz timebase) and a triac (for solid-state switching of the lamp). By having a simple 7-day alarm calendar (set at compile time), the clock seldom requires interaction except for the reading lamp function.

However, the design has two main problems:

read more…

31 January 2009, 16:29 UTC

Red Alert Box


Every morning I get up too late, and then I think to myself "I'll just check real quick to see that everything on my home network is running". 45 minutes later I've browsed all the new lolcats and read a few personal trainwreck posts on askme, and now I'm running really late.

This is the kind of problem we can solve with technology!

read more…

25 December 2007, 14:51 UTC

Improved Analog & Digital Interface with Arduino


Building on my earlier work, I've now improved the interface between HAL and the Arduino board to have:
  • 6 10-bit analog inputs
  • 6 8-bit PWM "analog" outputs
  • 6 digital inputs/outputs (partition chosen when component is loaded)
  • GPL license statement in source files
As before, the driver consists of an Arduino Sketch (halintf.pde) and a HAL Userspace Component written in Python (arduino.py).

read more…

All older entries
Website Copyright © 2004-2024 Jeff Epler