How to Build a Little Box of Poems

I wanted to build a little internet printer, spewing out weather and tweets and the like. When I was testing my thermal printer, however, I got bored reading sample text and replaced it with a short poem. And that gave me an idea: why not make a self-contained box that just prints a random poem when you press a button?

A few people seem to really like the idea, especially those working in education. It could be a great school project combining four different subjects: Science/Phyisics (the electronics and circuit wiring – why is a resistor needed? How can you supply the correct voltage & current to both Arduino and printer from 1 power supply?), ICT (programming the Arduino), DT (making the box) and English (get your class hunting for great, short poems, or better still get them writing their own Imagist poems, limericks or haikus).

You will need:

  • An Arduino Uno or similar. A starter kit would contain some of the other bits you need, eg http://proto-pic.co.uk/arduino-starter-kit/ (roughly £40 for a kit, about £20 for a bare Arduino)
  • A thermal printer such as http://proto-pic.co.uk/thermal-printer/ (about £40)
  • A 10 Ω resistor (may be in Arduino kit)
  • some wires (ditto)
  • a push button (ditto)
  • something to power the printer and the Arduino – the printer needs a hefty power supply that can provide between 5 and 9 volts at at least 1.5 amps. The Arduino needs a similar voltage but takes much less current.
  • a computer to program your Arduino running version 1.0 or above of the Arduino software, and a USB lead (only needed when you make it)
  • some till roll – either this http://proto-pic.co.uk/thermal-printer-paper-34/ or buy some from Ryman’s or another office supply store, and spool some off so the roll fits.
  • some short poems
  • a box to put it in – I used a Fairy washing tablet box made of strong cardboard.
  • Little Box of Poems - work in progress

When you get your printer, connect a suitable power supply insert the paper and test it by turning it on when you hold down the button. You should see a test pattern that tells you the baud rate of your printer. (Baud is a measure of how fast data is sent over a serial connection). It should look like this:

It prints!

If the baud rate is anything other than 19200 you need to tweak a number in my code, and in the Adafruit Thermal library – that’s a bunch of code that makes it easier to tell your printer what to do. They have instructions on their web site for how to install it. It’s essential.

Here’s how I wired it together, combining the sample Arduino button sketch with the Adafruit thermal printer example:

box-of-poems-diagram

I used a tiny breadboard that I got with my Arduino kit to test the code – it connects a small black push button via a resistor. I later replaced the small black button with a huge red button that I fitted to the top of the box.

I powered my Arduino by USB, either from a computer or from an iPhone charger, and I used a separate 5v 2A power supply for the printer – I daresay they can be wired so only 1 plug is needed.

Print on button press proof of concept

You can download my Arduino source code here or read it below. There are three files in the zip, the main one is displayed at the foot of this blog post. The other 2 files are logos.

Pome printed by ArduinoFeel free to edit it with your own choice of poems – I’m not sure how many can be crammed into the Arduino’s tiny memory, but I daresay you can get more in if you remove the graphics – I have a little ‘Blog My Wiki’ logo and a QR code that links to this blog. I used the Adafruit instructions on how to make graphics for the printer – I have to say that using ‘Processing’ to make them worked much better for me than using LCD Assistant. I used a random free web site to make the QR code and carefully resized it in Photoshop and saved it as a PNG.

The poems are split into three arrays – one for title, one for the main text of the poem, and a third for the author. This is because I wanted to print headings, text and footers in diffrent styles, and this seemed the simplest way to do it. ICT challenge: is there a more efficient way to code this?

So wire up the printer and switch to your Arduino. Upload the code, and press. Hopefully you will get a random poem. Rip & read. Share & enjoy.

Injecting a Pi filling to my Box o'Poems

Post-script: December 2012

Thanks to Twitter, The Little Box of Poems inspired Carrie Anne Philbin’s Little Box of Geek – this is a project based on a Raspberry Pi rather than an Arduino. I’ve found that I can only get about a dozen short poems in the Arduino before it starts spewing out gibberish – I’m guessing because it’s running out of memory. Clearly the Raspberry Pi has much more storage by default and, crucially, is easy to get on the internet, so I’m rebuilding my Little Box of Poems with a Raspberry Pi filling. I’ll post my results when I get it working, which shouldn’t take too long thanks to Carrie Anne’s excellent blogposts and videos. Do visit her site and spread the word about her important work which is getting girls into IT. You can follow @GeekGurlDiaries on Twitter.

/*
 Little Box of Poems
 © 2012 Giles Booth
 
 http://www.suppertime.co.uk/blogmywiki
 @blogmywiki

 not for commercial use
 if you modify this code for edcuational or charitable use
 please credit Giles Booth and/or @blogmywiki in printouts
 */

const int buttonPin = 2;     // the number of the pushbutton pin - doesn't change
int currState = 0;           // set variables to hold the state of the button
int prevState = 0;

