From d1317d01ba705596b86aebbdbdc72dfb21365b02 Mon Sep 17 00:00:00 2001 From: Bernhard Tittelbach Date: Wed, 11 Dec 2013 20:05:40 +0000 Subject: json stateless info update, topheater pwm, etc git-svn-id: https://svn.spreadspace.org/avr/trunk@249 aa12f405-d877-488e-9caf-2d797e2a1cc7 --- pcr-controller/cmd_queue.c | 14 ++++++--- pcr-controller/cmd_queue.h | 4 +-- pcr-controller/pcr-controller.c | 53 ++++++++++++++++++------------- pcr-controller/pid_control.c | 2 +- pcr-controller/protocol_uc.txt | 30 ++++++++++-------- pcr-controller/pwm.c | 69 +++++++++++++++++++++++++++++++---------- pcr-controller/pwm.h | 5 +-- pcr-controller/temp_curve.c | 10 +++--- pcr-controller/temp_curve.h | 4 +-- 9 files changed, 123 insertions(+), 68 deletions(-) (limited to 'pcr-controller') diff --git a/pcr-controller/cmd_queue.c b/pcr-controller/cmd_queue.c index 6d12296..9af0f8a 100644 --- a/pcr-controller/cmd_queue.c +++ b/pcr-controller/cmd_queue.c @@ -29,6 +29,7 @@ typedef struct { uint8_t num_args; + uint8_t cmd; void* function_ptr; int16_t input_list[CMDQ_INPUT_LIST_LEN]; uint8_t num_args_read; @@ -78,16 +79,17 @@ uint8_t cmdq_addCharToArgumentBuffer(uint8_t c) return 0; } -void cmdq_queueCmdWithNumArgs(void* fptr, uint8_t num_args) +void cmdq_queueCmdWithNumArgs(void* fptr, uint8_t num_args, uint8_t cmd) { if (num_args > CMDQ_INPUT_LIST_LEN) { - printf("{\"cmd_ok\":false,\"error\":\"max args == %d\"}\r\n", CMDQ_INPUT_LIST_LEN); - return; //can't do that Would hang cmdq + printf("{\"cmd\":\"%c\",\"cmd_ok\":false,\"error\":\"max args == %d\"}\r\n", cmd, CMDQ_INPUT_LIST_LEN); + return; //to continue would hang cmdq, so we don't } if ((cmd_queue_next_here_ +1) % CMQ_QUEUE_LENGTH == cmd_queue_todo_pos_) //for this check REQUIRED: CMQ_QUEUE_LENGTH > 2 cmdq_doWork(); //no more space in queue -> execute now ! cmd_queue_[cmd_queue_next_here_].num_args = num_args; + cmd_queue_[cmd_queue_next_here_].cmd = cmd; cmd_queue_[cmd_queue_next_here_].function_ptr = fptr; cmd_queue_[cmd_queue_next_here_].num_args_read = 0; cmd_queue_fillargs_pos_ = cmd_queue_next_here_; @@ -117,11 +119,13 @@ void cmdq_doWork(void) ((void(*)(int16_t,int16_t)) cmd_queue_[cmd_queue_todo_pos_].function_ptr)(cmd_queue_[cmd_queue_todo_pos_].input_list[0], cmd_queue_[cmd_queue_todo_pos_].input_list[1]); break; } + char cmd = cmd_queue_[cmd_queue_todo_pos_].cmd; cmd_queue_[cmd_queue_todo_pos_].num_args_read = 0; cmd_queue_[cmd_queue_todo_pos_].num_args = 0; cmd_queue_[cmd_queue_todo_pos_].function_ptr = 0; + cmd_queue_[cmd_queue_todo_pos_].cmd = 0; cmd_queue_todo_pos_++; cmd_queue_todo_pos_ %= CMQ_QUEUE_LENGTH; - printf("{\"cmd_ok\":true}\r\n"); + printf("{\"cmd\":\"%c\",\"cmd_ok\":true}\r\n",cmd); } -} \ No newline at end of file +} diff --git a/pcr-controller/cmd_queue.h b/pcr-controller/cmd_queue.h index d632f43..afa59c2 100644 --- a/pcr-controller/cmd_queue.h +++ b/pcr-controller/cmd_queue.h @@ -31,7 +31,7 @@ */ uint8_t cmdq_addCharToArgumentBuffer(uint8_t c); -void cmdq_queueCmdWithNumArgs(void* fptr, uint8_t num_args); +void cmdq_queueCmdWithNumArgs(void* fptr, uint8_t num_args, uint8_t cmd); void cmdq_doWork(void); -#endif \ No newline at end of file +#endif diff --git a/pcr-controller/pcr-controller.c b/pcr-controller/pcr-controller.c index 85c5b38..1f96292 100644 --- a/pcr-controller/pcr-controller.c +++ b/pcr-controller/pcr-controller.c @@ -61,10 +61,12 @@ #define PELTIER_INB_PORT PORTB #define PELTIER_INB_DDR DDRB +//OC1A #define PELETIER_PWM_EN_PIN PINB5 #define PELETIER_PWM_EN_PORT PORTB #define PELETIER_PWM_EN_DDR DDRB +//OC4D #define TOPHEAT_PIN PIND7 #define TOPHEAT_PORT PORTD #define TOPHEAT_DDR DDRD @@ -166,14 +168,14 @@ void printStatus(void) { if (num_temp_sensors_ == 0) { - printf("{\"cmd_ok\":false,\"error\": \"No DS1820 sensors on 1wire bus, thus no temperature\"}\r\n"); + printf("{\"cmd\":\"s\",\"cmd_ok\":false,\"error\": \"No DS1820 sensors on 1wire bus, thus no temperature\"}\r\n"); return; } if (raw_temp_ == DS1820_ERROR) { - printf("{\"cmd_ok\":false,\"error\":\"talking to DS18b20, no valid temperature!\"}\r\n"); + printf("{\"cmd\":\"s\",\"cmd_ok\":false,\"error\":\"talking to DS18b20, no valid temperature!\"}\r\n"); } else { - printf("{\"t\":%lu, \"currtemp\":", system_clk_); + printf("{\"cmd\":\"s\",\"t\":%lu, \"currtemp\":", system_clk_); printRawTemp(raw_temp_); printf(", \"targettemp\":"); printRawTemp(pid_getTargetValue()); @@ -217,16 +219,21 @@ void setPeltierCoolingDirectionPower(int16_t value) { PIN_LOW(PELTIER_INA_PORT, PELTIER_INA_PIN); PIN_HIGH(PELTIER_INB_PORT, PELTIER_INB_PIN); - pwm_set((uint8_t) value); + pwm_b5_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)); + pwm_b5_set((uint8_t) (-1 * value)); } if (debug_) 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 setTopHeaderValue(int16_t value) +{ + pwm_d7_set((uint8_t) (value & 0xFF)); +} + void handle_cmd(uint8_t cmd) { switch(cmd) { @@ -237,22 +244,23 @@ void handle_cmd(uint8_t cmd) case 'R': case 'r': reset2bootloader(); break; case '?': debug_ = ~debug_; break; - case 'm': monitor_temp_ = ~monitor_temp_; break; + case 'M': monitor_temp_ = 1; break; + case 'm': monitor_temp_ = 0; break; case '=': pid_setTargetValue(raw_temp_); break; case '#': pid_setTargetValue(PID_DISABLED); break; case 't': case 's': printStatus(); return; case 'L': led_toggle(); break; - case 'l': cmdq_queueCmdWithNumArgs((void*) led_toggle, 0); return; + case 'l': cmdq_queueCmdWithNumArgs((void*) led_toggle, 0, cmd); return; case 'p': case 'i': case 'd': pid_printVars(); return; - case 'T': cmdq_queueCmdWithNumArgs((void*) pid_setTargetValue, 1); return; - 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 'T': cmdq_queueCmdWithNumArgs((void*) pid_setTargetValue, 1, cmd); return; + case 'P': cmdq_queueCmdWithNumArgs((void*) pid_setP, 1, cmd); return; + case 'I': cmdq_queueCmdWithNumArgs((void*) pid_setI, 1, cmd); return; + case 'D': cmdq_queueCmdWithNumArgs((void*) pid_setD, 1, cmd); return; case 'A': PIN_HIGH(PUMP_PORT, PUMP_PIN); pump_autoon_ = 0; @@ -261,23 +269,25 @@ void handle_cmd(uint8_t cmd) 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 'B': cmdq_queueCmdWithNumArgs((void*) setTopHeaderValue, 1, cmd); return; + case 'b': setTopHeaderValue(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 '.': tcurve_printCurve(cmd); return; case '-': //reset temp curve tcurve_reset(); break; case '+': //add temp curve entry //~ tcurve_add(readNumber(), readNumber()); - cmdq_queueCmdWithNumArgs((void*) tcurve_add, 2); + cmdq_queueCmdWithNumArgs((void*) tcurve_add, 2, cmd); 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; - default: printf("{\"cmd_ok\":false,\"error\":\"unknown cmd\"}\r\n"); return; + case '>': cmdq_queueCmdWithNumArgs((void*) tcurve_setRepeatStartPosToLatestEntry, 0, cmd); return; + case '<': cmdq_queueCmdWithNumArgs((void*) tcurve_setRepeatEndPosToLatestEntry, 0, cmd); return; + case 'Z': cmdq_queueCmdWithNumArgs((void*) tcurve_setRepeats, 1, cmd); return; + default: printf("{\"cmd\":\"%c\",\"cmd_ok\":false,\"error\":\"unknown cmd\"}\r\n",cmd); return; } - printf("{\"cmd_ok\":true}\r\n"); + printf("{\"cmd\":\"%c\",\"cmd_ok\":true}\r\n",cmd); } int main(void) @@ -299,9 +309,10 @@ int main(void) PINMODE_OUTPUT(PELTIER_INB_DDR, PELTIER_INB_PIN); PINMODE_OUTPUT(PELTIER_INA_DDR, PELTIER_INA_PIN); PINMODE_OUTPUT(TOPHEAT_DDR, TOPHEAT_PIN); + PIN_LOW(TOPHEAT_PORT, TOPHEAT_PIN); pwm_init(); - pwm_set(0); + pwm_b5_set(0); pid_loadFromEEPROM(); diff --git a/pcr-controller/pid_control.c b/pcr-controller/pid_control.c index 95d190e..452be4d 100644 --- a/pcr-controller/pid_control.c +++ b/pcr-controller/pid_control.c @@ -134,4 +134,4 @@ void pid_saveToEEPROM(void) eeprom_write_dword((uint32_t *) &pid_i_eeprom_, pid_i_); eeprom_write_dword((uint32_t *) &pid_d_eeprom_, pid_d_); eeprom_write_word((uint16_t *) &crc_eeprom_, pid_p_ ^ pid_i_ ^ pid_d_); -} \ No newline at end of file +} diff --git a/pcr-controller/protocol_uc.txt b/pcr-controller/protocol_uc.txt index 9aeaad5..6326454 100644 --- a/pcr-controller/protocol_uc.txt +++ b/pcr-controller/protocol_uc.txt @@ -12,7 +12,7 @@ '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' Set top heater PWM to value between 0 and 255 (in future pwm value may be fixed and 'B' may return to simple on switch) <-IntValue 'b' Switch top heater off. 'L' Toggle LED (Debug) 'l' Toggle LED by using queuing system (Debug) @@ -31,7 +31,8 @@ E.g: 0 == default == no repetitions == 1 cycle 1 == 1 repetitions == 2 cycles) .... -'m' Toggle periodic status output as JSON string. +'M' Enable periodic status output as JSON string. +'m' Disable periodic status output as JSON string. '?' Toggle Debug Output. '#' Disable PID (i.e. set PID target temperature to -2048.00) (Only works if no temperature curve is set. If needed use '-' first.) @@ -67,20 +68,22 @@ A value of -2048.00 or -32768 generally means something is DISABLED or inapplica ==== Example uc Answers ==== -Responses to "t" or "s": -{"t":503, "currtemp":20.34, "targettemp":-2048.00, "curve":false, "curve_t_elapsed":0, "cycles_left":0} //curve and pid disabled (pid disabel when targettemp == -2048.00 -{"t":97000, "currtemp":40.34, "targettemp":70.00, "curve":true, "curve_t_elapsed":14, "cycles_left":11} -{"t":97200, "currtemp":69.72, "targettemp":70.00, "curve":true, "curve_t_elapsed":214, "cycles_left":11} -{"t":110123, "currtemp":30.14, "targettemp":30.00, "curve":true, "curve_t_elapsed":10, "cycles_left":9} -{"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 +Responses to "s": +{"cmd":"s","t":503, "currtemp":20.34, "targettemp":-2048.00, "curve":false, "curve_t_elapsed":0, "cycles_left":0} //curve and pid disabled (pid disabel when targettemp == -2048.00 +{"cmd":"s","t":97000, "currtemp":40.34, "targettemp":70.00, "curve":true, "curve_t_elapsed":14, "cycles_left":11} +{"cmd":"s","t":97200, "currtemp":69.72, "targettemp":70.00, "curve":true, "curve_t_elapsed":214, "cycles_left":11} +{"cmd":"s","t":110123, "currtemp":30.14, "targettemp":30.00, "curve":true, "curve_t_elapsed":10, "cycles_left":9} +{"cmd":"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":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} +{"cmd":".","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"} -{"cmd_ok":false,"error":"talking to DS18b20, no valid temperature!"} -{"cmd_ok":true} +{"cmd":"s","cmd_ok":false,"error": "No DS1820 sensors on 1wire bus, thus no temperature"} +{"cmd":"s","cmd_ok":false,"error":"talking to DS18b20, no valid temperature!"} +{"cmd":"A","cmd_ok":true} +{"cmd":"a","cmd_ok":true} +{"cmd":"#","cmd_ok":true} ==== Example Program ==== @@ -96,7 +99,7 @@ b < Z30 +64,9999 -m +M The sequence of above commands - prints current temperature @@ -111,3 +114,4 @@ The sequence of above commands (c) Bernhard Tittelbach, 2013 + diff --git a/pcr-controller/pwm.c b/pcr-controller/pwm.c index a4e3863..3ca5bbe 100644 --- a/pcr-controller/pwm.c +++ b/pcr-controller/pwm.c @@ -1,52 +1,87 @@ #include "pwm.h" - -#define PWM_VAL OCR1AL -//OC1A +//OutputCompareRegister for Timer1 and pin OC1A/B5 +#define PWMB5_VAL OCR1AL +//for FastPWM in Timer4 OCR4C is TOP for all OC4x pins, all other PWM Modes use OCR4A,OCR4B or OCR4D +#define PWMD7_VAL OCR4D void pwm_init(void) { + //for OC1A on pin B5 DDRB |= (1< 0) + pwm_b5_on(); + else + pwm_b5_off(); + PWMB5_VAL = val; } -void pwm_set(uint8_t val) +void pwm_d7_set(uint8_t val) { if (val > 0) - pwm_on(); + pwm_d7_on(); else - pwm_off(); - PWM_VAL = val; + pwm_d7_off(); + PWMD7_VAL = val; } -inline void pwm_inc(void) +inline void pwm_b5_inc(void) { - if(PWM_VAL < 255) - PWM_VAL++; + if(PWMB5_VAL < 255) + PWMB5_VAL++; } -inline void pwm_dec(void) +inline void pwm_b5_dec(void) { - if(PWM_VAL > 0) - PWM_VAL--; + if(PWMB5_VAL > 0) + PWMB5_VAL--; } diff --git a/pcr-controller/pwm.h b/pcr-controller/pwm.h index 1e5f184..2459cd3 100644 --- a/pcr-controller/pwm.h +++ b/pcr-controller/pwm.h @@ -4,7 +4,8 @@ #include void pwm_init(void); -void pwm_set(uint8_t val); +void pwm_b5_set(uint8_t val); +void pwm_d7_set(uint8_t val); -#endif \ No newline at end of file +#endif diff --git a/pcr-controller/temp_curve.c b/pcr-controller/temp_curve.c index f44981f..bf9b309 100644 --- a/pcr-controller/temp_curve.c +++ b/pcr-controller/temp_curve.c @@ -24,7 +24,7 @@ extern uint8_t debug_; -const int16_t temp_margin_ = 8; // 0.5 °C +const int16_t temp_margin_ = 16; // 1 °C typedef struct tc_entry tc_entry; struct tc_entry { @@ -122,14 +122,14 @@ void tcurve_setRepeatEndPosToLatestEntry(void) temp_curve_loop_last_ = temp_curve_end_; } -void tcurve_printCurve(void) +void tcurve_printCurve(uint8_t cmd) { if (temp_curve_ == 0) { - printf("{\"cmd_ok\":false,\"error\":\"No curve set\"}\r\n"); + printf("{\"cmd\":\"%c\",\"cmd_ok\":false,\"error\":\"No curve set\"}\r\n",cmd); return; } - printf("{\"curve\":["); + printf("{\"cmd\":\"%c\",\"curve\":[",cmd); for (tc_entry *ce = temp_curve_; ; ce=ce->next) { printf("{\"temp\":%d,\"duration\":%u,\"is_curr\":%d,\"is_loop_start\":%d,\"is_loop_end\":%d},", @@ -174,4 +174,4 @@ int16_t tcurve_getTempToSet(int16_t current_temp, uint16_t ticks_elapsed) //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 bbdd8b1..3af8788 100644 --- a/pcr-controller/temp_curve.h +++ b/pcr-controller/temp_curve.h @@ -35,6 +35,6 @@ uint16_t tcurve_getTimeElapsed(void); uint8_t tcurve_getRepeatsLeft(void); 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); +void tcurve_printCurve(uint8_t cmd); -#endif \ No newline at end of file +#endif -- cgit v1.2.3