Instagram filter used: Normal
Photo taken at: Tommy Thompson Park
I don’t know how many times I’ve written bad Arduino code to call a function every few milliseconds. Sometimes this bad code works well enough for my sketch to actually work. Often, it either doesn’t work at all or does something I really didn’t expect.
So on Arduino Day 2017, I’m glad I found out about bhagman/MillisTimer: A Wiring and Arduino library for working with millis(). It couldn’t be simpler to use: include the library, write the function you want to call every N milliseconds, set up the timer to run every N millis, and put timer.run() in a loop that’s called frequently. The library handles the timing and resetting all by itself.
As an example, here’s the eternal “Hello, World!†of the embedded world, Blink, rewritten to use MillisTimer:
// MillisTimerBlink - blink LED every second
// using Brett Hagman's MillisTimer library
// https://github.com/bhagman/MillisTimer
// (or use Sketch → Include Library → Manage Libraries … to install)
// scruss - 2017-04-01
#include <MillisTimer.h>
MillisTimer timer1; // new empty timer object
const int led_pin = LED_BUILTIN; // use the built-in LED
void flash() { // function called by timer
static boolean output = HIGH;
digitalWrite(led_pin, output); // set LED on or off
output = !output; // toggle variable state High/Low
}
void setup() {
pinMode(led_pin, OUTPUT); // use built-in LED for output
timer1.setInterval(1000); // set timer to trigger every 1000 millis
timer1.expiredHandler(flash); // call flash() function when timer runs out
timer1.setRepeats(0); // repeat forever if set to 0
timer1.start(); // start the timer when the sketch starts
}
void loop() {
timer1.run(); // trigger the timer only if it has run out
// note that run() has to be called more frequently than the timer interval
// or timings will not be accurate
}
Note that MillisTimer only triggers when timer.run() is called. Sticking a delay(2000) in the main loop will cause it to fire far less frequently than the interval you set. So it’s not technically a true periodic timer, but is good enough for most of my purposes. If you want a true interrupt-driven timer, use the MsTimer2 library. It relies on the timer interrupts built into the Arduino hardware, and isn’t quite as easy to use as MillisTimer.

A fairly accurate rendition of the 5×7 dot matrix font printed at the
top of punched cards by the IBM Type 29 Card Punch (1965).
Local copy: Keypunch029.zip.
Fontlibrary link: Keypunch029
The 029 (as it is sometimes known) generated a bitmap font from an engraved metal plate pressing on a matrix of pins. A picture of this plate from a field engineering manual was used to re-create the pin matrices, and thus an outline font.


