Overview

An accessory to an alarm clock which prints out nice quotes in response to sensing the sound of an alarm.

A more in-depth video of the full functionality, including responsiveness to sound:

 

A video of the final project:

 

Featured image of the overall project.

 

Detail shot 1: Thermal printer which uses heat (as one might expect) to print text onto a roll of receipt paper.

 

Detail shot 2: SD card for storing large sets of data (text, in this case).

 

Detail shot 3: Microphone to sense input sound.

 

Usage shot 1: Alarm clock sits comfortably beside the box; with clock speakers next to the microphone.

 

Usage shot 2: Speaker against the clock.

Process images and review

One pivot point was deciding how to import a large-ish amount of data into the Arduino. Rather than storing all the string data on the Arduino’s tiny brain, I split my Google doc full of quotes (perpetually accumulating) into many little .txt files with a Python script.

Decision point 1: Quotes and a quote splitter.

Another pivot point was when I realized my dxf for the wooden box didn’t have a kern that allowed press-fitting. I considered recutting and perhaps modulating the design of the final product, but owing to the time constraints, I ended up rapidly locating wood glue and gluing my box together, hoping it would cure overnight (and it mostly did!)

Decision point 2: Having to construct a box with wood glue.

Additionally, here are a few more pictures of the process:

The first successful run of the printer!

 

…and a buggy run of the printer when trying to sort out multiple serial ports. It’s modern art?

 

The SVG for the graphics on top of the box that I then laser cut!

Discussion

“I wonder if there is a place that already has a “hub” of positive messages that you could source from, that way it could be more of a surprise for you?”

I really like the idea of the messages being pleasant surprises. However, I feel like the large hubs of positive quotes that I might find online would be those really cheesy, hashtag-inspirational ones that are nice but somewhat grating and simplistic. This does spawn another idea, though. I have most of my conversations with my partner over Discord (…haha) and Discord has a really solid and in-depth data request system, so I think I could do some text parsing to create little snippets from nice past conversations that I could randomly output every morning. That would fulfill all the personal, warm, and random categories.

“The printing format is super flexible and lets you print everything from jokes and riddles to memories and reminders.”

I like it too—I think if I were to continue developing this work, a large part would be increasing the diversity of the text repository. Another critiquer mentioned the receipts as a way to get news or weather so that he might check his phone less in the mornings, and I also like that intention.

Overall, I am moderately happy with how the project came out. I got burnt-out/sick during the middle of it, losing some momentum, and also realized that I would have to purchase ~$100 worth of materials (plus replenishing the receipt paper regularly) in order to keep using the project, which kind of deterred me from being as invested in the final product. I think the final product’s physical fabrication is a little shaky, and I would like to get better at this aspect of physical computing. However, I like the artistic implications of the project and the organic touches that I added to it. The process of crowdsourcing poetry and chopping it up into little bits was therapeutic, especially knowing that I would have something that I could hold in my hands at the end of it. Really though, my favorite parts of this project involved community, i.e., learning people’s favorite poems or handing out the “test cases” and seeing people’s faces light up with joy.

I found some limitations in knowledge when I spent an embarrassing amount of time in the laser room trying to piece my box together around my project. I would like to get better at CAD so I can create nicer, organic forms. I also hit some roadblocks with maintaining two separate serial communication lines (with the SoftwareSerial library, which turns any pair of digital pins into data RX/TX lines)—one for debugging, and another for the thermal printer. And I had a weirdly hard time trying to figure out how to convert ints to strings because it’s different for C, normal C++, and Arduino C++?

I am not sure if I want to invest in another, long-term version of this project, but if I were to, there are a few things I would do differently. I’d probably make the speaker a little more sturdy—perhaps panel mounted with a hood above it so it stays in place nicely and outside sound doesn’t interfere as much. I’d probably manipulate the strings a little better so words don’t break in the middle (the printer seems to simply split strings into new lines wherever the receipt isn’t wide enough). I’d also position the printer a bit more nicely, so the receipt paper is closer to the top of the box and feeding and tearing it out is easier.

Technical information

 

Block diagram

Schematic

Code:

/*------------------------------------------------------------------------
Copyright 2021 Shenai Chan

Permission is hereby granted, free of charge, to any person obtaining a 
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation 
the rights to use, copy, modify, merge, publish, distribute, sublicense, 
and/or sell copies of the Software, and to permit persons to whom the 
Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included 
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 
IN THE SOFTWARE.
--------------------------------------------------------------------------*/

/*------------------------------------------------------------------------
Description:
Data is read into the Arduino by way of a micro SD card reader and printed
onto a receipt with a thermal printer when the appropriate threshold of 
sound is reached (as detected by sound detector).
--------------------------------------------------------------------------*/

/*------------------------------------------------------------------------
Connections:
Printer RX              <-->  6 Output
Printer TX              <-->  5 Input
SD MOSI                 <--> 11 Input
SD MISO                 <--> 12 Input
SD CLK                  <--> 13 Input
SD CS                   <-->  4 Input
Sound Detector Gate     <-->  2 Input
Sound Detector Envelope <--> A0 Input
--------------------------------------------------------------------------*/

// Initializing the printer:

#include "Adafruit_Thermal.h"

// Creating a separate serial channel for the printer specifically
// to talk to the Arduino
#include "SoftwareSerial.h"
#define TX_PIN 6 // Arduino transmit  YELLOW WIRE  labeled RX on printer
#define RX_PIN 5 // Arduino receive   GREEN WIRE   labeled TX on printer

SoftwareSerial mySerial(RX_PIN, TX_PIN); // Declare SoftwareSerial obj first
Adafruit_Thermal printer(&mySerial);     // Pass addr to printer constructor

/*-----------------------------------------------------------------------*/

// Initializing the SD card:

#include <SPI.h>
#include <SD.h>

const int chipSelect = 4;

/*-----------------------------------------------------------------------*/

// Initializing the sound detector connections

#define PIN_GATE_IN 2
#define PIN_ANALOG_IN A0

/*-----------------------------------------------------------------------*/

// Timer variables

unsigned long timer = 0;
const int wait = 5000;

/*-----------------------------------------------------------------------*/

void setup() {

  mySerial.begin(19200);  // Initialize SoftwareSerial
  printer.begin();        // Init printer (same regardless of serial type)
  
  // Open serial communications and wait for port to open:
  Serial.begin(19200);

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1);
  }
  Serial.println("card initialized.");

  // init pin for sound detector
  pinMode(PIN_GATE_IN, INPUT);
  
  delay(10000);

}

void loop() {
  int value;

  // Check the envelope input
  value = analogRead(PIN_ANALOG_IN);

  // Convert envelope value into a message
  Serial.print("Status: ");
  Serial.println(value);
  delay(1000);

  // If sound is loud enough
  if (value >= 20) {
    // and it's been long enough since the last printing
    if ((millis() - timer) >= wait) {
      timer = millis();
      int i = random(0, 19);

      // take a random .txt file
      String path = "text" + String(i, DEC) + ".txt";
      File myFile = SD.open(path);
      String text = "";

      // and print it
      if (myFile) { 
        while (myFile.available()) { //execute while file is available
          char letter = myFile.read(); //read next character from file
          text += letter;
        }
        myFile.close(); //close file
        printer.println("");
        printer.println(text);
        printer.println("");
      }
      else {
          Serial.println("error opening "+path);
      }
    }
  } 
}