|
@ -0,0 +1,129 @@ |
|
|
|
|
|
//
|
|
|
|
|
|
// Code written by Barb (Francesco Barbieri), March 2023, released as Open-Source.
|
|
|
|
|
|
// Functionality: Control a Nespresso/Delonghi and similar capsule/pod-based coffee maker
|
|
|
|
|
|
// I reused the original thermistor, but there's no reason why you couldn't pick your own
|
|
|
|
|
|
//
|
|
|
|
|
|
// Hardware required is minimal:
|
|
|
|
|
|
// - Arduino or compatible (I used an Attiny45 @8MHz)
|
|
|
|
|
|
// - 2 10A 250V Relay Modules
|
|
|
|
|
|
// - 230V AC to 5V DC 1A power-supply board (old phone charger will do, but ready-made modules exist)
|
|
|
|
|
|
// - Assorted resistors: the thermistor will require 10 or 100kOhm resistor, usually...
|
|
|
|
|
|
// - Some perf-board, wires, solder and soldering iron
|
|
|
|
|
|
//
|
|
|
|
|
|
//------------------------------------------------------------------------------------------
|
|
|
|
|
|
// Values for temperature sensor assignment and calibration
|
|
|
|
|
|
int ThermistorPin = A1; |
|
|
|
|
|
int Vo; |
|
|
|
|
|
float R1 = 10000; // the actual resistor is 100K, but so is the thermistor, hence it's fine.
|
|
|
|
|
|
float logR2, R2, T, Tc; |
|
|
|
|
|
float c1 = 1.009249522e-03, c2 = 2.378405444e-04, c3 = 2.019202697e-07; |
|
|
|
|
|
|
|
|
|
|
|
// Desired boiler temperature in C
|
|
|
|
|
|
int Tmax = 85; |
|
|
|
|
|
|
|
|
|
|
|
// Pumping Time for making Coffee (ms)
|
|
|
|
|
|
int PumpTime = 10000; |
|
|
|
|
|
|
|
|
|
|
|
// Digital Pin assignment for relays.
|
|
|
|
|
|
int BoilerPin = 0; |
|
|
|
|
|
int PumpPin = 1; |
|
|
|
|
|
|
|
|
|
|
|
// Pin assignment for buttons
|
|
|
|
|
|
int OnPin = 5; // this is actually the reset pin and we'll only use it as such.
|
|
|
|
|
|
int MakePin = 3; |
|
|
|
|
|
|
|
|
|
|
|
// Green status LED under make coffee button
|
|
|
|
|
|
int LED = 4; |
|
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------------------
|
|
|
|
|
|
// the setup function runs once when you press reset or power the board
|
|
|
|
|
|
void setup() { |
|
|
|
|
|
// initialize digital pins
|
|
|
|
|
|
pinMode(A1, INPUT); // A1 is the ADC we use to read the temperature from the thermistor
|
|
|
|
|
|
pinMode(OnPin, INPUT); // this is actually the reset pin and we'll only use it as such.
|
|
|
|
|
|
pinMode(MakePin, INPUT_PULLUP); |
|
|
|
|
|
pinMode(BoilerPin, OUTPUT); |
|
|
|
|
|
pinMode(PumpPin, OUTPUT); |
|
|
|
|
|
pinMode(LED, OUTPUT); |
|
|
|
|
|
digitalWrite(PumpPin, LOW); |
|
|
|
|
|
digitalWrite(BoilerPin, LOW); |
|
|
|
|
|
heat(); // heat once at boot and leave status LED on
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------------------
|
|
|
|
|
|
// the main loop function runs over and over again forever.
|
|
|
|
|
|
// Cointains control loops that call other functions
|
|
|
|
|
|
void loop() { |
|
|
|
|
|
// read current temperature
|
|
|
|
|
|
temp(); |
|
|
|
|
|
|
|
|
|
|
|
// turn off status LED when boiler is too cold
|
|
|
|
|
|
if (Tc < (Tmax - 10)) { |
|
|
|
|
|
digitalWrite(LED, LOW); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Make coffee when the green button is pressed
|
|
|
|
|
|
if (digitalRead(MakePin)==LOW){ |
|
|
|
|
|
delay(100); // button debounce
|
|
|
|
|
|
heat(); // call heat function before making coffee
|
|
|
|
|
|
delay(100); // relay activation safety delay
|
|
|
|
|
|
digitalWrite(PumpPin, HIGH); // Pump
|
|
|
|
|
|
delay(PumpTime); // pump for pre-established time
|
|
|
|
|
|
digitalWrite(PumpPin, LOW); // stop Pumping
|
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------------------
|
|
|
|
|
|
// Boiler heating function
|
|
|
|
|
|
void heat() { |
|
|
|
|
|
temp(); // Read current boiler temperature
|
|
|
|
|
|
while (Tc<Tmax){ // stay in the loop until desired Tmax is reached
|
|
|
|
|
|
digitalWrite(BoilerPin, HIGH); // turn on the boiler
|
|
|
|
|
|
digitalWrite(LED, LOW); // Blink the LED while heating
|
|
|
|
|
|
delay(500); |
|
|
|
|
|
digitalWrite(LED, HIGH); |
|
|
|
|
|
delay(500); |
|
|
|
|
|
temp(); // Read current boiler temperature before repeating cycle
|
|
|
|
|
|
} |
|
|
|
|
|
digitalWrite(LED, HIGH); |
|
|
|
|
|
digitalWrite(BoilerPin, LOW); // turn the boiler off when done
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------------------
|
|
|
|
|
|
// temperature reading function for the thermistor
|
|
|
|
|
|
// contains safety checks to avoid catastrophic failure if thermistor breaks
|
|
|
|
|
|
void temp() { |
|
|
|
|
|
Vo = analogRead(ThermistorPin); |
|
|
|
|
|
R2 = R1 * (1023.0 / (float)Vo - 1.0); |
|
|
|
|
|
logR2 = log(R2); |
|
|
|
|
|
T = (1.0 / (c1 + c2*logR2 + c3*logR2*logR2*logR2)); |
|
|
|
|
|
Tc = T - 273.15; // temperature in celsius
|
|
|
|
|
|
if (Tc < -20) { // if Tc is this low, thermocouple is probably unplugged
|
|
|
|
|
|
error(); |
|
|
|
|
|
} |
|
|
|
|
|
else if (Tc > 150) { // if Tc is this high, thermocouple is probably shorted
|
|
|
|
|
|
error(); |
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------------------
|
|
|
|
|
|
// error function to lock the machine in a while loop until reset
|
|
|
|
|
|
// created to prevent overheating in case of failed thermistor
|
|
|
|
|
|
void error() { |
|
|
|
|
|
while (true) { |
|
|
|
|
|
// turn off all relays
|
|
|
|
|
|
digitalWrite(BoilerPin, LOW); |
|
|
|
|
|
digitalWrite(PumpPin, LOW); |
|
|
|
|
|
delay(1000); |
|
|
|
|
|
// now blink the LED rapidly 5 times
|
|
|
|
|
|
for (int i = 0; i < 5; i++) { |
|
|
|
|
|
digitalWrite(LED, HIGH); |
|
|
|
|
|
delay(100); |
|
|
|
|
|
digitalWrite(LED, LOW); |
|
|
|
|
|
delay(200); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
//------------------------------------------------------------------------------------------
|