Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CVD safety system #49

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions cvd_safety/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
## Alert System for use with CVD Systems

The code in this module implements a QDA (Quazar Data Acquisition System) based approach to detect malfunction in the CVD (Chemical Vapour Deposition) setup.

The following parameters are monitored :
1. Smoke Concentration
2. LPG Concentration
3. Methane Concentration
4. Hydrogen Concentration
5. Temperature outside the CVD furnace

## Hardware Setup

- QDAL414B (Qty : 1)
- MQ-2 Gas Sensors (Qty : 2)
- PT100 Temperature Sensors (Qty : 2)

The MQ-2 are interfaced to Channel-1 and Channel-2 of QDAL414B. The PT100 Temperature Sensors are interfaced to Channel-3 and Channel-4.

The QDAL414B is connected to a computer using a USB interface.

## Prerequisites

- Configure ssmtp to send mail from the terminal using your gmail account.
- Install QDAL41xB driver

## Usage

- Compile using `make`. Make sure the QDAL41xB driver is installed before this step.
- Make sure the QDAL414B is connected and powered on.
- Use `./test` to execute the program
Binary file added cvd_safety/alarm.wav
Binary file not shown.
268 changes: 268 additions & 0 deletions cvd_safety/lab_safety_iQ.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
// g++ -pthread -Wall -O3 -std=c++14 test.cxx -o test -lL412B -lftdi

// QDAL41xB specific driver libraries
#include <L412B/driver/include/Driver.h>

// LiveData datastructure defined here
#include <L412B/driver/include/Data.h>

// Standard libraries
#include <vector>
#include <iostream>
#include <typeinfo>
#include <string>
#include <fstream>
#include <iomanip>

using namespace std;

// Constant definitions
#define SMOKE_SENS_THRESHOLD 1.15
#define TEMP_SENS_THRESHOLD 115.0

#define PRINT_PRECISION 8

void send_alert (int channel);
void add_status_to_email (std::string status);
void open_gas_valves (std::unique_ptr<L412B::Driver> &driver);
void close_gas_valves (std::unique_ptr<L412B::Driver> &driver);

