<?xml version="1.0" encoding="utf-8"?>
<feed version="0.3" xmlns="http://purl.org/atom/ns#">
<link rel="alternate" type="text/html" href="https://gamma.unpythonic.net/"/>

<title>Jeff Epler's blog</title>
<modified>2021-10-30T21:12:03Z</modified>
<tagline>Photos, electronics, cnc, and more</tagline>
<author><name>Jeff Epler</name><email>jepler@unpythonic.net</email></author>
<entry>
<title>Use printf() in Arduino programs</title>
<issued>2021-10-30T21:12:03Z</issued>
<modified>2021-10-30T21:12:03Z</modified>
<id>https://gamma.unpythonic.net/01635628323</id>
<link rel="alternate" type="text/html" href="https://gamma.unpythonic.net/01635628323"/>
<content type="text/html" mode="escaped">


&lt;p&gt;Are you happiest with printf() debugging?  Do circumstances lead to you
writing &amp;quot;arduino code&amp;quot; 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.

&lt;p&gt;I've only tested it on a sample of 1 board (the &lt;a href=&quot;https://www.adafruit.com/product/3857&quot;&gt;Adafruit Feather
M4 Express&lt;/a&gt;) but I suspect that
it works on a wide variety of &lt;strong&gt;arm-based&lt;/strong&gt; (or, actually,
newlib-based) boards.

&lt;p&gt;Long story short, put the following code in your &lt;strong&gt;.ino&lt;/strong&gt;
file, call &lt;code&gt;Serial.begin()&lt;/code&gt; as usual, then use 
&lt;code&gt;printf(...)&lt;/code&gt; and &lt;code&gt;fprintf(stderr, ...)&lt;/code&gt; just
like you would anywhere.  The only caveat I've discovered so far is that
printing floating-point numbers didn't work for me.

&lt;p&gt;&lt;pre&gt;
// This bridges from stdio output to Serial.write
#include &amp;lt;errno.h&amp;gt;
#undef errno
extern int errno;
extern &quot;C&quot; int _write(int file, char *ptr, int len);
int _write(int file, char *ptr, int len) {
    if (file &amp;lt; 1 || file &gt; 3) {
        errno = EBADF;
        return -1;         
    }                
     
    if (file == 3) { // File 3 does not do \n -&gt; \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(&quot;\033[95m&quot;);
        } else {
            Serial.write(&quot;\033[0m&quot;);
        }
        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 &quot;C&quot; int write(int file, char *ptr, int len);
int write(int file, char *ptr, int len) __attribute__((alias(&quot;_write&quot;)));
&lt;/pre&gt;
</content>
</entry>
<entry>
<title>Towards fast I/O in Arduino for AVRs</title>
<issued>2014-04-30T21:14:10Z</issued>
<modified>2014-04-30T21:14:10Z</modified>
<id>https://gamma.unpythonic.net/01398892450</id>
<link rel="alternate" type="text/html" href="https://gamma.unpythonic.net/01398892450"/>
<content type="text/html" mode="escaped">

So I've been working on something.  I've only looked at assembler output so far,
but it looks right and promising.

&lt;p&gt;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.

&lt;p&gt;All instruction counts are in Debian Wheezy's avr-gcc version 4.7.2 with 
&lt;tt&gt;-mmcu=atmega328p -Os&lt;/tt&gt; specified on the commandline.
&lt;pre&gt;
// You can declare ports (they use zero RAM)
typedef IOPIN&amp;lt;PORT_B, 0&amp;gt; iob0;
typedef IOPIN&amp;lt;PORT_B, 1&amp;gt; iob1;
typedef OCPIN&amp;lt;PORT_B, 1, true&amp;gt; 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); }
&lt;/pre&gt;

