From 75a29d4d986e32bd82bc6468bba11567932a5349 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Fri, 10 Apr 2009 16:56:51 +0200 Subject: pressure_control: Fix automatic pressure control Signed-off-by: Michael Buesch --- pressure_control/firmware/Makefile | 2 +- pressure_control/firmware/main.c | 56 +++++++++++++++++-------------------- pressure_control/firmware/main.h | 4 +-- pressure_control/firmware/remote.c | 13 ++++----- pressure_control/firmware/remote.h | 3 +- pressure_control/firmware/valves.c | 39 ++++++++++++++++++-------- pressure_control/firmware/valves.h | 10 +++++++ pressure_control/remote/pctl-remote | 5 ++-- 8 files changed, 75 insertions(+), 57 deletions(-) (limited to 'pressure_control') diff --git a/pressure_control/firmware/Makefile b/pressure_control/firmware/Makefile index f59f2b4..4502937 100644 --- a/pressure_control/firmware/Makefile +++ b/pressure_control/firmware/Makefile @@ -9,7 +9,7 @@ CC = avr-gcc OBJCOPY = avr-objcopy SIZE = avr-size -CFLAGS = -mmcu=$(ARCH) -std=gnu99 -g0 -O2 -fomit-frame-pointer -Wall -fpack-struct +CFLAGS = -mmcu=$(ARCH) -std=gnu99 -g0 -O2 -Wall CFLAGS += "-Dinline=inline __attribute__((__always_inline__))" diff --git a/pressure_control/firmware/main.c b/pressure_control/firmware/main.c index cd29339..7cf98f4 100644 --- a/pressure_control/firmware/main.c +++ b/pressure_control/firmware/main.c @@ -42,8 +42,8 @@ struct pressure_state state; /* EEPROM contents */ static struct eeprom_data EEMEM eeprom = { .cfg = { - .desired = 4000, /* 4 Bar */ - .hysteresis = 300, /* 0.3 Bar */ + .desired = 4000, /* Millibar */ + .hysteresis = 200, /* Millibar */ .autoadjust_enable = 1, }, }; @@ -118,30 +118,6 @@ void system_timer_init(void) TIMSK |= (1 << OCIE1A); } -static void valves_force_state(uint8_t new_state) -{ - if (state.valves == new_state) - return; - valves_global_switch(new_state); - state.valves = new_state; -} - -static void adjust_pressure(uint16_t abs_offset, bool raise_pressure) -{ - if (0) { - //TODO if offset= 0); + cur_state = valves_get_global_state(); if (abs_offset > cfg.hysteresis) { /* Adjust the pressure */ - adjust_pressure(abs_offset, !is_too_big); + report_change = (cur_state == VALVES_IDLE); + if (is_too_big) + valves_global_switch(VALVES_FLOW_OUT); + else + valves_global_switch(VALVES_FLOW_IN); + } else if (abs_offset > cfg.hysteresis / 4) { + /* If we're idle, stay idle. + * If we're increasing or decreasing pressure, + * keep on doing this to reach the desired center value + * more closely. */ } else { - /* The pressure is OK. Make sure the valves are + /* We're within half the hysteresis. + * The pressure is OK. Make sure the valves are * all idle. */ - valves_force_state(VALVES_IDLE); + report_change = (cur_state != VALVES_IDLE); + valves_global_switch(VALVES_IDLE); } } - remote_pressure_change_notification(state.mbar, cfg.hysteresis); + if (abs((int32_t)state.mbar - (int32_t)state.reported_mbar) >= 100) + report_change = 1; + if (report_change) { + remote_pressure_change_notification(state.mbar); + state.reported_mbar = state.mbar; + } } int main(void) @@ -179,7 +174,6 @@ int main(void) print("Pressure control initializing...\n"); valves_init(); - state.valves = VALVES_IDLE; sensor_init(); eeprom_load_config(); system_timer_init(); diff --git a/pressure_control/firmware/main.h b/pressure_control/firmware/main.h index 9f5cef1..cf6978a 100644 --- a/pressure_control/firmware/main.h +++ b/pressure_control/firmware/main.h @@ -18,6 +18,8 @@ struct pressure_config { struct pressure_state { /* Current pressure in the tank (in mBar) */ uint16_t mbar; + /* Reported pressure via RS232 */ + uint16_t reported_mbar; /* True, if the current pressure value needs checking against * the desired pressure config. */ bool needs_checking; @@ -26,8 +28,6 @@ struct pressure_state { * 0 = trigger now * -1 = triggered and running. */ int8_t sensor_trigger_cnt; - /* Current valves state (enum valves_global_state) */ - uint8_t valves; }; void get_pressure_config(struct pressure_config *cfg); diff --git a/pressure_control/firmware/remote.c b/pressure_control/firmware/remote.c index 87a9b17..cb646a7 100644 --- a/pressure_control/firmware/remote.c +++ b/pressure_control/firmware/remote.c @@ -200,9 +200,13 @@ static void handle_received_message(void) if (rx_msg.valve.nr == 0) { valve0_switch(rx_msg.valve.state == 0 ? VALVE_STATE_12 : VALVE_STATE_14); + valve_wait_toggle(); + valve0_switch(VALVE_STATE_IDLE); } else if (rx_msg.valve.nr == 1) { valve1_switch(rx_msg.valve.state == 0 ? VALVE_STATE_12 : VALVE_STATE_14); + valve_wait_toggle(); + valve0_switch(VALVE_STATE_IDLE); } else err = MSG_ERR_INVAL; break; @@ -370,17 +374,10 @@ void remote_1khz_work(void) usart_rx_timeout_check(); } -void remote_pressure_change_notification(uint16_t mbar, - uint16_t hysteresis) +void remote_pressure_change_notification(uint16_t mbar) { struct remote_message msg; - static uint16_t prev_value; - - if (abs((int32_t)mbar - (int32_t)prev_value) <= hysteresis) - return; - prev_value = mbar; - memset(&msg, 0, sizeof(msg)); msg.id = MSG_CURRENT_PRESSURE; msg.pressure.mbar = mbar; diff --git a/pressure_control/firmware/remote.h b/pressure_control/firmware/remote.h index 7c8d77c..14c4110 100644 --- a/pressure_control/firmware/remote.h +++ b/pressure_control/firmware/remote.h @@ -78,8 +78,7 @@ void print_dec(uint16_t number); void print_dec_signed(int16_t number); void print_hex(uint8_t number); -void remote_pressure_change_notification(uint16_t mbar, - uint16_t hysteresis); +void remote_pressure_change_notification(uint16_t mbar); void remote_work(void); void remote_1khz_work(void); diff --git a/pressure_control/firmware/valves.c b/pressure_control/firmware/valves.c index 70a2b6a..ec15518 100644 --- a/pressure_control/firmware/valves.c +++ b/pressure_control/firmware/valves.c @@ -2,7 +2,7 @@ * Pneumatic pressure controller. * Valve control. * - * Copyright (C) 2008 Michael Buesch + * Copyright (C) 2008-2009 Michael Buesch * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,6 +19,7 @@ */ #include "valves.h" +#include "util.h" #include @@ -26,10 +27,13 @@ /*** Valve interface definitions ***/ #define VALVE_DDR DDRD #define VALVE_PORT PORTD -#define VALVE0_14 4 /* Pin for valve-0 position 14 */ -#define VALVE0_12 5 /* Pin for valve-0 position 12 */ -#define VALVE1_14 6 /* Pin for valve-1 position 14 */ -#define VALVE1_12 7 /* Pin for valve-1 position 12 */ +#define VALVE0_14 6 /* Pin for valve-0 position 14 */ +#define VALVE0_12 7 /* Pin for valve-0 position 12 */ +#define VALVE1_14 4 /* Pin for valve-1 position 14 */ +#define VALVE1_12 5 /* Pin for valve-1 position 12 */ + + +static uint8_t current_global_state = 0xFF; void valve0_switch(uint8_t state) @@ -37,7 +41,7 @@ void valve0_switch(uint8_t state) VALVE_PORT &= ~((1 << VALVE0_12) | (1 << VALVE0_14)); if (state == VALVE_STATE_12) VALVE_PORT |= (1 << VALVE0_12); - else + else if (state == VALVE_STATE_14) VALVE_PORT |= (1 << VALVE0_14); } @@ -46,28 +50,41 @@ void valve1_switch(uint8_t state) VALVE_PORT &= ~((1 << VALVE1_12) | (1 << VALVE1_14)); if (state == VALVE_STATE_12) VALVE_PORT |= (1 << VALVE1_12); - else + else if (state == VALVE_STATE_14) VALVE_PORT |= (1 << VALVE1_14); } void valves_global_switch(uint8_t state) { + + if (state == current_global_state) + return; + current_global_state = state; + switch (state) { case VALVES_IDLE: valve0_switch(VALVE_STATE_12); valve1_switch(VALVE_STATE_12); + valve_wait_toggle(); + valve0_switch(VALVE_STATE_IDLE); + valve1_switch(VALVE_STATE_IDLE); break; case VALVES_FLOW_IN: - valve0_switch(VALVE_STATE_12); - valve1_switch(VALVE_STATE_14); - break; - case VALVES_FLOW_OUT: valve1_switch(VALVE_STATE_12); valve0_switch(VALVE_STATE_14); break; + case VALVES_FLOW_OUT: + valve0_switch(VALVE_STATE_12); + valve1_switch(VALVE_STATE_14); + break; } } +uint8_t valves_get_global_state(void) +{ + return current_global_state; +} + void valves_init(void) { VALVE_DDR |= (1 << VALVE0_12) | (1 << VALVE0_14) | diff --git a/pressure_control/firmware/valves.h b/pressure_control/firmware/valves.h index e7a5e74..320505d 100644 --- a/pressure_control/firmware/valves.h +++ b/pressure_control/firmware/valves.h @@ -1,6 +1,8 @@ #ifndef VALVES_H_ #define VALVES_H_ +#include "util.h" + #include @@ -13,12 +15,20 @@ enum valves_global_state { /* State for one valve. */ enum valve_state { + VALVE_STATE_IDLE, VALVE_STATE_12, VALVE_STATE_14, }; +/* Wait for the valve to toggle from one position to another. */ +static inline void valve_wait_toggle(void) +{ + mdelay(10); +} + void valves_init(void); void valves_global_switch(uint8_t global_state); +uint8_t valves_get_global_state(void); void valve0_switch(uint8_t state); void valve1_switch(uint8_t state); diff --git a/pressure_control/remote/pctl-remote b/pressure_control/remote/pctl-remote index 37aa535..3013870 100755 --- a/pressure_control/remote/pctl-remote +++ b/pressure_control/remote/pctl-remote @@ -288,7 +288,8 @@ class MainWidget(QWidget): h.addWidget(label) self.curPressure = QLCDNumber(self) self.curPressure.setSegmentStyle(QLCDNumber.Flat) - self.curPressure.display(0.0) + self.curPressure.setNumDigits(4) + self.curPressure.display(QString("0.00")) h.addWidget(self.curPressure) label = QLabel(self.tr("Bar"), self) h.addWidget(label) @@ -393,7 +394,7 @@ class MainWidget(QWidget): def parseCurrentPressureMsg(self, msg): msg = remote.getPayload(msg) mbar = ord(msg[0]) | (ord(msg[1]) << 8) - self.curPressure.display(float(mbar) / 1000) + self.curPressure.display(QString("%.2f" % (float(mbar) / 1000))) def desiredPressureChanged(self, value): if not self.initialized: -- cgit v1.2.3