Introduction: Mint-Sized Success Meter (quit Smoking!) With Arduino

There comes a time in life to put childish things behind and give up nasty habits. Some, like smoking, can be damn hard without constant encouragement. It was time for me to combine my favorite hobby with my driving goal and make this: The Quit Success Meter! For my other Arduino contraptions, take a look at thoughtfix.com 


Step 1: Parts, Tools, and Component Preparation

The links all go to the components I used in this project.

Main Components:
Arduino Pro Mini 3.3v (8MHz for low power use) - Sparkfun
Nokia 5110 LCD - Adafruit or SparkFun
LiPoly battery and USB charger kit - Sparkfun
ChronoDot RTC - Adafruit
Perma-Proto mint tin board and matching tin - Adafruit

Additional components:
Solid core hookup wire. - Radio Shack
Standoffs and screws (to mount the board in the tin. I used a kit for PC motherboards)
4 pin female header (for the ChronoDot) and 8 pin female header (for the LCD - I cut two pins off a 6 pin) - Adafruit
Two micro switches (one for system power, one for LCD power) - Radio Shack

Tools:
Solder and soldering iron - For this, having a digital station helped a lot. - Radio Shack
Flush/diagonal cutter
Wire stripper
Multimeter - Radio Shack
Dremel rotary tool or other cutting tool. I used a Dremel 4000
Panavise Junior, Helping Hands, or other tool to help soldering. - Radio Shack
FTDI Friend or FTDI Cable (to program the Arduino) - Adafruit
Arduino software.

Build everything on a prototyping board before you even touch the the Perma-Proto board. Worry about the power switches later.

First, assemble the ChronoDot, Arduino Pro Mini, and LiPoly charger according to their own instructions. Use the headers on the top of the LCD (the ones labeled 1-8, not the ones with the text labels) and use a right-angle pin line on the Arduino programming headers so they don't stick up. There is no need to attach headers to the ChronoDot's BAT/32K/SQW/RST pins.

Attach the LiPoly charger board's SYS OUT + pin to the proto boards voltage line and - to the ground line. Connect the Arduino's VCC and GND lines to the positive/negative rails on the proto board.

Step 2: Wiring

The LCD is wired just like Adafruit example code:
Proto board + rail - LCD VCC
Proto board - rail - LCD GND
Arduino pin 3 - LCD reset (RST)
Arduino pin 4 - LCD chip select (CS)
Arduino pin 5 - Data/Command select (D/C)
Arduino pin 6 - Serial data out (DIN)
Arduino pin 7 - Serial clock out (SCLK)
Proto board + rail (optional: adding a switch to this line) - LCD LED

The ChronoDot uses the I2C lines: A4 and A5. On the Arduino Pro Mini, those are not attached to the standard pin lines but are broken out into adjacent pins. The photo shows the location of the lines from the under side.

Arduino A4: ChronoDot SDL
Arduino A5: ChronoDot SCL
Power line: ChronoDot VCC
Ground line: ChronoDot GND

Step 3: Arduino Code

There are three additional libraries required to get this running:
Time
Adafruit_GFX
Adafruit_PCD8544

The code was HEAVILY inspired by the Maker Faire Bay Area countdown timer by MaceTech, through whom you can also get the latest ChronoDot. The .ino file is attached (Arduino 1.0 required) and the raw code is below.

In this example, the quit date is April 1, 2012. In reality, the quit date is April 14, 2012 but that's in the future. The best way to test this is to wire up everything, but test the individual components (ChronoDot, LCD) with their example code before trying to put it all together. 

/*
Smoke-free success timer
Using a ChronoDot and a Nokia 5110 LCD.

Time library, Adafruit PCD libraries, RTC and Wire required.

The purpose of this sketch is to show a new non-smoker
how long they have been without cigarettes in days and
hours and a constantly growing number of the amount of
money saved by not smoking.

Much of the code was inspired by the Maker Faire Bay
Area countdown clock posted at
http://macetech.com/blog/node/115

April 2012, Daniel Gentleman, thoughtfix.com
*/

#include <Wire.h>
#include <Time.h>
#include <DS1307RTC.h> // DS3231/ChronoDot works like DS1307

// LCD stuff:
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>


Adafruit_PCD8544 display = Adafruit_PCD8544(7, 6, 5, 4, 3);

// pin 7 - Serial clock out (SCLK)
// pin 6 - Serial data out (DIN)
// pin 5 - Data/Command select (D/C)
// pin 4 - LCD chip select (CS)
// pin 3 - LCD reset (RST)

// Setting variables:
time_t quit; // Day/Time of the last smoke
time_t difftime; // difference between current and quitting time
int diff_seconds;
int diff_minutes;
int diff_hours;
int diff_days;
float PackCost = 6.50; // Cost per pack. US $6.50
float PackDay = 1.5; // Smoking frequency. 1.5 packs/day
float MinutesQuit;
float CostPerHour;
float CashSaved;

// Initialize RTC and LCD
void setup() {
  Serial.begin(9600); // set baud to 9600
  display.begin();
  display.setContrast(40);
  display.clearDisplay();
  display.display();
  setSyncProvider(RTC.get); // set sync to use the ChronoDot
  setSyncInterval(10); // sync every 10 seconds if possible

  // check whether sync worked
  if(timeStatus()!= timeSet)
    Serial.println("Unable to sync with the RTC");
  else
    Serial.println("RTC has set the system time");

  tmElements_t quit_elements; // elements array to date of quitting smoking.

  // Midnight on April 1, 2012
  quit_elements.Second = 0;
  quit_elements.Minute = 0;
  quit_elements.Hour = 0;
  quit_elements.Wday = 7;
  quit_elements.Day = 1;
  quit_elements.Month = 4;
  quit_elements.Year = 2012 - 1970;
  quit = makeTime(quit_elements); // Unix timestamp quit date/time
  delay(1000);
}
time_t systime; // holds current time for diff calculation