int main (void)
{

/***************************************************
* Looks for L41x type of devices.
***************************************************/
auto device_list = L412B::Driver::scan();

/***************************************************
* If no device is detected, gracefully return
* with -1 exit status.
***************************************************/
if (device_list.empty())
{
std::cout << "No QDA device found." << std::endl;
return (-1);
}

/***************************************************
* Get the Serial number of the first QDAL41xB device
* found. All subsequent instructions for data
* acquisition will refer to this QDAL41xB device
***************************************************/
auto serialNo = device_list[0].serialNo();
std::cout << "Serial No:" << serialNo <<std::endl;

/***************************************************
* Create a unique instance of QDAL41xB driver
***************************************************/
auto driver = std::make_unique<L412B::Driver>();
std::cout << "driver type is " << typeid(driver).name() << std::endl;

/***************************************************
* Connect to QDAL41xB device
***************************************************/
driver->connect (serialNo);

std::cout << "Press Enter to open gas valves and start monitoring" << std::endl;
std::cin.ignore();
open_gas_valves(driver);

/***************************************************
* Start acquiring data from the QDAL41xB
***************************************************/
driver->start_acquisition ();


while(1)
{
/***************************************************
* Stream collected data from the QDAL41xB device
***************************************************/
auto live_data = driver->live_data();

/***************************************************
* live_data is a std::vector<data::LiveData>
* LiveData is defined in driver/include/Data.h
* LiveData.time() : Returns the time axis value (double) of the data
* LiveData.chn() : QDAL41xB channel (int) where the data originated
* LiveData.data() : Returns the data value (float)
* LiveData.logical_chn() : float /Use : TODO/
***************************************************/

/***************************************************
* Keep polling until data is available
***************************************************/
if (live_data.empty()) continue;


/***************************************************
* If data is available, check for threshold violations
***************************************************/
for (unsigned int i = 0; i < live_data.size(); i++)
{
// Checking data points spaced 1 second apart
double intpart = 0.0;

// Compare fractional part of time to zero
if (std::modf (live_data[i].time() * 1.0, &intpart) == 0.00)
{
// Data for Channel-1 (Smoke Sensor)
if (live_data[i].chn() == 0)
{
// Display data on terminal
std::cout << std::setprecision(PRINT_PRECISION) << "Time : \a" << live_data[i].time() << "\t Chn 1: " << live_data[i].data() << "\t";

// Alert if signal is above threshold
if (live_data[i].data() > SMOKE_SENS_THRESHOLD)
{
close_gas_valves (driver);
send_alert (live_data[i].chn());
break;
}

}

// Data for Channel-2 (Smoke Sensor)
if (live_data[i].chn() == 1)
{
std::cout << std::setprecision(PRINT_PRECISION) << "Time : \a" << live_data[i].time() << "\t Chn 2: " << live_data[i].data() << std::endl;

// Alert if signal is above threshold
if (live_data[i].data() > SMOKE_SENS_THRESHOLD)
{
close_gas_valves (driver);
send_alert (live_data[i].chn());
break;
}

}

// Data for Channel-3 (Temperature Sensor)
if (live_data[i].chn() == 2)
{
std::cout << std::setprecision(PRINT_PRECISION) << "Time : \a" << live_data[i].time() << "\t Chn 3: " << live_data[i].data() << "\t";

// Alert if signal is above threshold
if (live_data[i].data() > TEMP_SENS_THRESHOLD)
{
close_gas_valves (driver);
send_alert (live_data[i].chn());
break;
}

}

// Data for Channel-4 (Temperature Sensor)
if (live_data[i].chn() == 3)
{
std::cout << std::setprecision(PRINT_PRECISION) << "Time : \a" << live_data[i].time() << "\t Chn 4: " << live_data[i].data() << "\n" << std::endl;

// Alert if signal is above threshold
if (live_data[i].data() > TEMP_SENS_THRESHOLD)
{
close_gas_valves (driver);
send_alert (live_data[i].chn());
break;
}
}

}

}

} // while (1)

/***************************************************
* Stop acquisition
***************************************************/
driver->stop_acquisition ();

/***************************************************
* Disconnect QDAL41xB device
***************************************************/
driver->disconnect();

return 0;

} // end main

void add_status_to_email (std::string status)
{
// Open mail.txt to append data to end of file
ofstream mail_file;
mail_file.open ("mail.txt", ios::out | ios::app);

if (mail_file.is_open())
{
mail_file << status;
mail_file.close();
}

else
{
std::cout << "Unable to add alert status to mail." << std::endl;
}


}

void open_gas_valves (std::unique_ptr<L412B::Driver> &driver)
{
std::cout << "Switching on all gas supplies!" << std::endl;
uint8_t data = 0b00000001;
driver->clr_gpo (data);
}

void close_gas_valves (std::unique_ptr<L412B::Driver> &driver)
{
std::cout << "Switching off all gas supplies!" << std::endl;
uint8_t data = 0b00000001;
driver->set_gpo (data);
}

void send_alert (int channel)
{
std::string status;

switch (channel)
{
case 0 : status = "Smoke Sensor 1 : HIGH";
break;
case 1 : status = "Smoke Sensor 2 : HIGH";
break;
case 2 : status = "Temperature Sensor 1 : HIGH";
break;
case 3 : status = "Temperature Sensor 2 : HIGH";
break;
default : status = "Alert! Cause : Unknown";
break;
}

// Display Alert status on terminal
std::cout << "\n\n\t\t ****** DANGER ******" << std::endl;
std::cout << "\nAlert Status" << std::endl;
std::cout << "*********************" << std::endl;
std::cout << status << "\n" << std::endl;

// Update alert email with alert status
add_status_to_email ("\n\nAlert Status\n");
add_status_to_email ("*******************\n");
add_status_to_email (status);

std::cout << "Sending alert mails..." << std::endl;
// Send email to [email protected]
system("ssmtp [email protected] < mail.txt");

// Send email to [email protected]
system("ssmtp [email protected] < mail.txt");

// // Send email to [email protected]
// system("ssmtp [email protected] < mail.txt");

// Send email to [email protected]
system("ssmtp [email protected] < mail.txt");

std::cout << "\t \t Alert mails sent." << std::endl;
system("aplay alarm.wav");
}
55 changes: 55 additions & 0 deletions cvd_safety/mail.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
From: [email protected]
Subject: Testing : CVD UNUSUAL ACTIVITY ALERT!

