Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/device-client.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
- name: install flutter
uses: subosito/flutter-action@v2
with:
flutter-version: '3.24.3'
flutter-version: '3.27.1'
channel: 'stable'
- name: use cache
uses: actions/cache@v3
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/log_file_client.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
- name: install flutter
uses: subosito/flutter-action@v2
with:
flutter-version: '3.24.3'
flutter-version: '3.27.1'
channel: 'stable'
- name: use cache
uses: actions/cache@v3
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/log_file_server.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
- name: install flutter
uses: subosito/flutter-action@v2
with:
flutter-version: '3.24.3'
flutter-version: '3.27.1'
channel: 'stable'
- name: use cache
uses: actions/cache@v3
Expand Down
6 changes: 3 additions & 3 deletions examples/TankController/TankController.ino
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ void serialEvent1() { // if the hardware serial port_1 receives a char
tank->serialEvent1();
}
void setup() {
// the install process is followed by a reset and we get two startups
delay(500);
// the install process is followed by a reset and we can get two startups
delay(2000);
tank = TankController::instance(remoteLogName, pushingBoxID, tzOffsetHrs);
tank->setup();
}

void loop() {
tank->loop();
tank->loop(true);
}
2 changes: 1 addition & 1 deletion extras/device_client/lib/components/display.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class Display extends StatelessWidget {
color: Colors.grey.shade800,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.5),
color: Colors.black.withValues(alpha: 0.5),
spreadRadius: 5,
blurRadius: 7,
offset: const Offset(0, 3),
Expand Down
2 changes: 1 addition & 1 deletion extras/device_client/lib/model/version.dart
Original file line number Diff line number Diff line change
@@ -1 +1 @@
const String gitVersion = 'v24.10.2-3-g06a+';
const String gitVersion = 'v24.10.2-12-g1a+';
2 changes: 1 addition & 1 deletion extras/mockUI/libTC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ void loop() {
if (msBehind) {
delay(msBehind);
}
TankController::instance()->loop();
TankController::instance()->loop(true);
}

