Cold Drip Coffee (automated drip portion)

Had this idea a while back, decided to make it into a home project.
Started tinkering with the code already.
at the moment the requirements are:
Button to start the sequence
Button to pause & resume the sequence
One fuction to pre-soak the coffee for a set period of time
The other to drip for a set period of time, increasing the relay "time open" as the loop progresses (because gravity / water pressure?)

currently outputting text to terminal, will want this to display on a basic LCD.

Any suggestions / guidance is appreciated.
Here is my code so far:

void setup() {

  const int ready_led = 6;
  pinMode(ready_led, OUTPUT);
  const int running_led = 7;
  pinMode(running_led, OUTPUT);

  Serial.begin(9600);

  Serial.println("Press Start to Begin");

  const byte startbutton = 10;
  pinMode(startbutton, INPUT_PULLUP);
  while (digitalRead(startbutton) == HIGH)
  {
    digitalWrite(ready_led, HIGH);
  }
  digitalWrite(ready_led, LOW);

  Serial.println("Start Button Pressed, Begining PreSoak");
  digitalWrite(running_led, HIGH);
  PreSoak(); // Begin PreSoak Function

  Serial.println("PreSoak finished, Starting Drip Cycle");
  DripCycle(); // Begin Drip Function

  Serial.println("Drip Cycle has ended");
  digitalWrite(running_led, LOW);
}

void loop() {

  FinishLED ();

}

// Define Functions

// PreSoak Function, 60 Drips a Minute, Drip for 6 Minutes (480 times) approx
void PreSoak()
{

  const int pausebuttonPin = 9;
  int pausebuttonState = 0;
  pinMode(pausebuttonPin, INPUT);

  const int relay_pin = 12;
  pinMode(relay_pin, OUTPUT);

  int presoakcount = 0;
  while (presoakcount < 25)
  {
    pausebuttonState = digitalRead(pausebuttonPin);
    if (pausebuttonState == LOW)
    {
      Serial.println("Presoak Paused");
    }
    else
    {
      digitalWrite(relay_pin, HIGH);
      delay(250);
      digitalWrite(relay_pin, LOW);
      delay(500);
      presoakcount++;
    }
  }
}

// Drip Cycle Function, approx 7 hours required to dispense 1L of water, test.
void DripCycle()
{

  const int pausebuttonPin = 9;
  int pausebuttonState = 0;
  pinMode(pausebuttonPin, INPUT);

  const int relay_pin = 12;
  pinMode(relay_pin, OUTPUT);

  int dripcyclecount = 0;
  while (dripcyclecount < 5)
  {
    pausebuttonState = digitalRead(pausebuttonPin);
    if (pausebuttonState == LOW)
    {
      Serial.println("Drip Stage 1 Paused");
    }
    else
    {
      digitalWrite(relay_pin, HIGH);
      delay(500);
      digitalWrite(relay_pin, LOW);
      delay(2500);
      dripcyclecount++;
    }
  }
  while (dripcyclecount < 10)
  {
    pausebuttonState = digitalRead(pausebuttonPin);
    if (pausebuttonState == LOW)
    {
      Serial.println("Drip Stage 2 Paused");
    }
    else
    {
      digitalWrite(relay_pin, HIGH);
      delay(750);
      digitalWrite(relay_pin, LOW);
      delay(2250);
      dripcyclecount++;
    }
  }
  while (dripcyclecount < 15)
  {
    pausebuttonState = digitalRead(pausebuttonPin);
    if (pausebuttonState == LOW)
    {
      Serial.println("Drip Stage 3 Paused");
    }
    else
    {
      digitalWrite(relay_pin, HIGH);
      delay(1000);
      digitalWrite(relay_pin, LOW);
      delay(2000);
      dripcyclecount++;
    }
  }
}

// Pulse LED when finished
void FinishLED ()
{
  const int finish_led = 6;
  float in, out;

  for (in = 0; in < 6.283; in = in + 0.0005)
  {
    out = sin(in) * 127.5 + 127.5;
    analogWrite(finish_led, out);
  }
}

Does the code work ?

hammy:
Does the code work ?

for the most part, yes.
my knowledge on coding is quite basic.
Im sure there would be ways to improve what I'm trying to achieve.

Hi,
Welcome to the forum.

Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html . Then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Thanks.. Tom.... :slight_smile:

TomGeorge:
Hi,
Welcome to the forum.

Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html . Then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Thanks.. Tom.... :slight_smile:

Thanks Tom

Use the autoformat function of the IDE to nicely format your code, and make it more readable.

Use the F() macro for string constants (like you use in the print statements), saves your scarce RAM.

Lots of delay() statements. That will make your buttons far less responsive than they should be, as nothing gets done while in a delay(). You can get rid of them by turning your code into a finite state machine and using millis() for timing.

See if you can refactor it a bit. This while loop:

  while (dripcyclecount < 5)

Has the exact same code as the two that follow it except for the stage number and dripcyclecount. Put it in a function and pass those things to it.

wvmarle:
Use the autoformat function of the IDE to nicely format your code, and make it more readable.

Use the F() macro for string constants (like you use in the print statements), saves your scarce RAM.

Lots of delay() statements. That will make your buttons far less responsive than they should be, as nothing gets done while in a delay(). You can get rid of them by turning your code into a finite state machine and using millis() for timing.

Have auto-formatted and uploaded again. Thanks for that.

Yes I noticed that the buttons dont respond until the loop completes, not a big problem as the loop occurs every few seconds. I can afford for the loop to finish before it pauses.
however, I would like to have a status / pulsing led while the functions are running, I guess in this case Im better off going to the state machine route?

wildbill:
See if you can refactor it a bit. This while loop:

  while (dripcyclecount < 5)

Has the exact same code as the two that follow it except for the stage number and dripcyclecount. Put it in a function and pass those things to it.

Sorry im not sure what you mean by this?
the purpose of the nested while loop is to increase the open time of the valve as time progresses, so in 3 parts.
at the moment, yes the delays in the code are all the same.
Ill update the code.

Is there a better way to do this?

You have three pieces of effectively identical code:

  while (dripcyclecount < 5)
  {
    pausebuttonState = digitalRead(pausebuttonPin);
    if (pausebuttonState == LOW)
    {
      Serial.println("Drip Stage 1 Paused");
    }
    else
    {
      digitalWrite(relay_pin, HIGH);
      delay(500);
      digitalWrite(relay_pin, LOW);
      delay(2500);
      dripcyclecount++;
    }
  }

You could create a function that does that, passing the stage number to it (because that's the only difference) and call it three times, preferably using a for loop.

wildbill:
You could create a function that does that, passing the stage number to it (because that's the only difference) and call it three times, preferably using a for loop.

Ah, makes sense. Thank you.