I was able to successfully record data into a structure and display that data both on the serial monitor and a client webpage display. There was 1 analog input value and 4 digital input values. The digital inputs all display either '0' or '1' since the values are showing the digitalRead result with no manipulation.
My next step is to convert the digital reads to a 'char' value to read 'ON' for a 0 [LOW] and 'OFF' for a 1 [HIGH].
I modified the structure data types from 'int8_t' to 'char' and the code compiled w/o errors
but when I look at the values on the serial monitor there is a small square instead of the character string associated with ON and OFF.
I feel like the issue is within the 'void addHistoricalData' and that the conversion is getting
lost or incorrectly interpreted. I did see an example on Google that used a separate
definition of the structure data as data.name:
#include <iostream>
using namespace std;
struct Data {
int i;
float f;
char c;
};
int main() {
Data data;
data.i = 10;
data.f = 3.14;
data.c = 'a';
cout << data.i << endl;
cout << data.f << endl;
cout << data.c << endl;
return 0;
}
boolean sensor_read_1 = false;
boolean sensor_read_2 = false;
boolean sensor_read_3 = false;
boolean sensor_read_4 = false;
char lockout[4] = "OFF";
char aqua_cmd[4] = "OFF";
char blr_cmd[4] = "OFF";
char blr_stat[4] = "OFF";
struct BoilerData {
int16_t tank_temp;
char lockout;
char aqua_cmd;
char blr_cmd;
char blr_stat;
};
constexpr size_t maxCycleCount = 16;
BoilerData historicalData[maxCycleCount];
size_t nextHistoricalEntry = 0;
bool HistoricalDataIsFull = false;
void addHistoricalData(int16_t tank_temp, char lockout_state, char aqua_state, char cmd_state, char run_stat) {
historicalData[nextHistoricalEntry].tank_temp = tank_temp;
historicalData[nextHistoricalEntry].lockout = lockout_state;
historicalData[nextHistoricalEntry].aqua_cmd = aqua_state;
historicalData[nextHistoricalEntry].blr_cmd = cmd_state;
historicalData[nextHistoricalEntry].blr_stat = run_stat;
nextHistoricalEntry = (nextHistoricalEntry + 1) % maxCycleCount;
if (nextHistoricalEntry == 0) HistoricalDataIsFull = true;
}
void printHistoricalDataAtIndex(size_t idx) {
Serial.print(idx + 1); // for display start numbering at 1 (in C++ arrays starts at index 0)
Serial.write('\t');
Serial.print(historicalData[idx].tank_temp);
Serial.write(" ");
Serial.print(historicalData[idx].lockout);
Serial.write(" ");
Serial.print(historicalData[idx].aqua_cmd);
Serial.write(" ");
Serial.print(historicalData[idx].blr_cmd);
Serial.write(" ");
Serial.println(historicalData[idx].blr_stat);
}
void printHistoricalData() {
Serial.println(F("\n-----------------------------"));
// print the number of valid samples
if (HistoricalDataIsFull) Serial.print(maxCycleCount);
else Serial.print(nextHistoricalEntry);
Serial.println(F(" Historical Data sample(s)"));
Serial.println(F("-----------------------------"));
Serial.println(F("#\tsensor1 \ Lockout\ Aquastat \ Boiler Cmd \ Boiler Status"));
if (HistoricalDataIsFull) {
for (size_t i = nextHistoricalEntry; i < nextHistoricalEntry + maxCycleCount; ++i) {
printHistoricalDataAtIndex(i % maxCycleCount); // Ensure the index stays within bounds
}
} else {
for (size_t i = 0; i < nextHistoricalEntry; ++i) {
printHistoricalDataAtIndex(i);
}
}
}
void setup() {
Serial.begin(115200);
pinMode(kill_boiler_relay, OUTPUT);
pinMode(system_alarm_LED, OUTPUT);
pinMode(blr_current_relay, INPUT_PULLUP);
pinMode(zone_pump_wifi_input, INPUT_PULLUP);
pinMode(aquastat_run_command, INPUT_PULLUP);
void loop() {
current_Millis = millis(); //get the number of milliseconds since the program started
UNO_run_cycle_start = millis();
actualTime = now(); // retrieve UNO system timestamp
int16_t tempSensor1 = analogRead(A0);
int8_t boiler_lockout_state = digitalRead(zone_pump_wifi_input);
int8_t aquastat_state = digitalRead(aquastat_run_command);
int8_t blr_cmd_state = digitalRead(kill_boiler_relay);
int8_t blr_run_state = digitalRead(blr_current_relay);
if (boiler_lockout_state == HIGH) {
strcpy(lockout, "OFF");
sensor_read_1 = false;
}
if (boiler_lockout_state == LOW && sensor_read_1 == false) {
strcpy(lockout, "ON");
addHistoricalData(tempSensor1, lockout, aqua_cmd, blr_cmd, blr_run_state);
sensor_read_1 = true;
}
if (aquastat_state == HIGH) {
strcpy(aqua_cmd, "OFF");
sensor_read_2 = false;
}
if (aquastat_state == LOW && sensor_read_2 == false) {
strcpy(aqua_cmd, "ON");
addHistoricalData(tempSensor1, lockout, aqua_cmd, blr_cmd, blr_stat);
sensor_read_2 = true;
}
if (blr_cmd_state == HIGH) {
strcpy(blr_cmd, "OFF");
sensor_read_3 = false;
}
if (blr_cmd_state == LOW && sensor_read_3 == false) {
strcpy(blr_cmd, "ON");
addHistoricalData(tempSensor1, lockout, aqua_cmd, blr_cmd, blr_stat);
sensor_read_3 = true;
}
if (blr_run_state == HIGH) {
strcpy(blr_stat, "OFF");
sensor_read_4 = false;
}
if (blr_run_state == LOW && sensor_read_4 == false) {
strcpy(blr_stat, "ON");
addHistoricalData(tempSensor1, lockout, aqua_cmd, blr_cmd, blr_stat);
sensor_read_4 = true;
}
delay(1000);
printHistoricalData();
delay(1000);
int16_t Temp_Sensor_1 = A0;
tank_tmp = analogRead(Temp_Sensor_1);
const int B = 4275; // B value of the thermistor; +- 275 = .6 C (1.0 F)
const uint32_t R0 = 100000; // R0 = 100k; int type uint32_t required (unsigned 32 bit)
float R1 = 1023.0 / tank_tmp - 1.0;
R1 = R0 * R1;
tnk_temp = 1.0 / (log(R1 / R0) / B + 1 / 298.15) - 273.15;
int tank_temp = (tnk_temp * 9 / 5) + 32 - tmp_adj_1;
if (current_Millis - startMillis >= LED_period) //test whether the period has elapsed
{
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
startMillis = current_Millis;
}
}