Go Down

Topic: Coffee machine cleaning timer gadget (Read 1 time) previous topic - next topic

nickgammon

Jun 15, 2011, 08:07 am Last Edit: Jun 15, 2011, 08:38 am by Nick Gammon Reason: 1
I have a coffee-making machine that makes nice coffee:



Unfortunately it is supposed to be cleaned each week (each day?) using these rather complex instructions:



Every time I go to do that, it almost drives me insane as I try to get it right (run 5 seconds, off 2 seconds, repeat 10 times, etc.). So I thought, "why not make a gadget that does that?". So here it is:



Everything is "off the shelf" hardware-wise, except the addition of a soldered-on piezo buzzer (circled).

Buttons ($US 8.90):

http://iteadstudio.com/store/index.php?main_page=product_info&cPath=18&products_id=351

LCD ($US 6.80):

http://iteadstudio.com/store/index.php?main_page=product_info&cPath=57_60&products_id=155

Plus an Arduino Uno ($US 30).

You basically hit the "clean" or "rinse" button and it counts down the correct number of cycles, with a beep to alert you to change modes on the coffee machine. It doesn't operate the machine, but it does the timing and counting for you.


Code:

Code: [Select]
// Program for timing Cappuccino machine cleaning cycle

// Author: Nick Gammon
// Date: 15 June 2011

#include <avr/pgmspace.h>
#include <iBridge_Keypad.h>
#include <iBridge_LCD_display.h>

#define CLEANCYCLES 5   // number of cleaning cycles
#define CLEANSECS 5     // seconds to clean
#define CLEANSITSECS 15 // seconds to sit idle

#define RINSECYCLES 10  // number of rinse cycles
#define RINSESECS 5     // seconds to rinse
#define RINSESITSECS 2  // seconds to sit idle

// beep sound
#define FREQUENCY 880L  // Hz
#define PERIOD 500000L / FREQUENCY  // (1 / frequency) * 1e6 / 2

// pins buzzer is connected to
#define BUZZER1 A2
#define BUZZER2 A4

// keypad
const byte ROWS = 3;
const byte COLS = 3;
const char keys[ROWS][COLS] = {
 { '1', '2', '3' },
 { '4', '5', '6' },
 { '7', '8', '9' },
};

byte rowPins[ROWS] = { 2, 3, 4 }; //connect to the row pinouts of the keypad
byte colPins[COLS] = { 5, 6, 7 }; //connect to the column pinouts of the keypad

// Create the Keypad
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

// Create the LCD
iBridge_LCD_display lcd;

// Beep for duration times x number
void beep (const int duration, const int number = 1)
{

 for (int j = 0; j < number; j++)
   {
   for(int i = 0 ; i < duration ; i++)
   {
     digitalWrite (BUZZER1, HIGH);
     digitalWrite (BUZZER2, LOW);
     delayMicroseconds(PERIOD);
 
     digitalWrite (BUZZER1, LOW);
     digitalWrite (BUZZER2, HIGH);
     delayMicroseconds(PERIOD);
   }  // end of for duration
 
   digitalWrite (BUZZER1, LOW);
   digitalWrite (BUZZER2, LOW);
   
   delay (100);
   }  // end of for each number

}  // end of beep


void menu ()
{
 lcd.clear ();
 lcd.gotoxy (0, 0);
 lcd.string ("Coffee cleaner");
 lcd.gotoxy (0, 2);
 lcd.string ("1: Clean");
 lcd.gotoxy (0, 3);
 lcd.string ("3: Rinse");
 
}  // end of menu

void showcounter (char * s, byte line, byte c1, byte c2)
{
 lcd.gotoxy (0, line - 1);
 lcd.string (s);
 lcd.writeDecimal (c1);
 lcd.string ("/");
 lcd.writeDecimal (c2);
 lcd.string ("    ");
}  // end of showcounter

void clean ()
{
 for (byte cycle = 1; cycle <= CLEANCYCLES; cycle++)
   {
   beep (50, 2);
   lcd.gotoxy (0, 0);
   lcd.clear ();
   showcounter ("Clean #", 1, cycle, CLEANCYCLES);
 
   for (byte s = 1; s <= CLEANSECS; s++)
     {
     showcounter ("Run: ", 3, s, CLEANSECS);
     delay (1000);
     }

   beep (50, 5);
   
   for (byte s = 1; s <= CLEANSITSECS; s++)
     {
     showcounter ("Sit: ", 3, s, CLEANSITSECS);
     delay (1000);
     }
 
   } // end of for

 beep (50, 10);
 lcd.gotoxy (0, 0);
 lcd.clear ();
 lcd.string ("Rinse and");
 lcd.gotoxy (0, 1);
 lcd.string (" reinsert");
 lcd.gotoxy (0, 2);
 lcd.string (" handle.");
 delay (5000);

}  // end of clean

void rinse ()
{
 for (byte cycle = 1; cycle <= RINSECYCLES; cycle++)
   {
   beep (50, 2);
   lcd.gotoxy (0, 0);
   lcd.clear ();
   showcounter ("Rinse #", 1, cycle, RINSECYCLES);
   
   for (byte s = 1; s <= RINSESECS; s++)
     {
     showcounter ("Run: ", 3, s, RINSESECS);
     delay (1000);
     }
   
   beep (50, 5);

   for (byte s = 1; s <= RINSESITSECS; s++)
     {
     showcounter ("Sit: ", 3, s, RINSESITSECS);
     delay (1000);
     }
 
   } // end of for

 beep (50, 10);

 lcd.gotoxy (0, 0);
 lcd.clear ();
 lcd.string ("Brew and");
 lcd.gotoxy (0, 1);
 lcd.string (" discard");
 lcd.gotoxy (0, 2);
 lcd.string (" coffee.");
 delay (5000);

}  // end of rinse


void setup()
{
 lcd.begin();

 pinMode (BUZZER1, OUTPUT);   // piezo buzzer pins
 pinMode (BUZZER2, OUTPUT);

 beep (10);  // beep to show we started up

 menu ();
}  // end of setup

void loop()
{
 byte key = kpd.getKey();
 if (key)
   {
   delay (500);  // debounce
   switch (key)
     {
     case  '1': clean (); break;
     case  '3': rinse (); break;
     }  // end of switch
   menu ();
   }  // end if key pressed
}  // end of loop
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

robtillaart


Fun application, well done. Now the robotarm that does the cleaning ;)
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

tastewar

Nice looking coffee maker -- was that gauge always crooked, or is it just from the last time you took it all apart?

nickgammon

I didn't take it apart, it just *became* crooked. :-(
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

tastewar

Maybe it's time to :-)

Would give you the opportunity to figure out how to connect your nifty new toy so it could actually control the cleaning cycle as well! I remember how nervous I was taking my iPod apart for the first time...

Go Up