rename main file to ccu4-firmware
This commit is contained in:
-576
@@ -1,576 +0,0 @@
|
||||
#include "utils.h"
|
||||
#include "DispSerial.h"
|
||||
#include "SerialWrapper.h"
|
||||
#include "dipdisplay.h"
|
||||
#include "motor.h"
|
||||
#include "parser.h"
|
||||
#define ARRAY_CHECK
|
||||
#include "par.h"
|
||||
|
||||
#define RAMTEST 0
|
||||
#define SERIALCOMMON 0
|
||||
|
||||
PAR_TEXT configSoft[16] = "7.0";
|
||||
|
||||
long now; // global variable, updated by FastHandler
|
||||
byte inside;
|
||||
boolean displayAvailable;
|
||||
boolean online = 0;
|
||||
byte dispEco = 5; // default eco brightness: 5 %
|
||||
|
||||
// parameter list
|
||||
enum {
|
||||
p_none, p_flow, p_flowAvailable, p_flowSensState, p_motorState, p_motorAutoState,
|
||||
p_motorAvailable, p_motorPulse, p_motorOpenTime, p_motorCurrent, p_motorFreeCurrent,
|
||||
p_motorTorqueConst, p_motorTorque, p_motorTorqueLimit, p_motorFlowTarget,
|
||||
p_motorOverrunConst, p_motorOverrun, p_motorRead, p_motorWiggle,
|
||||
p_heLevel, p_heRaw, p_heAvailable, p_heDrive, p_heCurrent, p_heVolt, p_heHigh, p_heLow,
|
||||
p_heWiRes, p_heEmpty, p_heFull, p_heFastTime, p_heSlowTime, p_heSlope, p_heFirst,
|
||||
p_heValve, p_heSensState, p_heAuto, p_heMeas, p_heFast, p_heCommand, /* p_heBooster, */
|
||||
p_heIncreaseTolerance, p_heFastTimeout,
|
||||
p_n2Available, p_n2upper, p_n2lower, p_n2threshold, p_n2tubecooldelay,
|
||||
p_n2filltimeout, p_n2fault, p_n2auto, p_n2valve, p_n2command, p_boostdelay,
|
||||
p_codeA, p_codeB, p_codeAbad, p_codeBbad, p_freeRam,
|
||||
p_timC, p_timN, p_timH, p_timF, p_timM, p_timV, p_timQ,
|
||||
p_configDevice, p_configDeviceState, p_configSoft, p_configIdn, p_configSpecial,
|
||||
p_configSave, p_configVersion, p_configItem, p_configInstr,
|
||||
p_auxAvailable, p_aux, p_auxScale, p_auxDigits, p_auxLabel,
|
||||
p_heFeedback, p_n2Feedback, p_vuAvailable, p_heExtAvailable, p_heExtChannel,
|
||||
p_nBase
|
||||
};
|
||||
|
||||
enum {p_vu = p_nBase - 1, p_vuCmd = p_vu + 12}; // valve unit base (+ 24 parameters)
|
||||
enum {p_heExtWiRes = p_nBase, p_heExtEmpty, p_heExtFull, p_heExtLevel, p_heExtState = p_heExtLevel + 6}; // he ext base (+ 15 parameters)
|
||||
|
||||
enum {p_nPar = p_nBase + 24}; // max. parameter of all extensions
|
||||
|
||||
enum {no_extension, valve_extension, he_extension};
|
||||
byte extension = valve_extension;
|
||||
|
||||
char *menu_text = "menu|home|configuration";
|
||||
char *menu_text1_flow = "needle valve";
|
||||
char *menu_text2_n2 = "LN2";
|
||||
char *menu_text3_he = "LHe level";
|
||||
enum {m_none, m_menu, m_home, m_device, m_instr, m_loading, m_commands, m_config, m_nv, m_n2, m_he, m_ext};
|
||||
enum {stop_all};
|
||||
enum {N_hdl = 8};
|
||||
|
||||
byte screen = m_home; // screen shown on start
|
||||
|
||||
PAR_TEXT configIdn[16] = "CCU4";
|
||||
PAR_BYTE n2Available = 0;
|
||||
PAR_BYTE heAvailable = 0;
|
||||
PAR_BYTE flowAvailable = 0;
|
||||
PAR_BYTE motorAvailable = 0; // was 1, why?
|
||||
PAR_BYTE vuAvailable = 0;
|
||||
PAR_BYTE heExtAvailable = 0; // 0: no addition He Level channel, 1: 2nd He Channel, 6: 6 additional channels with He Extension
|
||||
PAR_BYTE auxAvailable = 0;
|
||||
PAR_LONG timC = 0;
|
||||
PAR_LONG timN = 0;
|
||||
PAR_LONG timH = 0;
|
||||
PAR_LONG timF = 0;
|
||||
PAR_LONG timM = 0;
|
||||
PAR_LONG timV = 0;
|
||||
PAR_LONG timQ = 0;
|
||||
|
||||
|
||||
// parameters for Summary command:
|
||||
int sumidx = 0; // actual position in parameter list
|
||||
int sumsup = 0; // index of next supplementary parameters to write
|
||||
|
||||
enum {
|
||||
io_lev_enable = 2,
|
||||
io_lev_current = 3,
|
||||
io_motor_enable = 4,
|
||||
io_motor_current = 5,
|
||||
io_motor_open = 6,
|
||||
io_motor_close = 7,
|
||||
io_n2_valve = 8,
|
||||
io_he_valve = 9,
|
||||
io_motor2_open = 10,
|
||||
io_motor2_close = 11,
|
||||
io_lev_boost = 12,
|
||||
io_valve_boost = 13,
|
||||
io_disp_input = 20,
|
||||
io_he_select = 21,
|
||||
io_ext1 = 22,
|
||||
io_ext2 = 30,
|
||||
io_ext3 = 38,
|
||||
io_ext4 = 46
|
||||
};
|
||||
|
||||
enum {
|
||||
a_lev_current = 0,
|
||||
a_lev_vplus = 1,
|
||||
a_levb_vplus = 2,
|
||||
a_lev_vminus = 3,
|
||||
a_codea = 4,
|
||||
a_codeb = 5,
|
||||
a_n2_lower = 6,
|
||||
a_n2_upper = 7,
|
||||
a_flow_prec = 8,
|
||||
a_flow_raw = 9,
|
||||
a_motor_volt = 10,
|
||||
a_motor_current = 11,
|
||||
a_lhe_feedback = 12,
|
||||
a_ln2_feedback = 13,
|
||||
a_aux_current = 14,
|
||||
a_levb_vminus = 15
|
||||
};
|
||||
|
||||
|
||||
#if (SERIALCOMMON)
|
||||
#define Serial2 Serial
|
||||
#endif
|
||||
|
||||
DispSerial SerialD(&Serial3);
|
||||
SerialWrapper SerialC(&Serial2);
|
||||
|
||||
void setup() {
|
||||
analogReference(EXTERNAL);
|
||||
#if (RAMTEST)
|
||||
RamFill();
|
||||
#endif
|
||||
Serial.begin(9600);
|
||||
Serial.print("\n---------\n");
|
||||
Serial3.begin(9600);
|
||||
#if (!SERIALCOMMON)
|
||||
Serial2.begin(9600);
|
||||
#endif
|
||||
SerialC.handler = HardHandler;
|
||||
SerialD.handler = HardHandler;
|
||||
ParSetAllChanged();
|
||||
ConfigInit();
|
||||
ValveInit();
|
||||
HeInit();
|
||||
FlowInit();
|
||||
switch (extension) {
|
||||
case valve_extension: VuInit(); break;
|
||||
case he_extension: break;
|
||||
}
|
||||
displayAvailable = DispInit(ParHandler, m_home); // initialize Display and tell that it should call ParHandler between every line written on the display
|
||||
WriteDisplay();
|
||||
}
|
||||
|
||||
void Pars() {
|
||||
FlowPars();
|
||||
HePars();
|
||||
N2Pars();
|
||||
ValvePars();
|
||||
ConfigPars();
|
||||
if (auxAvailable) AuxPars();
|
||||
ParFixed("tc", timC, 1);
|
||||
ParFixed("tn", timN, 1);
|
||||
ParFixed("th", timH, 1);
|
||||
ParFixed("tf", timF, 1);
|
||||
ParFixed("tm", timM, 1);
|
||||
ParFixed("tv", timV, 1);
|
||||
ParFixed("tq", timQ, 0);
|
||||
switch (extension) {
|
||||
case valve_extension: VuPars(); break;
|
||||
}
|
||||
}
|
||||
|
||||
void HomeDisp() {
|
||||
boolean run = false;
|
||||
boolean big = false;
|
||||
|
||||
ConfigDispShort(configSoft);
|
||||
DispFullScreenTouch(m_menu * 16); // indicate full screen touch
|
||||
if (HeShown()) {
|
||||
run |= HeDispShort(&big);
|
||||
DispLine();
|
||||
}
|
||||
if (flowAvailable || motorAvailable) {
|
||||
run |= FlowDispShort(!big);
|
||||
DispLine();
|
||||
}
|
||||
if (auxAvailable) {
|
||||
AuxDisp();
|
||||
DispLine();
|
||||
}
|
||||
if (N2Shown()) {
|
||||
run |= N2DispShort();
|
||||
DispLine();
|
||||
}
|
||||
switch (extension) {
|
||||
case valve_extension: VuDispShort(); DispLine(); break;
|
||||
}
|
||||
if (run) {
|
||||
DispButton(1, stop_all, "stop");
|
||||
} else if (!online) {
|
||||
DispButton(1, m_menu * 16, ":offline"); // button code as on full screen touch
|
||||
}
|
||||
DispButton(0, m_menu * 16 + m_commands, "menu");
|
||||
}
|
||||
|
||||
void CmdDisp() {
|
||||
N2Buttons(7);
|
||||
MotorButtons(12);
|
||||
HeButtons(13);
|
||||
switch (extension) {
|
||||
case valve_extension: VuButtons(6); break;
|
||||
}
|
||||
DispButton(2, m_menu * 16 + m_config, "config");
|
||||
DispButton(1, m_menu * 16 + m_home, "home");
|
||||
}
|
||||
|
||||
void WriteDisplay() {
|
||||
DispBegin(screen);
|
||||
/*
|
||||
DispMenu(0, 1, menu_text);
|
||||
if (flowAvailable || motorAvailable) {
|
||||
DispAppendToMenu(menu_text1_flow);
|
||||
}
|
||||
if (N2Shown()) {
|
||||
DispAppendToMenu(menu_text2_n2);
|
||||
}
|
||||
if (HeShown()) {
|
||||
DispAppendToMenu(menu_text3_he);
|
||||
}
|
||||
DispEndMenu();
|
||||
*/
|
||||
switch (screen) {
|
||||
case m_home:
|
||||
if (extension == he_extension) {
|
||||
HeDispExt();
|
||||
DispEnd();
|
||||
return;
|
||||
}
|
||||
HomeDisp();
|
||||
break;
|
||||
case m_loading:
|
||||
ConfigLoadingDisp();
|
||||
break;
|
||||
case m_commands:
|
||||
CmdDisp();
|
||||
break;
|
||||
case m_config:
|
||||
ConfigDispShort("cfg");
|
||||
ConfigDisp();
|
||||
break;
|
||||
case m_device:
|
||||
ConfigDeviceDisp();
|
||||
break;
|
||||
case m_instr:
|
||||
ConfigInstrDisp();
|
||||
break;
|
||||
case m_he:
|
||||
ConfigDispShort("LHe");
|
||||
HeDisp();
|
||||
break;
|
||||
case m_n2:
|
||||
ConfigDispShort("LN2");
|
||||
N2Disp();
|
||||
break;
|
||||
case m_nv:
|
||||
ConfigDispShort("n.v.");
|
||||
FlowDisp();
|
||||
break;
|
||||
case m_ext:
|
||||
switch (extension) {
|
||||
case valve_extension:
|
||||
ConfigDispShort("valves");
|
||||
VuDisp();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// DispButton(0, m_menu * 16 + m_commands, "menu");
|
||||
// DispButton(1, m_menu * 16 + m_home, "home");
|
||||
DispEnd();
|
||||
}
|
||||
|
||||
void DisplayHandler() {
|
||||
int button;
|
||||
byte menu, code;
|
||||
static ulong last=0;
|
||||
static ulong lastW=0;
|
||||
|
||||
//if (!expired(&last, 30)) return;
|
||||
DispGet(menu, code);
|
||||
switch (menu) {
|
||||
case disp_wake: // wake up
|
||||
screen = m_home;
|
||||
if (heExtAvailable <= 1) HeSetFast();
|
||||
break;
|
||||
case disp_none: // nothing touched
|
||||
break;
|
||||
case disp_sleep: // sleep
|
||||
screen = m_home;
|
||||
break;
|
||||
case m_menu:
|
||||
if (code == 0) {
|
||||
screen = m_commands;
|
||||
} else {
|
||||
screen = code;
|
||||
}
|
||||
break;
|
||||
case m_home:
|
||||
if (code == stop_all) {
|
||||
HeCmd(stop_all);
|
||||
N2Cmd(stop_all);
|
||||
MotorCmd(stop_all);
|
||||
}
|
||||
break;
|
||||
case m_config:
|
||||
ConfigCmd(code);
|
||||
break;
|
||||
case m_device:
|
||||
ConfigDeviceCmd(code);
|
||||
break;
|
||||
case m_instr:
|
||||
ConfigInstrCmd(code);
|
||||
break;
|
||||
case m_nv:
|
||||
MotorCmd(code);
|
||||
break;
|
||||
case m_n2:
|
||||
N2Cmd(code);
|
||||
break;
|
||||
case m_he:
|
||||
HeCmd(code);
|
||||
break;
|
||||
case m_ext:
|
||||
if (extension == valve_extension) VuCmd(code);
|
||||
break;
|
||||
}
|
||||
|
||||
ParHandler();
|
||||
if (!expired(&lastW, 100)) return;
|
||||
WriteDisplay();
|
||||
}
|
||||
|
||||
boolean spc;
|
||||
name_t name;
|
||||
|
||||
void OutResult(boolean ok) {
|
||||
char *value;
|
||||
long s;
|
||||
|
||||
if (name != 0) {
|
||||
if (spc) {
|
||||
SerialC.write(' ');
|
||||
} else {
|
||||
spc = true;
|
||||
}
|
||||
s = micros();
|
||||
value = ParFmtByName(name);
|
||||
SerialC.print(c40(name));
|
||||
if (value == 0 || !ok) {
|
||||
SerialC.write('?');
|
||||
} else {
|
||||
SerialC.write('=');
|
||||
SerialC.print(value);
|
||||
}
|
||||
name = 0;
|
||||
}
|
||||
}
|
||||
|
||||
byte List(byte nr, name_t name, const char *formatted, const char *astext, byte unchanged) {
|
||||
SerialC.print(c40(name));
|
||||
SerialC.print('\t');
|
||||
if (formatted) {
|
||||
SerialC.print(formatted);
|
||||
}
|
||||
if (astext) {
|
||||
SerialC.print('\t');
|
||||
if (astext[0] == '~') { // remove blink control character
|
||||
astext++;
|
||||
}
|
||||
SerialC.print(astext);
|
||||
}
|
||||
SerialC.print('\n');
|
||||
return 0;
|
||||
}
|
||||
|
||||
byte Summary(byte nr, name_t name, const char *formatted, const char *astext, byte unchanged) {
|
||||
char str[8];
|
||||
|
||||
if (!formatted) return 0;
|
||||
sumidx++;
|
||||
if (unchanged && sumsup / 4 != sumidx / 4) return 0; // write unchanged only if within sumsup ... sumsup + 3
|
||||
c40toString(name, str, sizeof str);
|
||||
SerialC.print(str);
|
||||
SerialC.print('=');
|
||||
SerialC.print(formatted);
|
||||
SerialC.print(' ');
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ShowSummary() {
|
||||
sumidx = 0;
|
||||
ParScan(Summary); // show changed values plus the parameters within sumsup ... sumsup + 3
|
||||
sumsup += 4;
|
||||
if (sumsup > sumidx) {
|
||||
sumsup = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ParHandler() {
|
||||
char *txt;
|
||||
ParserType type;
|
||||
char sym;
|
||||
static ulong lastQuery = 0;
|
||||
|
||||
if (bitRead(inside, 0)) {
|
||||
Serial.print("already inside ParHandler\n");
|
||||
return;
|
||||
}
|
||||
bitSet(inside,0);
|
||||
HardHandler();
|
||||
type = Parser();
|
||||
if (type == parser_none) {
|
||||
if (online && time_ge(now, lastQuery + 5000)) {
|
||||
online = false;
|
||||
}
|
||||
} else {
|
||||
lastQuery = now;
|
||||
online = true;
|
||||
|
||||
switch (type) {
|
||||
case parser_value:
|
||||
//Serial.println("number");
|
||||
if (name == 0) {
|
||||
SerialC.print('?');
|
||||
}
|
||||
OutResult(ParCommand(name));
|
||||
break;
|
||||
// case parser_colon:
|
||||
// name = ParserIdent();
|
||||
// ParSetHidden(name);
|
||||
// name = 0;
|
||||
// break;
|
||||
case parser_ident:
|
||||
OutResult(true);
|
||||
name = ParserIdent();
|
||||
break;
|
||||
case parser_symbol:
|
||||
sym = ParserSymbol();
|
||||
if (sym == ':') {
|
||||
ParHide(name);
|
||||
name = 0;
|
||||
break;
|
||||
}
|
||||
OutResult(true);
|
||||
if (sym == '*') {
|
||||
ParScan(List);
|
||||
} else if (sym == '?') {
|
||||
ShowSummary();
|
||||
} else if (sym == '!') {
|
||||
DispDebug(true);
|
||||
} else if (sym == '$') {
|
||||
#if (RAMTEST)
|
||||
RamTest();
|
||||
#else
|
||||
SerialC.print(F("ramtest disabled\n"));
|
||||
#endif
|
||||
} else {
|
||||
SerialC.print(sym);
|
||||
}
|
||||
spc = false;
|
||||
break;
|
||||
case parser_error:
|
||||
SerialC.print('?');
|
||||
break;
|
||||
}
|
||||
}
|
||||
bitClear(inside,0);
|
||||
}
|
||||
|
||||
int aRead(byte pin) {
|
||||
int result;
|
||||
|
||||
result = analogRead(pin);
|
||||
FastHandler();
|
||||
return result;
|
||||
}
|
||||
|
||||
void FastHandler() {
|
||||
static long old = 0;
|
||||
|
||||
now = millis();
|
||||
if (now == old) return;
|
||||
|
||||
if (now - old > timQ && old != 0) {
|
||||
//Serial.println(old);
|
||||
//Serial.println(now);
|
||||
ParSet(timQ, now - old);
|
||||
}
|
||||
/*
|
||||
if ((ulong) now / 1000 != (ulong) old / 1000) {
|
||||
//Serial.print(now, DEC); Serial.println("tick");
|
||||
}
|
||||
*/
|
||||
old = now;
|
||||
MotorFastHandler();
|
||||
ValveFastHandler();
|
||||
}
|
||||
|
||||
void HardHandler() {
|
||||
static byte hdl=0;
|
||||
static ulong callcnt = 0;
|
||||
static long times[N_hdl] = {0};
|
||||
static long cnt[N_hdl] = {0};
|
||||
static long last = 0;
|
||||
byte i;
|
||||
long t;
|
||||
long m;
|
||||
|
||||
if (bitRead(inside, 1)) {
|
||||
Serial.print("already inside HardHandler\n");
|
||||
return;
|
||||
}
|
||||
bitSet(inside, 1);
|
||||
FastHandler();
|
||||
callcnt++;
|
||||
if (time_ge(now, callcnt)) {
|
||||
bitClear(inside, 1);
|
||||
return; // make sure that this function does not consume more than 1 ms IN AVERAGE (for serial connections)
|
||||
}
|
||||
if (time_ge(now, callcnt + 1000)) {
|
||||
Serial.println(now);
|
||||
Serial.println(callcnt);
|
||||
Serial.print("HardHandler is not called often enough\n");
|
||||
callcnt = now - 1000;
|
||||
}
|
||||
|
||||
t = micros();
|
||||
switch (hdl) {
|
||||
case 0: ConfigHandler(); break;
|
||||
case 1: N2Handler(); break;
|
||||
case 2: HeHandler(); break;
|
||||
case 3: FlowHandler(); break;
|
||||
case 4: MotorHandler(); break;
|
||||
case 5: ValveHandler(); break;
|
||||
case 6: AuxHandler(); break;
|
||||
case 7: if (extension == valve_extension) VuHandler(); break;
|
||||
}
|
||||
t = micros() - t;
|
||||
times[hdl] += t;
|
||||
cnt[hdl] ++;
|
||||
if (cnt[hdl] >= 10) {
|
||||
m = times[hdl] * 0.001;
|
||||
switch (hdl) {
|
||||
case 0: ParSet(timC, m); break;
|
||||
case 1: ParSet(timN, m); break;
|
||||
case 2: ParSet(timH, m); break;
|
||||
case 3: ParSet(timF, m); break;
|
||||
case 4: ParSet(timM, m); break;
|
||||
case 5: ParSet(timV, m); break;
|
||||
}
|
||||
cnt[hdl] = 0;
|
||||
times[hdl] = 0;
|
||||
}
|
||||
hdl++;
|
||||
if (hdl >= N_hdl) {
|
||||
hdl = 0;
|
||||
}
|
||||
bitClear(inside, 1);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
ParHandler();
|
||||
if (displayAvailable) DisplayHandler();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user