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