The 029 could have many different code plates, but the one used here contained the characters:
<=>¬|_-,;:!?/.'"()@¢$*&#%+0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
The character glyphs have been sized such that if printed at 12 points, the 029’s character pitch of 0.087″ is accurately reproduced. No attempt to research the pin matrix pitch or pin diameter has been made: the spacing was eyeballed from a couple of punched cards in my collection.
The earlier IBM Type 26 Card Punch (“026”) included a glyph for a square lozenge (Unicode U+2311, ⌑). The 029 code plate did not include this character, but I added it here for completeness.
The character set was extended to include:
While there may have been official IBM renditions of some of these additional glyphs (with the exception of euro) no attempt has been made to research the original shapes. This font set is intended to help with the visually accurate reproduction of 1960s-era punched cards, mostly coinciding with my interest in the FORTRAN programming language. No attempt has been made to use historical BCD/EBCDIC encodings in these fonts. We have Unicode now.
The 029 card punch could not produce any bold or italic font variants, but FontForge can, so I did.
Of all the niche blog entries I’ve written, this must be the nichest. I don’t even like the topic I’m writing about. But I’ve worked it out, and there seems to be a shortage of documented solutions.
For the both of you that generate Rich Text Format (RTF) documents by hand, you might be wondering how RTF converts ‘💩’ (that’s code point U+1F4A9) to the seemingly nonsensical \u-10179?\u-9047?. It seems that RTF imposes two encoding limitations on characters: firstly, everything must be in 7-bit ASCII for easy transmission, and secondly, it uses the somewhat old-fashioned UTF-16 representation for non-ASCII characters.
UTF-16 grew out of an early standard, UCS-2, that was all like “Hey, there will never be a Unicode code point above 65536, so we can hard code the characters in two bytes … oh shiiii…â€. So not merely does it have to escape emoji code points down to two bytes using a very dank scheme indeed, it then has to further escape everything to ASCII. That’s how your single emoji becomes 17 bytes in an RTF document.
So here’s a tiny subroutine to do the conversion. I wrote it in Perl, but it doesn’t do anything Perl-specific:
#!/usr/bin/env -S perl -CAS
# emoji2rtf - 2017 - scruss
# See UTF-16 decoder for the dank details
# <https://en.wikipedia.org/wiki/UTF-16>
# run with 'perl -CAS ...' or set PERL_UNICODE to 'AS' for UTF-8 argv
# doesn't work from Windows cmd prompt because Windows ¯\_(ツ)_/¯
# https://scruss.com/blog/2017/03/12/in-the-unlikely-event-you-need-to-represent-emoji-in-rtf-using-perl/
use v5.20;
use strict;
use warnings qw( FATAL utf8 );
use utf8;
use open qw( :encoding(UTF-8) :std );
sub emoji2rtf($);
my $c = substr( $ARGV[0], 0, 1 );
say join( "\t⇒ ", $c, sprintf( "U+%X", ord($c) ), emoji2rtf($c) );
exit;
sub emoji2rtf($) {
my $n = ord( substr( shift, 0, 1 ) );
die "emoji2rtf: code must be >= 65536\n" if ( $n < 0x10000 );
return sprintf( "\\u%d?\\u%d?",
0xd800 + ( ( $n - 0x10000 ) & 0xffc00 ) / 0x400 - 0x10000,
0xdC00 + ( ( $n - 0x10000 ) & 0x3ff ) - 0x10000 );
}
This will take any emoji fed to it as a command line argument and spits out the RTF code:
📓 ⇒ U+1F4D3 ⇒ \u-10179?\u-9005? 💽 ⇒ U+1F4BD ⇒ \u-10179?\u-9027? 🗽 ⇒ U+1F5FD ⇒ \u-10179?\u-8707? 😱 ⇒ U+1F631 ⇒ \u-10179?\u-8655? 🙌 ⇒ U+1F64C ⇒ \u-10179?\u-8628? 🙟 ⇒ U+1F65F ⇒ \u-10179?\u-8609? 🙯 ⇒ U+1F66F ⇒ \u-10179?\u-8593? 🚥 ⇒ U+1F6A5 ⇒ \u-10179?\u-8539? 🚵 ⇒ U+1F6B5 ⇒ \u-10179?\u-8523? 🛅 ⇒ U+1F6C5 ⇒ \u-10179?\u-8507? 💨 ⇒ U+1F4A8 ⇒ \u-10179?\u-9048? 💩 ⇒ U+1F4A9 ⇒ \u-10179?\u-9047? 💪 ⇒ U+1F4AA ⇒ \u-10179?\u-9046?
Just to show that this encoding scheme really is correct, I made a tiny test RTF file unicode-emoji.rtf that looked like this in Google Docs on my desktop:

It looks a bit better on my phone, but there are still a couple of glyphs that won’t render:

Update, 2020-07: something has changed in the Unicode handling, so I’ve modified the code to expect arguments and stdio in UTF-8. Thanks to Piyush Jain for noticing this little piece of bitrot.
Further update: Windows command prompt does bad things to arguments in Unicode, so this script won’t work. Strawberry Perl gives me:
perl -CAS .\emoji2rtf.pl ☺
emoji2rtf: code must be >= 65536; saw 63
I have no interest in finding out why.
(to explain this: Origin of a geometric tile design pattern?)
If you try to run the (unmodified) BASIC code for Oregon Trail (1975) on PDP-8 BASIC, you get this:
DI 30 XC 45 XC 205 … IF 700 NM 730 … (many, many more lines …)
I thought at first it was a stack trace, but nope — it’s error messages! You need to dig through your trusty language manual, and on page 132 it has a table to explain:
DI ERROR IN DIM STATEMENT IF ERROR IN IF STATEMENT NM MISSING LINE NUMBER XC CHARS AFTER END OF LINE
(and yes, they’re in all-caps. Mixed case? Mixed feelings!)
So whenever Python throws a tantrum (or as it calls it, an exception) and wails at length about its problems, remember PDP-8 BASIC: Two letters + a line number. That’s all.
On FontLibrary: PoorFish
Local copy: PoorFish.zip
Full Language Support: Afrikaans, Baltic, Basic Latin, Catalan, Central European, Dutch, Esperanto, Euro, Turkish, Western European. Terrible kerning comes free.
(original version from 2010: PoorFish)