summaryrefslogtreecommitdiff
path: root/pcr-controller
diff options
context:
space:
mode:
Diffstat (limited to 'pcr-controller')
-rw-r--r--pcr-controller/pcr-controller.c32
-rw-r--r--pcr-controller/protocol_uc.txt31
-rw-r--r--pcr-controller/pwm.c12
-rw-r--r--pcr-controller/temp_curve.c88
-rw-r--r--pcr-controller/temp_curve.h2
5 files changed, 95 insertions, 70 deletions
diff --git a/pcr-controller/pcr-controller.c b/pcr-controller/pcr-controller.c
index 1b8741b..85c5b38 100644
--- a/pcr-controller/pcr-controller.c
+++ b/pcr-controller/pcr-controller.c
@@ -81,6 +81,7 @@ int16_t raw_temp_ = 0;
uint8_t temp_is_fresh_ = 0;
uint8_t debug_ = 0;
uint8_t monitor_temp_ = 0;
+uint8_t pump_autoon_ = 0;
// at f_system_clk = 10Hz, system_clk_ will not overrun for at least 13 years. PCR won't run that long
volatile uint32_t system_clk_ = 0;
@@ -214,16 +215,16 @@ void setPeltierCoolingDirectionPower(int16_t value)
if (value >= 0)
{
- PIN_HIGH(PELTIER_INA_PORT, PELTIER_INA_PIN);
- PIN_LOW(PELTIER_INB_PORT, PELTIER_INB_PIN);
- pwm_set((uint8_t) value);
- } else {
PIN_LOW(PELTIER_INA_PORT, PELTIER_INA_PIN);
PIN_HIGH(PELTIER_INB_PORT, PELTIER_INB_PIN);
+ pwm_set((uint8_t) value);
+ } else {
+ PIN_HIGH(PELTIER_INA_PORT, PELTIER_INA_PIN);
+ PIN_LOW(PELTIER_INB_PORT, PELTIER_INB_PIN);
pwm_set((uint8_t) (-1 * value));
}
if (debug_)
- printf("Peltier value: %d, INA: %d, INB: %d\r\n", value, (PELTIER_INA_PORT & _BV(PELTIER_INA_PIN)) > 0, (PELTIER_INB_PORT & _BV(PELTIER_INB_PIN)) > 0);
+ printf("Peltier value: %d, INA: %d, INB: %d, OCR1AH: %d, OCR1AL: %d\r\n", value, (PELTIER_INA_PORT & _BV(PELTIER_INA_PIN)) > 0, (PELTIER_INB_PORT & _BV(PELTIER_INB_PIN)) > 0, OCR1AH, OCR1AL);
}
void handle_cmd(uint8_t cmd)
@@ -252,10 +253,17 @@ void handle_cmd(uint8_t cmd)
case 'P': cmdq_queueCmdWithNumArgs((void*) pid_setP, 1); return;
case 'I': cmdq_queueCmdWithNumArgs((void*) pid_setI, 1); return;
case 'D': cmdq_queueCmdWithNumArgs((void*) pid_setD, 1); return;
- case 'A': PIN_HIGH(PUMP_PORT, PUMP_PIN); break;
- case 'a': PIN_LOW(PUMP_PORT, PUMP_PIN); break;
+ case 'A':
+ PIN_HIGH(PUMP_PORT, PUMP_PIN);
+ pump_autoon_ = 0;
+ break;
+ case 'a':
+ PIN_LOW(PUMP_PORT, PUMP_PIN);
+ pump_autoon_ = 0;
+ break;
case 'B': PIN_HIGH(TOPHEAT_PORT, TOPHEAT_PIN); break;
case 'b': PIN_LOW(TOPHEAT_PORT, TOPHEAT_PIN); break;
+ case '@': pump_autoon_ = 1; break;
case '.': tcurve_printCurve(); return;
case '-': //reset temp curve
tcurve_reset();
@@ -264,9 +272,9 @@ void handle_cmd(uint8_t cmd)
//~ tcurve_add(readNumber(), readNumber());
cmdq_queueCmdWithNumArgs((void*) tcurve_add, 2);
return;
- case '!': cmdq_queueCmdWithNumArgs((void*) tcurve_setRepeatStartPosToLatestEntry, 0); return;
+ case '>': cmdq_queueCmdWithNumArgs((void*) tcurve_setRepeatStartPosToLatestEntry, 0); return;
+ case '<': cmdq_queueCmdWithNumArgs((void*) tcurve_setRepeatEndPosToLatestEntry, 0); return;
case 'Z': cmdq_queueCmdWithNumArgs((void*) tcurve_setRepeats, 1); return;
- case 'E': cmdq_queueCmdWithNumArgs((void*) tcurve_setPostCycleTargetTemp, 1); return;
default: printf("{\"cmd_ok\":false,\"error\":\"unknown cmd\"}\r\n"); return;
}
printf("{\"cmd_ok\":true}\r\n");
@@ -342,6 +350,8 @@ int main(void)
// e.g. enable periodic temp monitoring 'm' rather than querying temp at some intervall 's'
if (pid_isEnabled())
{
+ if (pump_autoon_)
+ PIN_HIGH(PUMP_PORT, PUMP_PIN);
if (debug_)
printf("pid_calc..");
while (system_clk_ - last_time2 < 5); //wait until at least 500ms have passed since last time. Should be enough time for everything else to finish. (after 13 years, code will hang here)
@@ -352,7 +362,11 @@ int main(void)
setPeltierCoolingDirectionPower(pid_calc(raw_temp_));
}
else
+ {
setPeltierCoolingDirectionPower(0);
+ if (pump_autoon_)
+ PIN_LOW(PUMP_PORT, PUMP_PIN);
+ }
}
anyio_task();
diff --git a/pcr-controller/protocol_uc.txt b/pcr-controller/protocol_uc.txt
index 18a2465..9aeaad5 100644
--- a/pcr-controller/protocol_uc.txt
+++ b/pcr-controller/protocol_uc.txt
@@ -11,6 +11,7 @@
'd' Same as above
'A' Switch on pump.
'a' Switch pump off.
+'@' Switch pump on automatically if temp goes higher than 30°C or lower than 19°C
'B' Switch on top heater.
'b' Switch top heater off.
'L' Toggle LED (Debug)
@@ -22,13 +23,14 @@
'.' Print out currently programmed temperature curve as JSON string.
'+' Add a temperature curve point. <-TempValue <-Duration
Excpects 2 arguments: Targettemperature and duration for which that temperature is to be held after it has been reached.
-'!' Set the last added (with '+') temperature curve point to be the cycle start point.
+'>' Set the last added (with '+') temperature curve point to be the cycle start point.
E.g. if >0 curve repetitions are set (with 'Z') the repetitions will start here, instead of at the first added curve point.
+'<' Set the last added (with '+') temperature curve point to be the cycle end point.
+ E.g. this and any temperature points added after this marker will not be repeated, but programmed after the main loop
'Z' Set number of cycle repetitions <-IntValue
E.g: 0 == default == no repetitions == 1 cycle
1 == 1 repetitions == 2 cycles)
....
-'E' Program a final hold temperature. PID will try to hold this value after all cycles have finished. <-TempValue
'm' Toggle periodic status output as JSON string.
'?' Toggle Debug Output.
'#' Disable PID (i.e. set PID target temperature to -2048.00)
@@ -73,7 +75,7 @@ Responses to "t" or "s":
{"t":9999999, "currtemp":5.02, "targettemp":5.00, "curve":true, "curve_t_elapsed":65535, "cycles_left":0} //we know all is finished because targettemp is hold-temp
Response to "."
-{"curve":[{"temp":1520,"duration":9000,"is_curr":1,"is_loop_start":1},{"temp":1040,"duration":10,"is_curr":0,"is_loop_start":0},{"temp":960,"duration":300,"is_curr":0,"is_loop_start":0},{"temp":1120,"duration":300,"is_curr":0,"is_loop_start":0},0],"end_temp:":80}
+{"curve":[{"temp":1520,"duration":9000,"is_curr":1,"is_loop_start":0,"is_loop_end":0},{"temp":1040,"duration":10,"is_curr":0,"is_loop_start":1,"is_loop_end":0},{"temp":960,"duration":300,"is_curr":0,"is_loop_start":0,"is_loop_end":0},{"temp":1120,"duration":300,"is_curr":0,"is_loop_start":0,"is_loop_end":0},{"temp":1120,"duration":1000,"is_curr":0,"is_loop_start":0,"is_loop_end":1},0],"end_temp":80,"loop_repeats":30}
Response to other commands:
{"cmd_ok":false,"error": "No DS1820 sensors on 1wire bus, thus no temperature"}
@@ -85,25 +87,26 @@ Response to other commands:
s
-
=
-A
+@
b
-+1520,9000
-+1040,10
-!
-+960,300
-+1120,300
++1536,300
+>
++448,300
++1152,300
+<
Z30
-E80
++64,9999
m
The sequence of above commands
- prints current temperature
- deletes any currenlty set temperature curve
- instructs the PID controller to hold the current temperature
-- enables the pump
-- programms the following temperature curve: 95°C (15min) -> [ -> 65°C (1s) -> 60°C (30s) -> 70°C (30s) ]
-- sets the curve to repeat the items in [] brackets 30 times
-- programms final holding temperature of 5°C (after temperature curve and all cylces have finished).
+- set the pump to auto
+- switch off top heater
+- programms the following temperature curve: [ 96°C (30s) -> 28°C (30s) -> 72°C (30s) ]
+- sets the curve to repeat the items in >< brackets 30 times
+- programms final holding temperature of 4°C (note that duration of last entry does not really matter since it will always be held indefinately).
- activates periodic status output.
diff --git a/pcr-controller/pwm.c b/pcr-controller/pwm.c
index 918d37b..a4e3863 100644
--- a/pcr-controller/pwm.c
+++ b/pcr-controller/pwm.c
@@ -11,19 +11,23 @@ void pwm_init(void)
TCCR1A = 0;
TCNT1 = 0;
OCR1A = 0;
- TCCR1A = (1<<COM1A1) | (1<<WGM10);
- TCCR1B = (1<<WGM12);
+ TCCR1A = (1<<WGM10); //Fast PWM, 8-bit
+ TCCR1B = (1<<WGM12); //Fast PWM, 8-bit
+ //TCCR1A |= (1<<COM1A1) // Clear OCnA/OCnB/OCnC on compare match when up-counting. Set OCnA/OCnB/OCnC on compare match when downcounting.
}
inline void pwm_on(void)
{
- TCCR1B = (TCCR1A & 0xF8) | (1<<CS10);
+ TCCR1A |= (1<<COM1A1); // Clear OCnA/OCnB/OCnC on compare match when up-counting. Set OCnA/OCnB/OCnC on compare match when downcounting.
+ TCCR1B = (TCCR1B & 0xF8) | (1<<CS10); // enable timer clock, no prescaling
}
inline void pwm_off(void)
{
- TCCR1B = (TCCR1A & 0xF8);
+ TCCR1A &= ~((1<<COM1A1) | (1<<COM1A0)); //normal port operation
+ TCCR1B = (TCCR1B & 0xF8); //no clock source, timer stopped
TCNT1 = 0;
+ PORTB &= ~ (1 << PB5); //set pin to LOW (otherwise it will remain in state since last pwm toggle)
}
void pwm_set(uint8_t val)
diff --git a/pcr-controller/temp_curve.c b/pcr-controller/temp_curve.c
index 36ec55a..f44981f 100644
--- a/pcr-controller/temp_curve.c
+++ b/pcr-controller/temp_curve.c
@@ -33,16 +33,16 @@ struct tc_entry {
tc_entry *next;
};
-tc_entry *temp_curve_ = 0;
-tc_entry *temp_curve_end_ = 0;
-tc_entry *temp_curve_current_ = 0;
-tc_entry *temp_curve_restart_pos_ = 0;
+tc_entry *temp_curve_ = 0; //pointer to start of curve (so we can free it by going through the list)
+tc_entry *temp_curve_end_ = 0; //pointer to last added entry in curve (so we know can quickly append new entries)
+tc_entry *temp_curve_current_ = 0; //pointer to currently active entry (temp we currently hold)
+tc_entry *temp_curve_loop_first_ = 0; //pointer to start of loop (loop is a subset of curve list)
+tc_entry *temp_curve_loop_last_ = 0; //pointer to end of loop (loop is a subset of curve list)
uint16_t temp_stable_time_ = 0;
-uint8_t curve_num_repeats_ = 0;
-uint8_t temp_curve_finished_ = 0;
-int16_t post_cycle_target_temp_ = TCURVE_ERROR;
+uint8_t temp_curve_original_num_repeats_ = 0;
+uint8_t curve_loop_num_repeats_ = 0; // number of times the loop still needs to be reapeated before finishing the rest of the curve
void tcurve_reset(void)
{
@@ -60,18 +60,14 @@ void tcurve_reset(void)
temp_curve_ = 0;
temp_curve_end_ = 0;
temp_curve_current_ = 0;
- curve_num_repeats_ = 0;
- temp_curve_restart_pos_ = temp_curve_;
- temp_curve_finished_ = 0;
+ temp_curve_original_num_repeats_ = 0;
+ curve_loop_num_repeats_ = 0;
+ temp_curve_loop_first_ = temp_curve_;
+ temp_curve_loop_last_ = 0;
if (debug_)
printf("tcreset: done\n\n");
}
-uint8_t tcurve_hasFinished(void)
-{
- return temp_curve_finished_;
-}
-
uint16_t tcurve_getTimeElapsed(void)
{
return temp_stable_time_;
@@ -79,7 +75,7 @@ uint16_t tcurve_getTimeElapsed(void)
uint8_t tcurve_getRepeatsLeft(void)
{
- return curve_num_repeats_;
+ return curve_loop_num_repeats_;
}
uint8_t tcurve_isSet(void)
@@ -89,13 +85,8 @@ uint8_t tcurve_isSet(void)
void tcurve_setRepeats(uint8_t r)
{
- curve_num_repeats_ = r;
- temp_curve_finished_ = 0;
-}
-
-void tcurve_setPostCycleTargetTemp(int16_t v)
-{
- post_cycle_target_temp_ = v;
+ curve_loop_num_repeats_ = r;
+ temp_curve_original_num_repeats_ = r;
}
void tcurve_add(int16_t temp, uint16_t hold_for_ticks)
@@ -110,7 +101,7 @@ void tcurve_add(int16_t temp, uint16_t hold_for_ticks)
temp_curve_end_ = new_entry;
temp_curve_ = new_entry;
temp_curve_current_ = new_entry;
- temp_curve_restart_pos_ = new_entry;
+ temp_curve_loop_first_ = new_entry;
} else {
temp_curve_end_->next = new_entry;
temp_curve_end_ = new_entry;
@@ -119,7 +110,16 @@ void tcurve_add(int16_t temp, uint16_t hold_for_ticks)
void tcurve_setRepeatStartPosToLatestEntry(void)
{
- temp_curve_restart_pos_= temp_curve_end_;
+ //calling this again, overwrites last set loop start entry
+ temp_curve_loop_first_= temp_curve_end_;
+ //no loop_last_ before loop_first_
+ temp_curve_loop_last_ = 0;
+}
+
+void tcurve_setRepeatEndPosToLatestEntry(void)
+{
+ //calling this again, overwrites last set loop stop entry
+ temp_curve_loop_last_ = temp_curve_end_;
}
void tcurve_printCurve(void)
@@ -132,11 +132,17 @@ void tcurve_printCurve(void)
printf("{\"curve\":[");
for (tc_entry *ce = temp_curve_; ; ce=ce->next)
{
- printf("{\"temp\":%d,\"duration\":%u,\"is_curr\":%d,\"is_loop_start\":%d},",ce->target_temp, ce->hold_for_timeticks, ce == temp_curve_current_,ce == temp_curve_restart_pos_);
+ printf("{\"temp\":%d,\"duration\":%u,\"is_curr\":%d,\"is_loop_start\":%d,\"is_loop_end\":%d},",
+ ce->target_temp,
+ ce->hold_for_timeticks,
+ ce == temp_curve_current_,
+ ce == temp_curve_loop_first_,
+ ce == temp_curve_loop_last_);
+
if (ce == temp_curve_end_)
break;
}
- printf("0],\"end_temp:\":%d}\r\n", post_cycle_target_temp_);
+ printf("0],\"loop_repeats\":%d}\r\n", temp_curve_original_num_repeats_);
}
int16_t tcurve_getTempToSet(int16_t current_temp, uint16_t ticks_elapsed)
@@ -144,30 +150,28 @@ int16_t tcurve_getTempToSet(int16_t current_temp, uint16_t ticks_elapsed)
if (temp_curve_current_ == 0)
return TCURVE_ERROR;
- if (temp_curve_finished_ && post_cycle_target_temp_ != TCURVE_ERROR)
- return post_cycle_target_temp_;
-
if (current_temp > temp_curve_current_->target_temp - temp_margin_ && current_temp < temp_curve_current_->target_temp + temp_margin_)
{
temp_stable_time_ += ticks_elapsed;
} // else: ignore the case of temp falling temporarily outside of temp_margin_
- // if time has been stable for long enough, advance to next
- // if there is no next, repeat curve until curve_num_repeats_ == 0
- // once that happens, set to post_cycle_target_temp_ or hold last value
+ //if temp has been stable for the set amount of timeticks in current curve element
if (temp_stable_time_ >= temp_curve_current_->hold_for_timeticks)
{
temp_stable_time_ = 0;
- if (temp_curve_current_->next != 0)
- {
+
+ if (curve_loop_num_repeats_ && //if repetitions left
+ ( (temp_curve_loop_last_ != 0 && temp_curve_current_ == temp_curve_loop_last_) //and we have reached a set loop endpoint
+ || temp_curve_current_->next == 0 //or the end of the list
+ ))
+ { //go back to first point in loop
+ curve_loop_num_repeats_--;
+ temp_curve_current_ = temp_curve_loop_first_;
+ } else if (temp_curve_current_->next != 0) //else if elements left in curve list
+ { // go to next element
temp_curve_current_ = temp_curve_current_->next;
- } else if (curve_num_repeats_)
- {
- //restart temp curve from the beginning (or the set position)
- temp_curve_current_ = temp_curve_restart_pos_;
- curve_num_repeats_--;
- } else
- temp_curve_finished_ = 1;
+ }
+ //else stay on temperature of last element forever (until reset is called or new elements are added)
}
return temp_curve_current_->target_temp;
} \ No newline at end of file
diff --git a/pcr-controller/temp_curve.h b/pcr-controller/temp_curve.h
index 104ecb3..bbdd8b1 100644
--- a/pcr-controller/temp_curve.h
+++ b/pcr-controller/temp_curve.h
@@ -28,11 +28,11 @@
void tcurve_reset(void);
void tcurve_setRepeats(uint8_t r);
void tcurve_setRepeatStartPosToLatestEntry(void);
+void tcurve_setRepeatEndPosToLatestEntry(void);
uint8_t tcurve_isSet(void);
uint8_t tcurve_hasFinished(void);
uint16_t tcurve_getTimeElapsed(void);
uint8_t tcurve_getRepeatsLeft(void);
-void tcurve_setPostCycleTargetTemp(int16_t v);
void tcurve_add(int16_t temp, uint16_t hold_for_s);
int16_t tcurve_getTempToSet(int16_t current_temp, uint16_t time_elapsed);
void tcurve_printCurve(void);