The most important canine in the history of UNIX is called biff, and its name was used to name the program which notifies users of incoming mail. The biff program notifies the user's terminal when it is told to do so by the comsat server process after receiving a report of incoming mail.

With the advent of Web-based and desktop e-mail clients, the popularity of biff has diminished as these systems usually have some other way of notifying a user of new mail. Even so, as a first little Arduino project, I've created an alternative biff-like system in the form of a US letter box. (Some more examples).

I want to keep this simple, concentrating on trying to understand what the Arduino is capable of, and looking into doing fun things with it.

Even though I have an Ethernet shield for my Arduino, I'm using a serial connection here, which many will prefer, as it lowers the cost of the total setup. Speaking of which, here is what I used:

  • Arduino Duemillanove, but any other board will suffice.
  • An inexpensive 5V servo motor.
  • Four (4) LEDs, any colour.
  • Piezzo buzzer.
  • Half a bar of white chocolate.

Depending on what type of e-mail setup you have, there are a number of ways how to determine you have new messages (i.e. unread e-mail) in your mail box. You'd have to modify this portion if you want, for example, to find out how many unread messages you have in Apple's, Outlook, or whichever.

On UNIX these two are typical:

  1. With a trivial comsat-type daemon you run on UNIX/Linux. This UDP-based service is sent a UDP datagram by a mail delivery agent as soon as your (and anybody else's) mailbox on the system gets a message deposited on it. Note, that you'll be able to use this only if you don't already use a system-wide comsat service. There are several programs out there which inform comsat of new mail: one of these, is the versatile procmail delivery agent.

  2. I'll be discussing a small Perl program which queries your IMAP account to determine the number of unread messages waiting for you.

If you've been following closely, you'll have noticed there is a fundamental difference between these two methods. Using comsat, we are informed that one (1) new message has arrived each time it arrives, whereas the second, gives us a total count of unread messages each time we query the server. Keep this in mind for now, and we'll see later, how I handle this. (I'll be using a "protocol" to tell the Arduino whether to increment or to set the count of unread messages.)

This is what the finished "product" looks like:

The biff machine consists of the parts stuffed into a box. My young "art designer" was responsible for the colours. :-)

The sketch running on the Arduino handles the serial communication, reading a line of text (using the Arduino String library) from the serial connection, incrementing or setting the message counter depending on whether the input line starts with a "+" or "=" respectively. If the unread count is non-zero, the letterbox "arm" is raised, and the unread count is displayed in binary on the four LEDs. (You can use more if you like -- simply change the definition of BITS to match.) Note that I force the unread count to the maximum value allowed by BITS to ensure that all LEDs are lit, because an overflow of bits could indicate all LEDs off, even though unread count is set.

/* A Bifferent e-mail monitor 
 * by Jan-Piet Mens
 * April 2009
#define SPEAKERPIN   7
#define SERVOPIN    9
#define NBITS 4
/*  Bit positions        3  2  1  0    */
int ledPins[NBITS] = {   10, 11, 12, 13};

#include <WString.h>
#include <Servo.h> 

Servo myservo;  // create servo object to control a servo 
String cmd = String(60);    // external command to this sketch (i.e. what must we do?)

unsigned int nmails = 0;  // number of unread e-mail messages
boolean flagged = false;  // true if has been flagged