IMMEDIATE ATTENTION REQUIRED!
The gas leakage and temperature monitoring systems have detected unusual levels. Possible risk of FIRE!
Location : Quazar Tech. Workshop, 103b, Begumpur Village, New Delhi

PEASE SEE LAST LINE OF THIS EMAIL FOR THE CAUSE OF ALERT.


*^^^*/////
*.*
*****(/(***** (TEMP SENSOR-1) (TEMP SENSOR-2)
( ) .-------------------------------------------------.
,,,,,,,,( ),,,,,,,. | |
Pressure ,,. ( ) ,,. | Tubular Furnace |
Regulator ,,. (***********) ,,. | QBAKE1200 |
,,. On/Off Valve ,,. | |
(***/********, ,,. ,,. | |
*#/(/ ,,. ,,. | |
___ .. ,,. |-----------| ,,. | |
/ \ * / ,,. | | ,,. (********************************************************)
< * > ./ /,,,,,,,,,,,,,| |,,,,,,,,,,,,,,,,,(********************************************************),,,.
\ / . / | | (********************************************************) ,,.
/ \ |___________| |.................................................| ,,.
.///(((///( Restrictor ,,.
|,,,,,,,,,,| (SMOKE SENSOR-1) (SMOKE SENSOR-2) ,,.
|,,,,,,,,,,| ,,.
|,,,,,,,,,,| ,,.
|,,,,,,,,,,| ,,.
|,,,,,,,,,,| ,,.
|,,,,,,,,,,| | | ,,.
|,,,,,,,,,,| / \ ,,.
|,,,,,,,,,,| | | ,,.
|,,,,,,,,,,| | | ,,.
|,,,,,,,,,,| | | ,,.
|,,,,,,,,,,| | | ,,.
|,,,,,,,,,,| | | ,,.
|,,,,,,,,,,| | | ,,.
|,,,,,,,,,,| | | ,,.
|,,,,,,,,,,| | | ,,.
|,,,,,,,,,,| .* *. ,,.
|,,,,,,,,,,| \ / ,,.
|,,,,,,,,,,| . .,,,,,,,,,,,,,,,,,,,,,.
|,,,,,,,,,,| . ,,,,,,,,,,,,,,,,,,,,,,.
|,,,,,,,,,,| / \
|,,,,,,,,,,| * *
|,,,,,,,,,,| \ /
|,,,,,,,,,,| ^^^
|,,,,,,,,,,| Soap Bubble Meter
|,,,,,,,,,,|
|,,,,,,,,,,| Oxygen Cylinder
|,,,,,,,,,,| (Grade-1)
|,,,,,,,,,,|
\,,,,,,,,/
15 changes: 15 additions & 0 deletions cvd_safety/makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
objects = lab_safety_iQ.o

CC = "/usr/bin/g++"

test : $(objects)
@ echo Building $@
$(CC) -o test lab_safety_iQ.o -pthread -Wall -O3 -std=c++14 -lL412B -lftdi

lab_safety_iQ.o : lab_safety_iQ.cxx
$(CC) -c lab_safety_iQ.cxx -pthread -Wall -O3 -std=c++14 -lL412B -lftdi

.PHONY : clean
clean :
@ echo Cleaning...
rm -f test $(objects)