&lt;p&gt;&lt;p&gt;&lt;b&gt;Files currently attached to this page:&lt;/b&gt;
&lt;table cellpadding=5 style=&quot;width:auto!important; clear:none!important&quot;&gt;&lt;col&gt;&lt;col style=&quot;text-align: right&quot;&gt;&lt;tr bgcolor=#eeeeee&gt;&lt;td&gt;&lt;a href=&quot;https://media.unpythonic.net/emergent-files/01398892450/fast_io_prototype.cpp&quot;&gt;fast_io_prototype.cpp&lt;/a&gt;&lt;/td&gt;&lt;td&gt;6.2kB&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;
</content>
</entry>
<entry>
<title>Hash saturation calculator</title>
<issued>2013-01-14T13:42:33Z</issued>
<modified>2013-01-14T13:42:33Z</modified>
<id>https://gamma.unpythonic.net/01358170953</id>
<link rel="alternate" type="text/html" href="https://gamma.unpythonic.net/01358170953"/>
<content type="text/html" mode="escaped">
In the quest to &amp;quot;prove&amp;quot; the quality of the numbers output by my &lt;a href=&quot;https://gamma.unpythonic.net/01257868826&quot;&gt;Arduino Random Number Generator&lt;/a&gt;, I've come across
the concept of &lt;a href=&quot;http://www.av8n.com/turbid/paper/turbid.htm#sec-saturation&quot;&gt;hash
saturation&lt;/a&gt; while reading about the &lt;a href=&quot;http://www.av8n.com/turbid&quot;&gt;turbid&lt;/a&gt; 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.</content>
</entry>
<entry>
<title>Towards my GPS LED Light Clock</title>
<issued>2011-06-22T20:19:10Z</issued>
<modified>2011-06-22T20:19:10Z</modified>
<id>https://gamma.unpythonic.net/01308773950</id>
<link rel="alternate" type="text/html" href="https://gamma.unpythonic.net/01308773950"/>
<content type="text/html" mode="escaped">
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.

&lt;p&gt;However, the design has two main problems:</content>
</entry>
<entry>
<title>Red Alert Box</title>
<issued>2009-01-31T16:29:41Z</issued>
<modified>2009-01-31T16:29:41Z</modified>
<id>https://gamma.unpythonic.net/01233419381</id>
<link rel="alternate" type="text/html" href="https://gamma.unpythonic.net/01233419381"/>
<content type="text/html" mode="escaped">&lt;div style=&quot;float:right;clear:right&quot;&gt;&lt;!-- ohno.jpg--&gt;&lt;div class=albumouter style=width:306px id=&gt;&lt;div class=albumimage style=&quot;width:306px;margin-left:0.0px;&quot;&gt;&lt;a href=&quot;https://media.unpythonic.net/emergent-files/01233419381/ohno-medium.jpg&quot; class=&quot;thickbox&quot; rel=&quot;album&quot; title=&quot;Oh no, vmware crashed again&quot;&gt;&lt;img src=&quot;https://media.unpythonic.net/emergent-files/01233419381/ohno-small.jpg&quot; width=300 height=210&gt;&lt;/a&gt;&lt;div &gt;&lt;div style=&quot;float: right&quot; &gt;&lt;a href=&quot;https://media.unpythonic.net/emergent-files/01233419381/ohno-medium.jpg&quot;&gt;(M)&lt;/a&gt;&lt;a href=&quot;https://media.unpythonic.net/emergent-files/01233419381/ohno.jpg&quot;&gt;(L)&lt;/a&gt;&lt;/div&gt;&lt;a href=&quot;https://media.unpythonic.net/emergent-files/01233419381/ohno.jpg&quot;&gt;Oh no, vmware crashed again&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
Every morning I get up too late, and then I think to myself &amp;quot;I'll just check
real quick to see that everything on my home network is running&amp;quot;.  45 minutes
later I've browsed all the new &lt;a href=&quot;http://icanhascheezburger.com/&quot;&gt;lolcats&lt;/a&gt; and read a few personal trainwreck posts on &lt;a href=&quot;http://ask.metafilter.com&quot;&gt;askme&lt;/a&gt;, and now I'm running really late.