void setup()
  int n;

  digitalWrite(SPEAKERPIN, LOW);

  for (n =0; n < 50; n++) {
    digitalWrite(SPEAKERPIN, HIGH);

  Serial.begin(9600);        // connect to the serial port

  myservo.attach(SERVOPIN);  // attaches the servo to the servo object 
  mailflag(false);          // bring down the flag


void loop()

  if (Serial.available() > 0) {

void serialEvent()
  char ch =;    // get latest character
  if ((ch != '\n') && (ch != '\r') && (ch != 'E')) {
    cmd.append(ch);          // fill cmd line
  else {

void process()
  if (cmd.startsWith("+")) {
    nmails += atoi(cmd + 1);            // increment 
  else if (cmd.startsWith("=")) {
    nmails = atoi(cmd + 1);            // set
  Serial.print("nmails = ");

  if (nmails >= (2 << (NBITS - 1))  ) {    // sanitize value
    nmails = 2 << (NBITS - 1) | 0xFFFF;
  if (flagged == false && nmails > 0) {
    flagged = true;
  if (nmails == 0) {
    if (flagged == true) {
      flagged = false;

  cmd = "";                      // reset command

void showbits(int val)
  int n, bit, leds[NBITS];

  Serial.print("val = ");
  Serial.print("   ");

  for (n = (NBITS - 1); n >= 0; n--) {
    bit = val & 0x01;
    val >>= 1;

    leds[n] = bit;

  for (n = 0; n < NBITS; n++) {
    digitalWrite(ledPins[n], (leds[n]) ? LOW : HIGH);

void mailflag(boolean up) 
  int pos;

  if (up) {
    for(pos = 0; pos < 90; pos += 2) {
  else {
    for(pos = 90; pos>=1; pos -= 2) {

/* swiped from: Melody (cleft) 2005 D. Cuartielles for K3 */
int length = 2; // the number of notes
char notes[] = "gc"; // a space represents a rest
int beats[] = { 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 4 };
int tempo = 300;

void playTone(int tone, int duration) {
  for (long i = 0; i < duration * 1000L; i += tone * 2) {
    digitalWrite(SPEAKERPIN, HIGH);
    digitalWrite(SPEAKERPIN, LOW);

void playNote(char note, int duration) {
  char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C' };
  int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 956 };
  // play the tone corresponding to the note name
  for (int i = 0; i < 8; i++) {
    if (names[i] == note) {
      playTone(tones[i], duration);

void melody() {
  for (int i = 0; i < length; i++) {
    if (notes[i] == ' ') {
      delay(beats[i] * tempo); // rest
    } else {
      playNote(notes[i], beats[i] * tempo);
    // pause between notes
    delay(tempo / 2); 

I tested the sketch with the serial monitor in the IDE, sending it either a +1E (one new message) or something like =5E (a total of five unread messages).

When the Arduino modifies the unread count, it emits a beep on the piezo buzzer; you can make it play a nicer sound, however, if you desire.

The Perl program below connects to the serial proxy on the machine to which my Arduino is connected via USB. The serial proxy translates a TCP connection to a port you specify in serproxy.cfg to a particular serial interface.


use strict;
use IO::Socket;
use Mail::IMAPClient;

my $serproxy_host = "";
my $imap_host = '<your-imap-server>';
my $user = '<you>';
my $password = '<secret>';
my $folder = 'INBOX';

my $imap  = new Mail::IMAPClient(
    'Server' => $imap_host ,
    'User' => $user ,
    'Authmechanism' => 'LOGIN',
    'Password' => $password  ) or die "Unable to connect to imap server\n";

my $socket = IO::Socket::INET->new(PeerAddr => $serproxy_host,
                PeerPort => 5331,
                Proto    => "tcp",
                Type     => SOCK_STREAM)
    or die "Couldn't connect to $serproxy_host:5331 : $@\n";

while (1) {
    $imap->examine($folder) or die "Could not examine: $@\n";
    my @unread = $imap->unseen;
    print "Unread messages: " . ($#unread + 1) . "\n";

    print $socket "=" . ($#unread + 1) . "E";

$imap->disconnect() or die "Unable to disconnect\n";

The wiring on the breadboard isn't difficult, although mine is looks very messy. (Remeber, it is my first time...) Here is the board layout (with one LED only), done with Fritzing (a nice program -- if only I could lay the wires out nicely). You'll notice I'm using the marvellous 1 cent Arduino undershield (Open Source too! :-) ) to fasten the microcontroller to the breadboard.

As far as the "finished" product is concerned, ahem, here are some pictures: first the inside of the box: and then the "biff machine" with a raised flag and showing eleven unread messages: What I've learnt, you ask? Well, quite a bit:

  • Arduino is a huge bit of fun.
  • I need a new pair of eye glasses so that I can correctly identify the teeny tiny little bits and pieces. I'm not kidding.
  • My "enclosure" sucks, and it is a very far cry from professionalism.
Flattr this
Mail, Exim, Linux, IMAP, MacOSX, CLI, and Arduino :: 26 Apr 2009 :: e-mail


blog comments powered by Disqus