commit bada3c34ee560873e0fb38453910bc499c842856 Author: Jonah <37317681+rubberhelix@users.noreply.github.com> Date: Mon Sep 18 23:26:44 2023 -0400 Initial Upload diff --git a/interlock/.vscode/arduino.json b/interlock/.vscode/arduino.json new file mode 100644 index 0000000..25001b8 --- /dev/null +++ b/interlock/.vscode/arduino.json @@ -0,0 +1,4 @@ +{ + "board": "P1AM-100:samd:P1AM-100_native", + "sketch": "interlock.ino" +} \ No newline at end of file diff --git a/interlock/config.h b/interlock/config.h new file mode 100644 index 0000000..6d0be16 --- /dev/null +++ b/interlock/config.h @@ -0,0 +1,154 @@ +/************************ + * + * This file contains the settings for the ethernet module, GPIO pins for the LCD screen, the states, the data structure, the normal + * conditions for the inputs, the alarm priority they are associated with, the MODBUS modules, and the text strings used for the LCD display + * +*************************/ + + +/****** +* MAC address for the ethernet module +* +******/ +byte mac[] = {0x60, 0x52, 0xD0, 0x07, 0x17, 0x14}; + + +/****** +* GPIO pins for the LCD screen +* +******/ +const int rs = 0, en = 1, d4 = 11, d5 = 12, d6 = 13, d7 = 14; + + +/****** + * + * Number of states + * (CAUTION CHANGING THIS!!!) + * + ******/ +enum STATES{ + startup, + normal, + trouble1, + trouble2, + trouble3 +}; + + +/****** + * + * Input buffer and values + * + ******/ +char buf[2]; +uint16_t read; +int input[16]; +float analog1; +float analog2; +float analog3; +float tSniffer; +float vacuum; +float subPump; + + +/****** + * Initial state of the interlock + * + ******/ +STATES newState = normal; +STATES currentState = startup; + + +/****** +* Specify the trouble condition each input would trigger +* +******/ +STATES alarm[16] = { + normal, // Reset switch + trouble3, // Emergency source trip switch + trouble1, // Cage door contact + trouble3, // Fume hood flow switch + trouble2, // Vacuum condition - gnd + trouble3, // Tritium monitor + normal, // UNUSED + trouble3, // Power failure + trouble3, // Coolant flow - gnd + trouble2, // Vacuum condition - mid + normal, // UNUSED + trouble3, // Coolant flow - high + trouble3, // Smoke detector - high + normal, // UNUSED + normal, // UNUSED + normal // UNUSED + +}; + + +/****** +* Specify the normal condition for each input +* +*****/ +bool input_normal[16] = { + + OPEN, // Reset switch + CLOSED, // Emergency source trip switch + CLOSED, // Cage door contact + CLOSED, // Fume hood flow switch + OPEN, // Vacuum condition - gnd + CLOSED, // Tritium monitor + OPEN, // UNUSED + CLOSED, // Power failure + CLOSED, // Coolant flow - gnd + OPEN, // Vacuum condition - mid + OPEN, // UNUSED + CLOSED, // Coolant flow - high + OPEN, // Smoke detector - high + OPEN, // UNUSED + OPEN, // UNUSED + OPEN // UNUSED + +}; + +/****** +* Array to track the output status for updating interfaces +* +******/ +bool output[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + + +/****** +* Specify which modules are on the MODBUS +* +******/ +const char* RollCall[] = { + "P1-16ND3", "P1-08TRS", "P1-08TRS", "P1-04ADL-2" +}; + + +/****** +* Text strings for the LCD Display +* +******/ +String state_txt[] = {"Rebooting...", + "Source Normal", + "Cage Door Trip!", + "Vacuum Trip!", + "Source Trip!"}; + +String in_txt[] = { "Reset Button", + "Emergency Switch", + "Cage Door Open", + "Fume Hood Flow", + "Vacuum Gauge 2", + "Tritium Monitor", + "error: port map", + "Bldg Power Fail", + "Coolant Flow 2", + "Vacuum Gauge 1", + "error: port map", + "Coolant Flow 1", + "Smoke at Source", + "error: port map", + "error: port map", + "error: port map", + ""}; diff --git a/interlock/diagnostics.ino b/interlock/diagnostics.ino new file mode 100644 index 0000000..36bf82f --- /dev/null +++ b/interlock/diagnostics.ino @@ -0,0 +1,65 @@ +/************************ + * + * This file contains diagnostic functions and statements that can be copied into the main + * file or called from here if you un-comment them. + * +*************************/ + +// Included for Testing +//#include + + +// Verify modules configured without error +/* +if (P1.rollCall(RollCall, 4) == 0) { +Serial.println("True"); +} +*/ + +/******************** +* Function to print the state and any tripped conditions as well as the analog values +* +********************/ +void print_states(){ + + Serial.print("\nCurrent State: "); + + switch (newState) { + + case normal: + Serial.println("normal"); + break; + + case trouble1: + Serial.println("trouble 1 - cage door trip"); + break; + + case trouble2: + Serial.println("trouble 2 - vacuum trip"); + break; + + case trouble3: + Serial.println("trouble 3 - source trip"); + break; + } + + + for(int n=0; n<16; n++) { + + if (input[n] != input_normal[n]){ + Serial.print("Input "); + Serial.print(n+1); + Serial.println(" is tripped"); + } + } + + Serial.print("\nTritium Sniffer Voltage: "); + Serial.println(analog1,6); + + Serial.print("\nVaccuum Gauge Mid-Potential Voltage: "); + Serial.println(analog2,6); + + Serial.print("\nTitanium Sublimation Pump 1 Mid-Potential Voltage: "); + Serial.println(analog3,6); + +} \ No newline at end of file diff --git a/interlock/interlock.ino b/interlock/interlock.ino new file mode 100644 index 0000000..b0718a1 --- /dev/null +++ b/interlock/interlock.ino @@ -0,0 +1,109 @@ +/************************ + * + * This is the main file for the software. It contains boot up procedures, main routines and + * any diagnostic functions for development and testing. + * +*************************/ + +#include +#include "map.h" +#include "config.h" +#include +#include + + +// Network configuration +IPAddress ip(128, 186, 111, 180); +EthernetServer server(80); + +// LCD display configuration +LiquidCrystal lcd(rs, en, d4, d5, d6, d7); + +// Timer variables +unsigned long printerPace = 0; +unsigned long heartBeat = 0; +unsigned long lcdTimer = 0; +unsigned long lcdReset = 0; + +// LCD display variable +int lcdLooper = 0; +int lcdLine2 = 16; + +/******* + *Setup function runs once on startup + *******/ +void setup() { + + // Start LCD display and initial message + lcd.begin(16, 2); + lcd.clear(); + lcd.setCursor(0, 0); + lcd.print("Rebooting..."); + + // Flash LED during initialization of modules + while (!P1.init()) { + digitalWrite(heartbeat, !digitalRead(heartbeat)); + delay(250); + } + + // Initialize analog module settings + const char P1_04ADL_2_CONFIG[] = { 0x40, 0x02 }; //only 3 setup at the moment + + // Serial begin for any readouts + Serial.begin(9600); + + // Prints the modules connected to the bus + Serial.println(P1.rollCall(RollCall, 4)); + + // Watchdog timer resets the system if it stalls for 5 seconds without being pet + P1.configWD(5000, TOGGLE); + P1.startWD(); + + // Configure pin modes + pinMode(LED_BUILTIN,OUTPUT); + pinMode(SWITCH_BUILTIN,INPUT); + + // Ethernet setup and print info to serial + Ethernet.init(5); + Ethernet.begin(mac, ip); + server.begin(); + Serial.print("server is at "); + Serial.println(Ethernet.localIP()); + + // Interrupts for future use to streamline important input changes + //attachInterrupt(digitalPinToInterrupt(pin),ISR,mode); + //attachInterrupt(digitalPinToInterrupt(pin),ISR,mode); + + + /*###### + * Send start-up notice to logging server + ######*/ + + // Startup input check + app_Tasks(); + +} + +void loop() { + + + // Read button on front panel + if (P1.readDiscrete(in1) == CLOSED) { + acknowledge(); //Acknowledge alarm and silence buzzer + delay(2000); + if (P1.readDiscrete(in1) == CLOSED){ //Reset to normal condition + newState = normal; + } + } + + // Check the inputs and update the state + app_Tasks(); + + // Update the interfaces + app_Interfaces(); + + + // Reset the watchdog timer + P1.petWD(); + +} diff --git a/interlock/map.h b/interlock/map.h new file mode 100644 index 0000000..82eea3d --- /dev/null +++ b/interlock/map.h @@ -0,0 +1,57 @@ +/************************ + * + * This file contains the names for the signals and maps the ports and pins + * to convenient variable names (in# or out#). Only change the comments for the + * signals to match what's connected to the interlock for reference. + * +*************************/ + +//Logic +#define OPEN 0 +#define CLOSED 1 + +// P1-16ND3 - inputs signals +#define in1 1,1 // Reset switch +#define in2 1,2 // Gate valve close switch +#define in3 1,3 // Cage door contact +#define in4 1,4 // Fume hood flow switch +#define in5 1,5 // Vacuum condition - gnd +#define in6 1,6 // Tritium monitor +#define in7 1,7 // UNUSED +#define in8 1,8 // Power failure +#define in9 1,9 // Coolant flow - gnd +#define in10 1,10 // Vacuum condition - mid +#define in11 1,11 // UNUSED +#define in12 1,12 // Coolant flow - high +#define in13 1,13 // Smoke detector - high +#define in14 1,14 // UNUSED +#define in15 1,15 // UNUSED +#define in16 1,16 // UNUSED + +// P1-08TRS #1 - output relays +#define out1 2,1 // Green or flashing red LED +#define out2 2,2 // Buzzer +#define out3 2,3 // Red LED trouble 1 +#define out4 2,4 // Red LED trouble 2 +#define out5 2,5 // Red LED trouble 3 +#define out6 2,6 // Pre-accelerator power supply +#define out7 2,7 // Gate valve - gnd +#define out8 2,8 // Gate valve - mid + +// P1-08TRS #2 - output relays +#define out9 3,1 // UNUSED +#define out10 3,2 // UNUSED +#define out11 3,3 // UNUSED +#define out12 3,4 // UNUSED +#define out13 3,5 // UNUSED +#define out14 3,6 // High-volt power supplies - high +#define out15 3,7 // Boiler - high +#define out16 3,8 // Ionizer - high + +// P1-04ADL-2 - analog input voltages +#define anin1 4,1 //Tritium sniffer +#define anin2 4,2 //Vaccuum gauge - mid +#define anin3 4,3 //TSP1 - mid + +//LED heartbeat on controller +#define heartbeat 32 diff --git a/interlock/states.ino b/interlock/states.ino new file mode 100644 index 0000000..32044b8 --- /dev/null +++ b/interlock/states.ino @@ -0,0 +1,147 @@ +/************************ + * + * This file contains the settings for the output conditions for different states. + * +*************************/ + + +/******************** +* Function to reset to normal state +* +*********************/ +void normal_state(void) { + + P1.writeDiscrete(LOW,out1); //Main status LED green + output[0] = 0; + P1.writeDiscrete(LOW,out2); //Buzzer silent + output[1] = 0; + P1.writeDiscrete(LOW,out3); //Trouble 1 LED off + output[2] = 0; + P1.writeDiscrete(LOW,out4); //Trouble 2 LED off + output[3] = 0; + P1.writeDiscrete(LOW,out5); //Trouble 3 LED off + output[4] = 0; + + P1.writeDiscrete(HIGH,out6); //Pre-accelerator supply on + output[5] = 1; + + P1.writeDiscrete(HIGH,out7); //Gate Valve - Gnd Open + output[6] = 1; + P1.writeDiscrete(HIGH,out8); //Gate Valve - Mid Open + output[7] = 1; + + P1.writeDiscrete(HIGH,out14); //High-volt supplies on + output[13] = 1; + P1.writeDiscrete(HIGH,out15); //Boiler supply on + output[14] = 1; + P1.writeDiscrete(HIGH,out16); //Ionizer supply on + output[15] = 1; + +} + + +/******************** +* Function to initiate trouble 1 state +* +*********************/ +void trouble1_state(void) { + + P1.writeDiscrete(HIGH,out1); //Main Status LED flashing red + output[0] = 0; + P1.writeDiscrete(HIGH,out2); //Buzzer on + output[1] = 1; + P1.writeDiscrete(HIGH,out3); //Trouble 1 LED on + output[2] = 1; + P1.writeDiscrete(LOW,out4); //Trouble 2 LED off + output[3] = 0; + P1.writeDiscrete(LOW,out5); //Trouble 3 LED off + output[4] = 0; + + P1.writeDiscrete(LOW,out6); //Pre-accelerator supply off + output[5] = 0; + + P1.writeDiscrete(LOW,out14); //High-volt supplies off + output[13] = 0; + +} + + +/******************** +* Function to initiate trouble 2 state +* +*********************/ +void trouble2_state(void) { + + P1.writeDiscrete(HIGH,out1); //Main Status LED flashing red + output[0] = 1; + P1.writeDiscrete(HIGH,out2); //Buzzer on + output[1] = 1; + P1.writeDiscrete(LOW,out3); //Trouble 1 LED off + output[2] = 0; + P1.writeDiscrete(HIGH,out4); //Trouble 2 LED on + output[3] = 1; + P1.writeDiscrete(LOW,out5); //Trouble 3 LED off + output[4] = 0; + + P1.writeDiscrete(LOW,out6); //Pre-accelerator supply off + output[5] = 0; + + P1.writeDiscrete(LOW,out7); //Gate Valve - Gnd Closed + output[6] = 0; + P1.writeDiscrete(LOW,out8); //Gate Valve - Mid Closed + output[7] = 0; + + P1.writeDiscrete(LOW,out14); //High-volt supplies off + output[13] = 0; + P1.writeDiscrete(LOW,out16); //Ionizer supply off + + output[15] = 0; + +} + + +/******************** +* Function to initiate trouble 3 state +* +*********************/ +void trouble3_state(void) { + + P1.writeDiscrete(HIGH,out1); //Main Status LED flashing red + output[0] = 1; + P1.writeDiscrete(HIGH,out2); //Buzzer on + output[1] = 1; + P1.writeDiscrete(LOW,out3); //Trouble 1 LED off + output[2] = 0; + P1.writeDiscrete(LOW,out4); //Trouble 2 LED off + output[3] = 0; + P1.writeDiscrete(HIGH,out5); //Trouble 3 LED on + output[4] = 1; + + P1.writeDiscrete(LOW,out6); //Pre-accelerator supply off + output[5] = 0; + + P1.writeDiscrete(LOW,out7); //Gate Valve - Gnd Closed + output[6] = 0; + P1.writeDiscrete(LOW,out8); //Gate Valve - Mid Closed + output[7] = 0; + + P1.writeDiscrete(LOW,out14); //High-volt supplies off + output[13] = 0; + P1.writeDiscrete(LOW,out15); //Boiler supply off + output[14] = 0; + P1.writeDiscrete(LOW,out16); //Ionizer supply off + output[15] = 0; + +} + + +/******************** +* Function to silence the buzzer +* +*********************/ +void acknowledge(void) { + + P1.writeDiscrete(LOW,out2); //Buzzer silent + output[1] = 0; + +} diff --git a/interlock/tasks.ino b/interlock/tasks.ino new file mode 100644 index 0000000..ffa57d7 --- /dev/null +++ b/interlock/tasks.ino @@ -0,0 +1,149 @@ +/************************ + * + * This file contains the main functions for checking the inputs, changing states, + * and updating interfaces. + * +*************************/ + + +/******************** +* Function to check the condition of the inputs and update the state. +* +*********************/ +void app_Tasks(void){ + + // Read discrete input values from the buffer and shift into an array + P1.readBlockData(buf,2,0,DISCRETE_IN_BLOCK); + + read = (buf[1] << 8); + read += (buf[0] << 0); + + // If the input is in alarm, escalate the new state + for(int n=0; n<16; n++) { + input[n] = ((read >> n) & 0b1) ? 1 : 0; + if (input[n] != input_normal[n]){ + if (alarm[n] > newState) { + newState = alarm[n]; + } + } + } + + + // Read analog values and scale to the unit ranges + analog1 = P1.readAnalog(anin1)*10.0/8191.0; // voltage + analog2 = P1.readAnalog(anin2)*10.0/8191.0; // voltage + analog3 = P1.readAnalog(anin3)*10.0/8191.0; // voltage + tSniffer = analog1*2000.0-5.0; // volts to micro curies per meter^3 + vacuum = pow(10,(analog2-5.5)/0.5)*1000000; // volts to Torr - log scale + subPump = analog3*5; // volts to amps + + + // If the state didn't change, exit the function + if (newState == currentState) { return;} + + + // If there's a new alarm or a higher priority alarm, execute the new functions + if (newState > currentState) { + + if (currentState == startup) { + normal_state(); + } + + switch (newState) { + + case trouble1: + trouble1_state(); + break; + + case trouble2: + trouble2_state(); + break; + + case trouble3: + trouble3_state(); + break; + } + + } else if (newState == normal) { + normal_state(); + } + + // Set the current state to the new state + currentState = newState; + +} + + +/******************** +* Function to update interfaces- LEDs, LCD, log server, email notifications +* +********************/ + + +void app_Interfaces(void) { + + + //if state == not-normal, check last update time, if >5min, send update + + //send buffer to logs + + //notifications (email?) + + // LCD update, print, clear, etc + if (lcdLooper > 15 || lcdLooper < 0){ + lcdLooper = 0; + } else if (input[lcdLooper] == input_normal[lcdLooper]){ + lcdLooper++; + } else if (input[lcdLooper] != input_normal[lcdLooper]) { + lcdLine2 = lcdLooper; + } + + if (currentState == normal) { + lcdLine2 = 16; + } + + if (millis()-lcdTimer >= 2000) { + + lcdLooper++; + + lcdTimer = millis(); + + lcd.clear(); + + lcd.setCursor(0, 0); + lcd.print(state_txt[currentState]); + lcd.setCursor(0, 1); + lcd.print(in_txt[lcdLine2]); + + } else if (lcdTimer < 0) { + lcdTimer = millis(); + } + + if (millis()-lcdReset >= 20000) { + lcdReset = millis(); + lcd.begin(16, 2); + lcd.clear(); + } + + + // Webpage function + serve_webpage(); + + // Diagnostics -> Serial Output + if (digitalRead(SWITCH_BUILTIN) == 0){ + if ((millis()-printerPace)>3000) { + print_states(); + printerPace = millis(); + } + } + + // Heartbeat + if ((millis()-heartBeat)>1200) { + for (int i=0; i<4; i++){ + digitalWrite(heartbeat, !digitalRead(heartbeat)); + delay(100); + } + heartBeat = millis(); + } + +} diff --git a/interlock/web.ino b/interlock/web.ino new file mode 100644 index 0000000..b4c496a --- /dev/null +++ b/interlock/web.ino @@ -0,0 +1,307 @@ +/************************ + * + * This file contains the html code for the webpage served by the ethernet module. The webpage shows the state and conditions + * of the inputs as well as the analog values. + * +*************************/ + + +/******************** +* Function to serve the webpage showing the interlock system status +* +*********************/ +void serve_webpage(void) { + + String condition_txt; + + switch (currentState) { + case 0: + condition_txt = "Rebooting..."; + break; + case 1: + condition_txt = "normal"; + break; + case 2: + condition_txt = "Cage Door Trip"; + break; + case 3: + condition_txt = "Vacuum Trip"; + break; + case 4: + condition_txt = "Source Trip"; + break; + } + + + EthernetClient client = server.available(); + + if (client) { + //Serial.println("new client"); + // an http request ends with a blank line + boolean currentLineIsBlank = true; + while (client.connected()) { + if (client.available()) { + char c = client.read(); + //Serial.write(c); + // if you've gotten to the end of the line (received a newline + // character) and the line is blank, the http request has ended, + // so you can send a reply + if (c == '\n' && currentLineIsBlank) { + // send a standard http response header + client.println("HTTP/1.1 200 OK"); + client.println("Content-Type: text/html"); + client.println("Connection: close"); // the connection will be closed after completion of the response + client.println("Refresh: 5"); // refresh the page automatically every 5 sec + client.println(); + client.println(""); + client.println(""); + client.println(""); + client.println(" Multi-SNICS Interlock Status Display"); + client.println(" "); + client.println(""); + client.println(""); + client.println("

Multi-SNICS Interlock Status Display

"); + client.print("

Condition: "); + client.print(condition_txt); + client.println("

"); + client.println(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.print(" "); + client.println(" "); + client.print(" "); + client.print(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.print(" "); + client.println(" "); + client.print(" "); + client.print(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.print(" "); + client.println(" "); + client.print(" "); + client.print(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.print(" "); + client.println(" "); + client.print(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.print(" "); + client.println(" "); + client.print(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.print(" "); + client.println(" "); + client.print(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.print(" "); + client.println(" "); + client.print(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.print(" "); + client.println(" "); + client.print(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.print(" "); + client.println(" "); + client.print(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.print(" "); + client.println(" "); + client.print(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.print(" "); + client.println(" "); + client.print(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.print(" "); + client.println(" "); + client.print(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.print(" "); + client.println(" "); + client.print(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.print(" "); + client.println(" "); + client.print(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.print(" "); + client.println(" "); + client.print(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.print(" "); + client.println(" "); + client.print(" "); + client.println(" "); + client.println(" "); + client.println("
Input ConditionsOutput RelaysMeasurements
Reset Switch: "); + client.print((input[0]==input_normal[0]) ? "normal" : "TRIPPED"); + client.println("Switch LED: "); + client.print((output[0]==0) ? "Off" : "Flashing Red"); + client.println("Tritium Detector: "); + client.print(tSniffer, 1); + client.println(" uCi/m^3
Emergency Interlock Switch: "); + client.print((input[1]==input_normal[1]) ? "normal" : "TRIPPED"); + client.println("Buzzer: "); + client.print((output[1]==1) ? "Buzzing" : "Off"); + client.println("Vacuum Gauge: "); + client.print(vacuum); + client.println("E-6 Torr
Cage Door Contact: "); + client.print((input[2]==input_normal[2]) ? "normal" : "TRIPPED"); + client.println("Cage Door Trip LED: "); + client.print((output[2]==0) ? "Green/Off" : "Red"); + client.println("Titanium Sublimation Pump: "); + client.print(subPump, 1); + client.println(" Amps
Fume Hood Flow Switch: "); + client.print((input[3]==input_normal[3]) ? "normal" : "TRIPPED"); + client.println("Vacuum Trip LED: "); + client.print((output[3]==0) ? "Green/Off" : "Red"); + client.println("
Vacuum Condition - Ground: "); + client.print((input[4]==input_normal[4]) ? "normal" : "TRIPPED"); + client.println("Source Trip LED: "); + client.print((output[4]==0) ? "Green/Off" : "Red"); + client.println("
Tritium Detector: "); + client.print((input[5]==input_normal[5]) ? "normal" : "TRIPPED"); + client.println("Pre-accelerator Power Supply: "); + client.print((output[5]==1) ? "Unlocked" : "Locked Out"); + client.println("
UNUSED"); + client.print((input[6]==input_normal[6]) ? "normal" : "TRIPPED"); + client.println("Gate Valve - Ground: "); + client.print((output[6]==1) ? "Open" : "Closed"); + client.println("
Building Power Failure: "); + client.print((input[7]==input_normal[7]) ? "normal" : "TRIPPED"); + client.println("Gate Valve - Mid Potential: "); + client.print((output[7]==1) ? "Open" : "Closed"); + client.println("
Coolant Flow At Pump: "); + client.print((input[8]==input_normal[8]) ? "normal" : "TRIPPED"); + client.println("UNUSED"); + client.print((output[8]==0) ? "Open" : "Closed"); + client.println("
Vacuum Condition - Mid Potential: "); + client.print((input[9]==input_normal[9]) ? "normal" : "TRIPPED"); + client.println("UNUSED"); + client.print((output[9]==0) ? "Open" : "Closed"); + client.println("
UNUSED"); + client.print((input[10]==input_normal[10]) ? "normal" : "TRIPPED"); + client.println("UNUSED"); + client.print((output[10]==0) ? "Open" : "Closed"); + client.println("
Coolant Flow At Source: "); + client.print((input[11]==input_normal[11]) ? "normal" : "TRIPPED"); + client.println("UNUSED"); + client.print((output[11]==0) ? "Open" : "Closed"); + client.println("
Smoke Detector At Source: "); + client.print((input[12]==input_normal[12]) ? "normal" : "TRIPPED"); + client.println("UNUSED"); + client.print((output[12]==0) ? "Open" : "Closed"); + client.println("
UNUSED"); + client.print((input[13]==input_normal[13]) ? "normal" : "TRIPPED"); + client.println("High-voltage Power Supplies: "); + client.print((output[13]==1) ? "Unlocked" : "Locked Out"); + client.println("
UNUSED"); + client.print((input[14]==input_normal[14]) ? "normal" : "TRIPPED"); + client.println("Boiler: "); + client.print((output[14]==1) ? "Unlocked" : "Locked Out"); + client.println("
UNUSED"); + client.print((input[15]==input_normal[15]) ? "normal" : "TRIPPED"); + client.println("Ionizer: "); + client.print((output[15]==1) ? "Unlocked" : "Locked Out"); + client.println("
"); + client.println("
"); + client.println(""); + client.println(""); + break; + } + if (c == '\n') { + // you're starting a new line + currentLineIsBlank = true; + } else if (c != '\r') { + // you've gotten a character on the current line + currentLineIsBlank = false; + } + } + } + // give the web browser time to receive the data + delay(1); + // close the connection: + client.stop(); + //Serial.println("client disconnected"); + } + +}