&lt;p&gt;This is the kind of problem we can solve with technology!</content>
</entry>
<entry>
<title>Improved Analog & Digital Interface with Arduino</title>
<issued>2007-12-25T14:51:34Z</issued>
<modified>2007-12-25T14:51:34Z</modified>
<id>https://gamma.unpythonic.net/01198594294</id>
<link rel="alternate" type="text/html" href="https://gamma.unpythonic.net/01198594294"/>
<content type="text/html" mode="escaped">
&lt;div style=&quot;float:right;clear:right&quot;&gt;&lt;!-- arduino-vcp.png--&gt;&lt;div class=albumouter style=width:306px id=&gt;&lt;div class=albumimage style=&quot;width:306px;margin-left:0.0px;&quot;&gt;&lt;a href=&quot;https://media.unpythonic.net/emergent-files/01198594294/arduino-vcp-medium.png&quot; class=&quot;thickbox&quot; rel=&quot;album&quot; title=&quot;Arduino Virtual Control Panel&quot;&gt;&lt;img src=&quot;https://media.unpythonic.net/emergent-files/01198594294/arduino-vcp-small.png&quot; width=300 height=52&gt;&lt;/a&gt;&lt;div &gt;&lt;div style=&quot;float: right&quot; &gt;&lt;a href=&quot;https://media.unpythonic.net/emergent-files/01198594294/arduino-vcp-medium.png&quot;&gt;(M)&lt;/a&gt;&lt;a href=&quot;https://media.unpythonic.net/emergent-files/01198594294/arduino-vcp.png&quot;&gt;(L)&lt;/a&gt;&lt;/div&gt;&lt;a href=&quot;https://media.unpythonic.net/emergent-files/01198594294/arduino-vcp.png&quot;&gt;Arduino Virtual Control Panel&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;float:right;clear:right&quot;&gt;&lt;!-- ArduinoDiecimila400.jpg--&gt;&lt;div class=albumouter style=width:306px id=&gt;&lt;div class=albumimage style=&quot;width:306px;margin-left:0.0px;&quot;&gt;&lt;a href=&quot;https://media.unpythonic.net/emergent-files/01198594294/ArduinoDiecimila400-medium.jpg&quot; class=&quot;thickbox&quot; rel=&quot;album&quot; title=&quot;Arduino Diecimila board&quot;&gt;&lt;img src=&quot;https://media.unpythonic.net/emergent-files/01198594294/ArduinoDiecimila400-small.jpg&quot; width=300 height=230&gt;&lt;/a&gt;&lt;div &gt;&lt;div style=&quot;float: right&quot; &gt;&lt;a href=&quot;https://media.unpythonic.net/emergent-files/01198594294/ArduinoDiecimila400-medium.jpg&quot;&gt;(M)&lt;/a&gt;&lt;a href=&quot;https://media.unpythonic.net/emergent-files/01198594294/ArduinoDiecimila400.jpg&quot;&gt;(L)&lt;/a&gt;&lt;/div&gt;&lt;a href=&quot;https://media.unpythonic.net/emergent-files/01198594294/ArduinoDiecimila400.jpg&quot;&gt;Arduino Diecimila board&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
Building on my &lt;a href=&quot;https://gamma.unpythonic.net/01198525592&quot;&gt;earlier work&lt;/a&gt;, I've now improved
the interface between HAL and &lt;a href=&quot;http://arduino.cc&quot;&gt;the Arduino board&lt;/a&gt;
to have:
&lt;ul&gt;&lt;li&gt;6 10-bit analog inputs&lt;/li&gt;&lt;/ul&gt;
&lt;ul&gt;&lt;li&gt;6 8-bit PWM &amp;quot;analog&amp;quot; outputs&lt;/li&gt;&lt;/ul&gt;
&lt;ul&gt;&lt;li&gt;6 digital inputs/outputs (partition chosen when component is loaded)&lt;/li&gt;&lt;/ul&gt;
&lt;ul&gt;&lt;li&gt;GPL license statement in source files&lt;/li&gt;&lt;/ul&gt;
As before, the driver consists of an Arduino Sketch (&lt;a href=&quot;https://media.unpythonic.net/emergent-files/01198594294/halintf.pde&quot;&gt;halintf.pde&lt;/a&gt;)
and a HAL Userspace Component written in Python (&lt;a href=&quot;https://media.unpythonic.net/emergent-files/01198594294/arduino.py&quot;&gt;arduino.py&lt;/a&gt;).</content>
</entry>
</feed>
