Initial Upload
This commit is contained in:
commit
bada3c34ee
4
interlock/.vscode/arduino.json
vendored
Normal file
4
interlock/.vscode/arduino.json
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"board": "P1AM-100:samd:P1AM-100_native",
|
||||
"sketch": "interlock.ino"
|
||||
}
|
154
interlock/config.h
Normal file
154
interlock/config.h
Normal 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
65
interlock/diagnostics.ino
Normal 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
109
interlock/interlock.ino
Normal 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
57
interlock/map.h
Normal 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
147
interlock/states.ino
Normal 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
149
interlock/tasks.ino
Normal 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
307
interlock/web.ino
Normal 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");
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user