Initial Upload

This commit is contained in:
Jonah 2023-09-18 23:26:44 -04:00
commit bada3c34ee
8 changed files with 992 additions and 0 deletions

4
interlock/.vscode/arduino.json vendored Normal file
View File

@ -0,0 +1,4 @@
{
"board": "P1AM-100:samd:P1AM-100_native",
"sketch": "interlock.ino"
}

154
interlock/config.h Normal file
View File

@ -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",
""};

65
interlock/diagnostics.ino Normal file
View File

@ -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 <ArduinoTrace.h>
// 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);
}

109
interlock/interlock.ino Normal file
View File

@ -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 <P1AM.h>
#include "map.h"
#include "config.h"
#include <Ethernet.h>
#include <LiquidCrystal.h>
// 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();
}

57
interlock/map.h Normal file
View File

@ -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

147
interlock/states.ino Normal file
View File

@ -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;
}

149
interlock/tasks.ino Normal file
View File

@ -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();
}
}

307
interlock/web.ino Normal file
View File

@ -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("<!DOCTYPE html>");
client.println("<html>");
client.println("<head>");
client.println(" <title>Multi-SNICS Interlock Status Display</title>");
client.println(" <style>");
client.println(" body {");
client.println(" font-family: Arial, sans-serif;");
client.println(" margin: 20px;");
client.println(" background-image: url('https://public.magnet.fsu.edu/Logos/FSU_Seal_RGB.png');");
client.println(" background-size: 450px;");
client.println(" background-repeat: repeat-x;");
client.println(" background-position: center center;");
client.println(" text-align: center;");
client.println(" font-weight: bold;");
client.println(" }");
client.println(" table {");
client.println(" border-collapse: collapse;");
client.println(" width: 100%;");
if (currentState>1){
client.println(" background-color: #ffdddd;");
} else {
client.println(" background-color: #ddffdd;");
}
client.println(" opacity: 95%;");
client.println(" }");
client.println(" th, td {");
client.println(" border: 1px solid #dddddd;");
client.println(" padding: 8px;");
client.println(" }");
client.println(" th {");
client.println(" background-color: #f2f2f2;");
client.println(" }");
client.println(" </style>");
client.println("</head>");
client.println("<body>");
client.println(" <h1>Multi-SNICS Interlock Status Display</h1>");
client.print(" <h2>Condition: ");
client.print(condition_txt);
client.println("</h2>");
client.println(" <table>");
client.println(" <tr>");
client.println(" <th>Input Conditions</th>");
client.println(" <th></th>");
client.println(" <th>Output Relays</th>");
client.println(" <th></th>");
client.println(" <th>Measurements</th>");
client.println(" </tr>");
client.println(" <tr>");
client.println(" <td class='input-condition'>Reset Switch: </td>");
client.print(" <td class='input-condition'>");
client.print((input[0]==input_normal[0]) ? "normal" : "TRIPPED");
client.println("</td>");
client.println(" <td class='output-relay'>Switch LED: </td>");
client.print(" <td class='output-relay'>");
client.print((output[0]==0) ? "Off" : "Flashing Red");
client.println("</td>");
client.print(" <td class='measurement-number'>Tritium Detector: ");
client.print(tSniffer, 1);
client.println(" uCi/m^3</td>");
client.println(" </tr>");
client.println(" <tr>");
client.println(" <td class='input-condition'>Emergency Interlock Switch: </td>");
client.print(" <td class='input-condition'>");
client.print((input[1]==input_normal[1]) ? "normal" : "TRIPPED");
client.println("</td>");
client.println(" <td class='output-relay'>Buzzer: </td>");
client.print(" <td class='output-relay'>");
client.print((output[1]==1) ? "Buzzing" : "Off");
client.println("</td>");
client.print(" <td class='measurement-number'>Vacuum Gauge: ");
client.print(vacuum);
client.println("E-6 Torr</td>");
client.println(" </tr>");
client.println(" <tr>");
client.println(" <td class='input-condition'>Cage Door Contact: </td>");
client.print(" <td class='input-condition'>");
client.print((input[2]==input_normal[2]) ? "normal" : "TRIPPED");
client.println("</td>");
client.println(" <td class='output-relay'>Cage Door Trip LED: </td>");
client.print(" <td class='output-relay'>");
client.print((output[2]==0) ? "Green/Off" : "Red");
client.println("</td>");
client.print(" <td class='measurement-number'>Titanium Sublimation Pump: ");
client.print(subPump, 1);
client.println(" Amps</td>");
client.println(" </tr>");
client.println(" <tr>");
client.println(" <td class='input-condition'>Fume Hood Flow Switch: </td>");
client.print(" <td class='input-condition'>");
client.print((input[3]==input_normal[3]) ? "normal" : "TRIPPED");
client.println("</td>");
client.println(" <td class='output-relay'>Vacuum Trip LED: </td>");
client.print(" <td class='output-relay'>");
client.print((output[3]==0) ? "Green/Off" : "Red");
client.println("</td>");
client.println(" <td class='measurement-number'></td>");
client.println(" </tr>");
client.println(" <tr>");
client.println(" <td class='input-condition'>Vacuum Condition - Ground: </td>");
client.print(" <td class='input-condition'>");
client.print((input[4]==input_normal[4]) ? "normal" : "TRIPPED");
client.println("</td>");
client.println(" <td class='output-relay'>Source Trip LED: </td>");
client.print(" <td class='output-relay'>");
client.print((output[4]==0) ? "Green/Off" : "Red");
client.println("</td>");
client.println(" <td class='measurement-number'></td>");
client.println(" </tr>");
client.println(" <tr>");
client.println(" <td class='input-condition'>Tritium Detector: </td>");
client.print(" <td class='input-condition'>");
client.print((input[5]==input_normal[5]) ? "normal" : "TRIPPED");
client.println("</td>");
client.println(" <td class='output-relay'>Pre-accelerator Power Supply: </td>");
client.print(" <td class='output-relay'>");
client.print((output[5]==1) ? "Unlocked" : "Locked Out");
client.println("</td>");
client.println(" <td class='measurement-number'></td>");
client.println(" </tr>");
client.println(" <tr>");
client.println(" <td class='input-condition'>UNUSED</td>");
client.print(" <td class='input-condition'>");
client.print((input[6]==input_normal[6]) ? "normal" : "TRIPPED");
client.println("</td>");
client.println(" <td class='output-relay'>Gate Valve - Ground: </td>");
client.print(" <td class='output-relay'>");
client.print((output[6]==1) ? "Open" : "Closed");
client.println("</td>");
client.println(" <td class='measurement-number'></td>");
client.println(" </tr>");
client.println(" <tr>");
client.println(" <td class='input-condition'>Building Power Failure: </td>");
client.print(" <td class='input-condition'>");
client.print((input[7]==input_normal[7]) ? "normal" : "TRIPPED");
client.println("</td>");
client.println(" <td class='output-relay'>Gate Valve - Mid Potential: </td>");
client.print(" <td class='output-relay'>");
client.print((output[7]==1) ? "Open" : "Closed");
client.println("</td>");
client.println(" <td class='measurement-number'></td>");
client.println(" </tr>");
client.println(" <tr>");
client.println(" <td class='input-condition'>Coolant Flow At Pump: </td>");
client.print(" <td class='input-condition'>");
client.print((input[8]==input_normal[8]) ? "normal" : "TRIPPED");
client.println("</td>");
client.println(" <td class='output-relay'>UNUSED</td>");
client.print(" <td class='output-relay'>");
client.print((output[8]==0) ? "Open" : "Closed");
client.println("</td>");
client.println(" <td class='measurement-number'></td>");
client.println(" </tr>");
client.println(" <tr>");
client.println(" <td class='input-condition'>Vacuum Condition - Mid Potential: </td>");
client.print(" <td class='input-condition'>");
client.print((input[9]==input_normal[9]) ? "normal" : "TRIPPED");
client.println("</td>");
client.println(" <td class='output-relay'>UNUSED</td>");
client.print(" <td class='output-relay'>");
client.print((output[9]==0) ? "Open" : "Closed");
client.println("</td>");
client.println(" <td class='measurement-number'></td>");
client.println(" </tr>");
client.println(" <tr>");
client.println(" <td class='input-condition'>UNUSED</td>");
client.print(" <td class='input-condition'>");
client.print((input[10]==input_normal[10]) ? "normal" : "TRIPPED");
client.println("</td>");
client.println(" <td class='output-relay'>UNUSED</td>");
client.print(" <td class='output-relay'>");
client.print((output[10]==0) ? "Open" : "Closed");
client.println("</td>");
client.println(" <td class='measurement-number'></td>");
client.println(" </tr>");
client.println(" <tr>");
client.println(" <td class='input-condition'>Coolant Flow At Source: </td>");
client.print(" <td class='input-condition'>");
client.print((input[11]==input_normal[11]) ? "normal" : "TRIPPED");
client.println("</td>");
client.println(" <td class='output-relay'>UNUSED</td>");
client.print(" <td class='output-relay'>");
client.print((output[11]==0) ? "Open" : "Closed");
client.println("</td>");
client.println(" <td class='measurement-number'></td>");
client.println(" </tr>");
client.println(" <tr>");
client.println(" <td class='input-condition'>Smoke Detector At Source: </td>");
client.print(" <td class='input-condition'>");
client.print((input[12]==input_normal[12]) ? "normal" : "TRIPPED");
client.println("</td>");
client.println(" <td class='output-relay'>UNUSED</td>");
client.print(" <td class='output-relay'>");
client.print((output[12]==0) ? "Open" : "Closed");
client.println("</td>");
client.println(" <td class='measurement-number'></td>");
client.println(" </tr>");
client.println(" <tr>");
client.println(" <td class='input-condition'>UNUSED</td>");
client.print(" <td class='input-condition'>");
client.print((input[13]==input_normal[13]) ? "normal" : "TRIPPED");
client.println("</td>");
client.println(" <td class='output-relay'>High-voltage Power Supplies: </td>");
client.print(" <td class='output-relay'>");
client.print((output[13]==1) ? "Unlocked" : "Locked Out");
client.println("</td>");
client.println(" <td class='measurement-number'></td>");
client.println(" </tr>");
client.println(" <tr>");
client.println(" <td class='input-condition'>UNUSED</td>");
client.print(" <td class='input-condition'>");
client.print((input[14]==input_normal[14]) ? "normal" : "TRIPPED");
client.println("</td>");
client.println(" <td class='output-relay'>Boiler: </td>");
client.print(" <td class='output-relay'>");
client.print((output[14]==1) ? "Unlocked" : "Locked Out");
client.println("</td>");
client.println(" <td class='measurement-number'></td>");
client.println(" </tr>");
client.println(" <tr>");
client.println(" <td class='input-condition'>UNUSED</td>");
client.print(" <td class='input-condition'>");
client.print((input[15]==input_normal[15]) ? "normal" : "TRIPPED");
client.println("</td>");
client.println(" <td class='output-relay'>Ionizer: </td>");
client.print(" <td class='output-relay'>");
client.print((output[15]==1) ? "Unlocked" : "Locked Out");
client.println("</td>");
client.println(" <td class='measurement-number'></td>");
client.println(" </tr>");
client.println(" </table>");
client.println(" <br><footer>Written by yours truly, <a href='http://www.rubberhelix.com/'>Jonah K Gibbons</a></footer>");
client.println("</body>");
client.println("</html>");
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");
}
}