summaryrefslogtreecommitdiffstats
path: root/pressure_control/firmware
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2009-04-10 16:56:51 +0200
committerMichael Buesch <mb@bu3sch.de>2009-04-10 16:56:51 +0200
commit75a29d4d986e32bd82bc6468bba11567932a5349 (patch)
treec0a426aa40bf7f44bf87353460d9230326f77fac /pressure_control/firmware
parente54d84019bac17f0a7ac49e9147471ff5df85a02 (diff)
downloadcnc-75a29d4d986e32bd82bc6468bba11567932a5349.tar.xz
cnc-75a29d4d986e32bd82bc6468bba11567932a5349.zip
pressure_control: Fix automatic pressure control
Signed-off-by: Michael Buesch <mb@bu3sch.de>
Diffstat (limited to 'pressure_control/firmware')
-rw-r--r--pressure_control/firmware/Makefile2
-rw-r--r--pressure_control/firmware/main.c56
-rw-r--r--pressure_control/firmware/main.h4
-rw-r--r--pressure_control/firmware/remote.c13
-rw-r--r--pressure_control/firmware/remote.h3
-rw-r--r--pressure_control/firmware/valves.c39
-rw-r--r--pressure_control/firmware/valves.h10
7 files changed, 72 insertions, 55 deletions
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<value do only a short valve-open time.
- valves_force_state(VALVES_IDLE);
-
- } else {
- /* Open the valve. It's closed again next time we check
- * the pressure and it's OK. */
- if (raise_pressure)
- valves_force_state(VALVES_FLOW_IN);
- else
- valves_force_state(VALVES_FLOW_OUT);
- }
-}
-
/* Check the current pressure value against the desired value and
* adjust the pressure if needed. */
static void check_pressure(void)
@@ -149,22 +125,41 @@ static void check_pressure(void)
int32_t offset;
uint16_t abs_offset;
bool is_too_big;
+ bool report_change = 0;
+ uint8_t cur_state;
if (cfg.autoadjust_enable) {
offset = (int32_t)state.mbar - (int32_t)cfg.desired;
abs_offset = abs(offset);
is_too_big = (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 <mb@bu3sch.de>
+ * Copyright (C) 2008-2009 Michael Buesch <mb@bu3sch.de>
*
* 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 <avr/io.h>
@@ -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 <stdint.h>
@@ -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);
bues.ch cgit interface