#include "SoftwareSerial.h"
#include "Adafruit_Thermal.h" // you need to download this and put it in your Arduino library
#include "bmw.h"              // BlogMyWiki logo
#include "qr2.h"              // QR code graphic for my web site
#include <avr/pgmspace.h>     // I have no idea what this does

int buttonState = 0;     // variable for reading the button status
int printer_RX_Pin = 5;  // This is the green printer wire
int printer_TX_Pin = 6;  // This is the yellow printer wire

Adafruit_Thermal printer(printer_RX_Pin, printer_TX_Pin);

void setup() {
  pinMode(buttonPin, INPUT);
  Serial.begin(19200);   // this is the baud rate of your printer - may vary
  pinMode(7, OUTPUT); digitalWrite(7, LOW);
  printer.begin();
}

void loop(){
  // read the state of the button:
  currState = digitalRead(buttonPin);
  if (currState != prevState)   // if something has changed, do something
{
  if (currState == HIGH) {
    printPoem();
  }
  else {
    // if you want something to happen when the button is released, put it here
    // such as a beep, or a display saying 'your poem is on its way'
  }
prevState = currState;
}
}

void printPoem(){

  // put poem titles in order in here  
  char* myTitles[]={"In a Station of the Metro","This is just to say","Surprise","Moment","The Sick Rose","Women, Wine and Snuff"};

  // put poems in here in order
  // they must all be on the same line, in double quotes, separated by commas
  // use \n for a new line and \" to escape a quotation mark
  char* myPoems[]={"The apparition of these faces in the crowd;\nPetals on a wet, black bough.", "I have eaten\nthe plums\nthat were in\nthe icebox\n\nand which\nyou were probably\nsaving\nfor breakfast\n\nForgive me\nthey were delicious\nso sweet\nand so cold", "I lift the toilet seat\nas if it were the nest of a bird\nand i see cat tracks\nall around the edge of the bowl.",
"Clear moments are so short.\nThere is much more darkness.More\nocean than terra firma. More\nshadow than form.", "O rose, thou art sick!\nThe invisible worm,\nThat flies in the night,\nIn the howling storm,\n\nHas found out thy bed\nOf crimson joy,\nAnd his dark secret love\nDoes thy life destroy.","Give me women, wine and snuff\nUntil I cry out,\n\"hold, enough!\"You may do so sans objection\nTill the day of resurrection;\nFor, bless my beard, they aye shall be\nMy beloved Trinity."};

  // put author names & dates here, in order
  char* myAuthors[]={"Ezra Pound","William Carlos Williams","Richard Brautigan","Adam Zagajewski","William Blake","John Keats"};

  int poemChoice = random(0, 6);  // choose a random poem number between 0 and 5

  printer.doubleHeightOn();
  printer.println(myTitles[poemChoice]);
  printer.doubleHeightOff();
  printer.boldOn();
  printer.println(myPoems[poemChoice]);
  printer.boldOff();
  printer.justify('R');
  printer.println(myAuthors[poemChoice]);
  printer.justify('L');

  printer.printBitmap(bmw_width, bmw_height, bmw_data);    // print Blog My Wiki logo    
  printer.printBitmap(qr2_width, qr2_height, qr2_data);    // print QR code graphic
  printer.boldOn();
  printer.println("The Little Box of Poems");
  printer.boldOff();
  printer.setSize('S');     // Setting the size adds a linefeed
  printer.println("www.suppertime.co.uk/blogmywiki");
  printer.println("@blogmywiki");
  printer.feed(3);

  delay(2000);   // 2 second pause to help prevent multiple presses     
}
This entry was posted in Arduino, education, ICT, literature, poetry and tagged . Bookmark the permalink.

6 Responses to How to Build a Little Box of Poems

  1. Pingback: MAKE | Thermal Printer Outputs Poems

  2. Pingback: Thermal Printer Outputs Poems

  3. Pingback: Little Box of Poems with a Raspberry Filling | Blog My Wiki!

  4. Pingback: Raspberry Pi & Arduino powered box of Poems | GeekBoy.it

  5. Alex Green says:

    Hi,

    Ive tried running your code and it seems to not understand a lot of it. i have the adafruit library.

    Firstly it has a problem with this line saying it has no matching function.
    Adafruit_Thermal printer(printer_RX_Pin, printer_TX_Pin);

    Then throughout the code for the poems it doesn’t recognise the printer command.

    I really like the project and hopefully if i can get this working i can adapt it. I’m pretty new to all this so don’t feel like you are patronising me when explaining things!

    Thanks,
    Alex

  6. Trey Hackman says:

    I can’t seem to make this work. I am confused why you put pinmode(7,OUTPUT) when you never used pin 7 on the arduino?

Leave a Reply to Alex Green Cancel reply