void loop() {

  if (systime != now()) { // wait for new second to do anything
    systime = now();
    difftime = systime - quit; // subtract quit time from current time
    diff_seconds = difftime % 60; // get seconds
    difftime /= 60; // convert to minutes
    diff_minutes = difftime % 60; // get minutes
    difftime /= 60; // convert to hours
    diff_hours = difftime % 24; // get hours
    difftime /= 24; // convert to days
    diff_days = difftime; // get days
  }
  DisplayTime();
  delay(1000);
  display.clearDisplay();
}

// modified routine from Time Library example
void DisplayTime(){
  MinutesQuit = ((systime - quit)/60);
  CashSaved = ( (PackCost * PackDay * MinutesQuit) / 1440);
  // First, the LCD
  display.setTextSize(1);
  display.setTextColor(BLACK);
  display.setCursor(0,0);
  display.print(diff_days);
  display.print("d ");
  display.print(diff_hours);
  display.print(":");
  if(diff_minutes < 10)
    display.print('0');
  display.print(diff_minutes);
  display.print(":");
  if(diff_seconds < 10)
    display.print('0');
  display.print(diff_seconds);
  display.setCursor(0,10);
  display.println("Smoke free!");
  display.setCursor(0,30);
  display.print("$");
  display.print(CashSaved);
  display.println(" Saved ");
  display.display();
  //// Optionally: Serial
  //  Serial.print(diff_days);
  //  Serial.print("d ");
  //  Serial.print(diff_hours);
  //  Serial.print(":");
  //    if(diff_minutes < 10)
  //    Serial.print('0');
  //  Serial.print(diff_minutes);
  //  Serial.print(":");
  //    if(diff_seconds < 10)
  //    Serial.print('0');
  //  Serial.print(diff_seconds);
  //  Serial.println(" smoke free! ");
}

Step 4: Building With the PermaProto Board

Space and pin lines are at a premium inside the tin. This is designed so the charging circuit are on the bottom, the Perma-Proto board is above that, and the components are on top. The LCD is on a pin header to hold it over the Arduino and the ChronoDot is also elevated to allow space for the FTDI Friend for reprogramming.

There are switches on the bottom left and right by the ChronoDot. These switches take care of the overall power and LED power. The LED line is the white wire on the underside of the board.  I don't know how long the battery lasts, but I let it sit for 12 hours with the LED off and it was still running. 

Once the design is in place, solder the wire to match up the prototype. Don't trim any wire until everything is tested in case you have to de-solder any parts.


Step 5: Space Saving and Troubleshooting

These components do not fit perfectly, so I did everything I could to tighten things down. On the ChronoDot and LCD, I removed the plastic on the pin row and shortened the pins. I also cut out the bottom area with the USB charger to allow that part to stick out slightly. Even so, not everything fit perfectly so I made a "full window" of the cover of the mint tin. 

Once the components are soldered together, you may find problems in the code. In the case of the LCD, all the pins can be reassigned by software. Check the continuity between the pin and the LCD line and rearrange your software accordingly. 

Setting the Clock:
If your battery goes bad or you just never set your ChronoDot before, you can set it by installing Stephanie Maks Chronodot Library and uploading the example sketch to your Arduino. Once that is done, the clock is set and you can reinstall the smokefree sketch.

Step 6: Preparing the Mint Tin

Put the tip of a Sharpie through a washer and run it around the inside of the lid. This will create a nice round-edged guide for cutting. Also mark the Perma-Proto screw holes using the board while inside the tin. 

Using a Dremel with a cutting wheel and safety glasses, cut the rough outline of the tin window. Cut the corners in wide angles. Once the lid has the window removed, use a sanding attachment to round the edges, clean up burrs, and smooth everything out.

Drill the four screw holes out and an additional hole at the bottom center for the USB charger. Expand the charger hole with either small wire cutters or a "nibbler" tool. Hopefully yours will look better than mine.

Wash and dry the tin to get rid of the metal bits and dust.

Step 7: Mount and Assemble!

Attach the mounting risers inside the tin, but do not tighten them entirely. The holes may not perfectly match the Perma-Proto board and it's nice to be able to wiggle them slightly to get them in shape.

Switch off the device power and LED power. Remove the LCD and ChronoDot from their headers. Arrange the battery and charger in the bottom of the tin to lie flat and not interfere with the circuits above. A layer of very thin mounting tape will give security and insulation. Make sure no wires cross over the mounting risers.

Position the PermaProto board over the risers and screw it into place taking special care to avoid pinching wires. Connect the ChronoDot and LCD back up.


Step 8: Finishing Touches

Switch it on and make sure everything works. The LCD may still protrude slightly depending on the riser height and mounting techniques, but the rounded corners will make sure it does not fall out. I took a piece of thin plastic from some packaging and cut it to fit inside the tin over the ChronoDot and bottom of the LCD. 

In this picture, you can see some red glowing in the bottom left. That's an accidental piece of awesomeness: the SparkFun charger's LED is visible through the mounting holes. 

I programmed it to count from April 1, 2012, $6.50 per pack, 1.5 packs per day. My actual "quit date" will be midnight on April 14. The following day, I have a 2.5 hour drive (each way!) to the Parallax Expo. A constant reminder of my work and success and a cigarette pack-sized thing in my pocket will help. If you're using this design to help quit, good luck!