Files
CCU4-firmware/he.ino
2023-09-11 18:04:36 +02:00

913 lines
25 KiB
C++

#include "valve.h"
#define HEDEBUG 0
//--- Liquid Helium
PAR_LONG heLevel = 0; // channel 6 (internal)
PAR_LONG heRaw = 0;
PAR_LONG heHigh = 9500; // stop filling
PAR_LONG heLow = 1000; // start filling
PAR_LONG heDrive = 75;
PAR_LONG heWiRes = 500;
PAR_LONG heCurrent = 0;
PAR_LONG heVolt = 0;
PAR_LONG heFastTime = 30; // 20 sec
PAR_LONG heSlowTime = 300; // 300 sec
PAR_LONG heEmpty = 200;
PAR_LONG heFull = 0;
PAR_LONG heFirst = 0;
PAR_LONG heSlope = 0;
PAR_LONG heIncreaseTolerance = 500; // [0.01%] if increase higher than this switch to fast
PAR_LONG heFastTimeout = 600; // sec, switch to slow when no increase within this time
#define he_sens_text F("ok|sensor warm|no sensor|tmo|meas soon| ")
enum {he_sens_ok, he_sens_warm, he_no_sens, he_timeout, he_not_yet, he_disabled};
PAR_BYTE heSensState = he_not_yet; // internal channel
PAR_BYTE heValve = 0;
PAR_BYTE heFast = 1; // 0: slow, 1: fast
PAR_BYTE heAuto = 1; // 0: off, 1: auto fill
PAR_BYTE heMeas = 0; // 0: idle, 1: measuring, 2:checking
PAR_LONG heExtLevel[6] = {0};
PAR_BYTE heExtState[6] = {he_not_yet, he_disabled, he_disabled, he_disabled, he_disabled, he_disabled}; // disabled
PAR_LONG heExtWiRes = 460;
PAR_LONG heExtEmpty = 565;
PAR_LONG heExtFull = 90;
PAR_LONG heExtDrive = 75;
PAR_LONG heChannel = 7;
long heCableVolt0 = 0;
long heCableVolt1 = 1;
long heMinLev[7] = {0,0,0,0,0,0,0};
long heMinLevel;
long heIntLevel = 0;
byte heIntState = he_not_yet;
//PAR_BYTE heBooster = 0; // 48 V Booster enable
PAR_BYTE heCommand = 0;
#define he_cmd_text F("stop|fill|off|watch|slow|fast|more|manual on")
enum {he_stop=0, he_fill, he_off, he_watch, he_slow, he_fast, he_more, he_manual}; // commands
const long undef_mm = 999999;
const long heMeasSpeed = 50; // mm / sec
const long heMeasTol = 20; // mm
ulong heLastIncrease = -240000;
boolean checking = false;
boolean started = false;
float res_to_len = 300;
long empty_10um = 20000;
float mm_to_percent = 0.5;
long heIntDrive = 0;
void HePars() {
byte changed;
ParFixed("h", heLevel, 2);
ParFixed("hr", heRaw, 2);
changed = (ParFixed("hd", heDrive, 0) == par_command);
ParFixed("hc", heCurrent, 1);
ParFixed("hu", heVolt, 2);
ParFixed("hh", heHigh, 2);
ParFixed("hl", heLow, 2);
changed |= (ParFixed("hwr", heWiRes, 0) == par_command);
changed |= (ParFixed("hem", heEmpty, 0) == par_command);
changed |= (ParFixed("hfu", heFull, 0) == par_command);
if (changed && heSensState != he_disabled) {
ParSet(heSensState, he_not_yet);
}
ParFixed("htf", heFastTime, 0);
ParFixed("hts", heSlowTime, 0);
ParFixed("hms", heSlope, 0);
ParFixed("hmf", heFirst, 2);
ParFixed("hit", heIncreaseTolerance, 2);
changed = (ParFixed("hft", heFastTimeout, 0) == par_command);
if (changed) {
heLastIncrease = now;
}
ParEnum("hv", heValve, valve_text);
ParEnum("hsf", heSensState, he_sens_text);
ParEnum("ha", heAuto, F("off|auto"));
ParEnum("hm", heMeas, F("idle|meas|check"));
changed = (ParEnum("hf", heFast, F("slow|fast")) == par_command);
if (changed) {
heLastIncrease = now;
}
if (ParEnum("hav", heAvailable, F("no|yes|ext")) == par_command) {
if (heAvailable == 1) {
if (heSensState == he_disabled) {
ParSet(heSensState, he_not_yet);
}
}
}
//ParEnum("hbe", heBooster, F("disable|enable"));
if (ParEnum("hcd", heCommand, he_cmd_text) == par_command) {
HeRemoteCmd(heCommand);
}
changed = (ParEnum("hea", heExtAvailable, F("0")) == par_command); // use enum 0 for pure byte
if (heExtAvailable > 6) {
ParSet(heExtAvailable, 1);
}
changed |= (ParFixed("hd0", heExtDrive, 0) == par_command);
changed |= (ParFixed("hwr0", heExtWiRes, 0) == par_command);
changed |= (ParFixed("hem0", heExtEmpty, 0) == par_command);
changed |= (ParFixed("hfu0", heExtFull, 0) == par_command);
if (changed) {
if (heExtAvailable == 1) {
if (HEDEBUG) {
Serial.println("activate channel 0");
}
ParArraySet(heExtState, 0, he_not_yet);
} else {
for (byte n = 0; n < 6; n++) {
if (ARRAY(heExtState,n) != he_disabled) {
ParArraySet(heExtState, n, he_not_yet);
}
}
}
}
ParFixed("hch", heChannel, 0);
//ParFixedArray("h", heExtLevel, 0, heExtAvailable - 1, 2);
//ParEnumArray("hs", heExtState, 0, heExtAvailable - 1, he_sens_text);
ParFixedArray("h", heExtLevel, 0, 5, 2);
ParEnumArray("hs", heExtState, 0, 5, he_sens_text);
}
void HeInit() {
byte pin;
pinMode(io_motor_current, OUTPUT);
digitalWrite(io_lev_boost, HIGH); // 48 V booster inactive
pinMode(io_lev_boost, OUTPUT);
// switch off current
digitalWrite(io_lev_enable, LOW);
pinMode(io_lev_enable, OUTPUT);
// select main channel
digitalWrite(io_he_select, LOW);
pinMode(io_he_select, OUTPUT);
if (heExtAvailable > 1) {
for (pin = 0; pin < 8; pin++) {
digitalWrite(io_ext1 + pin, HIGH);
pinMode(io_ext1 + pin, OUTPUT);
}
}
}
byte HeValueNr(byte channel) {
if (channel >= 0 && channel < 6) {
return p_heExtLevel + channel;
}
return p_heLevel;
}
byte HeStateNr(byte channel) {
if (channel >= 0 && channel < 6) {
return p_heExtState + channel;
}
return p_heSensState;
}
void HeSetLev(byte channel, long value) {
if (channel >= 0 && channel < 6) {
ParArraySet(heExtLevel, channel, value);
} else if (channel == 6) {
ParSet(heLevel, value);
}
}
void HeSetState(byte channel, byte value) {
if (channel >= 0 && channel < 6) {
ParArraySet(heExtState, channel, value);
} else if (channel == 6) {
ParSet(heSensState, value);
}
}
byte HeGetState(byte channel) {
if (channel >= 0 && channel < heExtAvailable) {
return ARRAY(heExtState,channel);
} else if (channel == 6) {
return heSensState;
}
return he_disabled;
}
long HeGetLevel(byte channel) {
if (channel >= 0 && channel < 6) {
return ARRAY(heExtLevel,channel);
} else if (channel == 6) {
return heLevel;
}
return -990; //error
}
void HeLoadChannel() {
heIntState = HeGetState(heChannel);
heIntLevel = HeGetLevel(heChannel);
if (heChannel >= 0 && heChannel <= 6) {
heMinLevel = ARRAY(heMinLev,heChannel);
}
}
boolean HeShown() {
return heAvailable; // || heValve != no_valve;
}
void HeDispExt() {
char head[4];
byte channel;
byte st;
byte h=0; // summed height
byte n=0; // number of lines
DispTouchCmd(m_menu, m_menu); // open menu on a touch anywhere
// sum up height to check if we can use large numbers
for (channel = 0; channel < 7; channel++) {
st = HeGetState(channel);
if (st != he_disabled) {
n++;
if (st == he_sens_ok) {
h += DispRowHeight(fmt_large);
} else {
h += DispRowHeight(fmt_lsmall);
}
}
}
head[1] = ')';
head[2] = 0;
for (channel = 0; channel < 7; channel++) {
st = HeGetState(channel);
if (st != he_disabled) {
head[0] = '0' + channel;
if (st == he_sens_ok) {
if (h > 128) {
DispMediumValue(head, HeValueNr(channel), HeStateNr(channel));
} else {
DispLargeValue(head, HeValueNr(channel), HeStateNr(channel));
}
} else {
DispValue(head, HeValueNr(channel), HeStateNr(channel));
if (n < 6) {
DispText(" ");
}
}
}
}
}
boolean HeDispShort(boolean *big) {
boolean isbig = true;
HeStateDisp("He ");
if (heAvailable == 1 && heExtState[0] == he_sens_ok) {
isbig = true;
} else {
isbig = false;
}
if (heAvailable == 1) {
if (isbig) {
DispMediumValue("", p_heLevel, p_heSensState); // He level
} else {
DispBigValue(p_heLevel, p_heSensState); // He level
}
}
if (heExtState[0] == he_sens_ok) {
// DispValue("vessel", HeValueNr(0), HeStateNr(0));
DispMediumValue("vessel", HeValueNr(0), HeStateNr(0));
}
*big = isbig;
return heValve == valve_on;
}
void HeButtons(byte top) {
if (!heAvailable) return;
DispButton(top, m_menu, m_he, "*LHe");
if (heValve == no_valve) {
if (heFast) {
DispButton(top - 2, m_he, he_slow, "-slow");
} else {
DispButton(top - 2, m_he, he_fast, "-fast");
}
} else {
if (heValve == valve_on) {
DispButton(top - 2, m_he, he_watch, "-watch");
} else {
if (heAuto) {
DispButton(top - 2, m_he, he_off, "-off");
} else {
DispButton(top - 2, m_he, he_watch, "-watch");
}
DispButton(top - 4, m_he, he_fill, "-fill");
}
}
}
void HeDisp() {
boolean showAuto;
byte codebase = m_he * 16;
//DispFullScreenTouch(m_he, he_more);
//DispCheckbox(he_fast, he_slow, p_heFast, "fast");
//DispState(0, p_heValve);
if (DispPage()) {
DispValue("%:", p_heLevel, p_heSensState);
DispValue("high: ", p_heHigh, 0);
DispValue("low: ", p_heLow, 0);
HeStateDisp(" ");
DispValue("mm:", p_heRaw, 0);
DispValue("empty:", p_heEmpty, 0);
DispValue("full:", p_heFull, 0);
DispButton(2, m_he, he_more, "back");
} else {
//DispState(0, p_heMeas);
if (heAvailable == 1) {
DispText("He level/%");
DispBigValue(p_heLevel, p_heSensState); // He level
if (heExtAvailable == 1 && heExtState[0] != he_disabled) {
DispLargeValue("v", HeValueNr(0), HeStateNr(0));
}
DispButton(3, m_he, he_more, "more");
if (heFast) {
DispButton(2, m_he, he_slow, "slow");
} else {
DispButton(2, m_he, he_fast, "fast");
}
}
HeStateDisp("");
if (heValve == valve_on) {
DispButton(5, m_he, he_watch, "watch");
} else if (heValve != no_valve) {
if (heAuto) {
DispButton(5, m_he, he_off, "off");
} else {
DispButton(5, m_he, he_watch, "watch");
}
DispButton(4, m_he, he_fill, "fill");
}
}
DispButton(0, m_menu, m_menu, "menu");
DispButton(1, m_menu, m_home, "home");
}
void HeEndMeas() {
if (HEDEBUG) {Serial.print(heChannel); if (heMeas == 2) Serial.println(" HeEndChk"); else Serial.println(" HeEndMeas"); }
// switch off current
digitalWrite(io_lev_enable, LOW);
pinMode(io_lev_enable, OUTPUT);
analogWrite(io_lev_current, 0);
digitalWrite(io_lev_boost, HIGH); // 48 V booster inactive
if (HeGetState(heChannel) != he_disabled) {
if (HEDEBUG) {
Serial.print(heChannel); Serial.print(" state "); Serial.println(heIntState);
}
// saving result
HeSetState(heChannel, heIntState);
if (heChannel >= 0 && heChannel <= 6) {
ARRAY(heMinLev,heChannel) = heMinLevel;
}
if (heIntState == he_sens_ok) {
if (heMeas == 1) HeSetLev(heChannel, heIntLevel);
} else if (heIntState == he_no_sens) {
HeSetLev(heChannel, 0);
}
}
ParSet(heMeas, 0); // off
if (heValve == valve_on) {
if (heLevel > heHigh && heCommand != he_manual) {
HeCmd(he_stop);
}
} else {
if (heLevel < heLow && heAuto && heSensState == he_sens_ok) {
HeCmd(he_fill);
}
}
}
void HeSelect() {
byte pin;
if (heChannel == 6) {
heIntDrive = heDrive;
res_to_len = 1e7 / heWiRes; // result is in 1e-5 m (+5), input in 1e-2 V (-2), heWiRes in Ohm/m, heCurrent in 1e-4 A (+4)
mm_to_percent = 100.0 / (heEmpty - heFull);
empty_10um = 100 * heEmpty;
digitalWrite(io_he_select, LOW);
} else {
heIntDrive = heExtDrive;
res_to_len = 1e7 / heExtWiRes;
mm_to_percent = 100.0 / (heExtEmpty - heExtFull);
empty_10um = 100 * heExtEmpty;
digitalWrite(io_he_select, HIGH);
}
if (heExtAvailable > 1) {
for (pin = 0; pin < 6; pin++) {
digitalWrite(io_ext1 + pin, pin != heChannel);
}
}
}
void HeHandler() {
static ulong last = 0;
static ulong lastChk = -3600000;
static long sumc = 0;
static long sump = 0;
static long summ = 0;
static int cnt = 0;
static long lastLevels[4];
long lev; // level in 0.01 mm
byte i, n;
long heVplus;
long expTime;
static int8_t stab = 0;
static byte pos;
static ulong start = 0;
static byte heNoSensCnt = 0;
static long hiLev = 0;
static ulong hiTim = 0;
static long lev0 = 0;
static ulong tim0 = 0;
static long slope;
static long heDriveCurrent = 0;
static boolean heWarmCheck = false;
ulong tim;
const float sum_to_current = 1235. / 1024 / 100 / 5 / 0.1; // 1235 mV / 1024 adcsteps / 100 sum_counts / 5 Ohm / 0.1 mA
const float sum_to_volt = 1235. / 1024 / 200 * 105.62 / 5.62 / 10; // 1235 mV / 1024 adcsteps / 200 sum_counts * (105.62 kOhm / 5.62 kOhm) / 10 mV;
if (heAvailable != 1 && heExtAvailable == 0) {
return;
}
if (heMeas == 0) { // not measuring/checking
if (checking) {
if (heIntState == he_not_yet) {
ParSet(heMeas, 1);
started = true;
return;
}
ParSet(heChannel, heChannel + 1);
if (heChannel > 6) { // this was the last channel
checking = false;
return;
}
HeLoadChannel();
if (heIntState == he_disabled) return;
ParSet(heMeas, 2); // check
started = true;
} else if (heChannel <= 6) { // we are finished with measuring a channel
ParSet(heChannel, heChannel + 1);
if (heChannel > 6) { // this was the last channel
return;
}
HeLoadChannel();
if (heIntState == he_disabled) return;
ParSet(heMeas, 1);
started = true;
} else {
if (heFast) {
expTime = heFastTime;
} else {
expTime = heSlowTime;
}
if (expired(&last, 1000 * expTime)) {
ParSet(heChannel, 0);
HeLoadChannel();
if (heIntState == he_disabled) return;
ParSet(heMeas, 1);
started = true;
} else if (expired(&lastChk, 1000 * 2)) { // check period
checking = true;
ParSet(heChannel, 0);
HeLoadChannel();
if (heIntState == he_disabled) return;
ParSet(heMeas, 2); // check
started = true;
} else {
return;
}
}
}
if (heMeas == 2) { // check
if (started) {
HeSelect();
started = false;
if (HEDEBUG) { Serial.print(heChannel); Serial.print (" start chk, "); };
sumc = 0;
summ = 0;
cnt = 0;
start = now;
analogWrite(io_lev_current, 1); // drive current 1 mA
// switch on current
pinMode(io_lev_enable, INPUT);
digitalWrite(io_lev_enable, HIGH); // input pullup
}
for (i = 0 ; i < 20; i++) {
summ += aRead(a_levb_vminus);
sumc += aRead(a_lev_current);
}
cnt += 20;
if (cnt < 100) return;
// cnt == 100
long cur = sumc * sum_to_current;
if (heChannel < 6) { // external channels only (vessels)
summ = summ * ((47.5 + 5.62) / 105.62); // 47.5 + 5.62 instead of 105.62 kOhm
heCableVolt0 = (summ - sumc) * sum_to_volt * 2; // voltage between vminus and iminus (* 2 because voltages are NOT summed twice)
}
if (HEDEBUG) { Serial.print(cur); Serial.print(",");}
if (cur > 3) { // there is a current
if (HEDEBUG) Serial.print("sens yes ");
if (heIntState == he_no_sens) {
if (HEDEBUG) Serial.print("was no ");
heIntState = he_not_yet;
}
HeEndMeas();
} else if (time_ge(now, start + 100)) { // no current after 0.1 sec
if (HEDEBUG) Serial.print("no sens ");
heIntState = he_no_sens;
HeEndMeas();
}
return;
}
if (started) {
HeSelect();
started = false;
if (HEDEBUG) { Serial.print(heChannel); Serial.print (" start he, "); };
sumc = 0;
sump = 0;
summ = 0;
cnt = 0;
stab = 0;
start = now;
hiLev = 0;
slope = 0;
if (heIntState == he_sens_warm) {
heDriveCurrent = heIntDrive / 3;
heWarmCheck = true;
} else {
heDriveCurrent = heIntDrive;
heWarmCheck = false;
}
analogWrite(io_lev_current, heDriveCurrent);
// switch on current
pinMode(io_lev_enable, INPUT);
digitalWrite(io_lev_enable, HIGH); // input pullup
for (i = 0; i < 4; i++) {
ARRAY(lastLevels,i) = undef_mm;
}
}
tim = now;
if (heChannel < 6) {
for (i = 0 ; i < 20; i++) {
sump += aRead(a_levb_vplus);
summ += aRead(a_levb_vminus);
sumc += aRead(a_lev_current);
summ += aRead(a_levb_vminus);
sump += aRead(a_levb_vplus);
}
} else {
if (heAvailable != 1) { // ext only
// should not happen, but may be ...
ParSet(heMeas, 2); // check
return;
}
for (i = 0 ; i < 20; i++) {
sump += aRead(a_lev_vplus);
summ += aRead(a_lev_vminus);
sumc += aRead(a_lev_current);
summ += aRead(a_lev_vminus);
sump += aRead(a_lev_vplus);
}
}
tim += (now - tim) / 2;
cnt += 20;
if (cnt < 100) return;
// cnt == 100
ParSet(heCurrent, sumc * sum_to_current);
if (time_ge(now, start + 500)) { // after 0.5 sec
if (heCurrent < heDriveCurrent * 5) { // measured current less than 50 % of drive current
heIntState = he_no_sens;
heIntLevel = 0;
HeEndMeas();
return;
}
}
if (heChannel < 6) {
if (HEDEBUG && 0) {
Serial.print("he ");
Serial.println(heChannel);
Serial.println(sump);
Serial.println(summ);
}
sump = sump * ((221 + 5.62) / 105.62); // 221 + 5.62 kOhm instead of 100 + 5.62 kOhm
summ = summ * ((47.5 + 5.62) / 105.62); // 47.5 + 5.62 instead of 105.62 kOhm
heCableVolt1 = (summ - sumc * 2) * sum_to_volt; // voltage between vminus and iminus (* 2 because sumc is NOT summed twice)
}
ParSet(heVolt, (sump - summ) * sum_to_volt);
heVplus = sump * sum_to_volt;
if (HEDEBUG && 0) {
Serial.print("(");
Serial.print(sump * sum_to_volt);
Serial.print("-");
Serial.print(summ * sum_to_volt);
Serial.print("/");
Serial.print(heCurrent);
Serial.print(")");
}
/*
if (heVplus > 2000 && heBooster) { // 20.00 V
digitalWrite(io_lev_boost, LOW); // 48 V booster active
} else {
digitalWrite(io_lev_boost, HIGH); // 48 V booster inactive
}
*/
sumc = 0;
sump = 0;
summ = 0;
cnt = 0;
lev = heVolt * (res_to_len / heCurrent);
if (HEDEBUG) {
//Serial.print("("); Serial.print(heVolt); Serial.print(" "); Serial.print(heWiRes); Serial.print(" "); Serial.print(heCurrent); Serial.print(")");
//Serial.print(lev, DEC); Serial.print(" ");
}
if (lev > hiLev) {
if (hiLev == 0) {
lev0 = lev;
tim0 = tim;
} else {
slope = (lev - lev0) * 10 / (tim - tim0);
}
hiLev = lev;
hiTim = tim;
stab = 0;
} else if (lev < hiLev + heMeasSpeed * (tim - hiTim) / 10) {// 1/10 = mm / sec * msec / 0.01 mm
stab++;
} else if (stab > 0) {
stab--;
}
pos = (pos + 1) % 4;
ARRAY(lastLevels,pos) = lev;
if (HEDEBUG && 0) {Serial.print(lev); Serial.print("\n"); }
if (lev > empty_10um + empty_10um / 33) { // value more than 3% more than empty length:
heIntState = he_sens_warm;
if (HEDEBUG) Serial.print("warm");
HeEndMeas();
return;
}
if (time_ge(now, start + 30000)) { // timeout
heIntState = he_timeout;
if (HEDEBUG) Serial.print("tmo");
HeEndMeas();
return;
}
if (heWarmCheck) {
heIntState = he_not_yet;
if (HEDEBUG) Serial.print("not warm");
HeEndMeas();
return;
}
if (HEDEBUG) { if (stab) {Serial.print(" stab"); Serial.print(stab, DEC);} else {Serial.print("~");} }
if (stab < 8) return; // not yet finished
heIntState = he_sens_ok;
ParSet(heSlope, slope);
ParSet(heFirst, lev0 - slope * (tim0 - start) / 10);
// finished measuring
n = 1;
for (i = 0; i < 4; i++) {
if (ARRAY(lastLevels,i) != undef_mm) {
lev += ARRAY(lastLevels,i);
n++;
}
}
lev /= n; // calculate the mean of up to 5 values
heIntLevel = (empty_10um - lev) * mm_to_percent; // lev is in 10 um = 0.01 mm, result is in 0.01 %
ParSet(heRaw, -lev); // negative raw value: while filling, value increases
if (HEDEBUG) {
Serial.print("r="); Serial.print(heRaw, DEC); Serial.print(" lev="); Serial.print(heIntLevel, DEC); Serial.print(' '); Serial.println(heMinLevel, DEC);
}
if (heIntLevel < heMinLevel) { // level decrease
heMinLevel = heIntLevel;
if (HEDEBUG) {
Serial.print(now - heLastIncrease, DEC); Serial.print(" ");
Serial.print(heMinLevel);
Serial.println(" minlevel\n");
}
if ((heFast || heValve == valve_on) && time_ge(now, heLastIncrease + heFastTimeout * 1000)) {
if (heFast) ParSet(heFast, false);
if (heCommand != he_manual) {
if (heValve == valve_on) {
ParSet(heValve, valve_timeout);
}
HeCmd(he_stop); // stop when no substantial increase with heFastTimeout
}
}
} else if (heIntLevel > heMinLevel + heIncreaseTolerance) { // significant level increase
if (!heFast && heExtAvailable <= 1) {
ParSet(heFast, true);
}
heMinLevel = heIntLevel;
if (HEDEBUG) Serial.println("last increase now 3");
heLastIncrease = now;
if (HEDEBUG) {
Serial.print(heMinLevel);
Serial.println(" he increase\n");
}
}
HeEndMeas();
}
void HeSetStart() {
// n2start = now;
// n2StartThreshold = n2lower - 500;
// if (n2StartThreshold < n2threshold) {
// n2StartThreshold = n2threshold;
// }
}
void HeRemoteCmd(byte cmd) {
if (heAvailable == 1 && heSensState > he_sens_warm) {
if (cmd == he_fill || cmd == he_watch) return;
}
if (heValve >= valve_timeout) {
ParSet(heValve, valve_off);
}
HeCmd(cmd);
}
void HeStopFill() {
ValveSet(io_he_valve, LOW);
if (heValve == valve_on) {
ParSet(heValve, valve_off);
}
}
void HeCmd(byte cmd) {
switch (cmd) {
case he_stop:
HeStopFill();
ParSet(heFast, false);
break;
case he_fill:
heLastIncrease = now;
ParSet(heFast, true);
ParSet(heAuto, true);
if (heValve != no_valve && (heAvailable != 1 || heLevel < heHigh)) {
if (heValve != valve_on) {
ValveSet(io_he_valve, HIGH);
}
ParSet(heValve, valve_on);
if (HEDEBUG) Serial.println("valve on");
HeSetStart();
} else if (HEDEBUG) {
Serial.println(heValve);
Serial.println(heLevel);
}
break;
case he_watch:
HeStopFill();
ParSet(heFast, false);
ParSet(heAuto, true);
break;
case he_off:
HeStopFill();
ParSet(heFast, false);
ParSet(heAuto, false);
break;
case he_fast:
ParSet(heFast, true);
if (HEDEBUG) Serial.println("last increase now 4");
heLastIncrease = now;
break;
case he_slow:
ParSet(heFast, false);
break;
case he_more:
DispNextPage(2);
break;
case he_manual:
if (heValve != no_valve) {
if (heValve != valve_on) {
ValveSet(io_he_valve, HIGH);
}
ParSet(heValve, valve_on);
if (HEDEBUG) Serial.println("valve on");
};
break;
}
}
void HeSetFast() {
HeCmd(he_fast);
}
void HeValveState(boolean ok) {
if (ok) {
if (heValve == no_valve) {
ParSet(heValve, valve_off);
}
} else {
ParSet(heValve, no_valve);
}
}
boolean HeStateDisp(const char *title) {
const char *text;
static char old[32];
if (heValve == valve_on) {
if (heMeas && heChannel == 6) {
text = "~fill meas";
} else if (heCommand == he_manual) {
text = "manual on";
} else {
text = "~filling";
}
} else if (heAuto && heValve == valve_off) {
if (heMeas == 1 && heChannel == 6) {
text = "watc.meas";
} else {
text = "watching";
}
} else if (heAvailable == 2) {
text = "fill off";
} else if (heFast) {
if (heMeas == 1 && heChannel == 6) {
text = "fast meas";
} else {
text = "fast";
}
} else if (heMeas == 1 && heChannel == 6) {
text = "meas";
} else {
text = " ";
}
/*
if (!textequal(old, text)) {
textcopy(old, sizeof old, text);
Serial.print(text); Serial.println("<HETEXT");
}
*/
DispTextRow(fmt_lsmall, title, text);
}
void HeStore(EeMode mode) {
// store parameters for external device
byte channel, usedMask;
if (mode == ee_write) {
usedMask = 0;
for (channel = 0; channel <= 6; channel++) {
if (HeGetState(channel) != he_disabled) bitSet(usedMask, channel);
}
}
eeStore((void *)&heExtWiRes, sizeof heExtWiRes, mode);
eeStore((void *)&heExtDrive, sizeof heExtDrive, mode);
eeStore((void *)&heExtEmpty, sizeof heExtEmpty, mode);
eeStore((void *)&heExtFull, sizeof heExtFull, mode);
eeStore((void *)&usedMask, sizeof usedMask, mode);
if (mode == ee_read) {
Serial.print("enabled he channels:");
for (channel = 0; channel <= 6; channel++) {
if (bitRead(usedMask, channel)) {
HeSetState(channel, he_not_yet);
Serial.print(" ");Serial.print(channel, DEC);
} else {
HeSetState(channel, he_disabled);
}
}
Serial.print("\nwire res."); Serial.print(heExtWiRes);
Serial.print(" Ohm/m\ndrive current "); Serial.print(heExtDrive);
Serial.print(" mA\nempty at "); Serial.print(heExtEmpty);
Serial.print(" mm from top\nfull at "); Serial.print(heExtFull);
Serial.print(" mm from top\n");
dispEco = 35;
// default for vessels
ParSet(heFast, 0);
ParSet(heLow, 0);
ParSet(heSlowTime, 1800);
//ParSet(heIncreaseTolerance, 99999);
}
}
void HeConfig(byte avail, byte cur, int wires, int empty, int full) {
if (HEDEBUG) Serial.println("HeConfig");
ParSet(heAvailable, avail);
if (avail) {
ParSet(heDrive, cur);
ParSet(heWiRes, wires);
ParSet(heEmpty, empty);
ParSet(heFull, full);
if (heExtAvailable == 1) {
HeSetState(0, he_not_yet);
}
/*
if ((long)wires * empty * cur > 22000000) {
ParSet(heBooster, 1);
} else {
ParSet(heBooster, 0);
}
*/
}
}