diff --git a/brew.h b/brew.h index b41019ae89c17f0d3b04043dd78e03f6f99aa734..4ba39496a73020abff6060464d6026ea5d70d8c4 100644 --- a/brew.h +++ b/brew.h @@ -27,6 +27,8 @@ void runSettingsSelection(); #include "config.h" +#include "src/HeatingElement/HeatingElement.h" + #include "Melody.h" #include "Display.h" #include "Temperature.h" diff --git a/brew.ino b/brew.ino index 35b5046e052f357b299f02028dc08010def60d0e..ff760f4129da499d2c6b5358fdd2a15441893fe7 100644 --- a/brew.ino +++ b/brew.ino @@ -70,7 +70,7 @@ boolean refresh; boolean repaint; boolean cancel; -boolean bStatusElement; +//boolean bStatusElement; unsigned long loggingTimeInterval; @@ -90,10 +90,12 @@ volatile boolean onISR = false; unsigned long rotarySwDetectTime; // ++++++++++++++++++++++++ Heating Element Relay ++++++++++++++++++++++++ +/* int iWindowSize; // Time frame to operate in unsigned long windowStartTime; double dWattPerPulse; double dWattage; +*/ // ++++++++++++++++++++++++ Pump ++++++++++++++++++++++++ int iPumpSpeed; // Time frame to operate in @@ -119,6 +121,8 @@ Temperature downPT100("down", PT100_DOWN_TIME_BETWEEN_READINGS, 2.0309, 2.0288, 658.15, 655.35); +HeatingElement heatingElement(HEATING_ELEMENT_OUTPUT_PIN, LOW, HIGH); + // ######################### INTERRUPTS ######################### void isr () { // Interrupt service routine is executed when a HIGH to LOW transition is detected on CLK unsigned long interruptTime = millis(); @@ -224,8 +228,9 @@ void xSafeHardwarePowerOff() { // Force shutdown analogWrite(PUMP_PIN, PUMP_SPEED_STOP_MOSFET); // analogWrite values from 0 to 255 - digitalWrite(HEATING_ELEMENT_OUTPUT_PIN, LOW); // Turn heading element OFF for safety - bStatusElement = false; + heatingElement.shutDown(); // Turn heading element OFF for safety + //digitalWrite(HEATING_ELEMENT_OUTPUT_PIN, LOW); // Turn heading element OFF for safety + //bStatusElement = false; basePT100.setPumpStatus( false ); upPT100.setPumpStatus( false ); @@ -256,12 +261,14 @@ void setup() { attachInterrupt (ROTARY_ENCODER_INTERRUPT_NUMBER, isr, FALLING); // ++++++++++++++++++++++++ Heating Element Relay ++++++++++++++++++++++++ + /* pinMode (HEATING_ELEMENT_OUTPUT_PIN, OUTPUT); digitalWrite (HEATING_ELEMENT_OUTPUT_PIN, LOW); bStatusElement = false; windowStartTime = millis(); dWattPerPulse = HEATING_ELEMENT_MAX_WATTAGE / HEATING_ELEMENT_AC_FREQUENCY_HZ; dWattage = 0.0; + */ // ++++++++++++++++++++++++ Mixer ++++++++++++++++++++++++ @@ -347,7 +354,7 @@ void setup() { lastInterruptTime = 0; // ++++++++++++++++++++++++ PID ++++++++++++++++++++++++ - iWindowSize = HEATING_ELEMENT_DEFAULT_WINDOW_SIZE; // Time frame to operate in + //iWindowSize = HEATING_ELEMENT_DEFAULT_WINDOW_SIZE; // Time frame to operate in // ######################### Code - Run Once ######################### xSafeHardwarePowerOff (); @@ -432,16 +439,18 @@ bool isTimeLeft() { return false; } +/* //HEATING_ELEMENT_MAX_WATTAGE / HEATING_ELEMENT_AC_FREQUENCY_HZ double ulWattToWindowTime( double ulAppliedWatts ) { double ulPulsesRequired = ulAppliedWatts / dWattPerPulse; return (double)iWindowSize / 1000.0 * ulPulsesRequired * 1000.0 / HEATING_ELEMENT_AC_FREQUENCY_HZ; } +*/ bool xRegulateTemperature( boolean bMaximumOfUpDown ) { double difference = 0; bool overTemperature = false; - dWattage = 0.0; + //double dWattage = 0.0; float tup = upPT100.getCurrentTemperature(); float tdown = downPT100.getCurrentTemperature(); @@ -474,47 +483,59 @@ bool xRegulateTemperature( boolean bMaximumOfUpDown ) { // Calculate applied wattage, based on the distance from the target temperature if ( overTemperature ) { - dWattage = 0.0; // turn it off + //dWattage = 0.0; // turn it off + heatingElement.setWattage(heatingElement.getNullWattage()); // turn it off } else { if ( difference <= 0.5 ) { if ( cookTemperature > 99.0 ) { - dWattage = 2000.0; // pulse hardly at 2000 watt + //dWattage = 2000.0; // pulse hardly at 2000 watt + heatingElement.setWattage(heatingElement.getTwoThirdWattage()); // pulse hardly at 2000 watt } else { if ( cookTemperature > 70.0 ) { - dWattage = 1000.0; // pulse moderately at 1000 watt + //dWattage = 1000.0; // pulse moderately at 1000 watt + heatingElement.setWattage(heatingElement.getOneThirdWattage()); // pulse moderately at 1000 watt } else { - dWattage = 500.0; // pulse lightly at 500 watt + //dWattage = 500.0; // pulse lightly at 500 watt + heatingElement.setWattage(heatingElement.getOneSixthWattage()); // pulse lightly at 500 watt } } } else { if ( difference <= 1.0 ) { if ( cookTemperature > 99.0 ) { - dWattage = 2000.0; // pulse hardly at 2000 watt + //dWattage = 2000.0; // pulse hardly at 2000 watt + heatingElement.setWattage(heatingElement.getTwoThirdWattage()); // pulse hardly at 2000 watt } else { - dWattage = 1000.0; // pulse moderately at 1000 watt + //dWattage = 1000.0; // pulse moderately at 1000 watt + heatingElement.setWattage(heatingElement.getOneThirdWattage()); // pulse moderately at 1000 watt } } else { if ( difference <= 3.0 ) { - dWattage = 2000.0; // pulse hardly at 2000 watt + //dWattage = 2000.0; // pulse hardly at 2000 watt + heatingElement.setWattage(heatingElement.getTwoThirdWattage()); // pulse hardly at 2000 watt } else { - dWattage = HEATING_ELEMENT_MAX_WATTAGE; // pulse constantly at HEATING_ELEMENT_MAX_WATTAGE watt + //dWattage = HEATING_ELEMENT_MAX_WATTAGE; // pulse constantly at HEATING_ELEMENT_MAX_WATTAGE watt + heatingElement.setWattage(heatingElement.getMaxWattage()); // pulse constantly at HEATING_ELEMENT_MAX_WATTAGE watt } } } } + // Update the recorded time for the begining of the window, if the previous window has passed. Then apply wattage to the element at the right time + heatingElement.process(); + + /* // Update the recorded time for the begining of the window, if the previous window has passed while ((millis() - windowStartTime) > iWindowSize) { // Check if it's time to vary the pulse width modulation and if so do it by shifting the "Relay in ON" Window windowStartTime += iWindowSize; } - + // Apply wattage to the element at the right time if ( ulWattToWindowTime( dWattage ) > (millis() - windowStartTime) ) { digitalWrite(HEATING_ELEMENT_OUTPUT_PIN, HIGH); @@ -523,12 +544,13 @@ bool xRegulateTemperature( boolean bMaximumOfUpDown ) { digitalWrite(HEATING_ELEMENT_OUTPUT_PIN, LOW); bStatusElement = false; } + */ #ifdef DEBUG_OFF //debugPrintFunction("xRegulateTemperature"); debugPrintVar("difference", difference); //debugPrintVar("overTemperature", overTemperature); - debugPrintVar("dWattage", dWattage); + debugPrintVar("dWattage", heatingElement.getWattage()); //debugPrintVar("ulWattToWindowTime( dWattage )", ulWattToWindowTime( dWattage ) ); //debugPrintVar("millis()", millis()); //debugPrintVar("windowStartTime", windowStartTime); @@ -870,9 +892,10 @@ void xManageMachineSystems() { Serial.print("|"); Serial.print(downPT100.getCurrentTemperature()); Serial.print("|"); - Serial.print(dWattage); + Serial.print(heatingElement.getWattage()); Serial.print("|"); - if (bStatusElement) { +// if (bStatusElement) { + if (heatingElement.isStatusElement()) { Serial.print("1"); } else { diff --git a/config.h b/config.h index b21f5e3df3a9549a0a184fb7d330f73aa6be5baa..996025ac6b2a8bf3e837a0c20260e43d7b0e62ee 100644 --- a/config.h +++ b/config.h @@ -17,12 +17,12 @@ #define SETTING_WARNING_BEEP_INTERVAL 5000 // ++++++++++++++++++++++++ Heating Element Relay ++++++++++++++++++++++++ -#define HEATING_ELEMENT_DEFAULT_WINDOW_SIZE 1000 #define HEATING_ELEMENT_OUTPUT_PIN 24 -#define HEATING_ELEMENT_MAX_HEAT_PWM_INTEGER 5 -#define HEATING_ELEMENT_MAX_HEAT_PWM_FLOAT 5.0 -#define HEATING_ELEMENT_MAX_WATTAGE 3000.0 // Minimum = 2000.0 -#define HEATING_ELEMENT_AC_FREQUENCY_HZ 50.0 +//#define HEATING_ELEMENT_DEFAULT_WINDOW_SIZE 1000 +//#define HEATING_ELEMENT_MAX_HEAT_PWM_INTEGER 5 +//#define HEATING_ELEMENT_MAX_HEAT_PWM_FLOAT 5.0 +//#define HEATING_ELEMENT_MAX_WATTAGE 3000.0 // Minimum = 2000.0 +//#define HEATING_ELEMENT_AC_FREQUENCY_HZ 50.0 // ++++++++++++++++++++++++ Temperature ++++++++++++++++++++++++ #define TEMPERATURE_MIN_VALUE 0 diff --git a/libraries/Newliquidcrystal_1.3.5.zip b/libraries/Newliquidcrystal_1.3.5.zip new file mode 100644 index 0000000000000000000000000000000000000000..30b1e89cf639f19ace97cbabf06404c740f942b7 Binary files /dev/null and b/libraries/Newliquidcrystal_1.3.5.zip differ diff --git a/src/HeatingElement/HeatingElement.cpp b/src/HeatingElement/HeatingElement.cpp new file mode 100644 index 0000000000000000000000000000000000000000..72f0375b9071844c8258924518fa4c8e8178742f --- /dev/null +++ b/src/HeatingElement/HeatingElement.cpp @@ -0,0 +1,86 @@ +#include "HeatingElement.h" + +HeatingElement::HeatingElement( int iOutputPin, int uiOffValue, int uiOnValue ) { + _iOutputPin = iOutputPin; + _uiOffValue = uiOffValue; + _uiOnValue = uiOnValue; + + pinMode(_iOutputPin, OUTPUT); + digitalWrite(_iOutputPin, _uiOffValue); + + _bStatusElement = false; + _iWindowSize = HEATING_ELEMENT_DEFAULT_WINDOW_SIZE; // Time frame to operate in + _windowStartTime = millis(); + _dWattPerPulse = HEATING_ELEMENT_MAX_WATTAGE / HEATING_ELEMENT_AC_FREQUENCY_HZ; + _dWattage = 0.0; +} + +void HeatingElement::shutDown() { + digitalWrite(_iOutputPin, _uiOffValue); // Turn heading element OFF for safety + _bStatusElement = false; +} + +double HeatingElement::process( double dWattage ) { + setWattage(dWattage); + return process(); +} + +double HeatingElement::process() { + // Update the recorded time for the begining of the window, if the previous window has passed + while ((millis() - _windowStartTime) > _iWindowSize) { // Check if it's time to vary the pulse width modulation and if so do it by shifting the "Relay in ON" Window + _windowStartTime += _iWindowSize; + } + + // Apply wattage to the element at the right time + if ( ulWattToWindowTime( _dWattage ) > (millis() - _windowStartTime) ) { + digitalWrite(_iOutputPin, _uiOnValue); + _bStatusElement = true; + } else { + digitalWrite(_iOutputPin, _uiOffValue); + _bStatusElement = false; + } + + return _dWattage; +} + + +// Getter and setters +boolean HeatingElement::isStatusElement() { + return _bStatusElement; +} + +double HeatingElement::getWattage() { + return _dWattage; +} + +void HeatingElement::setWattage( double dWattage ) { + _dWattage = dWattage; +} + + +// Private functions +double HeatingElement::ulWattToWindowTime( double ulAppliedWatts ) { + double ulPulsesRequired = ulAppliedWatts / _dWattPerPulse; + return (double)_iWindowSize / 1000.0 * ulPulsesRequired * 1000.0 / HEATING_ELEMENT_AC_FREQUENCY_HZ; +} + + +// Power Increments +double HeatingElement::getNullWattage() { + return 0.0; +} +double HeatingElement::getOneSixthWattage() { + return HEATING_ELEMENT_MAX_WATTAGE/6.0; +} +double HeatingElement::getOneThirdWattage() { + return HEATING_ELEMENT_MAX_WATTAGE/3.0; +} +double HeatingElement::getHalfWattage() { + return HEATING_ELEMENT_MAX_WATTAGE/2.0; +} +double HeatingElement::getTwoThirdWattage() { + return HEATING_ELEMENT_MAX_WATTAGE*2.0/3.0; +} +double HeatingElement::getMaxWattage() { + return HEATING_ELEMENT_MAX_WATTAGE; +} \ No newline at end of file diff --git a/src/HeatingElement/HeatingElement.h b/src/HeatingElement/HeatingElement.h new file mode 100644 index 0000000000000000000000000000000000000000..182410fc4dc72095157f8db275c66c6de449a440 --- /dev/null +++ b/src/HeatingElement/HeatingElement.h @@ -0,0 +1,47 @@ +#ifndef HeatingElement_h +#define HeatingElement_h + +#include "Arduino.h" + +#define HEATING_ELEMENT_DEFAULT_WINDOW_SIZE 1000 +#define HEATING_ELEMENT_MAX_WATTAGE 3000.0 // Minimum = 2000.0 +#define HEATING_ELEMENT_AC_FREQUENCY_HZ 50.0 + +//#define HEATING_ELEMENT_MAX_HEAT_PWM_INTEGER 5 +//#define HEATING_ELEMENT_MAX_HEAT_PWM_FLOAT 5.0 + +class HeatingElement +{ + public: + HeatingElement( int iOutputPin, int uiOffValue, int uiOnValue ); + + void shutDown(); + double process(); + double process( double dWattage ); + + boolean isStatusElement(); + double getWattage(); + void setWattage( double dWattage ); + + double getNullWattage(); + double getOneSixthWattage(); + double getOneThirdWattage(); + double getHalfWattage(); + double getTwoThirdWattage(); + double getMaxWattage(); + + private: + + double ulWattToWindowTime( double ulAppliedWatts ); + + int _iOutputPin; + int _uiOnValue; + int _uiOffValue; + boolean _bStatusElement; + int _iWindowSize; // Time frame to operate in + unsigned long _windowStartTime; + double _dWattPerPulse; + double _dWattage; +}; + +#endif \ No newline at end of file