uint32_t millisecondsSinceEpoch() {
Expand Down
86 changes: 48 additions & 38 deletions src/TankController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,29 @@ TankController *TankController::_instance = nullptr;
*/
TankController *TankController::instance(const char *remoteLogName, const char *pushingBoxID, int tzOffsetHrs) {
if (!_instance) {
_instance = new TankController(remoteLogName);
serial(F("\r\n##############\r\nTankController %s"), TANK_CONTROLLER_VERSION);
_instance = new TankController();
unsigned long start = millis();
SD_TC::instance()->setRemoteLogName(remoteLogName);
EEPROM_TC::instance();
Keypad_TC::instance();
LiquidCrystal_TC::instance(TANK_CONTROLLER_VERSION);
DataLogger::instance();
DateTime_TC::rtc();
Ethernet_TC::instance();
EthernetServer_TC::instance();
ThermalProbe_TC::instance();
ThermalControl::instance();
PHProbe::instance();
PHControl::instance();
PID_TC::instance();
pinMode(LED_BUILTIN, OUTPUT);
_instance->state = new MainMenu();
PushingBox::instance(pushingBoxID);
GetTime::instance(tzOffsetHrs);
serial(F("Free memory = %i"), _instance->freeMemory());
wdt_enable(WDTO_8S);
serial(F("TankController::instance() - took %lu ms"), millis() - start);
}
return _instance;
}
Expand All @@ -58,25 +78,8 @@ void TankController::deleteInstance() {
/**
* Constructor
*/
TankController::TankController(const char *remoteLogName) {
serial(F("\r\n#################\r\nTankController::TankController() - version %s"), TANK_CONTROLLER_VERSION);
TankController::TankController() {
assert(!_instance);
// ensure we have instances
SD_TC::instance()->setRemoteLogName(remoteLogName);
EEPROM_TC::instance();
Keypad_TC::instance();
LiquidCrystal_TC::instance(TANK_CONTROLLER_VERSION);
DataLogger::instance();
DateTime_TC::rtc();
Ethernet_TC::instance();
EthernetServer_TC::instance();
ThermalProbe_TC::instance();
ThermalControl::instance();
PHProbe::instance();
PHControl::instance();
PID_TC::instance();
state = new MainMenu();
pinMode(LED_BUILTIN, OUTPUT);
}

/**
Expand Down Expand Up @@ -156,27 +159,36 @@ void TankController::handleUI() {
}

/**
* This is one of two public instance functions.
* This is one of two public instance functions (the other is setup()).
* It is called repeatedly while the board is on.
* (It appears to be called about once every 15 ms.)
* We monitor two elapsed times:
* 1. the time it takes to run the loop() function (our code); and,
* 2. the time from one loop start to the next (including the board delay).
*/
void TankController::loop(bool report_loop_delay) {
static unsigned long lastTime = 0;
unsigned long thisTime = millis();
if (report_loop_delay && lastTime && thisTime - lastTime > 500) {
// report unusual delay
serial(F("unexpected delay of %i ms"), thisTime - lastTime);
static unsigned long previousLoopStart = 0;
unsigned long currentLoopStart = millis();
if (report_loop_delay && previousLoopStart && currentLoopStart - previousLoopStart > 300) {
serial(F("unexpected overall delay of %i ms (at %lu sec uptime)"), currentLoopStart - previousLoopStart,
millis() / 1000);
}
lastTime = thisTime;
wdt_reset();
blink(); // blink the on-board LED to show that we are running
updateControls(); // turn CO2 and temperature controls on or off
handleUI(); // look at keypad, update LCD (~90ms)
DataLogger::instance()->loop(); // record current data to SD and serial
GetTime::instance()->loop(); // update the time
PushingBox::instance()->loop(); // write data to Google Sheets (~1130ms every report)
Ethernet_TC::instance()->loop(); // renew DHCP lease
EthernetServer_TC::instance()->loop(); // handle any HTTP requests
blink(); // blink the on-board LED to show that we are running (0ms)
updateControls(); // turn CO2 and temperature controls on or off (~90ms)
handleUI(); // look at keypad, update LCD (~10ms)
DataLogger::instance()->loop(); // record current data to SD and serial (~80ms)
GetTime::instance()->loop(); // update the time (~0ms)
PushingBox::instance()->loop(); // write data to Google Sheets (~0ms; ~1130ms every report)
Ethernet_TC::instance()->loop(); // renew DHCP lease (~0ms)
EthernetServer_TC::instance()->loop(); // handle any HTTP requests (~0ms)
if (report_loop_delay) {
static long int count = 0;
unsigned long currentLoopTime = millis() - currentLoopStart;
if (++count % 10000 == 1 || currentLoopTime > 200) { // first time through and periodically thereafter
serial(F("TankController::loop() - took %lu ms (at %lu sec uptime)"), currentLoopTime, millis() / 1000);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, just set previousLoopStop to millis() ("previous" isn't quite right, but it's about to be previous)

previousLoopStart = currentLoopStart;
}

/**
Expand Down Expand Up @@ -211,9 +223,7 @@ void TankController::setNextState(UIState *newState, bool update) {
* Here we do any one-time startup initialization.
*/
void TankController::setup() {
serial(F("TankController::setup()"));
serial(F("Free memory = %i"), freeMemory());
wdt_enable(WDTO_8S);
// all the setup happens in the instance() function
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/TankController.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class TankController {
// instance methods
bool isInCalibration();
int freeMemory();
void loop(bool report_loop_delay = true);
void loop(bool report_loop_delay = false);
void serialEvent();
void serialEvent1();
void setNextState(UIState* newState, bool update = false);
Expand All @@ -42,7 +42,7 @@ class TankController {
char nextKey = 0;

// instance methods
TankController(const char* remoteLogName);
TankController();
~TankController();
void blink();
void handleUI();
Expand Down
2 changes: 1 addition & 1 deletion src/Version.h
Original file line number Diff line number Diff line change
@@ -1 +1 @@
#define VERSION "v24.10.2-3-g06a+"
#define VERSION "v24.10.2-12-g1a+"
4 changes: 2 additions & 2 deletions src/model/JSONBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ int JSONBuilder::buildCurrentValues() {
char pHSlope[20];
float pHSineAmplitude = 0.0;
if ((EEPROM_TC::instance()->getPhSinePeriod() / 3600.0) > 0) {
pHSineAmplitude = (PHControl::instance()->getAmplitude() ? PHControl::instance()->getAmplitude() : 0);
pHSineAmplitude = PHControl::instance()->getAmplitude();
}
int pHSineAmplitude_f = (int)(pHSineAmplitude * 1000 + 0.5) % 1000;
while (pHSineAmplitude_f && pHSineAmplitude_f % 10 == 0) {
Expand Down Expand Up @@ -111,7 +111,7 @@ int JSONBuilder::buildCurrentValues() {
float pH_SinePeriodHours = 0.0;
int pH_SinePeriodHours_f = 0;
// if sine amplitude is nonzero, then we are in sine mode and display the sine period
if (pHSineAmplitude != 0) {
if (pHSineAmplitude > 0.01) {
pH_SinePeriodHours = EEPROM_TC::instance()->getPhSinePeriod() / 3600.0;
}
if (pH_SinePeriodHours > 0) {
Expand Down
2 changes: 1 addition & 1 deletion src/wrappers/SD_TC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ void SD_TC::deleteInstance() {
* constructor
*/
SD_TC::SD_TC() {
Serial.println(F("SD_TC()")); // Serial_TC might not be ready yet
Serial.println(F("SD_TC")); // Serial_TC might not be ready yet
assert(_instance == nullptr);
if (!sd.begin(SD_SELECT_PIN)) {
Serial.println(F("SD_TC failed to initialize!"));
Expand Down
18 changes: 9 additions & 9 deletions test/DataLoggerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ unittest(loop) {
assertEqual("", sd->mostRecentRemoteLogEntry);

// initial loop
tc->loop(false);
tc->loop();
assertEqual("", sd->mostRecentDataLogHeader);
assertEqual("", sd->mostRecentDataLogLine);
assertEqual("heater turned on at 6 after 6 ms", serialPort->getBuffer());
Expand All @@ -47,10 +47,10 @@ unittest(loop) {

// data log after one second
delay(1000);
tc->loop(false); // write to data log
tc->loop(false); // should not write to serial log
tc->loop(false); // should not write data to remote log
tc->loop(false); // should not write warning to remote log
tc->loop(); // write to data log
tc->loop(); // should not write to serial log
tc->loop(); // should not write data to remote log
tc->loop(); // should not write warning to remote log
assertEqual("time,tankid,temp,temp setpoint,pH,pH setpoint,upTime,Kp,Ki,Kd", sd->mostRecentDataLogHeader);
assertEqual("08/15/2023 00:00:01, 0, 0.00, 20.00, 0.000, 8.100, 1, 100000.0, 0.0, 0.0",
sd->mostRecentDataLogLine);
Expand All @@ -59,13 +59,13 @@ unittest(loop) {

// serial log after one minute
delay(59000);
tc->loop(false); // write to data log
tc->loop(false); // write to serial log
tc->loop(); // write to data log
tc->loop(); // write to serial log
assertEqual("00:01 pH=0.000 temp= 0.00", serialPort->getBuffer());

// remote log entry after one minute
assertFalse(0.0 == thermalProbe->getSampleMean());
tc->loop(false); // write info to remote log
tc->loop(); // write info to remote log
assertTrue(isnan(thermalProbe->getSampleMean())); // thermal sample has been collected
assertTrue(isnan(thermalProbe->getSampleStandardDeviation())); // thermal sample has been reset
char infoString[512] = "";
Expand All @@ -89,7 +89,7 @@ unittest(writeWarningToLog) {
dl->writeWarningSoon();
assertTrue(dl->getShouldWriteWarning());
delay(19000);
tc->loop(false); // write the warning
tc->loop(); // write the warning
char warningString[512] = "";
snprintf(warningString, sizeof(warningString), "%s\t%s", VERSION,
"0\tW\t2023-08-15 "
Expand Down
12 changes: 6 additions & 6 deletions test/EnablePIDTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ unittest(DisablePID) {
test->setValue(9.0);
assertFalse(PHControl::instance()->getUsePID());
assertEqual("EnablePID", tc->stateName());
tc->loop(false); // transition to Wait
tc->loop(); // transition to Wait
assertEqual("Wait", tc->stateName());
delay(3000);
tc->loop(false); // after the delay, Wait will call setNextState
tc->loop(false); // now transition back to main
tc->loop(); // after the delay, Wait will call setNextState
tc->loop(); // now transition back to main
assertEqual("MainMenu", tc->stateName());
}

Expand All @@ -42,11 +42,11 @@ unittest(EnablePID) {
test->setValue(1.0);
assertTrue(PHControl::instance()->getUsePID());
assertEqual("EnablePID", tc->stateName());
tc->loop(false); // transition to Wait
tc->loop(); // transition to Wait
assertEqual("Wait", tc->stateName());
delay(3000);
tc->loop(false); // after the delay, Wait will call setNextState
tc->loop(false); // now transition back to main
tc->loop(); // after the delay, Wait will call setNextState
tc->loop(); // now transition back to main
assertEqual("MainMenu", tc->stateName());
}

Expand Down
10 changes: 5 additions & 5 deletions test/EthernetServerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ unittest(display) {
server->loop();
EthernetClient_CI client = server->getClient();
TankController* tc = TankController::instance();
tc->loop(false); // for main menu to idle
tc->loop(); // for main menu to idle
const char request[] =
"GET /api/1/display HTTP/1.1\r\n"
"Host: localhost:80\r\n"
Expand All @@ -89,7 +89,7 @@ unittest(display) {
"Accept-Language: en-US\r\n"
"\r\n";
client.pushToReadBuffer(request);
tc->loop(false); // for targets to take effect
tc->loop(); // for targets to take effect
deque<uint8_t>* pBuffer = client.writeBuffer();
assertTrue(pBuffer->size() > 100);
String response;
Expand Down Expand Up @@ -147,10 +147,10 @@ unittest(keypress) {
"\r\n";
assertEqual(expectedResponse, response);
assertEqual(FINISHED, server->getState());
tc->loop(false); // Loop to handle the UI press
tc->loop(); // Loop to handle the UI press
assertEqual("Change settings ", lcd->getLines().at(0));
delay(60000); // IDLE_TIMEOUT
tc->loop(false);
tc->loop();
assertEqual("MainMenu", tc->stateName());
assertEqual(NOT_CONNECTED, server->getState());
client.stop();
Expand All @@ -171,7 +171,7 @@ unittest(currentData) {
ThermalControl::instance()->setThermalTarget(21.75); // target
EEPROM_TC::instance()->setHeat(0);
PID_TC::instance()->setTunings(5000.5, 1234.46, 987.44);
TankController::instance()->loop(false); // for targets to take effect
TankController::instance()->loop(); // for targets to take effect

EthernetServer_TC* server = EthernetServer_TC::instance();
server->setHasClientCalling(true);
Expand Down
12 changes: 6 additions & 6 deletions test/GetTimeTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ unittest_teardown() {
EthernetClient::stopMockServer(pGetTime->getServerDomain(), (uint32_t)0, 80);
}

unittest(without_DHCP) {
unittest(GetTimeTest_without_DHCP) {
Ethernet.mockDHCP(IPAddress((uint32_t)0));
assertFalse(Ethernet_TC::instance(true)->isConnectedToNetwork());
EthernetClient::startMockServer(pGetTime->getServerDomain(), (uint32_t)0, 80);
assertFalse(pClient->connected());
delay(45 * 1000); // wait for 45 seconds to ensure we do not send
tc->loop(false);
tc->loop();
assertFalse(pClient->connected());
}

Expand All @@ -55,10 +55,10 @@ unittest(with_DHCP) {
"\r\n");
assertFalse(pClient->connected()); // not yet connected!
delay(15 * 1000); // Allow bubbler to be turned off
tc->loop(false);
tc->loop();
delay(30 * 1000); // Wait for time query
assertEqual("2021-06-08 15:26", DateTime_TC::now().as16CharacterString());
tc->loop(false);
tc->loop();
assertEqual("2023-07-18 21:18", DateTime_TC::now().as16CharacterString());
assertTrue(pClient->connected());
pClient->stop(); // clears the readBuffer (but not the write buffer!?)
Expand All @@ -72,10 +72,10 @@ unittest(with_DHCP) {
"\r\n");
assertFalse(pClient->connected()); // not yet connected!
delay(23 * 60 * 60 * 1000); // should not be any change
tc->loop(false);
tc->loop();
assertEqual("2023-07-19 20:18", DateTime_TC::now().as16CharacterString());
delay(1 * 60 * 60 * 1000); // now should change
tc->loop(false);
tc->loop();
assertEqual("2023-07-20 07:18", DateTime_TC::now().as16CharacterString());
assertTrue(pClient->connected());
pClient->stop(); // clears the readBuffer (but not the write buffer!?)
Expand Down
Loading
Loading