Hardware components | ||||||
| × | 3 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
Software apps and online services | ||||||
| ||||||
Hand tools and fabrication machines | ||||||
| ||||||
|
Inspiration:
When the New York state governor demonstrated using a bag-mask compressor in a press conference and mentioned that the state will be soon out of ventilators, it was the first realization to our team. In a country like India once the pandemic blows over, the ventilators will not be enough and the patients, medical staff, their family will have to re-integrate in the environment in a safe and friendly manner. Over the next few days, we came together as a team with both the hackathon and COVID-19 in mind, we started gathering materials and components build the device. We even started to talk to doctors and hospitals and got good demand and validation from them and finalised on an idea to build over the weekend. As we go deeper in the pandemic, hospitals will see a spike in demand for ventilators, non breather masks, CPAP machines and ambu bag implementation, as confirmed by numerous medical teams we interviewed. With current bag valve mask technology and ventilator, a medical health professional needs to be with the patient 24/7 to manually operate the bag valve mask, if not a ventilator. This would be gruesomely tiring for the medical teams and would also expose them to the infected patients for extended periods of time. The understanding stands that the coronavirus damages the hosts lungs by almost 30%. This means that a patient who is affected by coronavirus is susceptible to viruses/diseases affecting the lungs and has lesser power to battle the same. In a post COVID-19 world it is extremely necessary to be prepared for emergencies related to such patients and be in abundance of ventilators and respirators that can be used at will.
what it does:
Our solution is a IoT portable ventilator device called reSPIRE that will provide respiration support to COVID-19 patients by compressing the bag valve mask at the correct breaths/minute, inhalation/expiration ratio, and tidal volume. It can be controlled by an operator using the on-system controls or using a control on an app. The device can be switched between pressure and volume modes making it seamless just like an actual ICU ventilator. Our app, integrated with the device, will enable the health care professionals as well as the patient caregivers to remotely monitor and control pressure, volume, and flow rates in response to changing patient behavior such as FIO2 levels. Post the COVID-19 pandemic, it will assist doctors to care for remote patients, as they re-integrate themselves into the world.
In a simple explanation, the reSPIRE device helps rhythmically compress the bag valve mask to provide air to the patients as a non-invasive medical procedure. However, it is much more sophisticated as it allows medical professionals to change various parameters of how the air is delivered, just like a ventilator. The device allows changing the tidal volume delivered, breaths per minute( BPM) as well as the inspiration:expiration ratio( I:E ratio). The device is also equipped with modes such as the SIMV-P and SIMV-C mode which runs the device on a feedback loop and allows it to auto-adjust based on the current state of the patient thus aiding the breathing of the patient. The device can be controlled using the on-board switches and knobs. The device has been coupled with a WiFi module which transmits the data to a cloud database which has been configured in SQL for easy storage of data based on the structure. The data is further picked up by a mobile application to further view the data as well as modify the controls using an internet connection. The data stored in the SQL Server is shifted to an AWS cloud repository for storage at a fixed time and at a fixed frequency to keep the databases empty. The data stored on the cloud repository further can be used for analytical purposes as well as profiling the patients under care and their breathing requirements during ailment.
How we built it:
We make a proper design on paper and also take feedback from medical professionals in our network. Then over the weekend we paced up prototyping, testing and validating the product.
Since what we are offering is a complete end to end product, we have numerous components that we are developing simultaneously, trying to make them more intuitive and context relevant. We used this opportunity to align these different components to make it more a holistic product. We even made a glass based wood casing using home based materials for proper prototyping.
The Electronics of the device is simple yet sophisticated to match the scale of a medical device. For our prototype, we’ve used an OSEPP Max- Arduino Compatible board along with a DS3235 Servo motor. There are 3 pressure sensors used in devices which serve different purposes.
The differential pressure sensor in the device helps measure the flow of air from the bag mask to the patient. The flow can be controlled and eventually used to measure the Tidal Volume of the respirator.
The gauge pressure sensors help measure the expiratory pressure and the plateau pressure generated by the respirator. These are critical measurements in terms of the device being medically feasible. The second gauge pressure sensor allows recording the activity of the patient. If a patient tries to put an effort into breathing himself/herself, the gauge pressure sensor records a drop and provides the feedback to the micro-controller device which in turn modifies the breathing cycles to aid the patient into breathing.
The proprietary code that has been developed for the device allows efficient control of the system as well as selection of modes which puts the ventilator into an autonomous setting for achieving the intended goals. The SIMV mode can control the bag mask compressor to achieve required Tidal volume, Inspiration:Expiration ratio as well as the Breaths per minute. The modes can either be selected using the controls present on the device as well as the mobile app. The mobile app allows remote control of the device as well as access to patient information in a highly organised format.
The device is equipped with a WiFi module which enables this functionality. The data is uploaded to a SQL database online which is hosted on a cloud server. The data is shifted to an AWS cloud repository every 10 minutes to allow seamless performance benefits for the application connected to the SQL database. The AWS cloud repository hosts the data for analytical purposes and further learning such as profiling of patterns based on patient information.
On the tech side we improved on our codes and integrated a cloud component with the device, on the design side we conducted various interviews of experts in practice, and incorporated the feedback that we received into the product-service. On research end we used this opportunity to read on various fields by talking to medical professionals. One comment we got from most interviews that we conducted was to have these materials ready since there is a lot of interest in such product- service offerings especially with the cloud-service, application for monitoring and control and the cost which is not matched by any other existing product. And hence, finally on the dissemination end we started preparing materials such as videos, app, write-ups that we can start using to reach out to the necessary network post.
The data is recorded using the sensors and control potentiometers on the device. The microcontroller unit further records the movements of the servo motor to record the number of breaths supplied per minute( BPM), Inspiration to Expiration Ratio ( I:E ratio) and the Tidal Volume achieved to verify if the required controls are having the intended effect.
Papers:
Testing:
- acv_mode.ino
- arduino_acv_simv_code.ino
- nodemcu_serial_wifi.ino
- acv_simv.ino
- nodemcu_simv_acv.ino
- uno_simv_acv-Queue.h
- uno_simv_acv/uno_simv_acv.ino
- uno_simv_acv/Queue.h
- arduino.json
- uno_simv_acv/uno_simv_acv.ino
- Pressure_Mode.csv
- c_cpp_properties.json
- gen_dataset.py
- nextion_write.ino
- nextion_2_pages.HMI
- nextion_2_pages.tft
- nextion_lcd_functions.ino
- nextion_test.ino
- maulik_test.ino
- uno_simv_acv_json_series_firebase.ino
- nodemcu_simv_acv_json_series_firebase.ino
- test.ino
- vent_3controls.ino
- test/Queue.h
- arduino_lcd.ino
- nodemcu_code.ino
- vent_3controls_mode.ino
- node_mcu_serial_firebase.ino
- uno_firebase_sd_screen.ino
- uno_serial_firebase.ino
- uno_serial_sd_firebase.ino
- wifi_sample_code.ino
#include <Guino.h>
#include <Servo.h>
Servo servoright;
int pos = 0;
// ==== Analog Pins =====
float potpinIE_ratio = 0;
int potpinTidVol = 1;
int potpinBPM = 2;
int pinguage_mask = 5;
int pinguage_expiration = 4;
int pinguage_diff = 3;
// ==== Analog Pins ====
int inPin = 4;
// ==== Sensor Offset =====
const float guageSensorOffset = 41;
const float pressureDiffSensorOffset = 41;
// ===== Other vars ======
float check_value;
float IE_ratio;
float TidVol;
float BPM;
float separation;
float sensorvalue;
float pressure_mask;
float pressure_expiration;
float pressure_diff;
int display_IE_ratio;
int display_BPM;
int display_TidVol;
int display_sensorvalue_cmh2o;
int display_sensorvalue_gp_cmh2o;
uint32_t endTime;
// ======= Mode changing vars =========
int state = HIGH; // the current state of the output pin
int mode; // the current reading from the input pin
int previous = LOW; // the previous reading from the input pin
long t_time = 0; // the last time the output pin was toggled
long debounce = 200; // the debounce time, increase if the output flickers
void setup()
{
servoright.attach(9); // attaches the servo on pin 9 to the servo object
Serial.begin(9600);
// attachInterrupt(0, pin_ISR, CHANGE);
}
void loop()
{
// ========== Read all analog input & Detecting Mode Settings =============
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
mode = digitalRead(inPin);
IE_ratio = map(analogRead(potpinIE_ratio), 0, 1023, 1.00, 4.00); // scale it to use it with the servo (value between 0 and 180)
TidVol = map(analogRead(potpinTidVol), 0, 1023, 40.00, 90.00); // scale it to use it with the servo (value between 0 and 180)
BPM = map(analogRead(potpinBPM), 0, 1023, 8.00, 30.00); // scale it to use it with the servo (value between 0 and 180)
// ====== Copmute respiration separation time based on pot inputs ==========
separation = 60/BPM - (1+IE_ratio);
if (separation < 0)
{
IE_ratio = 60/BPM - 1;
separation = 60/BPM - (1+IE_ratio);
}
/* if (mode == HIGH && previous == LOW && millis() - t_time > debounce)
{
// ========= Servo a-Clockwise motion =============
for(pos = 30; pos <= TidVol+30; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
servoright.write(pos);
delay(1000/TidVol);
// ============ Update pressure values =========
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
Serial.println(pressure_mask);
//Serial.println(pressure_diff);
//Serial.println(pressure_expiration);
}
delay(15);
// ========= Servo Clockwise motion ============
for(pos = TidVol+30; pos>=30; pos-=1) // goes from 180 degrees to 0 degrees
{
servoright.write(pos);
delay(1000*IE_ratio/TidVol);
// ============ Update pressure values =========
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
Serial.println(pressure_mask);
//Serial.println(pressure_diff);
//Serial.println(pressure_expiration);
}
delay(separation*1000);
}
else
{ */
endTime = millis();
while(digitalRead(inPin) == HIGH)
{
pressure_diff = analogRead(pinguage_diff);
acv_mode();
}
// }
previous = mode;
}
void acv_mode()
{
float IE_ratio;
float TidVol;
float BPM;
float per_breath_time;
float per_inspiration_time;
float per_expiration_time;
float human_effort;
float separation;
uint32_t cycleEndTime;
bool firstRun = true;
while(digitalRead(inPin) == HIGH)
{
// Fetch all potentiometer values
IE_ratio = map(analogRead(potpinIE_ratio), 0, 1023, 1.00, 4.00);
TidVol = map(analogRead(potpinTidVol), 0, 1023, 40.00, 90.00);
BPM = map(analogRead(potpinBPM), 0, 1023, 8.00, 30.00);
separation = (60/BPM - (1+IE_ratio));
if (separation < 0)
{
IE_ratio = 60/BPM - 1;
separation = 60/BPM - (1+IE_ratio);
}
// Fetch pressure sensor values
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = analogRead(pinguage_diff);
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
// Initiate the cycle
if(firstRun)
{
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
firstRun = false;
}
// ========= Identify trigger and initiate the cycle =============
if(millis() - cycleEndTime >= (uint32_t)separation*1000 || pressure_mask < -1)
{
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
}
}
/* per_breath_time = 1/BPM*60;
per_inspiration_time = 1/(1+1/IE_ratio)*per_breath_time;
per_expiration_time = per_breath_time - per_inspiration_time;
for(int i=0;i<5;i++){
human_effort = analogRead(pinguage_mask);
check_value = (map(analogRead(human_effort), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
delay(5);
}
//human_effort = analogRead(pinguage_mask);
if(check_value < -1){
if( check_value < -0.5 && check_value > -1){
TidVol = 0.8*TidVol;
per_inspiration_time = 0.8*per_inspiration_time;
delay(per_inspiration_time);
IE_ratio = per_inspiration_time/per_expiration_time;
}
else if (check_value < -1 && check_value > -2){
TidVol = 0.6*TidVol;
per_inspiration_time = 0.6*per_inspiration_time;
delay(per_inspiration_time);
IE_ratio = per_inspiration_time/per_expiration_time;
}
else if (check_value < -2 && check_value > -3){
TidVol = 0.4*TidVol;
per_inspiration_time = 0.4*per_inspiration_time;
delay(per_inspiration_time);
IE_ratio = per_inspiration_time/per_expiration_time;
}
else if (check_value < -4){
TidVol = 0.2*TidVol;
per_inspiration_time = 0.2*per_inspiration_time;
delay(per_inspiration_time);
IE_ratio = per_inspiration_time/per_expiration_time;
}
}
*/
}
// =======================
// Inspiration Function
// =======================
void inspiration(float TidVol)
{ int pos;
for(pos = 30; pos <= TidVol+30; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
servoright.write(pos);
delay(1000/TidVol);
// ============ Update pressure values =========
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = analogRead(pinguage_diff);
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
if (millis() - endTime > (uint32_t)100)
{
Serial.println(pressure_mask);
endTime = millis();
}
//Serial.println(pressure_mask);
//Serial.println(pressure_diff);
//Serial.println(pressure_expiration);
}
}
// =====================
// Expiration Function
// =====================
uint32_t expiration(float TidVol, float IE_ratio)
{
for(pos = TidVol+30; pos>=30; pos-=1) // goes from 180 degrees to 0 degrees
{
servoright.write(pos);
delay(1000*IE_ratio/TidVol);
// ============ Update pressure values =========
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = analogRead(pinguage_diff);
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
if (millis() - endTime > (uint32_t)100)
{
Serial.println(pressure_mask);
endTime = millis();
}
//Serial.println(pressure_mask);
//Serial.println(pressure_diff);
//Serial.println(pressure_expiration);
}
return millis();
}
// =============================
// Copmute volume and flow rates
// =============================
void computeFlows(float area_1, float area2)
{
float pressureDiff;
float pressure_cmH2o;
float pressure_pa;
float rho = 1.225;
float massFlow;
float volFlow;
pressure_cmH2o = (analogRead(pinguage_diff) - pressureDiffSensorOffset)*10.1972/92;
pressure_pa = pressure_cmH2o*98.0665;
// massFlow=1000*sqrt((abs(pressure_pa)*2*rho)/((1/(pow(area_2,2)))-(1/(pow(area_1,2)))));
volFlow = massFlow/rho;
}
#include <Guino.h>
#include <Servo.h>
#include<SoftwareSerial.h>
//====== Serial COnnection with NODEMCU =====
SoftwareSerial SUART(2, 3); //SRX=Dpin-2; STX-DPin-3
Servo servoright;
int pos = 0;
// ==== Analog Pins =====
float potpinIE_ratio = 0;
int potpinTidVol = 1;
int potpinBPM = 2;
int pinguage_mask = 4;
int pinguage_expiration = 3;
int pinguage_diff = 2;
// ==== Analog Pins ====
int inPin = 4;
// ==== Sensor Offset =====
const float guageSensorOffset = 41;
const float pressureDiffSensorOffset = 41;
// ===== Other vars ======
float check_value;
float IE_ratio;
float TidVol;
float BPM;
float separation;
float sensorvalue;
float pressure_mask;
float pressure_expiration;
float pressure_diff;
int display_IE_ratio;
int display_BPM;
int display_TidVol;
int display_sensorvalue_cmh2o;
int display_sensorvalue_gp_cmh2o;
// ======= Mode changing vars =========
int state = HIGH; // the current state of the output pin
int mode; // the current reading from the input pin
int previous = LOW; // the previous reading from the input pin
long t_time = 0; // the last time the output pin was toggled
long debounce = 200; // the debounce time, increase if the output flickers
void setup()
{
servoright.attach(9); // attaches the servo on pin 9 to the servo object
Serial.begin(9600);
SUART.begin(115200); //enable SUART Port for communication with NODEMCU
// attachInterrupt(0, pin_ISR, CHANGE);
}
void loop()
{
if (digitalRead(inPin) == LOW)
{
while(digitalRead(inPin)==LOW)
{
simv_mode();
}
}
else
{ while(digitalRead(inPin) == HIGH)
{
acv_mode();
}
}
}
// =======================
// ACV MODE Function
// =======================
void acv_mode()
{
float IE_ratio;
float TidVol;
float BPM;
float per_breath_time;
float per_inspiration_time;
float per_expiration_time;
float human_effort;
float separation;
uint32_t cycleEndTime;
bool firstRun = true;
while(digitalRead(inPin) == HIGH)
{
// Fetch all potentiometer values
IE_ratio = map(analogRead(potpinIE_ratio), 0, 1023, 1.00, 4.00);
TidVol = map(analogRead(potpinTidVol), 0, 1023, 40.00, 90.00);
BPM = map(analogRead(potpinBPM), 0, 1023, 8.00, 30.00);
separation = (60/BPM - (1+IE_ratio));
if (separation < 0)
{ IE_ratio = 60/BPM - 1;
separation = 60/BPM - (1+IE_ratio);
}
// Fetch pressure sensor values
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
SUART.print('<'); //<(start mark)
SUART.print((int)BPM,DEC);
SUART.print(','); //,(data seperator)
SUART.print((int)IE_ratio, DEC);
SUART.print(','); //,(data seperator)
SUART.print((int)TidVol, DEC);
SUART.print(','); //,(data seperator)
SUART.print((int)pressure_mask, DEC);
SUART.print(','); //,(data seperator)
SUART.print((int)pressure_diff, DEC);
SUART.print(','); //,(data seperator)
SUART.print((int)pressure_expiration, DEC);
SUART.print('>'); //>(end mark)
SUART.println();
// Initiate the cycle
if(firstRun)
{
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
firstRun = false;
}
// ========= Identify trigger and initiate the cycle =============
if(millis() - cycleEndTime >= (uint32_t)separation*1000 || pressure_mask < -1)
{
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
}
}
}
// =======================
// SIMV Logic Function
// =======================
uint32_t simv_logic(float pressure_mask, float TidVol, float IE_ratio)
{
uint32_t cycleEndTime;
pressure_mask = int(floor(pressure_mask));
switch(int(pressure_mask)){
case -6:
case -5:
case -4:
TidVol = TidVol*0.25;
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
case -3:
TidVol = TidVol*0.50;
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
case -2:
TidVol = TidVol*0.75;
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
case -1:
TidVol = TidVol*0.75;
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
default:
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
}
return cycleEndTime;
}
// =======================
// SIMV MODE Function
// =======================
void simv_mode()
{
float IE_ratio;
float TidVol;
float BPM;
float per_breath_time;
float per_inspiration_time;
float per_expiration_time;
float human_effort;
float separation;
uint32_t cycleEndTime;
bool firstRun = true;
while(digitalRead(inPin) == LOW)
{
// Fetch all potentiometer values
IE_ratio = map(analogRead(potpinIE_ratio), 0, 1023, 1.00, 4.00);
TidVol = map(analogRead(potpinTidVol), 0, 1023, 40.00, 90.00);
BPM = map(analogRead(potpinBPM), 0, 1023, 8.00, 30.00);
separation = (60/BPM - (1+IE_ratio));
if (separation < 0)
{ IE_ratio = 60/BPM - 1;
separation = 60/BPM - (1+IE_ratio);}
// Fetch pressure sensor values
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
SUART.print('<'); //<(start mark)
SUART.print((int)BPM,DEC);
SUART.print(','); //,(data seperator)
SUART.print((int)IE_ratio, DEC);
SUART.print(','); //,(data seperator)
SUART.print((int)TidVol, DEC);
SUART.print(','); //,(data seperator)
SUART.print((int)pressure_mask, DEC);
SUART.print(','); //,(data seperator)
SUART.print((int)pressure_diff, DEC);
SUART.print(','); //,(data seperator)
SUART.print((int)pressure_expiration, DEC);
SUART.print('>'); //>(end mark)
SUART.println();
// Initiate the cycle
if(firstRun)
{
pressure_mask = average_pressure_mask();
cycleEndTime = simv_logic(pressure_mask, TidVol, IE_ratio);
firstRun = false;
}
// ========= Identify trigger and initiate the cycle =============
if(millis() - cycleEndTime >= (uint32_t)separation*1000 || average_pressure_mask() < -1)
{
pressure_mask = average_pressure_mask();
cycleEndTime = simv_logic(pressure_mask, TidVol, IE_ratio);
}
}
}
// =======================
// Average Pressure Function
// =======================
float average_pressure_mask()
{
pressure_mask = 0;
for(int i=0;i<5;i++)
{
pressure_mask = pressure_mask + (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
delay(3);
}
return (pressure_mask/5);
}
// =======================
// Inspiration Function
// =======================
void inspiration(float TidVol)
{ int pos;
for(pos = 30; pos <= TidVol+30; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
servoright.write(pos);
delay(1000/TidVol);
// ============ Update pressure values =========
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
Serial.println(pressure_mask);
//Serial.println(pressure_diff);
//Serial.println(pressure_expiration);
}
}
// =====================
// Expiration Function
// =====================
uint32_t expiration(float TidVol, float IE_ratio)
{
for(pos = TidVol+30; pos>=30; pos-=1) // goes from 180 degrees to 0 degrees
{
servoright.write(pos);
delay(1000*IE_ratio/TidVol);
// ============ Update pressure values =========
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
Serial.println(pressure_mask);
//Serial.println(pressure_diff);
//Serial.println(pressure_expiration);
}
return millis();
}
#ifdef ESP32
#include <WiFi.h>
#include <HTTPClient.h>
#else
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#endif
#include <Wire.h>
#include<SoftwareSerial.h>
SoftwareSerial SUART(4, 5); //SRX=Dpin-D2; STX-DPin-D1
//===================================
// Variables for storing pressure data
//===================================
float BPM = 0.00;
float IE_ratio = 0.00;
float TidVol = 0.00;
float pressure_mask = 0.00;
float pressure_diff = 0.00;
float pressure_expiration = 0.00;
float list_values[5] ;
//=======================================
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars]; // temporary array for use when parsing
boolean newData = false;
// Replace with your network credentials
const char* ssid = "NETGEAR43";
const char* password = "smilingnest196";
// REPLACE with your Domain name and URL path or IP address with path
const char* serverName = "http://respire.000webhostapp.com/post-esp-data.php";
// Keep this API Key value to be compatible with the PHP code provided in the project page.
// If you change the apiKeyValue value, the PHP file /post-esp-data.php also needs to have the same key
String apiKeyValue = "xPmAT5Ab3j7F6";
String sensorName = "MPXDIFF";
String sensorLocation = "San Diego";
void setup() {
Serial.begin(115200); //enable Serial Monitor
SUART.begin(115200); //enable SUART Port
WiFi.begin(ssid, password);
Serial.println("Connecting");
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to WiFi network with IP Address: ");
Serial.println(WiFi.localIP());
}
void loop() {
recvWithStartEndMarkers();
if (newData == true) {
strcpy(tempChars, receivedChars);
// this temporary copy is necessary to protect the original data
// because strtok() used in parseData() replaces the commas with \0
parseData();
newData = false;
}
Serial.print(list_values[0]);
send_data(list_values);
}
//======================================
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (Serial.available() > 0 && newData == false) {
rc = Serial.read();
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
}
//========================================
void parseData() { // split the data into its parts
char * strtokIndx; // this is used by strtok() as an index
for (int i=0;i<5;i++)
{
if(i=0){
strtokIndx = strtok(tempChars,",");
}
else
{
strtokIndx = strtok(NULL, ",");
}
list_values[i] = atof(strtokIndx);
}
}
void send_data(float list_data[]) {
if(WiFi.status()== WL_CONNECTED){
HTTPClient http;
// Your Domain name with URL path or IP address with path
http.begin(serverName);
// Specify content-type header
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
// Prepare your HTTP POST request data
//sample1 = sample1 + 0.646;
//sample2 = sample2 + 0.545;
//sample3 = sample3 + 0.666;
String httpRequestData = "api_key=" + apiKeyValue + "&sensor=" + sensorName
+ "&location=" + sensorLocation + "&value1=" + String(list_data[0])
+ "&value2=" + String(list_data[1]) + "&value3=" + String(list_data[2]) + "";
Serial.print("httpRequestData: ");
Serial.println(httpRequestData);
int httpResponseCode = http.POST(httpRequestData);
if (httpResponseCode>0) {
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
}
else {
Serial.print("Error code: ");
Serial.println(httpResponseCode);
}
// Free resources
http.end();
}}
#include <Guino.h>
#include <Servo.h>
Servo servoright;
int pos = 0;
// ==== Analog Pins =====
float potpinIE_ratio = 0;
int potpinTidVol = 1;
int potpinBPM = 2;
int pinguage_mask = 4;
int pinguage_expiration = 3;
int pinguage_diff = 3;
// ==== Analog Pins ====
int inPin = 2;
// ==== Sensor Offset =====
const float guageSensorOffset = 41;
const float pressureDiffSensorOffset = 41;
// ===== Other vars ======
float check_value;
float IE_ratio;
float TidVol;
float BPM;
float separation;
float sensorvalue;
float pressure_mask;
float pressure_expiration;
float pressure_diff;
int display_IE_ratio;
int display_BPM;
int display_TidVol;
int display_sensorvalue_cmh2o;
int display_sensorvalue_gp_cmh2o;
// ======= Mode changing vars =========
int state = HIGH; // the current state of the output pin
int mode; // the current reading from the input pin
int previous = LOW; // the previous reading from the input pin
long t_time = 0; // the last time the output pin was toggled
long debounce = 200; // the debounce time, increase if the output flickers
void setup()
{
servoright.attach(9); // attaches the servo on pin 9 to the servo object
Serial.begin(9600);
// attachInterrupt(0, pin_ISR, CHANGE);
}
void loop()
{
if (digitalRead(inPin) == LOW)
{
while(digitalRead(inPin)==LOW)
{
simv_mode();
}
}
else
{ while(digitalRead(inPin) == HIGH)
{
acv_mode();
}
}
}
// =======================
// ACV MODE Function
// =======================
void acv_mode()
{
float IE_ratio;
float TidVol;
float BPM;
float per_breath_time;
float per_inspiration_time;
float per_expiration_time;
float human_effort;
float separation;
uint32_t cycleEndTime;
bool firstRun = true;
while(digitalRead(inPin) == HIGH)
{
// Fetch all potentiometer values
IE_ratio = map(analogRead(potpinIE_ratio), 0, 1023, 1.00, 4.00);
TidVol = map(analogRead(potpinTidVol), 0, 1023, 40.00, 90.00);
BPM = map(analogRead(potpinBPM), 0, 1023, 8.00, 30.00);
separation = (60/BPM - (1+IE_ratio));
if (separation < 0)
{ IE_ratio = 60/BPM - 1;
separation = 60/BPM - (1+IE_ratio);
}
// Fetch pressure sensor values
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
// Initiate the cycle
if(firstRun)
{
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
firstRun = false;
}
// ========= Identify trigger and initiate the cycle =============
if(millis() - cycleEndTime >= (uint32_t)separation*1000 || pressure_mask < -1)
{
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
}
}
}
// =======================
// SIMV Logic Function
// =======================
uint32_t simv_logic(float pressure_mask, float TidVol, float IE_ratio)
{
uint32_t cycleEndTime;
pressure_mask = int(floor(pressure_mask));
switch(int(pressure_mask)){
case -6:
case -5:
case -4:
TidVol = TidVol*0.25;
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
case -3:
TidVol = TidVol*0.50;
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
case -2:
TidVol = TidVol*0.75;
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
case -1:
TidVol = TidVol*0.75;
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
default:
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
}
return cycleEndTime;
}
// =======================
// SIMV MODE Function
// =======================
void simv_mode()
{
float IE_ratio;
float TidVol;
float BPM;
float per_breath_time;
float per_inspiration_time;
float per_expiration_time;
float human_effort;
float separation;
uint32_t cycleEndTime;
bool firstRun = true;
while(digitalRead(inPin) == LOW)
{
// Fetch all potentiometer values
IE_ratio = map(analogRead(potpinIE_ratio), 0, 1023, 1.00, 4.00);
TidVol = map(analogRead(potpinTidVol), 0, 1023, 40.00, 90.00);
BPM = map(analogRead(potpinBPM), 0, 1023, 8.00, 30.00);
separation = (60/BPM - (1+IE_ratio));
if (separation < 0)
{ IE_ratio = 60/BPM - 1;
separation = 60/BPM - (1+IE_ratio);
}
// Fetch pressure sensor values
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
// Initiate the cycle
if(firstRun)
{
pressure_mask = average_pressure_mask();
cycleEndTime = simv_logic(pressure_mask, TidVol, IE_ratio);
firstRun = false;
}
// ========= Identify trigger and initiate the cycle =============
if(millis() - cycleEndTime >= (uint32_t)separation*1000 || average_pressure_mask() < -1)
{
pressure_mask = average_pressure_mask();
cycleEndTime = simv_logic(pressure_mask, TidVol, IE_ratio);
}
}
}
// =======================
// Average Pressure Function
// =======================
float average_pressure_mask()
{
pressure_mask = 0;
for(int i=0;i<5;i++)
{
pressure_mask = pressure_mask + (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
delay(3);
}
return (pressure_mask/5);
}
// =======================
// Inspiration Function
// =======================
void inspiration(float TidVol)
{ int pos;
for(pos = 30; pos <= TidVol+30; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
servoright.write(pos);
delay(1000/TidVol);
// ============ Update pressure values =========
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
Serial.println(pressure_diff);
//Serial.println(pressure_diff);
//Serial.println(pressure_expiration);
}
}
// =====================
// Expiration Function
// =====================
uint32_t expiration(float TidVol, float IE_ratio)
{
for(pos = TidVol+30; pos>=30; pos-=1) // goes from 180 degrees to 0 degrees
{
servoright.write(pos);
delay(1000*IE_ratio/TidVol);
// ============ Update pressure values =========
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
Serial.println(pressure_diff);
//Serial.println(pressure_diff);
//Serial.println(pressure_expiration);
}
return millis();
}
// =======================
// Layer 0: Alarm Function
// =======================
void alarm();
#ifdef ESP32
#include <WiFi.h>
#include <HTTPClient.h>
#else
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#endif
#include <ArduinoJson.h>
#include <Wire.h>
#include<SoftwareSerial.h>
SoftwareSerial SUART(4, 5); //SRX=Dpin-D2; STX-DPin-D1
//===================================
// Variables for storing pressure data
//===================================
float BPM = 0.00;
float IE_ratio = 0.00;
float TidVol = 0.00;
float pressure_mask = 0.00;
float pressure_diff = 0.00;
float pressure_expiration = 0.00;
//=======================================
unsigned long time_1;
bool test_2;
String last_char = "}";
// Replace with your network credentials
const char* ssid = "1.21 Jiggawatts!";
const char* password = "itburnswhenIP";
// REPLACE with your Domain name and URL path or IP address with path
const char* serverName = "http://respire.000webhostapp.com/post-esp-data.php";
// Keep this API Key value to be compatible with the PHP code provided in the project page.
// If you change the apiKeyValue value, the PHP file /post-esp-data.php also needs to have the same key
String apiKeyValue = "xPmAT5Ab3j7F6";
String sensorName = "MPXDIFF";
String sensorLocation = "San Diego";
void setup() {
Serial.begin(9600); //enable Serial Monitor
SUART.begin(9600); //enable SUART Port
WiFi.begin(ssid, password);
Serial.println("Connecting");
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to WiFi network with IP Address: ");
Serial.println(WiFi.localIP());
}
void loop() {
String message = "";
//String test = "";
DynamicJsonDocument doc(1024);
doc["type"] = "request";
//serializeJson(doc, test);
//Serial.println(test);
serializeJson(doc,SUART);
// Reading the response
boolean messageReady = false;
time_1 = millis();
while(messageReady == false) { // blocking but that's ok
if(SUART.available()) {
message = SUART.readString();
Serial.println(message);
test_2 = message.endsWith(last_char);
Serial.println(test_2);
if (!(test_2)){
return;
}
Serial.println("I am here");
messageReady = true;
}
}
send_data(message);
delay(3000);
}
//======================================
void send_data(String message) {
DynamicJsonDocument doc(1024);
DeserializationError error = deserializeJson(doc,message);
if(error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.c_str());
return;
}
if(WiFi.status()== WL_CONNECTED){
HTTPClient http;
// Your Domain name with URL path or IP address with path
http.begin(serverName);
// Specify content-type header
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
String BPM = doc["BPM"];
String IE_ratio = doc["IE_ratio"];
String TidVol = doc["TidVol"];
String httpRequestData = "api_key=" + apiKeyValue + "&sensor=" + sensorName
+ "&location=" + sensorLocation + "&value1=" + BPM
+ "&value2=" + IE_ratio + "&value3=" + TidVol + "";
Serial.print("httpRequestData: ");
Serial.println(httpRequestData);
int httpResponseCode = http.POST(httpRequestData);
if (httpResponseCode>0) {
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
}
else {
Serial.print("Error code: ");
Serial.println(httpResponseCode);
}
// Free resources
http.end();
}}
/*
* Queue.h
*
* By Steven de Salas
*
* Defines a templated (generic) class for a queue of things.
* Used for Arduino projects, just #include "Queue.h" and add this file via the IDE.
*
* Examples:
*
* Queue<char> queue(10); // Max 10 chars in this queue
* queue.push('H');
* queue.push('e');
* queue.count(); // 2
* queue.push('l');
* queue.push('l');
* queue.count(); // 4
* Serial.print(queue.pop()); // H
* Serial.print(queue.pop()); // e
* queue.count(); // 2
* queue.push('o');
* queue.count(); // 3
* Serial.print(queue.pop()); // l
* Serial.print(queue.pop()); // l
* Serial.print(queue.pop()); // o
*
* struct Point { int x; int y; }
* Queue<Point> points(5);
* points.push(Point{2,4});
* points.push(Point{5,0});
* points.count(); // 2
*
*/
#ifndef QUEUE_H
#define QUEUE_H
#include <Arduino.h>
template<class T>
class Queue {
private:
int _front, _back, _count;
T *_data;
int _maxitems;
public:
Queue(int maxitems = 256) {
_front = 0;
_back = 0;
_count = 0;
_maxitems = maxitems;
_data = new T[maxitems + 1];
}
~Queue() {
delete[] _data;
}
inline int count();
inline int front();
inline int back();
void push(const T &item);
T peek();
T pop();
void clear();
};
template<class T>
inline int Queue<T>::count()
{
return _count;
}
template<class T>
inline int Queue<T>::front()
{
return _front;
}
template<class T>
inline int Queue<T>::back()
{
return _back;
}
template<class T>
void Queue<T>::push(const T &item)
{
if(_count < _maxitems) { // Drops out when full
_data[_back++]=item;
++_count;
// Check wrap around
if (_back > _maxitems)
_back -= (_maxitems + 1);
}
}
template<class T>
T Queue<T>::pop() {
if(_count <= 0) return T(); // Returns empty
else {
T result = _data[_front];
_front++;
--_count;
// Check wrap around
if (_front > _maxitems)
_front -= (_maxitems + 1);
return result;
}
}
template<class T>
T Queue<T>::peek() {
if(_count <= 0) return T(); // Returns empty
else return _data[_front];
}
template<class T>
void Queue<T>::clear()
{
_front = _back;
_count = 0;
}
#endif
// ========================
// SETUP
// ========================
#include <Servo.h>
#include<SoftwareSerial.h>
#include <ArduinoJson.h>
#include <Nextion.h>
#include <SPI.h>
#include <SD.h>
//====== Serial Connection with NODEMCU =====
SoftwareSerial SUART(2, 3); //SRX=Dpin-2; STX-DPin-3
// setup servo
Servo servo;
int pos = 0;
// ==== Analog Pins =====
int potpinIE_ratio = 0;
int potpinTidVol = 1;
int potpinBPM = 2;
int pinMask = 4;
int pinDiff = 3;
int ledState = LOW;
// ==== Digital Pins =====
const int buzzerPin = 5;
const int ledPin = 6;
// ==== Sensor Offset =====
float constPressureMask = 41;
float slopePressureMask = 92;
float constPressureDiff = 548;
float slopePressureDiff = 204.8;
// ===== Other vars ======
float IE_ratio;
float TidVol;
float BPM;
float separation;
float sensorvalue;
float maskPressure;
float diffPressure;
float volFlow;
float diffPressureArr[90];
float maskPressureArr[90];
float area_1 = 0.0002835287370;
float area_2 = 0.00007853981634;
float rho = 1.225;
float totVolume;
float timeNow;
String acvLabel = "acv";
String simvLabel = "simv";
// ======= Mode changing vars =========
int state = HIGH;
uint32_t lastPrint = millis();
// Declare your Nextion objects - Example (page id = 0, component id = 1, component name = "b0")
//====== LCD Variables ==============
int id_1 = 5;
int ch = 0;
int id_2 = 4;
int id_3 = 3;
String ad = "add ";
static char buffer[10] = {};
static char buffer_2[10] = {};
static char buffer_3[10] = {};
static char buffer_mode[10] = {};
String set_mode = "ACV";
NexText t_ie_ratio = NexText(0, 8, "t_ie_ratio");
NexText t_bpm = NexText(0, 9, "t_bpm");
NexText t_tidvol = NexText(0, 10, "t_tidvol");
NexText t_mode = NexText(0, 12, "t_mode");
NexButton b0 = NexButton(0, 2, "b0");
NexButton b1 = NexButton(0, 3, "b1");
NexTouch *nex_listen_list[] = {&b0, &b1, NULL};
/* NexText t_mode = NexText(0, 9, "t_mode");
NexButton b0 = NexButton(0, 2, "b0");
NexButton b1 = NexButton(0, 3, "b1");
NexButton b2 = NexButton(0, 4, "b2");
NexText t3 = NexText(1, 5, "t3");
NexText t4 = NexText(1, 6, "t4");
NexText t5 = NexText(1, 7, "t5");
NexText t_ie_ratio = NexText(0, 10, "t_ie_Ratio");
NexText t_bpm = NexText(0, 11, "t_bpm");
NexText t_tidvol = NexText(0, 12, "t_tidvol");
String set_mode;
NexTouch *nex_listen_list[] = {&b0,&b1,&b2,NULL}; */
void b0PopCallback(void *ptr) {
set_mode = "ACV";
t_mode.setText(set_mode.c_str());
}
void b1PopCallback(void *ptr) {
set_mode = "SIMV";
t_mode.setText(set_mode.c_str());
}
//======= SD Card File ===========
File myFile;
void setup()
{
servo.attach(9);
Serial.begin(9600);
SUART.begin(9600);
pinMode(ledPin,OUTPUT);
pinMode(buzzerPin,OUTPUT);
pinMode(10, OUTPUT);
nexInit();
b0.attachPop(b0PopCallback, &b0);
b1.attachPop(b1PopCallback, &b1);
if (!SD.begin(4)) {
Serial.println("initialization failed!");
return;
}
Serial.println("SD Card Initialization done.");
/* myFile = SD.open("example.txt", FILE_WRITE);
myFile.close(); */
}
//////////////////
////// Loop //////
//////////////////
// ===========================================
// RUN RESPIRATOR
// ===========================================
void loop()
{
//acv_mode();
/* fetchPotValues();
Serial.println(IE_ratio);
Serial.println(BPM);
Serial.println(TidVol);
delay(1000); */
// Run ventilator
acv_mode();
/* send_to_screen_values();
if (set_mode == "ACV") {
//myFile = SD.open("example.txt", FILE_WRITE);
acv_mode();
//myFile.close();
}
else if (set_mode == "SIMV") {
//myFile = SD.open("example.txt", FILE_WRITE);
simv_mode();
//myFile.close();
} */
//while(set_mode == simvLabel) simv_mode();
// get b0.val;
//while(set_mode == acvLabel) acv_mode();
//maskPressure = pressureFromAnalog(pinMask,1000);
//diffPressure = pressureFromAnalog(pinDiff,1000);
//fetchPotValues();
//nexLoop(nex_listen_list);
}
// ***************** END RUN RESPIRATOR *******************
// ============ LAYER 1 FUNCTIONS ===============
// =================================================
// ACV MODE Function
// =================================================
void acv_mode()
{
uint32_t cycleEndTime;
bool firstRun = true;
while(true)
{
// Fetch all potentiometer values
fetchPotValues();
// Initiate first run
if(firstRun)
{
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
firstRun = false;
}
// ========= Identify trigger and initiate the cycle =============
if(millis() - cycleEndTime >= (uint32_t)separation || maskPressure < -1)
{
myFile = SD.open("example.txt", FILE_WRITE);
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
myFile.close();
}
sanityCheckBuzzer();
// ============ Update pressure values =========
maskPressure = pressureFromAnalog(pinMask,1000);
diffPressure = pressureFromAnalog(pinDiff,1000);
send_to_screen_values();
send_to_screen_graph();
nexLoop(nex_listen_list);
//Serial.println(maskPressure);
//print_to_screen();
//nexLoop(nex_listen_list);
//computePrintVolFlow();
}
return;
}
// ===========================================
// SIMV MODE Function
// ===========================================
void simv_mode()
{
uint32_t cycleEndTime;
bool firstRun = true;
while(set_mode = simvLabel)
{
// Fetch all potentiometer values
fetchPotValues();
// ==== Initiate the cycle =====
if(firstRun)
{
maskPressure = average_maskPressure();
cycleEndTime = simv_logic(maskPressure, TidVol, IE_ratio);
firstRun = false;
}
// ========= Identify trigger and initiate the cycle =============
if(millis() - cycleEndTime >= (uint32_t)separation || average_maskPressure() < -1)
{
maskPressure = average_maskPressure();
cycleEndTime = simv_logic(maskPressure, TidVol, IE_ratio);
}
send_to_screen_values();
//send_to_screen_graph();
}
return;
}
// ============ LAYER 2 FUNCTIONS ================
// =======================
// SIMV Logic Function
// =======================
uint32_t simv_logic(float maskPressure, float TidVol, float IE_ratio)
{
uint32_t cycleEndTime;
maskPressure = int(floor(maskPressure));
switch(int(maskPressure)){
case -6:
case -5:
case -4:
TidVol = TidVol*0.25;
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
case -3:
TidVol = TidVol*0.50;
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
case -2:
TidVol = TidVol*0.75;
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
case -1:
TidVol = TidVol*0.75;
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
default:
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
}
return cycleEndTime;
}
// =======================
// Average Pressure Function
// =======================
float average_maskPressure()
{
maskPressure = 0;
for(int i=0;i<5;i++)
{
maskPressure = maskPressure + pressureFromAnalog(pinMask, 1);
delay(3);
}
return (maskPressure/5);
}
// =======================
// Inspiration Function
// =======================
void inspiration(float TidVol)
{ int count = 0;
totVolume = 0;
timeNow = millis();
for(pos = 30; pos <= TidVol+30; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
servo.write(pos);
delay(1000/TidVol);
// ============ Update pressure values =========
maskPressure = pressureFromAnalog(pinMask, count);
diffPressure = pressureFromAnalog(pinDiff, count);
computePrintVolFlow();
//String data = set_mode + "," + String(maskPressure) + "," + String(volFlow) + "," + String(totVolume) + ";";
Serial.println(set_mode + "," + String(maskPressure) + "," + String(volFlow) + "," + String(totVolume) + ";");
//myFile.println(data);
send_to_screen_graph();
//send_to_screen_values();
//nexLoop(nex_listen_list);
count++;
}
}
// =====================
// Expiration Function
// =====================
uint32_t expiration(float TidVol, float IE_ratio)
{
int count = 0;
totVolume = 0;
timeNow = millis();
for(int pos = TidVol+30; pos>=30; pos-=1) // goes from 180 degrees to 0 degrees
{
servo.write(pos);
delay(1000*IE_ratio/TidVol);
// ============ Update pressure values =========
maskPressure = pressureFromAnalog(pinMask, count);
diffPressure = pressureFromAnalog(pinDiff, count);
computePrintVolFlow();
//String data = set_mode + "," + String(maskPressure) + "," + String(volFlow) + "," + String(totVolume) + ";";
Serial.println(set_mode + "," + String(maskPressure) + "," + String(volFlow) + "," + String(totVolume) + ";");
//myFile.println(data);
send_to_screen_graph();
//send_to_screen_values();
//nexLoop(nex_listen_list);
count++;
}
return millis();
}
// ======================================================
// Fetch Potentiometer values and adjust separation time
// ======================================================
void fetchPotValues()
{
// Fetch all potentiometer values
IE_ratio = map(analogRead(potpinIE_ratio), 0, 1023, 1.00, 4.00);
TidVol = map(analogRead(potpinTidVol), 0, 1023, 40.00, 90.00);
BPM = map(analogRead(potpinBPM), 0, 1023, 8.00, 30.00);
separation = 1000*(60/BPM - (1+IE_ratio)); // convert to milliseconds
// Correct separation time if needed
if (separation < 0)
{
IE_ratio = 60/BPM - 1;
separation = (60/BPM - (1+IE_ratio))*1000;
}
}
// ================= LAYER 3 FUNCTIONS =============
// =============================
// Pressure from Analog Function
// =============================
float pressureFromAnalog(int pin, int count)
{ float pressure;
pressure = analogRead(pin);
// Differential pressure sensor - output cmH2O
if (pin == pinDiff)
{
pressure = (pressure - constPressureDiff)*1000/slopePressureDiff;
if (count != 1000) {diffPressureArr[count] = pressure;}
}
// Guage pressure sensor - output Pascal
if (pin == pinMask)
{
pressure = pressure = (pressure - constPressureMask)*10.1972/slopePressureMask;;
if (count != 1000) {maskPressureArr[count] = pressure;}
}
return pressure;
}
// =============================
// Alarm Sanity Check
// =============================
void sanityCheckBuzzer()
{
float SDPressure;
SDPressure = calcSD(maskPressureArr);
//Serial.println(SDPressure);
//Serial.println(SDPressure);
if(SDPressure < 0.01) buzzAlarm(true);
if(SDPressure >= 0.01) buzzAlarm(false);
}
// ================= LAYER 4 FUNCTIONS =============
// =============================
// Calculate standard deviation
// =============================
float calcSD(float data[])
{
float avg = 0.0, SD = 0.0;
int length = sizeof(data);
for (int i = 0; i < length; i++)
{
avg += data[i];
}
avg = avg/length;
for (int i = 0; i < length; i++)
{SD += pow(data[i] - avg, 2);}
return sqrt(SD/length);
}
// ================================================================
// Buzz Alarm if there is a problem; stop alarm if problem resolved
// ================================================================
void buzzAlarm(bool turnOn)
{
if (turnOn == true)
{
ledState = HIGH;
tone(buzzerPin,500);
}
if (turnOn == false)
{
ledState = LOW;
noTone(buzzerPin);
}
}
// =======================
// Copmute Vol Flow
// =======================
void computePrintVolFlow()
{
volFlow = 1000*sqrt((abs(diffPressure)*2*rho)/((1/(pow(area_2,2)))-(1/(pow(area_1,2)))))/rho;
if (millis() - lastPrint >= uint32_t(100))
{
//Serial.println(flow);
lastPrint = millis();
}
if(volFlow > 0.4)totVolume = totVolume + volFlow*(millis() - timeNow);
timeNow = millis();
//Serial.println(totVolume);
}
// =======================
// Nextion Screen Functions
// =======================
/* void b0PopCallback(void *ptr) {
set_mode = "MODE : ACV";
t_mode.setText(set_mode.c_str());
}
void b1PopCallback(void *ptr) {
set_mode = "MODE : SIMV";
t_mode.setText(set_mode.c_str());
}
void b2PopCallback(void *ptr) {
set_mode = "MODE : None";
t_mode.setText(set_mode.c_str());
} */
// =====================
// Print to Screen
// =====================
/* void print_to_screen()
{
t_mode.setText(set_mode.c_str());
static char ps_diff[6];
dtostrf(diffPressure, 6, 2, ps_diff);
static char ps_mask[6];
dtostrf(maskPressure, 6, 2, ps_mask);
t3.setText(ps_diff);
t5.setText(ps_mask);
static char ie_ratio[6];
dtostrf(IE_ratio, 6, 2, ie_ratio);
t_ie_ratio.setText(ie_ratio);
static char bpm[6];
dtostrf(BPM, 6, 2, bpm);
t_bpm.setText(bpm);
static char tidvol[6];
dtostrf(TidVol, 6, 2, tidvol);
t_tidvol.setText(tidvol);
} */
// =====================
// Transmit to DB
// =====================
void transmit(){
Serial.println("Inside the transmit function");
String message = "";
boolean messageReady = false;
while(SUART.available()) {
message = SUART.readString();
Serial.println(message);
messageReady = true;
}
if(messageReady) {
const int capacity_data = JSON_OBJECT_SIZE(7);
StaticJsonBuffer<capacity_data> jb_data;
JsonObject& doc = jb_data.createObject();
doc["type"].set("response");
doc["BPM"].set(BPM);
doc["IE_ratio"].set(IE_ratio);
doc["maskPressure"].set(maskPressure);
doc["flowRate"].set(volFlow);
doc["TidVol"].set(TidVol);
doc["totVolume"].set(totVolume);
doc.printTo(SUART);
doc.printTo(Serial);
}
}
// =====================
// Print to Screen
// =====================
void send_to_screen_graph() {
String to_send_p_mask = ad + id_1 + "," + ch + "," + int(maskPressure);
print_screen(to_send_p_mask);
String to_send_volFlow = ad + id_2 + "," + ch + "," + int(volFlow);
print_screen(to_send_volFlow);
String to_send_totVolume = ad + id_3 + "," + ch + "," + int(totVolume);
print_screen(to_send_totVolume);
}
void send_to_screen_values() {
dtostrf(BPM, 6, 2, buffer);
t_bpm.setText(buffer);
dtostrf(IE_ratio, 6, 2, buffer_2);
t_ie_ratio.setText(buffer_2);
dtostrf(TidVol, 6, 2, buffer_3);
t_tidvol.setText(buffer_3);
t_mode.setText(set_mode.c_str());
}
void print_screen(String to_send) {
Serial.print(to_send);
Serial.print("\xFF\xFF\xFF");
}
/*
* Queue.h
*
* By Steven de Salas
*
* Defines a templated (generic) class for a queue of things.
* Used for Arduino projects, just #include "Queue.h" and add this file via the IDE.
*
* Examples:
*
* Queue<char> queue(10); // Max 10 chars in this queue
* queue.push('H');
* queue.push('e');
* queue.count(); // 2
* queue.push('l');
* queue.push('l');
* queue.count(); // 4
* Serial.print(queue.pop()); // H
* Serial.print(queue.pop()); // e
* queue.count(); // 2
* queue.push('o');
* queue.count(); // 3
* Serial.print(queue.pop()); // l
* Serial.print(queue.pop()); // l
* Serial.print(queue.pop()); // o
*
* struct Point { int x; int y; }
* Queue<Point> points(5);
* points.push(Point{2,4});
* points.push(Point{5,0});
* points.count(); // 2
*
*/
#ifndef QUEUE_H
#define QUEUE_H
#include <Arduino.h>
template<class T>
class Queue {
private:
int _front, _back, _count;
T *_data;
int _maxitems;
public:
Queue(int maxitems = 256) {
_front = 0;
_back = 0;
_count = 0;
_maxitems = maxitems;
_data = new T[maxitems + 1];
}
~Queue() {
delete[] _data;
}
inline int count();
inline int front();
inline int back();
void push(const T &item);
T peek();
T pop();
void clear();
};
template<class T>
inline int Queue<T>::count()
{
return _count;
}
template<class T>
inline int Queue<T>::front()
{
return _front;
}
template<class T>
inline int Queue<T>::back()
{
return _back;
}
template<class T>
void Queue<T>::push(const T &item)
{
if(_count < _maxitems) { // Drops out when full
_data[_back++]=item;
++_count;
// Check wrap around
if (_back > _maxitems)
_back -= (_maxitems + 1);
}
}
template<class T>
T Queue<T>::pop() {
if(_count <= 0) return T(); // Returns empty
else {
T result = _data[_front];
_front++;
--_count;
// Check wrap around
if (_front > _maxitems)
_front -= (_maxitems + 1);
return result;
}
}
template<class T>
T Queue<T>::peek() {
if(_count <= 0) return T(); // Returns empty
else return _data[_front];
}
template<class T>
void Queue<T>::clear()
{
_front = _back;
_count = 0;
}
#endif
{
"board": "esp8266:esp8266:d1",
"sketch": "acv_simv/acv_simv.ino",
"port": "COM4",
"configuration": "xtal=80,vt=flash,exception=legacy,ssl=all,eesz=4M2M,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=921600"
}
// ========================
// SETUP
// ========================
#include <Servo.h>
#include<SoftwareSerial.h>
#include <ArduinoJson.h>
#include <Nextion.h>
#include <SPI.h>
#include <SD.h>
//====== Serial Connection with NODEMCU =====
SoftwareSerial SUART(2, 3); //SRX=Dpin-2; STX-DPin-3
// setup servo
Servo servo;
int pos = 0;
// ==== Analog Pins =====
int potpinIE_ratio = 0;
int potpinTidVol = 1;
int potpinBPM = 2;
int pinMask = 4;
int pinDiff = 3;
int ledState = LOW;
// ==== Digital Pins =====
const int buzzerPin = 5;
const int ledPin = 6;
// ==== Sensor Offset =====
float constPressureMask = 41;
float slopePressureMask = 92;
float constPressureDiff = 548;
float slopePressureDiff = 204.8;
// ===== Other vars ======
float IE_ratio;
float TidVol;
float BPM;
float separation;
float sensorvalue;
float maskPressure;
float diffPressure;
float volFlow;
float diffPressureArr[90];
float maskPressureArr[90];
float area_1 = 0.0002835287370;
float area_2 = 0.00007853981634;
float rho = 1.225;
float totVolume;
float timeNow;
String acvLabel = "acv";
String simvLabel = "simv";
// ======= Mode changing vars =========
int state = HIGH;
uint32_t lastPrint = millis();
// Declare your Nextion objects - Example (page id = 0, component id = 1, component name = "b0")
//====== LCD Variables ==============
int id_1 = 5;
int ch = 0;
int id_2 = 4;
int id_3 = 3;
String ad = "add ";
static char buffer[10] = {};
static char buffer_2[10] = {};
static char buffer_3[10] = {};
static char buffer_mode[10] = {};
String set_mode = "ACV";
NexText t_ie_ratio = NexText(0, 8, "t_ie_ratio");
NexText t_bpm = NexText(0, 9, "t_bpm");
NexText t_tidvol = NexText(0, 10, "t_tidvol");
NexText t_mode = NexText(0, 12, "t_mode");
NexButton b0 = NexButton(0, 2, "b0");
NexButton b1 = NexButton(0, 3, "b1");
NexTouch *nex_listen_list[] = {&b0, &b1, NULL};
/* NexText t_mode = NexText(0, 9, "t_mode");
NexButton b0 = NexButton(0, 2, "b0");
NexButton b1 = NexButton(0, 3, "b1");
NexButton b2 = NexButton(0, 4, "b2");
NexText t3 = NexText(1, 5, "t3");
NexText t4 = NexText(1, 6, "t4");
NexText t5 = NexText(1, 7, "t5");
NexText t_ie_ratio = NexText(0, 10, "t_ie_Ratio");
NexText t_bpm = NexText(0, 11, "t_bpm");
NexText t_tidvol = NexText(0, 12, "t_tidvol");
String set_mode;
NexTouch *nex_listen_list[] = {&b0,&b1,&b2,NULL}; */
void b0PopCallback(void *ptr) {
set_mode = "ACV";
t_mode.setText(set_mode.c_str());
}
void b1PopCallback(void *ptr) {
set_mode = "SIMV";
t_mode.setText(set_mode.c_str());
}
//======= SD Card File ===========
File myFile;
void setup()
{
servo.attach(9);
Serial.begin(9600);
SUART.begin(9600);
pinMode(ledPin,OUTPUT);
pinMode(buzzerPin,OUTPUT);
pinMode(10, OUTPUT);
nexInit();
b0.attachPop(b0PopCallback, &b0);
b1.attachPop(b1PopCallback, &b1);
if (!SD.begin(4)) {
Serial.println("initialization failed!");
return;
}
Serial.println("SD Card Initialization done.");
/* myFile = SD.open("example.txt", FILE_WRITE);
myFile.close(); */
}
//////////////////
////// Loop //////
//////////////////
// ===========================================
// RUN RESPIRATOR
// ===========================================
void loop()
{
//acv_mode();
/* fetchPotValues();
Serial.println(IE_ratio);
Serial.println(BPM);
Serial.println(TidVol);
delay(1000); */
// Run ventilator
acv_mode();
/* send_to_screen_values();
if (set_mode == "ACV") {
//myFile = SD.open("example.txt", FILE_WRITE);
acv_mode();
//myFile.close();
}
else if (set_mode == "SIMV") {
//myFile = SD.open("example.txt", FILE_WRITE);
simv_mode();
//myFile.close();
} */
//while(set_mode == simvLabel) simv_mode();
// get b0.val;
//while(set_mode == acvLabel) acv_mode();
//maskPressure = pressureFromAnalog(pinMask,1000);
//diffPressure = pressureFromAnalog(pinDiff,1000);
//fetchPotValues();
//nexLoop(nex_listen_list);
}
// ***************** END RUN RESPIRATOR *******************
// ============ LAYER 1 FUNCTIONS ===============
// =================================================
// ACV MODE Function
// =================================================
void acv_mode()
{
uint32_t cycleEndTime;
bool firstRun = true;
while(true)
{
// Fetch all potentiometer values
fetchPotValues();
// Initiate first run
if(firstRun)
{
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
firstRun = false;
}
// ========= Identify trigger and initiate the cycle =============
if(millis() - cycleEndTime >= (uint32_t)separation || maskPressure < -1)
{
myFile = SD.open("example.txt", FILE_WRITE);
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
myFile.close();
}
sanityCheckBuzzer();
// ============ Update pressure values =========
maskPressure = pressureFromAnalog(pinMask,1000);
diffPressure = pressureFromAnalog(pinDiff,1000);
send_to_screen_values();
send_to_screen_graph();
nexLoop(nex_listen_list);
//Serial.println(maskPressure);
//print_to_screen();
//nexLoop(nex_listen_list);
//computePrintVolFlow();
}
return;
}
// ===========================================
// SIMV MODE Function
// ===========================================
void simv_mode()
{
uint32_t cycleEndTime;
bool firstRun = true;
while(set_mode = simvLabel)
{
// Fetch all potentiometer values
fetchPotValues();
// ==== Initiate the cycle =====
if(firstRun)
{
maskPressure = average_maskPressure();
cycleEndTime = simv_logic(maskPressure, TidVol, IE_ratio);
firstRun = false;
}
// ========= Identify trigger and initiate the cycle =============
if(millis() - cycleEndTime >= (uint32_t)separation || average_maskPressure() < -1)
{
maskPressure = average_maskPressure();
cycleEndTime = simv_logic(maskPressure, TidVol, IE_ratio);
}
send_to_screen_values();
//send_to_screen_graph();
}
return;
}
// ============ LAYER 2 FUNCTIONS ================
// =======================
// SIMV Logic Function
// =======================
uint32_t simv_logic(float maskPressure, float TidVol, float IE_ratio)
{
uint32_t cycleEndTime;
maskPressure = int(floor(maskPressure));
switch(int(maskPressure)){
case -6:
case -5:
case -4:
TidVol = TidVol*0.25;
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
case -3:
TidVol = TidVol*0.50;
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
case -2:
TidVol = TidVol*0.75;
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
case -1:
TidVol = TidVol*0.75;
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
default:
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
}
return cycleEndTime;
}
// =======================
// Average Pressure Function
// =======================
float average_maskPressure()
{
maskPressure = 0;
for(int i=0;i<5;i++)
{
maskPressure = maskPressure + pressureFromAnalog(pinMask, 1);
delay(3);
}
return (maskPressure/5);
}
// =======================
// Inspiration Function
// =======================
void inspiration(float TidVol)
{ int count = 0;
totVolume = 0;
timeNow = millis();
for(pos = 30; pos <= TidVol+30; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
servo.write(pos);
delay(1000/TidVol);
// ============ Update pressure values =========
maskPressure = pressureFromAnalog(pinMask, count);
diffPressure = pressureFromAnalog(pinDiff, count);
computePrintVolFlow();
//String data = set_mode + "," + String(maskPressure) + "," + String(volFlow) + "," + String(totVolume) + ";";
Serial.println(set_mode + "," + String(maskPressure) + "," + String(volFlow) + "," + String(totVolume) + ";");
//myFile.println(data);
send_to_screen_graph();
//send_to_screen_values();
//nexLoop(nex_listen_list);
count++;
}
}
// =====================
// Expiration Function
// =====================
uint32_t expiration(float TidVol, float IE_ratio)
{
int count = 0;
totVolume = 0;
timeNow = millis();
for(int pos = TidVol+30; pos>=30; pos-=1) // goes from 180 degrees to 0 degrees
{
servo.write(pos);
delay(1000*IE_ratio/TidVol);
// ============ Update pressure values =========
maskPressure = pressureFromAnalog(pinMask, count);
diffPressure = pressureFromAnalog(pinDiff, count);
computePrintVolFlow();
//String data = set_mode + "," + String(maskPressure) + "," + String(volFlow) + "," + String(totVolume) + ";";
Serial.println(set_mode + "," + String(maskPressure) + "," + String(volFlow) + "," + String(totVolume) + ";");
//myFile.println(data);
send_to_screen_graph();
//send_to_screen_values();
//nexLoop(nex_listen_list);
count++;
}
return millis();
}
// ======================================================
// Fetch Potentiometer values and adjust separation time
// ======================================================
void fetchPotValues()
{
// Fetch all potentiometer values
IE_ratio = map(analogRead(potpinIE_ratio), 0, 1023, 1.00, 4.00);
TidVol = map(analogRead(potpinTidVol), 0, 1023, 40.00, 90.00);
BPM = map(analogRead(potpinBPM), 0, 1023, 8.00, 30.00);
separation = 1000*(60/BPM - (1+IE_ratio)); // convert to milliseconds
// Correct separation time if needed
if (separation < 0)
{
IE_ratio = 60/BPM - 1;
separation = (60/BPM - (1+IE_ratio))*1000;
}
}
// ================= LAYER 3 FUNCTIONS =============
// =============================
// Pressure from Analog Function
// =============================
float pressureFromAnalog(int pin, int count)
{ float pressure;
pressure = analogRead(pin);
// Differential pressure sensor - output cmH2O
if (pin == pinDiff)
{
pressure = (pressure - constPressureDiff)*1000/slopePressureDiff;
if (count != 1000) {diffPressureArr[count] = pressure;}
}
// Guage pressure sensor - output Pascal
if (pin == pinMask)
{
pressure = pressure = (pressure - constPressureMask)*10.1972/slopePressureMask;;
if (count != 1000) {maskPressureArr[count] = pressure;}
}
return pressure;
}
// =============================
// Alarm Sanity Check
// =============================
void sanityCheckBuzzer()
{
float SDPressure;
SDPressure = calcSD(maskPressureArr);
//Serial.println(SDPressure);
//Serial.println(SDPressure);
if(SDPressure < 0.01) buzzAlarm(true);
if(SDPressure >= 0.01) buzzAlarm(false);
}
// ================= LAYER 4 FUNCTIONS =============
// =============================
// Calculate standard deviation
// =============================
float calcSD(float data[])
{
float avg = 0.0, SD = 0.0;
int length = sizeof(data);
for (int i = 0; i < length; i++)
{
avg += data[i];
}
avg = avg/length;
for (int i = 0; i < length; i++)
{SD += pow(data[i] - avg, 2);}
return sqrt(SD/length);
}
// ================================================================
// Buzz Alarm if there is a problem; stop alarm if problem resolved
// ================================================================
void buzzAlarm(bool turnOn)
{
if (turnOn == true)
{
ledState = HIGH;
tone(buzzerPin,500);
}
if (turnOn == false)
{
ledState = LOW;
noTone(buzzerPin);
}
}
// =======================
// Copmute Vol Flow
// =======================
void computePrintVolFlow()
{
volFlow = 1000*sqrt((abs(diffPressure)*2*rho)/((1/(pow(area_2,2)))-(1/(pow(area_1,2)))))/rho;
if (millis() - lastPrint >= uint32_t(100))
{
//Serial.println(flow);
lastPrint = millis();
}
if(volFlow > 0.4)totVolume = totVolume + volFlow*(millis() - timeNow);
timeNow = millis();
//Serial.println(totVolume);
}
// =======================
// Nextion Screen Functions
// =======================
/* void b0PopCallback(void *ptr) {
set_mode = "MODE : ACV";
t_mode.setText(set_mode.c_str());
}
void b1PopCallback(void *ptr) {
set_mode = "MODE : SIMV";
t_mode.setText(set_mode.c_str());
}
void b2PopCallback(void *ptr) {
set_mode = "MODE : None";
t_mode.setText(set_mode.c_str());
} */
// =====================
// Print to Screen
// =====================
/* void print_to_screen()
{
t_mode.setText(set_mode.c_str());
static char ps_diff[6];
dtostrf(diffPressure, 6, 2, ps_diff);
static char ps_mask[6];
dtostrf(maskPressure, 6, 2, ps_mask);
t3.setText(ps_diff);
t5.setText(ps_mask);
static char ie_ratio[6];
dtostrf(IE_ratio, 6, 2, ie_ratio);
t_ie_ratio.setText(ie_ratio);
static char bpm[6];
dtostrf(BPM, 6, 2, bpm);
t_bpm.setText(bpm);
static char tidvol[6];
dtostrf(TidVol, 6, 2, tidvol);
t_tidvol.setText(tidvol);
} */
// =====================
// Transmit to DB
// =====================
void transmit(){
Serial.println("Inside the transmit function");
String message = "";
boolean messageReady = false;
while(SUART.available()) {
message = SUART.readString();
Serial.println(message);
messageReady = true;
}
if(messageReady) {
const int capacity_data = JSON_OBJECT_SIZE(7);
StaticJsonBuffer<capacity_data> jb_data;
JsonObject& doc = jb_data.createObject();
doc["type"].set("response");
doc["BPM"].set(BPM);
doc["IE_ratio"].set(IE_ratio);
doc["maskPressure"].set(maskPressure);
doc["flowRate"].set(volFlow);
doc["TidVol"].set(TidVol);
doc["totVolume"].set(totVolume);
doc.printTo(SUART);
doc.printTo(Serial);
}
}
// =====================
// Print to Screen
// =====================
void send_to_screen_graph() {
String to_send_p_mask = ad + id_1 + "," + ch + "," + int(maskPressure);
print_screen(to_send_p_mask);
String to_send_volFlow = ad + id_2 + "," + ch + "," + int(volFlow);
print_screen(to_send_volFlow);
String to_send_totVolume = ad + id_3 + "," + ch + "," + int(totVolume);
print_screen(to_send_totVolume);
}
void send_to_screen_values() {
dtostrf(BPM, 6, 2, buffer);
t_bpm.setText(buffer);
dtostrf(IE_ratio, 6, 2, buffer_2);
t_ie_ratio.setText(buffer_2);
dtostrf(TidVol, 6, 2, buffer_3);
t_tidvol.setText(buffer_3);
t_mode.setText(set_mode.c_str());
}
void print_screen(String to_send) {
Serial.print(to_send);
Serial.print("\xFF\xFF\xFF");
}
,Time,Pressure,Flow,Volume
0,0.0,0.4442870291872473,0.05527777369075705,0.7231685956780632
1,0.10000124970319549,0.290242623143001,1.238381943948462,0.14185068146210808
2,0.20000249940639098,-0.9661143414909829,-0.4578747504133094,-0.30787006396772376
3,0.3000037491095865,0.7670286457826542,0.11123732520524092,0.8026950827797061
4,0.40000499881278195,-0.3912524782101275,-0.7823200543589414,0.5108665517793185
5,0.5000062485159774,-0.5015751444292047,-0.08954781101522022,0.8675839263446976
6,0.600007498219173,0.20543354052935156,0.17445560157184573,0.28856850945243395
7,0.7000087479223684,0.8020437472443975,-0.1969349225359255,0.42073382497788975
8,0.8000099976255639,0.07804981688748058,0.06735389541562085,-0.7336418685965963
9,0.9000112473287594,0.4483468570667566,1.292941268530478,-0.5190181284041365
10,1.0000124970319548,0.7308336391623975,-0.22326437595845414,-1.324162607635834
11,1.1000137467351503,0.16967842870992667,-0.5287989030359169,0.26944213677359485
12,1.200014996438346,-0.13314909710868725,-0.4282891810405944,-0.10663551160100271
13,1.3000162461415414,0.6577929087437274,0.10735377503582623,0.6809128651602749
14,1.400017495844737,0.41350576770649766,0.010755520713676348,0.09991354144968986
15,1.5000187455479324,0.32962590282130055,0.3923639087639866,-0.2819797668841528
16,1.6000199952511278,-0.5248991303816627,-0.20479427402799077,-0.4298958946375976
17,1.7000212449543233,0.5099885725094043,-0.759639724328958,-0.3139085844349437
18,1.8000224946575187,-0.06332219171885607,0.7519121187662698,0.25167930895860413
19,1.9000237443607142,0.2612780017931324,0.0282643509738926,0.5471253608754644
20,2.0000249940639097,39.676356317296204,15.041893523073455,2.3509608414058105
21,2.1000262437671053,39.4772919920304,13.929725626672486,3.0280256685733806
22,2.2000274934703006,40.173790643284136,14.414888949979863,2.359494570127325
23,2.3000287431734963,39.651348336717525,14.417581372698036,3.0527550322836943
24,2.400029992876692,40.39447175736241,14.477622213245363,2.2971242572944646
25,2.500031242579887,39.934625269995664,14.420575610398407,2.6690191740072806
26,2.600032492283083,40.17624127926895,13.622508137453401,2.737473286084107
27,2.700033741986278,40.94641130080306,14.301741622729715,3.09044663275055
28,2.800034991689474,39.20922747176185,13.652751184515212,2.6102253576395116
29,2.900036241392669,39.99624638843631,14.0318218118711,3.5519670197747772
30,3.0000374910958647,40.45327163165292,13.31106954255396,2.636610284523015
31,3.10003874079906,40.24327860617379,13.38949632938472,4.446981450669239
32,3.2000399905022556,39.8647365581469,13.709599184398044,4.582517788137938
33,3.3000412402054513,39.70182186932854,12.97674803487895,3.5513640941071403
34,3.4000424899086465,40.378729489751116,12.810849179694664,2.967702718307856
35,3.5000437396118422,39.76241323842081,12.669817556381947,3.5513168464552
36,3.6000449893150375,39.827165071565815,11.346674037877134,3.4911700031252852
37,3.700046239018233,40.34081498163381,12.203924510034309,4.002998459230303
38,3.8000474887214284,39.34868769664976,12.778011745935773,4.174560381115509
39,3.900048738424624,40.79879202767033,11.88268298710951,3.853282350437871
40,4.000049988127819,39.82045592299935,10.820642582105169,5.005056009336865
41,4.100051237831015,40.24130031627691,12.442700711292837,3.6580697524909813
42,4.200052487534211,39.44095710041147,12.136708896166567,4.039299324656676
43,4.300053737237406,39.56882489919915,11.923697457177049,4.940488186169312
44,4.400054986940601,40.3752390048432,11.18248008871425,3.827410312646376
45,4.500056236643797,39.800764868747635,12.041125965139857,5.145324476394133
46,4.6000574863469925,39.55509236805168,10.916774886663402,4.178118045889503
47,4.700058736050188,40.69177571700485,11.449146086024362,4.393042322604586
48,4.800059985753384,39.60071791136262,11.205632367872298,5.027017901968952
49,4.900061235456579,40.74179226768329,9.553832897869768,4.182387672214753
50,5.000062485159774,39.46481243244443,9.973190314812205,4.422938434553982
51,5.10006373486297,40.645664701855054,10.690051884447964,5.165042013237117
52,5.200064984566166,39.75325610528615,10.381569094607691,5.502174765865349
53,5.3000662342693605,40.30047235894059,10.06175901719023,5.307197223035885
54,5.400067483972556,39.89557300338437,9.631460936007096,5.060935474394805
55,5.500068733675752,40.40143819035686,9.163804355962192,5.981883605669922
56,5.600069983378948,39.14840279738084,9.848880792242468,5.903996566414725
57,5.700071233082143,39.65393719758146,9.44824463173113,6.404275792572526
58,5.800072482785338,40.39790439386496,9.85076895567836,6.309085576817652
59,5.900073732488534,39.12591453513457,8.45136649431385,5.7071891969979935
60,6.000074982191729,40.24570611364736,9.466133499326032,5.623974651639048
61,6.100076231894925,39.681368538887845,8.933005557683456,5.309628343492222
62,6.20007748159812,39.39053668868258,8.418523747080911,6.5478816257619155
63,6.300078731301316,39.93810880394414,8.808400398037021,7.281867343876803
64,6.400079981004511,39.372480347387175,8.422659333178997,6.305619924269296
65,6.500081230707707,39.75988663692049,8.643138809567938,6.437816776798834
66,6.600082480410903,39.715516197149945,8.030924145105343,7.291585442071973
67,6.700083730114097,40.16381341546465,7.4718868296319405,6.7302261609054845
68,6.800084979817293,39.4178211517028,7.676789534594028,7.244328252721535
69,6.900086229520489,40.03133907658614,7.244753555387089,7.234709556914357
70,7.0000874792236845,40.73240339242001,7.3446244653377,7.042733392648405
71,7.100088728926879,39.810697693758705,7.262125565923559,7.7226589434641575
72,7.200089978630075,39.80402929281886,8.826140031932592,7.733721033338147
73,7.300091228333271,39.271944190401285,6.8990639977901385,8.253198861986629
74,7.400092478036466,39.396778797236166,7.344107790828642,8.750235382091818
75,7.500093727739662,39.9112470722853,7.003135415200865,8.730757614121815
76,7.600094977442857,39.14676323305678,5.993259960228134,7.933432342085189
77,7.7000962271460525,40.453562751482515,6.3807488532512,9.016270120262558
78,7.800097476849248,39.4333971392411,5.953325450142274,9.707187382382212
79,7.900098726552444,39.36294643302033,6.0513253708834975,9.316020022224723
80,8.000099976255639,39.58356475504564,5.517762822176594,7.992031491811579
81,8.100101225958834,39.60186277200088,6.709695267134425,9.590454886245745
82,8.20010247566203,39.32257483413808,5.2475635902129625,9.726703687308042
83,8.300103725365226,40.04459253532641,5.526694991176434,10.458700163207848
84,8.400104975068421,40.79697761320993,5.173577531699288,8.360984082014834
85,8.500106224771617,40.59850375838081,5.254956302678248,10.204565566669245
86,8.600107474474813,40.31829312577862,5.2015951187842155,10.925310684173722
87,8.700108724178007,39.78638435268903,4.8885384112620365,10.706554656833312
88,8.800109973881202,40.99017833476169,4.368755798300334,9.465308904674568
89,8.900111223584398,39.60413665225514,4.038282188711273,10.008265215526293
90,9.000112473287594,40.073986114489585,4.0068110177980545,10.896570563486101
91,9.10011372299079,40.67736754663993,4.705154935883748,12.048500519382172
92,9.200114972693985,40.07712961534579,4.0689152415845795,12.404855770893922
93,9.30011622239718,39.90627039718186,3.079479351019262,11.411325974769555
94,9.400117472100376,40.6145783124634,3.891646826532846,12.292666668645236
95,9.500118721803572,39.974544754503356,3.3973408256438695,11.640276268701795
96,9.600119971506768,40.37230738370352,4.731114287483841,12.20086320122582
97,9.700121221209962,39.6254779289669,4.035367470816082,13.10287502400191
98,9.800122470913157,40.45275487876092,2.3163248645485095,12.819493908421846
99,9.900123720616353,40.39764941645855,2.6454973259146093,13.49568274540658
100,10.000124970319549,40.47994938751996,2.1585201447712747,12.817329139714566
101,10.100126220022744,40.067979447625106,2.543384530639922,13.729745682508273
102,10.20012746972594,39.658600961660056,2.5937479357713107,13.966123760054813
103,10.300128719429136,39.185507020733226,1.8263953718892596,13.819210210685592
104,10.400129969132331,39.2186680232346,1.4621842353253,14.614597198290694
105,10.500131218835527,39.90266166260904,2.693333582118302,15.380737612327653
106,10.600132468538721,38.938198687048185,1.580680962026128,15.680362503448334
107,10.700133718241917,39.70584783318751,2.4023626075629814,15.499068150893693
108,10.800134967945112,40.42648125167482,0.933554114669065,16.028133621085146
109,10.900136217648308,40.234997324267795,1.3089122093803647,15.379684571252248
110,11.000137467351504,39.64643237531784,1.104467992916667,16.24830484705585
111,11.1001387170547,40.40433329538608,0.7140269594553049,17.497171392579
112,11.200139966757895,39.9841791015459,1.3488459383225955,17.263250423507976
113,11.30014121646109,40.41709716271218,0.901365448250614,17.874795818955068
114,11.400142466164287,39.7870803368051,0.8021359347002058,17.775098705495115
115,11.50014371586748,39.471595902318974,0.981512582711431,17.58443401920997
116,11.600144965570676,40.7029477552417,0.24264592897664164,19.039605894913727
117,11.700146215273872,40.03165803478826,0.3451339591321547,20.026841162259043
118,11.800147464977067,40.33441073545463,0.4065578189657301,19.692224273408698
119,11.900148714680263,39.52898333386905,0.009778212501932348,20.165994448646217
120,12.000149964383459,40.04244154964088,0.2126868477861593,19.66119982881949
121,12.100151214086655,39.82387343675968,-0.06402027191814542,19.963301046582192
122,12.20015246378985,39.6847319741217,-0.3284546997312651,19.48991320898399
123,12.300153713493046,39.767772921476265,-0.3188399285098851,19.494247442438596
124,12.40015496319624,39.25515531710004,-0.3059579181632069,18.93826650481899
125,12.500156212899435,40.124157921293126,0.11061468083531559,20.780210189569235
126,12.600157462602631,40.42735374292092,0.13418833617128476,19.856981306259488
127,12.700158712305827,40.09047982889096,0.41514577093598903,19.87854262019926
128,12.800159962009023,39.73920197921174,0.5802337929374928,20.332021078000096
129,12.900161211712218,39.90963645287713,-0.7607370111563254,19.454727955402884
130,13.000162461415414,39.986608861651504,0.23888783089931928,20.490471357948646
131,13.10016371111861,40.04776939308605,0.6068568989684164,20.76113534335185
132,13.200164960821805,39.826996683178045,-0.05364860394043094,19.94876700472235
133,13.300166210525,40.003302330103025,0.26259776282477143,19.8252279299547
134,13.400167460228195,39.845740480125784,-1.1440415167516296,19.902110697989258
135,13.50016870993139,40.11946105958178,0.1698106794744897,19.214274349032802
136,13.600169959634586,40.089977141607676,0.5809260379998814,20.031830447913936
137,13.700171209337782,39.613975846337375,0.18244778839212553,20.22235801086799
138,13.800172459040978,40.45066120789557,0.49506267966528045,19.620871002578117
139,13.900173708744173,39.72053768382128,-0.07813230491133699,19.442642198075646
140,14.000174958447369,40.31495197823957,0.04137313203674581,20.801361399994473
141,14.100176208150565,39.8392778405535,-1.041255047846596,18.965492576952155
142,14.200177457853759,40.18594807133878,-0.40915228530782843,19.208000465848315
143,14.300178707556954,40.33546169584521,-0.9477813802292147,19.809736042877773
144,14.40017995726015,40.35114125090207,-0.5740831375296427,20.22534565943953
145,14.500181206963346,39.57417496204906,0.001939610233716598,19.62351306651151
146,14.600182456666541,40.74540813777349,0.21483613106259317,20.54173472409379
147,14.700183706369737,39.640589698335994,-0.08353197045374126,19.547986618679293
148,14.800184956072933,39.758489687891,0.11976553708862919,19.637080841481772
149,14.900186205776128,41.06395299402328,0.1899227497189743,19.458575516899906
150,15.000187455479324,39.69275992715512,-0.5917904362723728,19.981687948270544
151,15.100188705182518,39.473604645318154,-1.235835029837858,19.82802178648086
152,15.200189954885714,41.04392803358852,-0.5077517996915466,19.608948386889118
153,15.30019120458891,39.39103209695981,0.35078855439711354,19.506304608519265
154,15.400192454292105,40.609473984927654,0.32451327615162445,20.199805398762216
155,15.5001937039953,39.47419190141931,-0.100179308553223,20.03500492713977
156,15.600194953698496,39.906368884935155,-0.33055234489553237,20.00233982786234
157,15.700196203401692,40.27679810220176,-0.23303188257122193,19.322187553051087
158,15.800197453104888,39.90656807969351,0.13420621870448848,19.76501240913102
159,15.900198702808083,39.63648018766545,0.6847280447018761,21.071638951176272
160,16.000199952511277,40.223146487853995,-0.22784424685842572,20.908732452108378
161,16.100201202214475,39.31753510545326,0.59995999152072,19.31041063078367
162,16.20020245191767,39.74717430829424,-0.37533769127437294,19.797719037128658
163,16.300203701620866,39.94805117402201,-0.16494757992412454,19.53289162605559
164,16.40020495132406,39.49711625172718,0.01061132666265391,19.792882192788802
165,16.500206201027254,39.463171682827955,0.5152436258454135,20.469122526819653
166,16.60020745073045,38.84374700251037,-0.6971967428309002,19.490517096411693
167,16.700208700433645,40.50445947605007,-0.6587423353150386,20.350934419143314
168,16.800209950136843,39.87243444803691,0.24135885528216985,20.076879878966967
169,16.900211199840037,39.57082868135997,-0.5005774633114837,19.18687362243611
170,17.000212449543234,-0.1785088927532954,-15.092599711397357,20.7899731469596
171,17.100213699246428,0.44605040876469887,-13.721630581662517,20.138629831780577
172,17.200214948949625,0.6578301908359092,-13.887934902106476,18.37927719500859
173,17.30021619865282,-0.17631781453903916,-13.35956426915024,19.682221490585395
174,17.400217448356013,-0.047409856239996856,-12.864001819270737,17.958100456218798
175,17.50021869805921,-0.010325512585888343,-12.739277115580078,19.412217585879777
176,17.600219947762405,-0.4539095546205968,-11.531258072195962,17.77879200167482
177,17.700221197465602,1.1250461548342343,-11.232707662845435,17.18034155346997
178,17.800222447168796,0.030574403711446076,-12.317939820348483,16.471642968302753
179,17.900223696871993,-0.971181181995755,-11.346778826907022,16.478026324103727
180,18.000224946575187,-0.7443128414957889,-11.942798285385303,16.14908985815823
181,18.100226196278385,-0.024778152636477903,-9.367427485853753,16.804224360534246
182,18.20022744598158,0.17088738964425723,-10.227210959990693,15.459578795543027
183,18.300228695684773,0.3271919050952578,-9.638872933793941,14.747283297150716
184,18.40022994538797,-0.20341448879692572,-9.432354356187822,14.347457648859168
185,18.500231195091164,0.49937380998191316,-9.480512275230605,14.725864203970108
186,18.60023244479436,-0.8943357579753672,-8.61233456970784,14.019519619131014
187,18.700233694497555,-0.2616564212981533,-9.115578388145218,13.31203598233721
188,18.800234944200753,-0.7606790580015792,-9.388740372960495,14.113814457382173
189,18.900236193903947,0.2192833741501351,-8.228067388162158,13.952477327344429
190,19.000237443607144,-0.1561229291521828,-7.504151444092682,13.040018154687605
191,19.100238693310338,-0.4146302105791862,-6.972919504978642,12.653520734041999
192,19.200239943013536,-0.7211069546325445,-7.444317081247453,12.877480614324138
193,19.30024119271673,-0.2906826729170969,-6.644078891460625,12.290311656466509
194,19.400242442419923,0.8200154498721364,-5.751625914118921,12.535702325657454
195,19.50024369212312,-0.660843619656955,-6.9106348372325925,11.235984865488929
196,19.600244941826315,-0.2053496791773829,-6.058686915926571,12.538655729494225
197,19.700246191529512,0.15552352209352097,-6.521861834781967,12.141143574413519
198,19.800247441232706,0.11797978815429686,-6.085574641555514,11.687098972185051
199,19.900248690935904,0.41053029522275813,-5.299205272307379,10.509478830786385
200,20.000249940639097,0.2726744347022862,-6.018352223225231,11.416617684509081
201,20.100251190342295,-0.3992444838458848,-5.3902314765806105,11.161101451527234
202,20.20025244004549,-0.20184315803729522,-5.023017002411536,10.38853810797803
203,20.300253689748683,0.14747549980065028,-4.584439356625502,10.6827719789919
204,20.40025493945188,0.23361304125831006,-4.233977902146246,9.593468772322812
205,20.500256189155074,-0.46251510445081145,-4.894176921944602,10.110517503972057
206,20.60025743885827,-1.0831045407360935,-4.3408041328459435,10.071466984454595
207,20.700258688561465,0.9340784796837284,-4.09567473882459,10.265712468301276
208,20.800259938264663,0.5155500086709576,-4.339149002314836,9.865369246809868
209,20.900261187967857,0.20322824036713746,-3.5800883651870192,9.678170517256037
210,21.000262437671054,0.36742064909099786,-3.6055335608042336,8.467871835657734
211,21.100263687374248,0.2910031542851348,-3.645462281496712,8.762667334334019
212,21.200264937077442,-0.9848320740624649,-3.1329679858731927,7.797596211101648
213,21.30026618678064,0.2516907457973592,-2.9685172267482796,8.948265776149235
214,21.400267436483833,-0.040588760894576886,-3.8101124140733695,9.107276968209002
215,21.50026868618703,-0.514090272822916,-2.989137800582234,7.871638790040251
216,21.600269935890225,-1.1857203511076329,-3.930749619282165,8.103209483669946
217,21.700271185593422,-0.4257312188893265,-2.795563798034787,7.181772338755655
218,21.800272435296616,-0.5632164577853029,-2.341313689909422,8.432153628217753
219,21.900273684999814,-0.5897096746932737,-3.2311031749690993,7.233905714830441
220,22.000274934703008,-0.012514118317094298,-2.450804988305012,6.567406418947303
221,22.1002761844062,-0.24553388593503908,-3.1734429312029944,6.905654250887844
222,22.2002774341094,-0.45674768134553756,-2.4913304978111417,7.079202048862789
223,22.300278683812593,0.2306041561897504,-1.5021817267908968,6.3082232405182195
224,22.40027993351579,0.6746613501545121,-1.9065213101012208,6.663115775376865
225,22.500281183218984,-0.48020552971875313,-2.2890819154359905,6.046272724730828
226,22.60028243292218,-0.2187856788500126,-2.601275442691607,6.271070066625869
227,22.700283682625376,-0.580824091361654,-3.230210876725518,6.622034289969561
228,22.800284932328573,-0.2066549535015631,-2.2781333831056623,5.95527776310882
229,22.900286182031767,-0.1342315244590671,-1.440093156720856,6.057875047101161
230,23.00028743173496,-0.6032364244826165,-1.80423145586485,6.4317270343579604
231,23.10028868143816,0.1722797009114965,-2.2413780753408807,5.261856415435559
232,23.200289931141352,-0.16210657013388508,-1.5543765316243916,6.818343393325334
233,23.30029118084455,-0.5683666312065596,-0.9145451795858129,6.007048330455265
234,23.400292430547744,0.40165992346355267,-1.4720522486530387,6.265589167761275
235,23.50029368025094,-0.48056886727860354,-1.6736636687875588,5.104752386036676
236,23.600294929954135,0.4483217605220577,-1.6459657402982772,5.006651497886325
237,23.700296179657332,-0.9553097153643031,-0.9427505238196487,6.032206648598208
238,23.800297429360526,-0.4945526010959481,-1.1005343677621502,5.348872549303184
239,23.90029867906372,0.9395074604323731,-1.818710651765827,5.050234730071944
240,24.000299928766918,0.6999208907848956,-1.75193651601671,5.61838931320419
241,24.10030117847011,0.07638187764188738,-1.6944869737964647,5.358634906810003
242,24.20030242817331,0.02451279604258332,-1.8373919282891642,4.872055219764909
243,24.300303677876503,0.5029402427488087,-1.0302147537839885,5.156093209575661
244,24.4003049275797,0.6226028056294746,-1.073493223211667,5.431647629118998
245,24.500306177282894,-0.6064941027910926,-0.3506512036605385,3.620248176896911
246,24.60030742698609,-0.43059152963984404,-1.3042124898890024,4.363489639302338
247,24.700308676689286,-0.44128467151875533,-0.6656504436452435,4.205975814125609
248,24.80030992639248,-0.060120194724471915,-1.3851501142953904,3.8707251900262145
249,24.900311176095677,-0.5472334719844256,-1.8187287089137052,4.105510083361967
250,25.00031242579887,0.5790159402619754,-2.265575986352071,4.226666824353724
251,25.10031367550207,1.0144579280955164,-1.0206227127605738,4.229107126239178
252,25.200314925205262,0.20022718141193824,-0.39143016227926997,3.483464175000946
253,25.30031617490846,0.24598894813700656,-1.6202625878098256,4.112332898272944
254,25.400317424611654,-0.01800058871034991,-0.7149816319866074,3.930375443783455
255,25.50031867431485,-0.30808047024284235,-0.611036340892936,2.963928874907258
256,25.600319924018045,-0.6824490898279862,-1.0251362721514372,4.005965628512626
257,25.70032117372124,0.3628118749564801,-0.633645132941954,2.9921292159932413
258,25.800322423424436,-0.4454491704481667,-1.6825736132667657,3.164228321578568
259,25.90032367312763,-0.4009415278355792,-0.819822103253498,3.059070892131489
260,26.000324922830828,0.8062237674555995,-1.5121389905542753,3.2636445341936167
261,26.10032617253402,-0.0741217450850633,-0.5466166548383957,3.1834244963205633
262,26.20032742223722,0.2195975738818563,-0.7508727362175224,3.4602358487472564
263,26.300328671940413,-0.04282445877077871,-0.9622769160583151,2.4551439111522693
264,26.40032992164361,0.2594124226138222,-0.20140918978637695,3.479771085555383
265,26.500331171346804,-0.2499616334543733,-0.21395014641235383,2.486621530086495
266,26.60033242105,-0.5559444324367177,-0.6916437068902936,3.1437990820654886
267,26.700333670753196,0.05651550792334975,-0.9034809314773147,2.817481125517155
268,26.80033492045639,0.922698486223253,-0.8989799481832756,2.9631315767661865
269,26.900336170159587,0.3090931462544841,0.593407811798474,3.0063712040322454
270,27.00033741986278,0.6140343165148041,-0.27102552880877867,2.1784554114402654
271,27.10033866956598,-0.11357393895922016,-1.0601053619227259,2.9539657965954724
272,27.200339919269172,-0.04105800482313144,-0.1462391104526678,2.1446481999805345
273,27.30034116897237,0.6372277375974297,-0.7818326682712007,2.327260068247776
274,27.400342418675564,0.5132092988268375,0.29600871915528526,1.9277378066523092
275,27.500343668378758,0.007180061820817078,-0.7840809345994573,1.6366443138500897
276,27.600344918081955,0.30812310606330073,0.3140666436436227,1.6524106333711286
277,27.70034616778515,-0.6021412875522757,-0.9702519766008957,2.8210524570851714
278,27.800347417488346,0.5645227452279913,-0.8376873872480041,2.3883760005730488
279,27.90034866719154,0.39673351938923634,0.09155637991246252,2.4619699768007486
280,28.000349916894738,0.3533263203251999,-0.18562317266737338,2.346021150092035
281,28.10035116659793,-0.47041662724997707,-0.022920277098389563,2.8935782284992446
282,28.20035241630113,-0.1940508859516996,-0.4832922639649192,2.0707087478709436
283,28.300353666004323,-0.009528684670654805,-0.29742677351939106,2.6082334056821006
284,28.400354915707517,-0.10037154240844583,-1.306587452854414,2.511791785967758
285,28.500356165410714,0.006728616372520484,-1.3523414628393693,2.5152156311730893
286,28.60035741511391,-0.5269765829004392,-0.21599233560408693,0.7892088082158655
287,28.700358664817106,-0.15407636388221316,0.42407363965981726,1.9205417675199947
288,28.8003599145203,0.5401131497508278,0.3052833564388524,1.9873008773056533
289,28.900361164223497,0.018988385661219416,0.5488919678047636,2.2669627277699793
290,29.00036241392669,0.10896491682198317,-0.47489396272403206,2.3304937874833427
291,29.10036366362989,-0.3790305326908696,-0.7618837583666359,1.6102908750732903
292,29.200364913333082,-0.08289408673643549,-0.30250448857094114,1.615664584770668
293,29.300366163036276,-0.14191745627163121,-0.11125552266112887,1.7960871328611372
294,29.400367412739474,0.17410340547791459,-0.02437233885291587,1.4696688465540417
295,29.500368662442668,-0.3448972260591714,-0.8086158101709903,2.034814090632702
296,29.600369912145865,-0.1124863555803243,-0.02910687744069934,2.1477550703290014
297,29.70037116184906,-0.511008538928229,-0.04551143285694981,1.1562151422662512
298,29.800372411552257,0.6753317745441653,-0.18849666298440035,0.8784705088646316
299,29.90037366125545,-0.7641233604704957,-0.27507584617408054,1.1480089123559805
300,30.000374910958648,0.10799411577351202,0.6583746664944901,2.0024814517297695
301,30.100376160661842,0.3273395426631095,-0.8137303686203822,1.3704369136852168
302,30.200377410365036,-1.398912392579495,-0.8584941950336938,1.6841196818509647
303,30.300378660068233,-0.2632391245197283,-0.29202684711161886,1.4116883873936257
304,30.400379909771427,-0.6302534785838024,0.8421183722353478,0.6723076273596086
305,30.500381159474625,0.0474814615026669,-0.7492508580955367,1.6604257513146161
306,30.60038240917782,-1.2555082941097513,-0.530945841847631,1.2145274136400397
307,30.700383658881016,-0.28446409822795077,0.27709384035185847,1.4511146239218813
308,30.80038490858421,-0.305748938915578,-0.23001850572504806,1.3446936653440387
309,30.900386158287407,0.2806877458347113,0.09136130636427023,1.7313445088851838
310,31.0003874079906,0.349790506320458,0.4863107571589449,1.25977565525866
311,31.100388657693795,0.08676395345492996,-0.4541006000099502,1.2992357108841346
312,31.200389907396993,-0.2912045475870747,0.005754185870726347,1.3518693070113152
313,31.300391157100186,-0.7702980819051193,-0.1789022038041326,0.9806182762869243
314,31.400392406803384,-0.4113473428967062,-1.5577274041498337,1.478842989578754
315,31.500393656506578,-0.3632193547950238,-0.2334985978437311,0.06756641101871641
316,31.600394906209775,-0.6657913730469791,-0.7763232761497891,0.5329383078519887
317,31.70039615591297,0.7054043683611706,0.5087074269989418,0.26803272839742587
318,31.800397405616167,1.0358125457228806,-0.1100437360222622,0.26488607833916855
319,31.90039865531936,0.024631245615807772,0.019470139429303576,1.092669923918276
320,32.000399905022554,-0.38278113917245044,0.2002152242195002,0.6047263309909294
321,32.10040115472575,0.6693109930643087,0.38828982489298536,0.7022106282079095
322,32.20040240442895,-1.069244456499178,0.12990316241640398,0.9172203391989053
323,32.30040365413214,0.4569536346828764,-0.20491693558387608,1.2275864069464375
324,32.40040490383534,0.20659451767792286,0.26991397794115013,1.0391540774458088
325,32.500406153538535,-0.6287964459423562,0.4449906088222113,1.093134482905502
326,32.60040740324173,-0.5622370946261498,-0.7362939523001684,0.47197112002336167
327,32.70040865294492,-0.3769272496906079,-0.18348069923436972,1.3844372257643898
328,32.80040990264812,0.3234076169139841,-0.23596645291343685,0.6547634424470017
329,32.90041115235132,-0.6805743934423097,0.08267595037735534,1.2220029098438179
330,33.00041240205451,0.15324054935982792,0.53218947865308,0.7067563911297774
331,33.100413651757705,0.23950031271928696,0.7479452609477525,1.2834297721373253
332,33.2004149014609,0.9179966469581334,-0.4712619105429583,1.250958438228755
333,33.3004161511641,0.12653565393977062,-0.2677894784445186,1.5021922646814572
334,33.40041740086729,-0.8925697616212201,0.6808533657748901,0.5883786838415268
335,33.50041865057049,0.22368387901012313,0.4836447666564644,0.5057881057648612
336,33.600419900273685,0.9927167280095681,0.7274306369480855,0.9720744150103153
337,33.70042114997688,-0.08685908058162549,-0.3876262052886231,1.6629928314164661
338,33.80042239968007,0.07614988963365081,1.113688605081813,0.7180406258678251
339,33.90042364938327,-0.03115928045819237,0.589329562599565,0.1772254516415548
340,34.00042489908647,-0.09712397827919302,-0.8211766484003648,0.5983336577635917
341,34.10042614878966,-0.2478231306794397,0.8970283870097506,1.369512549897006
342,34.200427398492856,0.5941748226343172,0.6645047741425265,1.196189740046285
343,34.30042864819605,0.6103610624944261,-0.5286517919811806,0.9901222651176498
344,34.40042989789925,-0.563286060341158,-0.43054277088591836,0.0016450541562379462
345,34.50043114760244,0.4050589911861173,-0.43966504128552986,0.6432064045992534
346,34.60043239730564,-0.00975285067987534,-0.5859586033554448,0.5772795441898312
347,34.700433647008836,-0.17143484462899808,0.5805913425063228,0.16667356716129977
348,34.80043489671203,-0.4374782841930333,-0.73685617139051,0.3580884015797958
349,34.900436146415224,-0.5743809758992933,-0.37943331670583813,1.0224856044233999
350,35.00043739611842,0.3402982597621469,-0.8533711111995887,0.67370302237125
351,35.10043864582162,-0.07027463777907075,0.9413671040834433,0.5462611156218449
352,35.20043989552481,0.046233599323354184,0.04323446482597313,0.3232191541814867
353,35.30044114522801,0.6521153368741729,0.46867210915987917,0.8869254220474525
354,35.400442394931204,-0.08216696531403561,0.5114093835832159,0.7030090839596624
355,35.5004436446344,-0.0712324496660549,-0.0944884399263341,0.7036158273106571
356,35.60044489433759,0.2716597997391413,0.7114872604552985,0.6064202563544556
357,35.70044614404079,0.422245092447095,0.09120241128339932,0.5302233585563154
358,35.80044739374399,0.16386687794435947,0.5656385089067723,0.6224823920270746
359,35.90044864344718,0.26060258642528217,-0.20885501487631755,0.5268601815730052
360,36.000449893150375,0.5886702508403113,1.1157903066863664,0.37558539560573834
361,36.10045114285357,0.2696134077235228,-0.17185681545344692,1.0308496444636255
362,36.20045239255677,-0.7563915766757054,0.020850900850406008,0.5715375581840709
363,36.30045364225996,-0.8565747987848513,-0.4953628933031489,-0.06824066204239598
364,36.40045489196316,0.2723080561621328,-0.18426074426025424,1.227145219360878
365,36.500456141666355,-0.11524223918365065,-0.4944244137213628,0.2962270128746025
366,36.600457391369545,-0.16056230410666555,0.4695912398546278,1.221964404922848
367,36.70045864107274,-0.2324448993038041,0.2973824106239364,0.6495112124385598
368,36.80045989077594,-0.9079639657260818,0.2575473242066954,0.29725175409476157
369,36.90046114047914,0.435545037604703,-0.49684721322814474,0.7439344421811509
370,37.00046239018233,-0.5252583546765264,-0.20067129199161585,0.29684633894943463
371,37.100463639885525,0.7003907531837258,-0.2649903909811535,1.417650597050395
372,37.20046488958872,0.4685739667704363,0.662875159427298,0.05317917085639429
373,37.30046613929192,0.48480113108163636,0.16652906815592075,-0.3544136243595659
374,37.40046738899511,-0.023887505368577727,0.5577256075196786,0.6318268451801726
375,37.50046863869831,-0.7370864605874327,0.8028677054648914,0.1534235249601409
376,37.600469888401506,-0.37753231523830577,0.42872543612102804,0.01283700860380188
377,37.700471138104696,-0.01894314575585269,-0.8863748403407633,0.9135627391228678
378,37.80047238780789,0.3977789326460563,0.43931347981314844,-0.008227294936981988
379,37.90047363751109,-0.02419336199564737,-0.9856445486921591,0.7292709520747656
380,38.00047488721429,-1.0479330545576977,0.34409207390636154,0.17604246225392994
381,38.10047613691748,-0.4936878504136678,-0.49070366872869237,0.7023689887254705
382,38.200477386620676,-0.0071232337177903745,-1.0320068694716187,0.4189755375234313
383,38.300478636323874,-0.5233011128590418,-0.903796211236963,1.073881216734415
384,38.40047988602707,-0.026450881473004496,-0.48143144477451594,1.542226767158134
385,38.50048113573026,0.06316558717107247,-1.401200525712624,0.5704274058046215
386,38.60048238543346,0.22124920067115866,0.1446353390012143,-0.19640924245989583
387,38.700483635136656,-0.26745482154789,0.03673657667962104,-0.23256929312836172
388,38.80048488483985,-0.4912375326528167,0.5640880835262373,0.19904906214046603
389,38.900486134543044,0.217282469549334,-0.4359582142452318,0.5854022013701266
390,39.00048738424624,-0.15389808663514792,0.511140528563363,0.09815842983717907
391,39.10048863394944,0.007033718440003367,-1.0157759194597444,0.518736005189163
392,39.20048988365263,-0.7075182935911912,-0.7050632348336199,0.416337685429345
393,39.30049113335583,-0.8901070386531407,-0.3134018777520316,0.45362731378389365
394,39.400492383059024,0.06575037521919692,-0.7159490530153947,0.19350381938221173
395,39.500493632762215,-0.46081842829533864,-0.03724315696910751,0.5872286587320363
396,39.60049488246541,0.1064926384808588,-0.433635657956601,0.2943119128052066
397,39.70049613216861,0.6130277477105182,0.2656189200343332,-0.1274288669378558
398,39.80049738187181,0.777537317444525,-0.2539423279331759,0.9310608501994638
399,39.900498631575,-0.31178460827185234,-0.16319148109440745,0.08838947945340178
400,40.000499881278195,-0.003510017905365614,0.15307473489114767,0.45131456625257044
401,40.10050113098139,-0.16070964544402425,0.22263766374313612,0.5286890357454751
402,40.20050238068459,-0.03794253858777639,0.5605744135899292,0.2771395551346222
403,40.30050363038778,0.35244178199354304,-0.15774671980847169,-0.215635788098264
404,40.40050488009098,-0.03437038552186465,-0.3959396869303354,0.48801876228044105
405,40.500506129794175,0.17479159986647086,0.1849025568095008,-0.19050131257925124
406,40.600507379497365,-0.8401005477249363,-0.6215479257249925,0.7595882015957592
407,40.70050862920056,-0.0008089150939781441,-0.7054327347858141,0.9453692595538532
408,40.80050987890376,-0.08302365645182572,-0.007577841793330839,0.398123797635363
409,40.90051112860696,-0.3913333245843906,0.4358683424782011,-0.19221096999292764
410,41.00051237831015,0.48507917189633737,0.11817603679848133,0.4849140055302694
411,41.100513628013346,0.5988112421599343,-0.4697913867285423,0.45879170780365586
412,41.20051487771654,-0.3670470838700742,0.17014099548331446,0.2016082944638188
413,41.30051612741973,-0.5066304583157968,1.0260375541680073,1.7285209445943155
414,41.40051737712293,0.7314169361540883,-0.10641882796894389,0.4119304899995434
415,41.50051862682613,0.03593749930811897,0.08573619228954049,0.043645169638011974
416,41.600519876529326,-0.6609606845543207,-0.03203452023680299,0.023871691305578258
417,41.700521126232516,0.17282157715065763,0.22804510050058702,-0.8239419566161932
418,41.800522375935714,0.05137785258124985,0.2807354115689501,0.04315329060138556
419,41.90052362563891,-0.29269172685477207,0.6582063767163457,-0.3218694495668631
420,42.00052487534211,40.367535535505596,15.553178795766593,2.9113813117661387
421,42.1005261250453,39.522232492332115,15.178107513886772,3.684385714719347
422,42.200527374748496,39.61641832002889,14.634440215419442,3.101735810124159
423,42.300528624451694,39.27382808149115,14.358964061516978,3.2138728655263993
424,42.400529874154884,40.04258223003834,14.917213283375489,2.289765269145548
425,42.50053112385808,40.15542108292739,13.726972491731322,3.2788147577487807
426,42.60053237356128,40.60904923430001,14.1848726232554,2.7483222856778045
427,42.70053362326448,39.45526251591603,14.397727373113163,3.242708357191047
428,42.80053487296767,41.24730035544504,13.777201196200703,3.138050886825649
429,42.900536122670864,40.48136347172712,14.250365964124343,3.5251554047570766
430,43.00053737237406,38.98335922801922,14.033819808734298,3.5597080689266116
431,43.10053862207725,40.21177672202841,13.988338224215367,2.688687954471396
432,43.20053987178045,39.66270503455816,13.342280705549172,3.533653969769797
433,43.30054112148365,39.65323097008696,12.499495694798043,2.9852797706986185
434,43.400542371186845,40.1819654788535,13.32995884530035,3.6370616282139996
435,43.500543620890035,39.783827029884954,12.673819097606899,3.8917934577146007
436,43.60054487059323,39.92555746658128,13.132230476345772,3.8803252925286107
437,43.70054612029643,39.87422016966427,12.036947310877913,3.6642767855824823
438,43.80054736999963,40.176301203974546,12.138849607292498,3.8270014963245282
439,43.90054861970282,39.4741295204798,11.397103773521621,4.2093731252313376
440,44.000549869406015,39.477775774968954,10.907908113418882,4.49241885509969
441,44.10055111910921,41.06367041773761,10.844959903094868,3.371827921068975
442,44.2005523688124,39.525181363328976,11.489008404279458,4.457980542302534
443,44.3005536185156,40.46114651081588,11.368399035187268,4.325294862353479
444,44.4005548682188,39.959100346971745,11.800363495834036,3.578453758887034
445,44.500556117921995,39.65128379278654,10.56062338832206,5.301544089058053
446,44.600557367625186,39.72023663564731,10.90647329852495,3.897925999814912
447,44.70055861732838,39.718434177818175,10.186339934872825,5.212346912205165
448,44.80055986703158,40.58041782623359,10.4351716676573,4.724931736174592
449,44.90056111673477,39.709953632085295,9.717660143019863,3.9917730547324792
450,45.00056236643797,40.6221208761236,11.050643021150046,5.290657858135361
451,45.100563616141166,39.56740766997174,10.290068806066218,5.1848263184147765
452,45.20056486584436,41.049199877017934,10.279277459457896,4.793633469133173
453,45.300566115547554,39.787828384504245,9.5976325140637,4.628001720003111
454,45.40056736525075,39.556243520553174,9.623964757680993,4.797686547789686
455,45.50056861495395,39.92779800309788,9.309210550488038,5.3403027334195
456,45.600569864657146,40.26541353997683,9.126398340900812,6.279017700185188
457,45.700571114360336,37.776336016759714,9.553514686554411,5.015323432139669
458,45.800572364063534,39.557174894511554,8.417907576278601,5.573830171369672
459,45.90057361376673,40.33351198763635,8.811823170428239,5.429940610691273
460,46.00057486346992,39.97468251368823,10.808229211367253,6.409201709663081
461,46.10057611317312,40.1686670170677,8.294067488322726,6.449911961808469
462,46.20057736287632,39.86122742603587,8.84246722409746,6.878110709947139
463,46.300578612579514,39.719392246152076,9.264212570791663,6.923410644043588
464,46.400579862282704,40.00003853061472,8.02474103499388,7.0554567284154075
465,46.5005811119859,40.18627538076857,7.834398837679574,6.622157527946981
466,46.6005823616891,39.467050167569965,8.304556739861017,6.862937408541541
467,46.70058361139229,39.68715559952044,7.777571388287945,7.022811151982618
468,46.80058486109549,40.51366441622048,7.644735497216198,6.724543483311204
469,46.900586110798685,40.08364496268514,6.1753122964374505,6.938945942937097
470,47.00058736050188,39.8314625846171,7.223725975365367,6.4214496693230405
471,47.10058861020507,40.201529901214855,6.825227318416458,7.9487811943066875
472,47.20058985990827,39.37133398421164,6.546923795222857,8.556337291126734
473,47.30059110961147,40.298059673198665,6.800535369438239,8.46200673844821
474,47.400592359314665,41.03358648278595,7.9648583569991604,8.21740523663089
475,47.500593609017855,40.10550178075836,6.3264934692159045,8.759442564156712
476,47.60059485872105,40.66265286133337,6.506348816889512,9.029309530015588
477,47.70059610842425,40.4799184903969,5.915136185221001,7.377704743486459
478,47.80059735812744,40.140233234930314,6.58098812738687,8.374714746137474
479,47.90059860783064,40.1681725173203,5.200065356705174,8.785817683771066
480,48.000599857533835,39.45327467219124,6.596326045490789,9.534287912921167
481,48.10060110723703,39.4209680111274,5.4505629891016385,10.032333394289264
482,48.20060235694022,40.30045469556589,5.861407919120208,9.630420737672742
483,48.30060360664342,39.65509713317745,5.655681867659559,10.436271250250488
484,48.40060485634662,39.21013371822499,4.985700422092017,8.984778999057072
485,48.50060610604981,40.19339799204044,4.88951256989066,9.838262903074586
486,48.600607355753006,40.63419433544133,5.445404694311612,10.178698814359539
487,48.7006086054562,40.63472533835423,5.146236209252317,10.758152443114879
488,48.8006098551594,40.01905239579958,3.97915772936314,10.930312612881973
489,48.90061110486259,39.705864051689396,4.235341906667419,11.42522500905613
490,49.00061235456579,39.5118150139969,3.8916515615629477,10.481130471886143
491,49.100613604268986,40.93591068090094,3.378688062854458,11.129556690132503
492,49.20061485397218,38.81883150518827,4.050009508967072,11.540284526373691
493,49.300616103675374,40.32114045477655,4.677903481965593,12.423444785612194
494,49.40061735337857,40.302436216739565,4.3838652712309765,11.631816271693474
495,49.50061860308177,40.6671345697205,3.824498243316757,12.502456317792783
496,49.60061985278496,39.93860214249938,3.0448444932509826,13.002450458006424
497,49.70062110248816,39.1875064108967,4.242447924445691,13.376338796733805
498,49.800622352191354,39.78157706012631,3.985294059572513,13.110474951562804
499,49.90062360189455,40.596118314456305,2.5574535452237432,13.500592970047565
500,50.00062485159774,40.490878101020485,2.213379991825819,13.21967890447637
501,50.10062610130094,40.01242374367696,3.2688301293780087,14.017354636752314
502,50.20062735100414,39.8087048839079,2.338940206902716,14.445776985158759
503,50.30062860070733,39.69189643032704,3.0029956085150835,15.057850763421651
504,50.400629850410525,39.92437470069736,2.4737363906038685,14.59729558928493
505,50.50063110011372,41.00756405444473,1.6831723106493375,15.42202187196812
506,50.60063234981692,40.01903302043295,1.5320654719090614,16.494220798605188
507,50.70063359952011,39.648335829324694,1.2235017630354323,15.171233186857705
508,50.80063484922331,40.08853345028571,1.4073825313505157,16.983956860460246
509,50.900636098926505,39.559740740315924,1.253348672877594,16.274396822451457
510,51.0006373486297,40.71695080747287,2.289906018996665,15.945085274336588
511,51.10063859833289,40.1400310015185,1.2088479344250984,17.107454309267972
512,51.20063984803609,39.75419622404141,0.5067205451996696,17.71145270072832
513,51.30064109773929,40.62230616658285,1.307244392319356,18.29712236995914
514,51.40064234744248,39.37916175651978,0.15593771316364413,17.85494876631772
515,51.500643597145675,39.595486032095614,0.7403182729575191,18.96197400621805
516,51.60064484684887,40.754172278246045,-0.29717403426758937,19.04584195753857
517,51.70064609655207,40.52328067547215,-0.06847364603803718,19.282421514370018
518,51.80064734625526,39.443370065729184,0.43482201639314594,20.086139788012495
519,51.90064859595846,39.81510295315894,-0.2466617605466893,20.204561226790638
520,52.000649845661655,39.5958821097157,-0.2826551234031901,19.402163589585772
521,52.10065109536485,40.40218719547425,-0.20604748433850784,19.532787988233142
522,52.20065234506804,40.374625943628914,-0.8641367375408756,20.590913432216897
523,52.30065359477124,39.01028883739243,-0.10368601172874532,20.613006274016556
524,52.40065484447444,39.60016058824756,0.7053405540092129,20.262847673081946
525,52.50065609417763,38.95570172305365,0.7645828935198035,19.744486085483707
526,52.600657343880826,39.735604317503686,-0.2653979984514223,20.468860047125844
527,52.70065859358402,38.91725163089441,0.4512710655132167,18.88703067846292
528,52.80065984328722,39.82236479124336,0.4129572146265617,19.720881033564392
529,52.90066109299041,39.89482573536698,1.4479861034531045,20.021374184303152
530,53.00066234269361,40.30657830913469,-0.28301786994632666,19.749169074695327
531,53.100663592396806,40.40599420893196,0.34472026926847193,19.937273257459953
532,53.2006648421,39.74872737037352,0.2970485362654567,20.85208126752463
533,53.300666091803194,38.921757993426205,-0.2353750847368221,20.061605957131388
534,53.40066734150639,39.89739672997418,0.08884417788866784,20.276505454435927
535,53.50066859120959,40.56490144393404,1.2522284962091734,19.771093075676337
536,53.60066984091278,39.82478812192287,-0.7568032833844521,20.06378293430843
537,53.70067109061598,40.06656518554563,-0.1724602041116854,19.246306633454974
538,53.800672340319174,40.249152011915676,-0.10577045467049763,20.68778492908201
539,53.90067359002237,39.85597629828887,-0.4633486283645847,20.368615284155823
540,54.00067483972556,40.412257861826106,-0.3380428151739098,19.565848483364704
541,54.10067608942876,40.66065288109627,0.3374149265530671,20.247163817482118
542,54.20067733913196,40.28651221626776,-0.3367800307166844,20.13176910774222
543,54.30067858883515,40.30445745154631,0.001656393198407107,19.41664666382375
544,54.400679838538345,39.69530803340636,-0.02308276190962008,20.437129603459578
545,54.50068108824154,40.3874212276384,-0.4873885408616198,19.97451852254646
546,54.60068233794474,39.96035349317232,-0.5313281044514999,21.078490196125767
547,54.70068358764793,39.91199963908577,-0.6304594565601044,19.539904257184062
548,54.80068483735113,39.387569887038175,0.5458121107341338,19.355930280242276
549,54.900686087054325,39.97891196263834,-0.279349593994459,20.263653676261782
550,55.000687336757515,40.03181033869881,-0.3115300673105409,19.828979956506025
551,55.10068858646071,39.829938264943735,0.6999013680855717,19.845919243923515
552,55.20068983616391,40.19001254297373,0.06436177103441343,19.637246261490926
553,55.30069108586711,40.513681127448756,0.219226561386349,20.622364749082912
554,55.4006923355703,40.057639466255864,-0.2419269098364511,19.707848524986947
555,55.500693585273496,39.49004527163662,0.19919469394515843,19.499239278241603
556,55.60069483497669,40.155352741932795,-0.2917013857203924,19.576330860530028
557,55.70069608467989,39.983294480536735,0.09911505198431281,19.662431396008355
558,55.80069733438308,40.03494398632076,0.31526414522952484,20.24205223396764
559,55.90069858408628,39.5931140408544,-0.48078722601641444,20.244008482226505
560,56.000699833789476,40.03213709353356,0.3977933766176128,20.427230688510107
561,56.100701083492666,40.25674816886016,0.3477898150815768,20.587714143188663
562,56.20070233319586,39.637182856336764,0.3172921339528508,19.88009563482123
563,56.30070358289906,39.90404030506809,-1.1191542105369618,20.43493700134053
564,56.40070483260226,40.42247572982841,-0.5347554006681104,19.37244996773055
565,56.50070608230545,39.21854672170354,-0.12579636751749335,20.682703380937514
566,56.600707332008646,40.29636903984662,-0.08706584612526322,19.833906976040147
567,56.700708581711844,39.133065960870724,0.22523480606857096,20.55816190288918
568,56.800709831415034,39.96932950796436,-0.7410804947280507,20.37739073958787
569,56.90071108111823,40.212693015931265,0.40085008558343516,19.45172495648045
570,57.00071233082143,-0.08370035987239423,-15.22675107000978,20.283379321314015
571,57.100713580524626,-0.596769016937881,-14.642937575294242,19.039659511810516
572,57.20071483022782,0.39763991651459646,-13.904159793677096,18.718761219825605
573,57.300716079931014,0.18956504719549863,-13.234140902697996,19.316463614642522
574,57.40071732963421,-0.291199090673212,-13.598811039959191,19.609652188937652
575,57.50071857933741,-1.2740359667005459,-12.861694107322538,18.249052703382674
576,57.6007198290406,-0.6075281513470956,-11.926367338701171,18.33222120149558
577,57.7007210787438,0.3107633491739548,-12.590322406959146,17.4825666715499
578,57.800722328446994,0.034887256150375294,-12.3882865701127,16.842784783259567
579,57.900723578150185,0.18081590467400846,-11.219993151592691,17.18489849022114
580,58.00072482785338,-0.47526124200339825,-10.93940467117473,15.554537865124697
581,58.10072607755658,0.25429952568869646,-9.393501997159326,16.58320376889108
582,58.20072732725978,-0.052776690785863674,-9.505811694502759,15.666912068132175
583,58.30072857696297,-0.025605941097546887,-9.594128929171125,15.643860322519217
584,58.400729826666165,0.20363595177764066,-10.130011571978955,15.47398666918569
585,58.50073107636936,-0.07212611066228153,-8.351721791611324,14.582468451194865
586,58.60073232607255,-0.29263371906773067,-8.87194363009968,14.159396043986641
587,58.70073357577575,0.5330274934100662,-8.074565990965102,14.737177867140584
588,58.80073482547895,-0.5425132082619779,-7.395785131842746,14.214941688120351
589,58.900736075182145,-0.3811461787055542,-8.117830413706804,13.472903093026519
590,59.000737324885336,0.09266591871778326,-7.275070448215937,13.641636973876327
591,59.10073857458853,0.46675500099016537,-7.308174491253321,13.134188617193914
592,59.20073982429173,-0.1873310636594938,-7.508544221682386,13.892154514767679
593,59.30074107399493,-0.02464417078759955,-7.699799279928747,12.282014184050198
594,59.40074232369812,0.11085300677347956,-6.422901356765626,13.529085832268272
595,59.500743573401316,0.4168625718335755,-7.488504740685635,12.381492349170156
596,59.60074482310451,-0.8051257361147919,-6.0577725895583665,11.498893579339184
597,59.7007460728077,0.3654276013115921,-6.71968618308757,11.832010214473828
598,59.8007473225109,0.0963815609734928,-5.635173479306096,11.04072556751779
599,59.9007485722141,-0.47556419895092983,-6.090433853173478,12.169718914146792
600,60.000749821917296,0.9765524880717515,-5.422765641792744,11.088932716177851
601,60.100751071620486,0.71441832281785,-5.4299600961284336,10.572098575218044
602,60.200752321323684,0.0979957489099917,-5.851083670738877,10.476446489968025
603,60.30075357102688,-0.23692894435759312,-3.9998816605713117,10.286586062047748
604,60.40075482073007,-0.719351945923542,-5.458122892951338,10.344419322459485
605,60.50075607043327,0.0651073318659994,-4.692549975807287,9.605010183453485
606,60.600757320136466,0.3382311284673309,-3.4930117971683616,10.428504565410286
607,60.700758569839664,-0.3833569926400068,-3.5267771874952665,9.269009409471979
608,60.800759819542854,-1.0091103677489859,-4.144959330898363,8.806241940730942
609,60.90076106924605,-0.2812233017834203,-3.750478230409853,8.426684264720349
610,61.00076231894925,-0.02776751461938526,-4.3678288275483705,8.501613323594336
611,61.10076356865245,0.9296733550256091,-3.095666446465522,8.97623196895406
612,61.20076481835564,0.04317231731504267,-3.417952226461098,8.435926366594455
613,61.300766068058834,-0.24175792223418105,-4.403529179283268,7.598238109908305
614,61.40076731776203,0.36493888821994197,-3.650800167129827,9.035556887581567
615,61.50076856746522,0.2014455242558327,-4.25047291050249,7.811413474536715
616,61.60076981716842,0.15817268708938187,-2.0937556634440386,8.359681355248506
617,61.70077106687162,0.09677070687219294,-3.729578547082329,7.26888687072444
618,61.800772316574815,-0.10064484229945728,-3.229370990005717,8.45771254236852
619,61.900773566278005,0.22688938475324313,-2.485173285434195,6.820195643023876
620,62.0007748159812,-0.6563375286266219,-3.8304602300535935,6.7623796858227
621,62.1007760656844,0.6234149302236461,-2.367184179794301,6.623721243205779
622,62.20077731538759,-0.7940424253396213,-2.3226013003871797,6.659855935321477
623,62.30077856509079,0.39502516285311434,-2.882332447866103,8.487974282702014
624,62.400779814793985,-0.33253571407144866,-2.198194970325519,6.791758431145039
625,62.50078106449718,-0.5055336861232246,-1.8445044163132318,6.780232538904284
626,62.60078231420037,0.18531418855292706,-2.2801474084196873,6.264588632400274
627,62.70078356390357,0.4155424139598071,-2.2007687477469133,6.175706189322873
628,62.80078481360677,0.05088130031023903,-1.9661552657815953,6.41772748210086
629,62.900786063309965,0.6260775146265349,-3.038385118895874,6.02099887224332
630,63.000787313013156,0.5572922911110427,-2.1676297691213415,6.190377079031032
631,63.10078856271635,0.1396184770620744,-2.1505814462855377,5.584508738723592
632,63.20078981241955,0.49696056424597596,-2.31690845362082,6.396084903177048
633,63.30079106212274,0.7861781853959989,-1.6935132618357276,5.695406981806581
634,63.40079231182594,-0.6906806025279,-1.3794237880420122,4.383532364106711
635,63.500793561529136,-0.4140051112873568,-1.8129733342673389,5.393633379260412
636,63.60079481123233,-0.6321650599592237,-2.0961628573714486,5.511406046340298
637,63.700796060935524,-0.8997347083824652,-1.3711167561755395,4.681465627559474
638,63.80079731063872,-0.25739170397601174,-1.9974789771854198,6.114062821048251
639,63.90079856034192,-1.0222551186094404,-1.0331032124409303,4.927143531184121
640,64.00079981004511,0.4045341495685054,-0.9317199356266309,5.074909975515441
641,64.1008010597483,0.22395946110175946,-2.1844165776047317,5.773053339559562
642,64.2008023094515,0.3013863494854845,-0.7985998693108479,4.908582658982798
643,64.3008035591547,-0.16517766684446264,-0.8426709733196139,4.037042152369973
644,64.4008048088579,0.045141556189978976,-0.9806457884687325,4.239978197427014
645,64.5008060585611,0.21543587395229563,-0.3330459273879537,4.582397897559937
646,64.60080730826428,0.14920091091915416,-0.9225835030516504,4.667294564894758
647,64.70080855796748,-0.09685401777785575,-1.0458234289077721,4.15440872775631
648,64.80080980767067,-0.48314827959631956,-1.251823827838273,5.18806691257911
649,64.90081105737387,-0.6170200784771405,-1.4403207418411,3.237489733224005
650,65.00081230707707,-0.6565446962091704,-0.7972008735422947,4.321299459896578
651,65.10081355678027,-0.6275065736361253,-0.22018089147662046,4.2126563290399535
652,65.20081480648346,-0.6225013838736704,-0.5452450878402684,3.136106216301278
653,65.30081605618665,0.04462582886851227,-0.8765267217216375,3.409948158584477
654,65.40081730588984,-0.44843311300085337,-0.43356489086204425,4.340394167958336
655,65.50081855559304,0.9337108438964318,-0.9252224226321883,3.1970463208647537
656,65.60081980529624,0.07887848131778363,-0.33397084514071407,4.277370849067835
657,65.70082105499944,0.9721985800569365,-1.3600692882674628,3.73156390144525
658,65.80082230470263,-0.2882351550823874,-1.0283459905466579,3.6838513819151077
659,65.90082355440583,0.8187792079695783,-1.1287042002985728,2.5019077934891407
660,66.00082480410902,-0.33912665591877444,0.11554057872134749,3.110173533997605
661,66.10082605381221,0.7486548725565725,-0.45341152808731183,4.056641877628011
662,66.20082730351541,-0.3362564512874541,-0.8445290031434521,3.662876357654432
663,66.30082855321861,0.07403760511888466,-1.0810218935928555,2.5548883985202817
664,66.4008298029218,0.07191665159374401,-0.4162083308804617,3.2044382045199167
665,66.500831052625,0.4475228806913538,-0.7330453479046573,3.118915900770787
666,66.6008323023282,-0.01869576448053408,-0.19542393878609693,2.7169199897542735
667,66.7008335520314,0.3600519696305426,-1.013157380888868,2.619337953255793
668,66.80083480173458,0.5132199626942534,-0.3938839456068447,2.8902269649613097
669,66.90083605143778,1.2232502044119615,-0.4351441192028207,3.3851529842537085
670,67.00083730114098,-0.34332087794501165,-0.05235535016787407,2.959716421007272
671,67.10083855084417,-0.1507986103161757,-0.7022069484561972,2.9158632359007903
672,67.20083980054737,0.0007451052929750234,-0.7524998713236009,2.742100108846343
673,67.30084105025057,-0.23287489275654236,-0.4061402836070325,2.698529021293906
674,67.40084229995377,0.6849165391656825,-0.2933697770842436,3.0174184700593507
675,67.50084354965695,0.31863921564529807,-0.41547132404815595,2.0882107586258583
676,67.60084479936015,-0.21941627120618093,-0.7838622147855889,2.5756544515346307
677,67.70084604906334,0.43951562659151056,-0.31878448453249464,1.8017299252122125
678,67.80084729876654,-0.6618906689897418,0.4190179615607733,1.4070203534363093
679,67.90084854846974,0.7585419473035498,-0.7661224270520086,2.1957133613289765
680,68.00084979817294,-0.18117269824206161,-0.05677146053622406,2.547813687757814
681,68.10085104787613,0.5140430270410821,-0.36390519097700746,2.196540031391878
682,68.20085229757932,-0.2781414810373977,0.10891760185977994,1.3659738558279861
683,68.30085354728251,0.057334975939251714,-0.25186485604999354,2.731393625228953
684,68.40085479698571,0.43800681251939544,-0.34329942411943987,1.0312858485019714
685,68.50085604668891,-0.1852393356834152,-0.6623951302092896,1.2407407718816996
686,68.6008572963921,-0.06293798236272226,-0.05615864743941937,1.5735314709517905
687,68.7008585460953,0.3185090451084704,-0.5807548613678978,2.078275879827766
688,68.8008597957985,-0.4524038412766819,-0.3709727359542831,1.6427623949390389
689,68.90086104550168,-0.2953633748534464,-0.5650587949014496,2.4223287561690805
690,69.00086229520488,0.10672025233523363,0.5530129863442211,1.0431565288339004
691,69.10086354490808,0.549589529822362,-0.20640617337375872,2.1651671188274753
692,69.20086479461128,0.46384163287219843,0.34218703054639965,2.178961136718477
693,69.30086604431447,0.3716292575942021,-0.10827218390596391,2.246022818834481
694,69.40086729401767,0.6010679926641385,-0.7149881469742672,1.7273891945143112
695,69.50086854372087,-0.24255327930459628,-0.4732735651390537,0.9937506260949703
696,69.60086979342405,0.37444757331309775,-0.06095939603284045,2.7220028345784675
697,69.70087104312725,-0.3812888787857306,-0.6497996285916248,1.3530330092440734
698,69.80087229283045,0.029165608302124366,0.31560189059345334,2.3418343737099665
699,69.90087354253365,-0.18622255502153942,0.07574034294697218,1.5544259069529125
700,70.00087479223684,0.45847380170668783,0.30932091867803446,1.8423464929222377
701,70.10087604194004,-1.0027781337760684,-1.0618036825471673,0.2905234930729925
702,70.20087729164324,0.2630154301642577,0.6566994711304104,1.3137183203469045
703,70.30087854134644,-0.34127716027904564,0.2961683108400025,1.4902430792202084
704,70.40087979104962,-0.4595442263025891,-0.42930983027565855,1.4958684472677422
705,70.50088104075282,0.8095540400046362,0.4564900462915973,1.381693753761121
706,70.60088229045601,0.5817319238447971,-0.391909470451113,1.4786038005867004
707,70.70088354015921,-0.16562222798295612,-0.22243731307007575,1.0723181167389175
708,70.80088478986241,0.45537884219192354,-0.1618654640815078,0.16123361042608564
709,70.9008860395656,-0.06656784830409548,-0.4323342437598357,1.399281784415416
710,71.0008872892688,-0.6684776022640787,0.20908290157835602,1.4448937679568463
711,71.10088853897199,0.5364491710235327,0.3049239068026371,1.3909351061177286
712,71.20088978867518,0.045831767729990154,1.0063544628765684,1.2002114048606045
713,71.30089103837838,0.22356858222867929,-0.3463863755400345,1.4443312731271654
714,71.40089228808158,-0.17558823673116508,-0.7524334166943641,1.3780930619801925
715,71.50089353778478,0.4045863341463832,-0.28059738786475075,0.5258011235163312
716,71.60089478748797,0.7657753095648208,0.2800217439451116,1.0495539436835306
717,71.70089603719117,-0.608938223617164,0.5845450253301586,0.6738227763818094
718,71.80089728689435,-0.45441107328310054,0.8278207624607051,1.3435396204726144
719,71.90089853659755,-0.22059071431888283,0.5740741641549232,2.078786205781594
720,72.00089978630075,1.37893082513669,0.459777906253697,0.7424719517539324
721,72.10090103600395,0.27624380356950806,-1.0490339901174575,1.3800697348381523
722,72.20090228570714,-0.006479917935897768,-0.03217318749695747,0.9306580880978921
723,72.30090353541034,0.6230959095689119,-0.8828382097223103,1.2226816961148104
724,72.40090478511354,-0.11858245788290057,0.15411393261285042,0.549915388099111
725,72.50090603481672,-0.06888452959050327,0.4311009258155841,1.0006428332374706
726,72.60090728451992,0.4276976988943089,0.030605620775865865,1.85721108471748
727,72.70090853422312,-0.1313177081444161,-0.23528487992518837,1.539927178260934
728,72.80090978392631,-0.1769926389497063,0.3199056549349148,1.2111444642600586
729,72.90091103362951,0.14439050556642805,-0.17307119803740603,1.1575634802808306
730,73.00091228333271,0.5472047473894334,-0.47772098644216815,0.42033889172737515
731,73.10091353303591,0.12681712718467467,0.24607885828631818,0.23797665690840308
732,73.20091478273909,-0.312409120649845,0.7395410546306139,0.48065230713661944
733,73.30091603244229,0.11867672100079214,-0.7238467151953466,-0.06883007682350584
734,73.40091728214549,0.41235495065405914,-0.11140374593784724,-0.018589954933495578
735,73.50091853184868,-0.14450019900040656,0.9033619461182725,1.2249803761851807
736,73.60091978155188,0.37433543491628063,0.03683254235892005,1.0159804283504121
737,73.70092103125508,-0.15786318860112758,-0.34927989165163115,0.14076616504326056
738,73.80092228095828,-0.9655993979104917,-0.09276195510250342,0.3185135913530666
739,73.90092353066147,-0.6583501013521663,-0.10553546388525163,0.25556533603623255
740,74.00092478036466,0.2726019629567167,0.1484025248219597,-0.47131539956405466
741,74.10092603006785,0.265764039424273,-0.3476182594199317,0.06977063418831331
742,74.20092727977105,0.4436805603011194,0.16734480440723198,1.0789537979141874
743,74.30092852947425,-1.1422595588836437,0.39127219880267616,0.8776717137718741
744,74.40092977917745,0.1937192979547509,0.6793044242428534,1.1182755050289503
745,74.50093102888064,0.011858166988222868,-0.30488044984944696,0.38061115192162265
746,74.60093227858384,-1.0264098364115721,-0.501322581567479,0.263097332496123
747,74.70093352828702,0.298823506926967,-0.734726907306257,0.589029108143103
748,74.80093477799022,-0.45958261208893714,0.04300637261565212,0.7171139559071573
749,74.90093602769342,0.4535316579921512,0.16793496543504724,1.0721231694246913
750,75.00093727739662,-0.8907617931570191,-0.7866287333958089,0.6972994762411069
751,75.10093852709981,-0.9015722078337688,-0.37374676395264317,0.8499602519553506
752,75.20093977680301,-0.4078703152552693,0.4965001352769394,-0.2238341883217101
753,75.30094102650621,-0.6804406326504319,0.6836564923723312,0.5320957506406865
754,75.40094227620939,0.3440725104630058,0.313479293364427,0.5588734718829335
755,75.50094352591259,0.3659994671538331,-0.015061295050640995,0.16921583560659514
756,75.60094477561579,0.3418106270510686,0.3798837497871951,0.09607814662922914
757,75.70094602531898,-0.5397975503629162,0.6136218986882213,0.19921119077651916
758,75.80094727502218,-0.03209525629730518,-0.08654933145976647,0.15252301803117096
759,75.90094852472538,0.3753913319412422,-0.03343325705819428,0.5769152082232321
760,76.00094977442858,0.049292422364833915,-0.055679366489362114,1.0944188988798123
761,76.10095102413176,-0.3624621328187335,-0.4854975287610252,0.7497396178584249
762,76.20095227383496,-0.6547483942939636,-0.07300552328919546,1.056311471643954
763,76.30095352353815,-0.46611679684245816,0.0438120821089171,0.5421484429076272
764,76.40095477324135,0.46970427062821013,0.06317151696490808,0.1074013975213648
765,76.50095602294455,-0.3394499467892878,0.07326753307571482,0.4642410192738998
766,76.60095727264775,-0.3621811387530202,-0.20621106686790378,0.41344749390492685
767,76.70095852235094,-0.3517370026920056,-0.33144114157530863,0.6198963112265051
768,76.80095977205414,0.4542487820984304,0.24890732812422542,0.9074215306310168
769,76.90096102175733,0.6782016910986886,-0.16638812602982433,0.6235537782540058
770,77.00096227146052,-0.3331411239099514,-0.4630380751841084,-0.4246274577241226
771,77.10096352116372,0.8355111140277923,-0.11120113199691072,0.2667856222764599
772,77.20096477086692,-0.19954405649044907,0.04883307688715793,-0.09590555364613601
773,77.30096602057012,-0.2371702521063778,0.6480843324298861,-0.10723430481770718
774,77.40096727027331,0.16611984707937166,-0.14961980167408706,0.39026737647645204
775,77.50096851997651,-1.277101077609219,0.24329046481353941,0.5967838547027662
776,77.6009697696797,-0.06941932624932382,-0.2667018978303071,1.1373897319444792
777,77.70097101938289,0.18545152954518868,0.3276196373281439,0.729979554793672
778,77.80097226908609,-0.33444183510901687,0.3356627936259977,0.7058648354032979
779,77.90097351878929,0.2587792603439574,0.1714463402238103,-0.17284002961061384
780,78.00097476849248,0.7629397673208714,-0.1630139779621466,0.2286719358985636
781,78.10097601819568,-0.46426194299228757,0.49959023538149533,-0.29331993716684157
782,78.20097726789888,-0.9354816571217863,-0.56890654874712,0.5781627731053415
783,78.30097851760206,-0.6205904312464522,-0.2668291338170599,-0.004911404391120422
784,78.40097976730526,-0.08344642896792517,0.06036886868400358,0.08900268794848246
785,78.50098101700846,-0.9812815803793913,0.296030819106915,0.8084203100312299
786,78.60098226671165,0.198848476832813,-0.2826481052370207,0.4610846493952833
787,78.70098351641485,0.08410796590498229,-0.21215158798000183,-0.6089396682376487
788,78.80098476611805,1.0030888953545911,0.5086331716517443,0.03510491578238109
789,78.90098601582125,1.2807059533731155,-0.22329961185392486,0.8296183942490791
790,79.00098726552443,0.2420228208250635,-0.46722361045107874,1.1076127122750135
791,79.10098851522763,0.1611701478808601,-0.1391048484864442,-0.0018769222707197275
792,79.20098976493082,-0.15967216794150565,-0.08946105783648026,-0.04804283653484548
793,79.30099101463402,0.3347494252292377,-0.04575453293529026,-0.1311707016822389
794,79.40099226433722,0.39663285502001033,-0.1863688455457191,0.8766036333327843
795,79.50099351404042,-0.7210248338162627,0.30355899516984075,-0.25439841127342583
796,79.60099476374361,0.17939076645316943,-0.6599709153853344,0.6104415802833049
797,79.7009960134468,-0.6373175607194036,-0.08483888883495166,0.4436271191948594
798,79.80099726315,-0.36740665757463603,0.05267310623894388,-0.718992232713141
799,79.90099851285319,0.11345533536841455,0.22312406504863228,0.1710457769253053
800,80.00099976255639,0.41564925220141863,-0.26898545235060506,-0.27824493475586276
801,80.10100101225959,0.4701211757079769,-0.3538430873255347,-0.6153250562111855
802,80.20100226196278,0.2554734675336971,-0.4179288686956058,-0.06569707274874961
803,80.30100351166598,-0.5045475426943454,1.1484594383419897,0.4450448096961154
804,80.40100476136918,0.03313179018813345,0.13111315440622334,-1.1059585448116875
805,80.50100601107236,-0.7017272143967729,0.3919280978981487,0.564343783665294
806,80.60100726077556,0.1868656336521362,-0.13067023998781443,0.3296995781962917
807,80.70100851047876,-0.07329947815254696,-0.2943559875649734,1.3171102855266144
808,80.80100976018196,-0.1231136065632208,-0.24164682439618776,-0.2792168319377222
809,80.90101100988515,0.02821354425245753,0.5600332554930844,0.012572976267476027
810,81.00101225958835,-0.7337157296106005,0.23483084139035304,0.4870986271036642
811,81.10101350929155,0.8785645076156224,0.3385501315073869,0.8510686577554323
812,81.20101475899473,-0.7819537365362044,0.37787858796447493,-0.18701693986613954
813,81.30101600869793,-0.6825233063067725,0.0616159620968954,0.3057487913316246
814,81.40101725840113,-0.6238886331754103,-0.28055908651560574,0.17170766131113205
815,81.50101850810432,-0.24202813974612555,-0.004693932149262948,0.16660867212839178
816,81.60101975780752,-0.3452710347639048,0.3189194419953305,-0.39058252512499214
817,81.70102100751072,-0.03889230505562797,-0.48909573144162655,0.3737440953420331
818,81.80102225721392,-0.34870122089633077,-0.703554408959717,0.5552292046663747
819,81.9010235069171,0.6168933478142381,0.508508956365804,0.16473289386302353
820,82.0010247566203,39.96865852558703,15.031849639840617,2.315913167927773
821,82.1010260063235,39.6699096087505,13.846861070440418,2.842764377847977
822,82.20102725602669,39.540714590668074,14.449908100759131,2.7522574979183796
823,82.30102850572989,39.80122435027673,14.984521053879842,3.340443429737861
824,82.40102975543309,40.45250189417557,14.515677721812857,3.4204888527850765
825,82.50103100513628,40.195482779496665,14.583839644029906,2.73782957919928
826,82.60103225483947,39.711564399988895,14.09213651655843,2.264950290663088
827,82.70103350454266,39.94623440046725,14.591765602646113,2.991411396812392
828,82.80103475424586,40.499240797448145,13.559359058877295,4.232556029247068
829,82.90103600394906,39.948992057252575,13.914254245035282,3.5750955155811805
830,83.00103725365226,39.74000727015414,13.45910643414678,3.604069490676372
831,83.10103850335545,39.620688873660995,13.397536847321692,3.4457362193017103
832,83.20103975305865,39.97435655243045,13.688783267314284,3.325842760919984
833,83.30104100276183,40.08850231709025,14.070094492987792,3.4375699826538604
834,83.40104225246503,39.162492366944576,14.187490193745187,3.8220129102685965
835,83.50104350216823,39.63683986054727,13.447383284368648,3.839165422023397
836,83.60104475187143,39.07137150255819,12.560441838871858,4.012314834519034
837,83.70104600157462,39.47883320294523,12.392026323718932,4.027262977317451
838,83.80104725127782,40.547572961972534,11.843278869305513,4.0051671418163215
839,83.90104850098102,40.10600019274047,12.110955603974768,2.871997595378345
840,84.00104975068422,39.745517160641285,12.649496844353575,3.83505804998657
841,84.1010510003874,39.83525422053637,12.74980177089365,3.845105795820587
842,84.2010522500906,40.25754421307318,12.314598894325119,4.172070252900343
843,84.3010534997938,40.478879197514125,11.676242346442587,4.073103625357348
844,84.40105474949699,39.88125705276562,10.919867439005827,3.858936290168658
845,84.50105599920019,39.60450152377146,10.558063390274452,4.708467311423843
846,84.60105724890339,40.53528844616767,11.409323508024114,4.237211975926544
847,84.70105849860659,40.15017777557522,10.485363546099103,5.784312164052983
848,84.80105974830977,39.480906822261545,10.232685207143366,5.840457559275901
849,84.90106099801297,40.10219540279734,11.079942150565012,3.90175778161723
850,85.00106224771616,40.86433669146865,9.836285172500213,5.859485342627723
851,85.10106349741936,39.02482033040615,9.631308601597363,4.72027693867901
852,85.20106474712256,40.42203391447172,9.991575123263946,5.640268609950048
853,85.30106599682576,39.65807132910298,10.36411932814622,6.038685984356955
854,85.40106724652895,39.88966967920849,10.176405392081158,6.139765170197898
855,85.50106849623214,41.84637837666513,9.498982814433818,5.72160524046056
856,85.60106974593533,40.08585811840786,9.108156948203241,5.8159167361287984
857,85.70107099563853,40.09027128499287,9.292020998048693,6.224190387934614
858,85.80107224534173,40.822484211616604,9.004141025445191,6.10360889903453
859,85.90107349504493,39.92580490962565,9.309445304840075,6.7020396414222
860,86.00107474474812,40.00131553291941,9.359352539345586,5.642390497399868
861,86.10107599445132,40.342114992516336,9.162535378131214,7.128806118628466
862,86.2010772441545,40.2566101513145,8.18304501690423,7.5628779573454725
863,86.3010784938577,39.911010222816685,8.40322750236656,7.964605332746716
864,86.4010797435609,40.18511923773608,7.479479666911665,6.325995525082895
865,86.5010809932641,39.47935216621265,8.467519885317525,5.577491918128732
866,86.6010822429673,39.97907432068032,9.089633829374948,7.102769797619919
867,86.70108349267049,39.625124861183686,8.106697437339115,6.303500844167868
868,86.80108474237369,40.63537256696982,8.033758759649839,6.6474796648286185
869,86.90108599207687,39.447950675922236,7.351628525305455,7.415995777512524
870,87.00108724178007,39.663095583355954,7.101690697029932,8.153701716006557
871,87.10108849148327,39.4875596178007,7.385897659545492,7.583193255696913
872,87.20108974118646,39.91028318202084,7.526020374799852,7.609695301687982
873,87.30109099088966,39.937341759215016,6.502739119074776,8.164364321171622
874,87.40109224059286,39.49328557453016,6.892919062075386,8.069414970781724
875,87.50109349029606,39.88557275110081,6.264379529184375,8.485392089107618
876,87.60109473999925,39.40160558651665,5.98913624164597,9.376598682013814
877,87.70109598970244,40.56648709374098,5.80222232734601,8.591931105842944
878,87.80109723940564,39.27624806564488,5.872696891438236,8.386174818059747
879,87.90109848910883,40.03028780376013,6.43798813681838,9.775695213247204
880,88.00109973881203,39.67508495606067,5.761821500532165,8.18006213991412
881,88.10110098851523,40.3028734940109,6.487385518590558,8.916062848908918
882,88.20110223821843,40.259373746099826,6.136045372451032,9.505919042844287
883,88.30110348792162,40.25273908910426,5.368482597015908,9.405664539625889
884,88.4011047376248,40.74759180854924,4.820017848723196,9.97761950544062
885,88.501105987328,38.93085840872031,5.279760166069355,9.516692024633747
886,88.6011072370312,40.58861894362477,5.036083811744341,10.571104813416651
887,88.7011084867344,40.01810713394813,4.657598906000468,9.879500138633468
888,88.8011097364376,39.55334671758594,4.644409878322904,11.498924597735952
889,88.9011109861408,40.019650452412364,4.57137405528923,10.937971680721146
890,89.00111223584399,40.5561930054472,4.869802862705651,11.015770907814929
891,89.10111348554717,39.91547006398132,3.736439238934479,11.203855888802934
892,89.20111473525037,39.9824678234972,3.819725572805024,11.237175818899795
893,89.30111598495357,40.36313323405653,3.533061713191823,11.924804759433345
894,89.40111723465677,40.46205106269625,4.347134155311632,11.596685257382559
895,89.50111848435996,39.19710822865453,3.456486078700358,12.457705742069612
896,89.60111973406316,39.973538509919855,3.5790533298487515,11.834383630071843
897,89.70112098376636,39.61026895645267,3.566799571315048,13.141819639932221
898,89.80112223346954,39.73094201419819,3.746385904410462,12.669048128585235
899,89.90112348317274,40.3952911130965,3.4860458762382383,14.206992554473775
900,90.00112473287594,39.39799566759925,2.7674962530679315,13.669753622277142
901,90.10112598257913,38.76832119367951,2.8688194377897354,14.422852351497562
902,90.20112723228233,40.51697255424536,3.315539975257193,14.033736043971844
903,90.30112848198553,39.64829545705206,3.0026596064151403,13.627377060813505
904,90.40112973168873,39.513336335409434,2.866687224868529,13.849653086394609
905,90.50113098139192,39.51511528268643,1.9742161798843214,15.363565539948954
906,90.60113223109511,39.37051790555876,1.1414987089530515,14.488156758091131
907,90.7011334807983,40.912771003314994,1.4020053959792858,16.08856434380269
908,90.8011347305015,39.69524846083921,1.3923360135207756,16.124270842721835
909,90.9011359802047,40.1208492098407,2.3961451625931334,16.546133723444484
910,91.0011372299079,40.31523283026237,1.0956291980908048,16.06088533977718
911,91.1011384796111,38.876998729052595,1.5038810069941555,17.581356306682565
912,91.20113972931429,39.71289607418759,1.2465405176358006,16.31107756911515
913,91.30114097901748,40.194806476104105,2.170461200097316,17.97040565663285
914,91.40114222872067,40.37008799733154,1.1022940536330241,17.81863093693309
915,91.50114347842387,40.10850846712197,0.7568046335401319,17.591832080321446
916,91.60114472812707,40.07892570420404,-0.1998917042055387,18.724344290076004
917,91.70114597783027,40.51702171391384,0.159572868951673,19.610501881215065
918,91.80114722753346,39.864905502069334,0.4680633923000188,19.624993004276746
919,91.90114847723666,41.092034365265214,-0.05773601393018525,19.332770774549434
920,92.00114972693984,39.925761428809004,-1.1049893697118554,21.130300073802008
921,92.10115097664304,39.73427711336076,0.11274827014458731,19.550392123438236
922,92.20115222634624,39.37712958492115,-1.2150449797757483,20.104411477420243
923,92.30115347604944,39.9692005450302,0.4102073894951419,19.039638952297825
924,92.40115472575263,39.49108853946137,-0.19478636650591133,19.972356266479228
925,92.50115597545583,38.96774196809778,-0.4348077416062104,20.14685133663465
926,92.60115722515903,40.24415329373392,0.10241702291534771,20.452617911120644
927,92.70115847486221,40.08047563071153,0.22535164288913398,20.426778452102333
928,92.80115972456541,39.76736369659186,-0.4618401329369904,20.46325022867451
929,92.9011609742686,39.87241300794221,-0.3208141089785252,18.98139408784806
930,93.0011622239718,40.51521890329606,-0.19764434489791285,19.984343932267915
931,93.101163473675,40.021857587835825,-0.13250978917367584,19.848501322472973
932,93.2011647233782,40.30492464034387,0.7130697263524145,19.605513878255234
933,93.3011659730814,40.2917723424431,-0.39074797253740556,20.097467644131125
934,93.40116722278458,40.432584512336206,-0.8974390908674515,20.102429595853724
935,93.50116847248778,40.27799107203056,-0.12696625617927282,20.26766841798357
936,93.60116972219097,39.989588710102915,-1.3064332696559264,20.12229309180863
937,93.70117097189417,39.73664758026414,0.4495194662485125,19.5905046911846
938,93.80117222159737,40.125132525499,0.014566736761136227,19.882117375256158
939,93.90117347130057,40.305757959303826,-0.3206655342659407,19.834175871332025
940,94.00117472100376,40.01240504023484,-0.2340146607048009,20.13994259051019
941,94.10117597070696,38.767886467456755,-0.4125561275337808,20.08663447251454
942,94.20117722041014,39.09462308465794,-0.06401353762852006,19.70602464899434
943,94.30117847011334,39.28458606055149,-0.4616787541302383,20.392872030960856
944,94.40117971981654,40.30319235283127,-0.10014757121155941,21.080092576353792
945,94.50118096951974,39.31900998268223,-0.05426414321474121,20.435223245026272
946,94.60118221922293,38.85450252494595,-0.08569264562690133,20.225554707070028
947,94.70118346892613,39.68903015575324,0.21052132544709867,20.311051401239663
948,94.80118471862933,39.30000976099479,-1.0597448729472974,20.54525704859531
949,94.90118596833251,39.71414606408619,-0.8579833774024874,20.158528745029667
950,95.00118721803571,40.85318401289787,0.05271463078305758,19.99465141128703
951,95.10118846773891,40.38230278587799,-0.4806105313271299,19.7786056785518
952,95.2011897174421,39.29191211192522,0.5810395945873024,19.493863612127537
953,95.3011909671453,39.602967805607854,0.6851648453744501,18.99364954678785
954,95.4011922168485,40.28162975196367,0.015581428962603398,20.46375821772923
955,95.5011934665517,40.02007928944769,-0.6145815356530568,20.345453049084607
956,95.60119471625488,39.67006519165385,-0.5872861346004871,19.73257406957774
957,95.70119596595808,40.18631521318079,-0.9674134476742277,20.185558885519487
958,95.80119721566128,40.23729178784496,0.3310814745214145,19.594123621299758
959,95.90119846536447,40.10550227327129,-0.1470520784350978,19.295616738797303
960,96.00119971506767,40.25277133983536,0.33309630781757266,20.09633586756035
961,96.10120096477087,40.17072452744798,-0.6707449760435619,21.29742263485153
962,96.20120221447407,40.847820059802004,-0.18845184163877685,19.75244903150541
963,96.30120346417725,41.10098240809924,-0.37169941186413613,20.04573790799331
964,96.40120471388045,39.92372601842418,-0.20199538367931796,20.018252604378684
965,96.50120596358364,39.67726767866232,-1.5823839134086886,20.12738735065675
966,96.60120721328684,39.795456398479466,-0.622299116299538,20.088947109016157
967,96.70120846299004,39.893515317698096,0.1519399192505748,19.837280014972734
968,96.80120971269324,39.714860086936,0.2133243597610395,20.175694711490276
969,96.90121096239643,40.453977891922705,0.443692842704583,19.811361328288122
970,97.00121221209962,0.25719467217677366,-14.758931438107801,19.859257339032293
971,97.10121346180281,0.1222698716079941,-14.170943436668363,20.031356083232435
972,97.20121471150601,-0.03668056840769275,-13.984219205427591,19.00592785557164
973,97.30121596120921,0.3008646593048977,-13.629686543117677,18.870040464195345
974,97.4012172109124,0.31274143658657216,-12.839091613234926,18.597806908409733
975,97.5012184606156,0.4345709298872005,-12.590615902739549,18.489224516423068
976,97.6012197103188,-0.05733075314963223,-11.813934428083288,18.326098367940265
977,97.701220960022,-0.443047616409815,-10.960467209921966,17.42928016907922
978,97.80122220972518,0.15005242977101899,-11.230800287894745,16.590763041436396
979,97.90122345942838,0.5371850142064974,-11.133334218046464,16.870701686394515
980,98.00122470913158,0.5788572931838148,-10.606102367769589,16.0710520902649
981,98.10122595883477,-0.016571162388118642,-10.376490238416896,14.64078764244539
982,98.20122720853797,-0.17380739156439193,-9.400610778904062,15.229962271355435
983,98.30122845824117,-0.11660979004635448,-9.067693300584839,15.564238568108927
984,98.40122970794437,-0.7630924088159229,-9.160502408665906,14.637983888146563
985,98.50123095764755,-0.2736071722253269,-8.695557177748134,15.903964437363667
986,98.60123220735075,0.34569608007549585,-8.958765335654999,15.675629735235766
987,98.70123345705395,0.11389496727926525,-9.354660738813203,15.490467134468027
988,98.80123470675714,-0.3283527933117781,-7.692410306074707,13.801758105129826
989,98.90123595646034,-0.4079776331938477,-7.908062548715819,14.019587382221967
990,99.00123720616354,-0.4457138782317989,-7.304541339810423,13.735934510741059
991,99.10123845586673,0.06884301762777284,-7.720256759222734,12.233022410240158
992,99.20123970556992,0.5273926810223554,-7.198648964971571,13.259091772685496
993,99.30124095527312,0.6045587797307787,-6.4087386473825045,12.523562468128086
994,99.40124220497631,0.3181262404321561,-6.208616883100106,12.153179455978506
995,99.50124345467951,0.6701897860434355,-7.089418939998286,11.654264796928931
996,99.60124470438271,0.193483615353933,-6.295307386886263,11.561662901761082
997,99.7012459540859,-0.08374239441619283,-6.536883654496854,11.490671415460582
998,99.8012472037891,-0.8537507156592196,-6.051973823837041,10.903709082527277
...
This file has been truncated, please download it to see its full contents.
{
"configurations": [
{
"name": "Mac",
"includePath": [
"/Users/poojan/Library/Arduino15/packages/esp8266/tools/**",
"/Users/poojan/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/**",
"/Applications/Arduino.app/Contents/Java/tools/**",
"/Applications/Arduino.app/Contents/Java/hardware/arduino/avr/**",
"/Users/poojan/anaconda/include/c++/v1",
"C:\\Users\\Ranjith\\AppData\\Local\\Arduino15\\packages\\esp8266\\hardware\\esp8266\\2.6.3\\**",
"C:\\Users\\Ranjith\\AppData\\Local\\Arduino15\\packages\\esp8266\\tools\\**"
],
"forcedInclude": [
"/Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino/Arduino.h"
],
"macFrameworkPath": [
"/System/Library/Frameworks",
"/Library/Frameworks"
],
"intelliSenseMode": "clang-x64",
"compilerPath": "/Users/poojan/anaconda/bin/clang",
"cStandard": "c11",
"cppStandard": "c++17"
},
{
"name": "Win32",
"includePath": [
"C:\\Users\\Ranjith\\AppData\\Local\\Arduino15\\packages\\esp8266\\tools\\**",
"C:\\Users\\Ranjith\\AppData\\Local\\Arduino15\\packages\\esp8266\\hardware\\esp8266\\2.6.3\\**"
],
"forcedInclude": []
}
],
"version": 4
}
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
# Exponential function
def exp_rise(time=10, max=40, shift=0, exp=0.2):
mult=max-shift
expt=[]
t_arr = np.linspace(start=0, stop=time, num=time*10)
expt_max = mult*np.exp(time*exp)/mult
for t in t_arr:
expt.append(shift+((mult*np.exp(t*exp))/expt_max))
return expt
# Saturating Exponential function
def exp_sat_rise(time=10, mult=20, shift = -20, exp=2):
exp_sat =[]
t_arr = np.linspace(start=0, stop=time, num=time*10)
for t in t_arr:
exp_sat.append(shift + mult*(1 - np.exp(-t/exp)))
return exp_sat
def exp_sat_fall(time=10, mult=40, exp=5):
exp_sat =[]
t_arr = np.linspace(start=0, stop=time, num=time*10)
for t in t_arr:
exp_sat.append(mult*(np.exp(-t/exp)))
return exp_sat
# Ramp Increment function
def ramp(time=10, left=5, right=40):
ramp = []
slope = (right-left)/time
t_arr = np.linspace(start=0, stop=time, num=time*10)
for t in t_arr:
ramp.append(left + (t*slope))
return ramp
# Square Function
def square (time=10,val=40):
sqr = []
t_arr = np.linspace(start=0, stop=time, num=time*10)
for t in t_arr:
sqr.append(val)
return sqr
# Noise Function
def add_gauss_noise(arr,amp=0.5):
noise = amp*np.random.normal(size=len(arr))
arr = arr + noise
return arr
def add_time(time):
return np.linspace(start=0, stop=time, num=time*10)
##### VOLUME MODE #####
time=[]
pressure=[]
flow=[]
volume=[]
tot_time=0
##2sec
tot_time+=2
pressure.extend(square(2,0))
flow.extend(square(2,0))
volume.extend(square(2,0))
for j in range (200):
##15sec
tot_time+=15
pressure.extend(ramp(15,5,40))
flow.extend(square(15,15))
volume.extend(ramp(15,0,20))
##2sec
tot_time+=2
pressure.extend(square(2,35))
flow.extend(square(2,0))
volume.extend(square(2,20))
##25sec
tot_time+=25
pressure.extend(exp_sat_fall(25,35))
flow.extend(exp_sat_rise(25,15,-15))
volume.extend(exp_sat_fall(25,20))
##total_time=86sec
time.extend(add_time(tot_time))
pressure = add_gauss_noise(pressure)
flow = add_gauss_noise(flow)
volume = add_gauss_noise(volume)
vol_mod_fig, (pre, flo, vol) = plt.subplots(3)
vol_mod_fig.suptitle('Volume Mode')
pre.plot(time,pressure)
flo.plot(time,flow)
vol.plot(time,volume)
vol_mode_df = pd.DataFrame(
{'Time': time,
'Pressure': pressure,
'Flow': flow,
'Volume': volume
})
vol_mode_df.to_csv(r'/Users/saumilgogri/reSPIRE_proj/devPost/dataset/Volume_Mode.csv')
##### PRESSURE MODE #####
time=[]
pressure=[]
flow=[]
volume=[]
tot_time=0
##2sec
tot_time+=2
pressure.extend(square(2,0))
flow.extend(square(2,0))
volume.extend(square(2,0))
for j in range (200):
##15sec
tot_time+=15
pressure.extend(square(15,40))
flow.extend(ramp(10,15,0))
flow.extend(square(5,0))
volume.extend(exp_rise(10,20))
volume.extend(square(5,20))
##25sec
tot_time+=25
pressure.extend(square(25,0))
flow.extend(exp_sat_rise(15,15,-15,3))
flow.extend(square(10,0))
volume.extend(exp_sat_fall(25,20))
##total_time=86sec
time.extend(add_time(tot_time))
pressure = add_gauss_noise(pressure)
flow = add_gauss_noise(flow)
volume = add_gauss_noise(volume)
pres_mode_df = pd.DataFrame(
{'Time': time,
'Pressure': pressure,
'Flow': flow,
'Volume': volume
})
pres_mode_df.to_csv(r'/Users/saumilgogri/reSPIRE_proj/devPost/dataset/Pressure_Mode.csv')
pre_mode_fig, (pre, flo, vol) = plt.subplots(3)
pre_mode_fig.suptitle('Pressure Mode')
pre.plot(time,pressure)
flo.plot(time,flow)
vol.plot(time,volume)
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); /*Even though you can use the hardware serial port in this case I think it is better to
leave the hardware serial open for debugging purposes*/
void setup() {
// put your setup code here, to run once:
pinMode(0, INPUT); //This is our analog input pin
Serial.begin(57600); //open the hardware serial port
while (!Serial) { // wait for serial port to connect. Needed for native USB port only
;
}
Serial.println("Serial On"); //Print this messages when the serial port is connected
mySerial.begin(9600); // set the data rate for the SoftwareSerial port
}
void loop() {
String sendThis = ""; //Declare and initialise the string we will send
delay(300); //Probably unneccessary, but I give the screen some time to respond
sendThis = "n0.val="; //Build the part of the string that we know
sendThis.concat(analogRead(0)); //Add the variable we want to send
writeString(sendThis); /*Use a function to write the message character by character to the Nextion because
mySerial.write(sendThis) gives you an error due to a datatype mismatch*/
}
//NOTE: A great big thanks to: RamjetX for writing this function. You can find his/her post here: http://forum.arduino.cc/index.php?topic=89143.0. Please go give him/her some Karma!
void writeString(String stringData) { // Used to serially push out a String with Serial.write()
for (int i = 0; i < stringData.length(); i++)
{
mySerial.write(stringData[i]); // Push each char 1 by 1 on each loop pass
}
mySerial.write(0xff); //We need to write the 3 ending bits to the Nextion as well
mySerial.write(0xff); //it will tell the Nextion that this is the end of what we want to send.
mySerial.write(0xff);
}// end writeString function
mit(float BPM, float IE_ratio, float pressure_mask, float pressure_expiration, float TidVol, float pressure_diff){
p_mask = map(pressure_mask, 5.00, 20.00, 0, 255);
p_expiration = map(pressure_mask, 5.00, 20.00, 0, 255);
p_diff = map(pressure_mask, 5.00, 20.00, 0, 255);
String to_send_p_mask = ad + id_1 + "," + ch + "," + int(p_mask);
print_screen(to_send_p_mask);
String to_send_p_diff = ad + id_2 + "," + ch + "," + int(p_diff);
print_screen(to_send_p_diff);
String to_send_p_exp = ad + id_1 + "," + ch + "," + int(p_expiration);
print_screen(to_send_p_exp);
dtostrf(BPM, 6, 2, buffer);
t0.setText(buffer);
dtostrf(IE_ratio,6,2,buffer_2);
t1.setText(buffer_2);
dtostrf(TidVol,6,2,buffer_2);
t1.setText(buffer_3);
}
void print_screen(String to_send){
Serial.print(to_send);
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
}
#include <Servo.h>
#include<SoftwareSerial.h>
#include <ArduinoJson.h>
#include <Nextion.h>
#include "NexButton.h"
//====== Serial COnnection with NODEMCU =====
SoftwareSerial SUART(2, 3); //SRX=Dpin-2; STX-DPin-3
Servo servoright;
int pos = 0;
// ==== Analog Pins =====
float potpinIE_ratio = 0;
int potpinTidVol = 1;
int potpinBPM = 5;
int pinguage_mask = 4;
int pinguage_expiration = 3;
int pinguage_diff = 2;
// ==== Analog Pins ====
//int inPin = 4;
// Declare your Nextion objects - Example (page id = 0, component id = 1, component name = "b0")
NexText t_mode = NexText(0, 9, "t_mode");
NexButton b0 = NexButton(0, 2, "b0");
NexButton b1 = NexButton(0, 3, "b1");
NexButton b2 = NexButton(0, 4, "b2");
NexText t3 = NexText(1, 5, "t3");
NexText t4 = NexText(1, 6, "t4");
NexText t5 = NexText(1, 7, "t5");
NexText t_ie_ratio = NexText(0, 10, "t_ie_Ratio");
NexText t_bpm = NexText(0, 11, "t_bpm");
NexText t_tidvol = NexText(0, 12, "t_tidvol");
String set_mode = "";
NexTouch *nex_listen_list[] = {&b0,&b1,&b2,NULL};
void b0PopCallback(void *ptr) {
t_mode.setText("MODE : ACV");
set_mode = "acv";
Serial.println(set_mode);
//acv_mode();
}
void b1PopCallback(void *ptr) {
t_mode.setText("MODE : SIMV");
//simv_mode();
set_mode = "simv";
}
void b2PopCallback(void *ptr) {
t_mode.setText("MODE : None");
//no_mode();
set_mode = "None";
Serial.println(set_mode);
}
// ==== Sensor Offset =====
const float guageSensorOffset = 41;
const float pressureDiffSensorOffset = 41;
// ===== Other vars ======
float check_value;
float IE_ratio;
float TidVol;
float BPM;
float separation;
float sensorvalue;
float pressure_mask;
float pressure_expiration;
float pressure_diff;
int display_IE_ratio;
int display_BPM;
int display_TidVol;
int display_sensorvalue_cmh2o;
int display_sensorvalue_gp_cmh2o;
void setup()
{
servoright.attach(9); // attaches the servo on pin 9 to the servo object
Serial.begin(9600);
SUART.begin(9600); //enable SUART Port for communication with NODEMCU
nexInit();
// Register the pop event callback function of the components
b0.attachPop(b0PopCallback, &b0);
b1.attachPop(b1PopCallback, &b1);
b2.attachPop(b2PopCallback, &b2);
}
void loop()
{ nexLoop(nex_listen_list);
/* if (set_mode == "simv")
{
while(set_mode=="simv")
{
simv_mode();
}
}
else
{ while(set_mode == "acv")
{
acv_mode();
}
} */
}
// =======================
// ACV MODE Function
// =======================
void acv_mode()
{
float IE_ratio;
float TidVol;
float BPM;
float per_breath_time;
float per_inspiration_time;
float per_expiration_time;
float human_effort;
float separation;
uint32_t cycleEndTime;
bool firstRun = true;
while(set_mode == "acv")
{
// Fetch all potentiometer values
IE_ratio = map(analogRead(potpinIE_ratio), 0, 1023, 1.00, 4.00);
TidVol = map(analogRead(potpinTidVol), 0, 1023, 40.00, 90.00);
BPM = map(analogRead(potpinBPM), 0, 1023, 8.00, 30.00);
separation = (60/BPM - (1+IE_ratio));
if (separation < 0)
{ IE_ratio = 60/BPM - 1;
separation = 60/BPM - (1+IE_ratio);
}
// Fetch pressure sensor values
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
// Initiate the cycle
if(firstRun)
{
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
firstRun = false;
}
// ========= Identify trigger and initiate the cycle =============
if(millis() - cycleEndTime >= (uint32_t)separation*1000 || pressure_mask < -1)
{
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
}
print_to_screen(BPM, IE_ratio, pressure_mask, pressure_expiration, TidVol, pressure_diff);
}
}
// =======================
// SIMV Logic Function
// =======================
uint32_t simv_logic(float pressure_mask, float TidVol, float IE_ratio)
{
uint32_t cycleEndTime;
pressure_mask = int(floor(pressure_mask));
switch(int(pressure_mask)){
case -6:
case -5:
case -4:
TidVol = TidVol*0.25;
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
case -3:
TidVol = TidVol*0.50;
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
case -2:
TidVol = TidVol*0.75;
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
case -1:
TidVol = TidVol*0.75;
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
default:
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
}
return cycleEndTime;
}
// =======================
// SIMV MODE Function
// =======================
void simv_mode()
{
uint32_t cycleEndTime;
bool firstRun = true;
while(set_mode == "simv")
{
// Fetch all potentiometer values
IE_ratio = map(analogRead(potpinIE_ratio), 0, 1023, 1.00, 4.00);
TidVol = map(analogRead(potpinTidVol), 0, 1023, 40.00, 90.00);
BPM = map(analogRead(potpinBPM), 0, 1023, 8.00, 30.00);
separation = (60/BPM - (1+IE_ratio));
if (separation < 0)
{ IE_ratio = 60/BPM - 1;
separation = 60/BPM - (1+IE_ratio);}
// Fetch pressure sensor values
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
// Initiate the cycle
if(firstRun)
{
pressure_mask = average_pressure_mask();
cycleEndTime = simv_logic(pressure_mask, TidVol, IE_ratio);
firstRun = false;
}
// ========= Identify trigger and initiate the cycle =============
if(millis() - cycleEndTime >= (uint32_t)separation*1000 || average_pressure_mask() < -1)
{
pressure_mask = average_pressure_mask();
cycleEndTime = simv_logic(pressure_mask, TidVol, IE_ratio);
}
print_to_screen(BPM, IE_ratio, pressure_mask, pressure_expiration, TidVol, pressure_diff);
}
}
// =======================
// Average Pressure Function
// =======================
float average_pressure_mask()
{
pressure_mask = 0;
for(int i=0;i<5;i++)
{
pressure_mask = pressure_mask + (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
delay(3);
}
return (pressure_mask/5);
}
// =======================
// Inspiration Function
// =======================
void inspiration(float TidVol)
{ int pos;
for(pos = 30; pos <= TidVol+30; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
servoright.write(pos);
delay(1000/TidVol);
// ============ Update pressure values =========
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
Serial.println(pressure_mask);
//Serial.println(pressure_diff);
//Serial.println(pressure_expiration);
}
}
// =====================
// Expiration Function
// =====================
uint32_t expiration(float TidVol, float IE_ratio)
{
for(pos = TidVol+30; pos>=30; pos-=1) // goes from 180 degrees to 0 degrees
{
servoright.write(pos);
delay(1000*IE_ratio/TidVol);
// ============ Update pressure values =========
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
Serial.println(pressure_mask);
//Serial.println(pressure_diff);
//Serial.println(pressure_expiration);
}
return millis();
}
// =====================
// Transmit to DB
// =====================
// =====================
// Print to Screen
// =====================
void print_to_screen(float BPM, float IE_ratio, float pressure_mask, float pressure_expiration, float TidVol, float pressure_diff){
static char ps_diff[6];
dtostrf(pressure_diff, 6, 2, ps_diff);
static char ps_exp[6];
dtostrf(pressure_expiration, 6, 2, ps_exp);
static char ps_mask[6];
dtostrf(pressure_expiration, 6, 2, ps_exp);
t3.setText(ps_diff);
t4.setText(ps_exp);
t5.setText(ps_mask);
static char ie_ratio[6];
dtostrf(IE_ratio, 6, 2, ie_ratio);
t_ie_ratio.setText(ie_ratio);
static char bpm[6];
dtostrf(BPM, 6, 2, bpm);
t_bpm.setText(bpm);
static char tidvol[6];
dtostrf(TidVol, 6, 2, tidvol);
t_tidvol.setText(tidvol);
}
#include <Servo.h>
Servo servoright;
void setup() {
// put your setup code here, to run once:
servoright.attach(9); // attaches the servo on pin 9 to the servo object
}
void loop() {
// put your main code here, to run repeatedly:
int pos;
for(pos = 0; pos <= 90; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
servoright.write(pos);
delay(10);
// ============ Update pressure valu
//Serial.println(pressure_diff);
//Serial.println(pressure_expiration);
}
delay(3000);
for(pos = 90; pos >= 0; pos -= 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
servoright.write(pos);
delay(10);
// ============ Update pressure valu
//Serial.println(pressure_diff);
//Serial.println(pressure_expiration);
}
delay(3000);
}
#include <Servo.h>
#include<SoftwareSerial.h>
#include <ArduinoJson.h>
#include "Nextion.h"
//====== Serial COnnection with NODEMCU =====
SoftwareSerial SUART(2, 3); //SRX=Dpin-2; STX-DPin-3
Servo servoright;
int pos = 0;
// ==== Analog Pins =====
float potpinIE_ratio = 0;
int potpinTidVol = 1;
int potpinBPM = 5;
int pinguage_mask = 4;
int pinguage_expiration = 3;
int pinguage_diff = 2;
// ==== Analog Pins ====
int inPin = 4;
// ==== Sensor Offset =====
const float guageSensorOffset = 41;
const float pressureDiffSensorOffset = 41;
// ===== Other vars ======
float check_value;
float IE_ratio;
float TidVol;
float BPM;
float separation;
float sensorvalue;
float pressure_mask;
float pressure_expiration;
float pressure_diff;
int display_IE_ratio;
int display_BPM;
int display_TidVol;
int display_sensorvalue_cmh2o;
int display_sensorvalue_gp_cmh2o;
// ======= Mode changing vars =========
int state = HIGH; // the current state of the output pin
int mode; // the current reading from the input pin
int previous = LOW; // the previous reading from the input pin
long t_time = 0; // the last time the output pin was toggled
long debounce = 200; // the debounce time, increase if the output flickers
// ======= JSON For storing data =========
String message = "";
boolean messageReady = false;
int obj_number = 1;
const int send_doc_capacity = JSON_ARRAY_SIZE(10) + 2*JSON_OBJECT_SIZE(7);
StaticJsonBuffer<send_doc_capacity> send_doc_json_buffer;
JsonArray& arr = send_doc_json_buffer.createArray();
void setup()
{
servoright.attach(9); // attaches the servo on pin 9 to the servo object
Serial.begin(9600);
SUART.begin(9600); //enable SUART Port for communication with NODEMCU
// attachInterrupt(0, pin_ISR, CHANGE);
}
void loop()
{
if (digitalRead(inPin) == LOW)
{
while(digitalRead(inPin)==LOW)
{
simv_mode();
while(SUART.available()) {
message = SUART.readString();
Serial.println(message);
messageReady = true;
}
if(messageReady) {
transmit(message);
}
}
}
else
{ while(digitalRead(inPin) == HIGH)
{
acv_mode();
while(SUART.available()) {
message = SUART.readString();
Serial.println(message);
messageReady = true;
}
if(messageReady) {
transmit(message);
}
}
}
}
// =======================
// ACV MODE Function
// =======================
void acv_mode()
{
float IE_ratio;
float TidVol;
float BPM;
float per_breath_time;
float per_inspiration_time;
float per_expiration_time;
float human_effort;
float separation;
uint32_t cycleEndTime;
bool firstRun = true;
while(digitalRead(inPin) == HIGH)
{
// Fetch all potentiometer values
IE_ratio = map(analogRead(potpinIE_ratio), 0, 1023, 1.00, 4.00);
TidVol = map(analogRead(potpinTidVol), 0, 1023, 40.00, 90.00);
BPM = map(analogRead(potpinBPM), 0, 1023, 8.00, 30.00);
separation = (60/BPM - (1+IE_ratio));
if (separation < 0)
{ IE_ratio = 60/BPM - 1;
separation = 60/BPM - (1+IE_ratio);
}
// Fetch pressure sensor values
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
// Initiate the cycle
if(firstRun)
{
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
firstRun = false;
}
// ========= Identify trigger and initiate the cycle =============
if(millis() - cycleEndTime >= (uint32_t)separation*1000 || pressure_mask < -1)
{
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
}
make_json(BPM, IE_ratio, pressure_mask, pressure_expiration, TidVol, pressure_diff);
}
}
// =======================
// SIMV Logic Function
// =======================
uint32_t simv_logic(float pressure_mask, float TidVol, float IE_ratio)
{
uint32_t cycleEndTime;
pressure_mask = int(floor(pressure_mask));
switch(int(pressure_mask)){
case -6:
case -5:
case -4:
TidVol = TidVol*0.25;
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
case -3:
TidVol = TidVol*0.50;
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
case -2:
TidVol = TidVol*0.75;
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
case -1:
TidVol = TidVol*0.75;
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
default:
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
}
return cycleEndTime;
}
// =======================
// SIMV MODE Function
// =======================
void simv_mode()
{
uint32_t cycleEndTime;
bool firstRun = true;
while(digitalRead(inPin) == LOW)
{
// Fetch all potentiometer values
IE_ratio = map(analogRead(potpinIE_ratio), 0, 1023, 1.00, 4.00);
TidVol = map(analogRead(potpinTidVol), 0, 1023, 40.00, 90.00);
BPM = map(analogRead(potpinBPM), 0, 1023, 8.00, 30.00);
separation = (60/BPM - (1+IE_ratio));
if (separation < 0)
{ IE_ratio = 60/BPM - 1;
separation = 60/BPM - (1+IE_ratio);}
// Fetch pressure sensor values
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
// Initiate the cycle
if(firstRun)
{
pressure_mask = average_pressure_mask();
cycleEndTime = simv_logic(pressure_mask, TidVol, IE_ratio);
firstRun = false;
}
// ========= Identify trigger and initiate the cycle =============
if(millis() - cycleEndTime >= (uint32_t)separation*1000 || average_pressure_mask() < -1)
{
pressure_mask = average_pressure_mask();
cycleEndTime = simv_logic(pressure_mask, TidVol, IE_ratio);
}
make_json(BPM, IE_ratio, pressure_mask, pressure_expiration, TidVol, pressure_diff);
}
}
// =======================
// Average Pressure Function
// =======================
float average_pressure_mask()
{
pressure_mask = 0;
for(int i=0;i<5;i++)
{
pressure_mask = pressure_mask + (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
delay(3);
}
return (pressure_mask/5);
}
// =======================
// Inspiration Function
// =======================
void inspiration(float TidVol)
{ int pos;
for(pos = 30; pos <= TidVol+30; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
servoright.write(pos);
delay(1000/TidVol);
// ============ Update pressure values =========
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
Serial.println(pressure_mask);
//Serial.println(pressure_diff);
//Serial.println(pressure_expiration);
}
}
// =====================
// Expiration Function
// =====================
uint32_t expiration(float TidVol, float IE_ratio)
{
for(pos = TidVol+30; pos>=30; pos-=1) // goes from 180 degrees to 0 degrees
{
servoright.write(pos);
delay(1000*IE_ratio/TidVol);
// ============ Update pressure values =========
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
Serial.println(pressure_mask);
//Serial.println(pressure_diff);
//Serial.println(pressure_expiration);
}
return millis();
}
// =====================
// Transmit to DB
// =====================
void transmit(String message){
// The only messages we'll parse will be formatted in JSON
const int capacity = JSON_OBJECT_SIZE(2);
StaticJsonBuffer<capacity> jb;
JsonObject& doc = jb.parseObject(message);
//DynamicJsonDocument doc(1024); // ArduinoJson version 6+
// Attempt to deserialize the message
if(!(doc.success())){
Serial.println("Doc conversion failed");
messageReady = false;
doc["type"] = "incorrect";
}
if(doc["type"] == "request") {
arr.printTo(SUART);
send_doc_json_buffer.clear();
}
}
// =====================
// Make the JSON
// =====================
void make_json(float BPM, float IE_ratio, float pressure_mask, float pressure_expiration, float TidVol, float pressure_diff){
JsonObject& obj = send_doc_json_buffer.createObject();
obj["type"] = "response";
obj["BPM"] = BPM;
obj["IE_ratio"] = IE_ratio;
obj["pressure_mask"] = pressure_mask;
obj["pressure_expiration"] = pressure_expiration;
obj["TidVol"] = TidVol;
obj["pressure_diff"] = pressure_diff;
arr.add(obj);
obj.remove("type");
obj.remove("TidVOl");
obj.remove("pressure_expiration");
obj.remove("pressure_mask");
obj.remove("IE_ratio");
obj.remove("BPM");
}
#ifdef ESP32
#include <WiFi.h>
#include <HTTPClient.h>
#else
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#endif
#include <ArduinoJson.h>
#include <Wire.h>
#include <FirebaseArduino.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include<SoftwareSerial.h>
SoftwareSerial SUART(4, 5); //SRX=Dpin-D2; STX-DPin-D1
#define FIREBASE_HOST "respire-447da.firebaseio.com"
#define FIREBASE_AUTH "vsloiSErdIEyQMV6ydzwaELOPVSP5dPqiOobAURm"
#define NTP_OFFSET 60 * 60 // In seconds
#define NTP_INTERVAL 60 * 1000 // In miliseconds
#define NTP_ADDRESS "europe.pool.ntp.org"
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, NTP_ADDRESS, NTP_OFFSET, NTP_INTERVAL);
//=======================================
unsigned long time_1;
bool test_2;
String last_char = "}";
time_t t;
// Replace with your network credentials
const char* ssid = "NETGEAR43";
const char* password = "smilingnest196";
// REPLACE with your Domain name and URL path or IP address with path
const char* serverName = "http://respire.000webhostapp.com/post-esp-data.php";
// Keep this API Key value to be compatible with the PHP code provided in the project page.
// If you change the apiKeyValue value, the PHP file /post-esp-data.php also needs to have the same key
String apiKeyValue = "xPmAT5Ab3j7F6";
String sensorName = "MPXDIFF";
String sensorLocation = "San Diego";
void setup() {
Serial.begin(9600); //enable Serial Monitor
SUART.begin(9600); //enable SUART Port
WiFi.begin(ssid, password);
Serial.println("Connecting");
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to WiFi network with IP Address: ");
Serial.println(WiFi.localIP());
Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
Serial.println("Connected to Firebase");
timeClient.begin();
}
void loop() {
timeClient.update();
const int capacity = JSON_OBJECT_SIZE(1);
StaticJsonBuffer<capacity> jb;
JsonObject& doc = jb.createObject();
doc["type"] = "request";
String message = "";
String test = "";
boolean messageReady = false;
doc.printTo(test);
Serial.println(test);
doc.printTo(Serial);
doc.printTo(SUART);
SUART.println(test);
while(messageReady == false) { // blocking but that's ok
if(SUART.available()) {
message = SUART.readString();
Serial.println("message was received");
Serial.println(message);
test_2 = message.endsWith(last_char);
Serial.println(test_2);
if (!(test_2)){
return;
}
messageReady = true;
}
}
send_data(message);
delay(3000);
}
//======================================
void send_data(String message) {
const int capacity = JSON_ARRAY_SIZE(10)+ 15*JSON_OBJECT_SIZE(7);
StaticJsonBuffer<capacity> jb;
JsonArray& doc = jb.parseArray(message);
if(WiFi.status()== WL_CONNECTED){
String time_now = timeClient.getFormattedTime();
Serial.println(time_now);
//doc["send_time"] = time_now;
String message_fb = "";
doc.printTo(message_fb);
Firebase.pushString(time_now, message_fb);
Serial.println(message_fb);
if(Firebase.success()){
Serial.println("The push was successful");
}
else
{
Serial.println("The push to Firebase failed");
}
}}
#include "Queue.h"
Queue<char> queue = Queue<char>(5);
void setup() {
Serial.begin(9600);
}
void loop() {
queue.push("1");
Serial.print(millis() / 1000);
Serial.print(": ");
int count = queue.count();
if (count > 0) {
Serial.print("Found ");
Serial.print(count);
Serial.print(" items.. '");
Serial.print(int(queue.pop()));
Serial.print("' is the oldest. We are ");
Serial.print(queue.front());
Serial.print(" in front and ");
Serial.print(queue.back());
Serial.print(" in back. Next is.. '");
Serial.print(queue.peek());
Serial.println("'.");
} else {
Serial.println("Nothing to process...");
}
delay(2000);
}
#include <Guino.h>
#include <Servo.h>
Servo servoright;
int pos = 0;
// ==== Analog Pins =====
float potpinIE_ratio = 0;
int potpinTidVol = 1;
int potpinBPM = 5;
int pinguage_mask = 4;
int pinguage_expiration = 3;
int pinguage_diff = 2;
// ==== Sensor Offset =====
const float guageSensorOffset = 41;
const float pressureDiffSensorOffset = 41;
// ===== Other vars ======
float valIE_ratio;
float valTidVol;
float valBPM;
float separation;
float sensorvalue;
float pressure_mask;
float pressure_expiration;
float pressure_diff;
int display_IE_ratio;
int display_valBPM;
int display_valTidVol;
int display_sensorvalue_cmh2o;
int display_sensorvalue_gp_cmh2o;
void setup()
{
servoright.attach(9); // attaches the servo on pin 9 to the servo object
Serial.begin(9600);
}
void loop()
{
// ** Main update call for the guino
//guino_update();
// ========== Read all analog input =============
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
valIE_ratio = analogRead(potpinIE_ratio); // reads the value of the potentiometer (value between 0 and 1023)
valIE_ratio = map(valIE_ratio, 0, 1023, 1.00, 4.00); // scale it to use it with the servo (value between 0 and 180)
valTidVol = analogRead(potpinTidVol); // reads the value of the potentiometer (value between 0 and 1023)
valTidVol = map(valTidVol, 0, 1023, 40.00, 90.00); // scale it to use it with the servo (value between 0 and 180)
valBPM = analogRead(potpinBPM); // reads the value of the potentiometer (value between 0 and 1023)
valBPM = map(valBPM, 0, 1023, 8.00, 30.00); // scale it to use it with the servo (value between 0 and 180)
// ====== Copmute respiration separation time based on pot inputs ==========
separation = 60/valBPM - (1+valIE_ratio);
if (separation < 0)
{
valIE_ratio = 60/valBPM - 1;
separation = 60/valBPM - (1+valIE_ratio);
}
// ========= Servo a-Clockwise motion =============
for(pos = 30; pos <= valTidVol+30; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
servoright.write(pos);
delay(1000/valTidVol);
// ============ Update pressure values =========
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
Serial.println(pressure_mask);
Serial.println(pressure_diff);
Serial.println(pressure_expiration);
}
delay(15);
// ========= Servo Clockwise motion ============
for(pos = valTidVol+30; pos>=30; pos-=1) // goes from 180 degrees to 0 degrees
{
servoright.write(pos);
delay(1000*valIE_ratio/valTidVol);
// ============ Update pressure values =========
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
Serial.println(pressure_mask);
Serial.println(pressure_diff);
Serial.println(pressure_expiration);
}
delay(separation*1000);
}
/*
* Queue.h
*
* By Steven de Salas
*
* Defines a templated (generic) class for a queue of things.
* Used for Arduino projects, just #include "Queue.h" and add this file via the IDE.
*
* Examples:
*
* Queue<char> queue(10); // Max 10 chars in this queue
* queue.push('H');
* queue.push('e');
* queue.count(); // 2
* queue.push('l');
* queue.push('l');
* queue.count(); // 4
* Serial.print(queue.pop()); // H
* Serial.print(queue.pop()); // e
* queue.count(); // 2
* queue.push('o');
* queue.count(); // 3
* Serial.print(queue.pop()); // l
* Serial.print(queue.pop()); // l
* Serial.print(queue.pop()); // o
*
* struct Point { int x; int y; }
* Queue<Point> points(5);
* points.push(Point{2,4});
* points.push(Point{5,0});
* points.count(); // 2
*
*/
#ifndef QUEUE_H
#define QUEUE_H
#include <Arduino.h>
template<class T>
class Queue {
private:
int _front, _back, _count;
T *_data;
int _maxitems;
public:
Queue(int maxitems = 256) {
_front = 0;
_back = 0;
_count = 0;
_maxitems = maxitems;
_data = new T[maxitems + 1];
}
~Queue() {
delete[] _data;
}
inline int count();
inline int front();
inline int back();
void push(const T &item);
T peek();
T pop();
void clear();
};
template<class T>
inline int Queue<T>::count()
{
return _count;
}
template<class T>
inline int Queue<T>::front()
{
return _front;
}
template<class T>
inline int Queue<T>::back()
{
return _back;
}
template<class T>
void Queue<T>::push(const T &item)
{
if(_count < _maxitems) { // Drops out when full
_data[_back++]=item;
++_count;
// Check wrap around
if (_back > _maxitems)
_back -= (_maxitems + 1);
}
}
template<class T>
T Queue<T>::pop() {
if(_count <= 0) return T(); // Returns empty
else {
T result = _data[_front];
_front++;
--_count;
// Check wrap around
if (_front > _maxitems)
_front -= (_maxitems + 1);
return result;
}
}
template<class T>
T Queue<T>::peek() {
if(_count <= 0) return T(); // Returns empty
else return _data[_front];
}
template<class T>
void Queue<T>::clear()
{
_front = _back;
_count = 0;
}
#endif
#include <Servo.h>
#include<SoftwareSerial.h>
#include <ArduinoJson.h>
#include <SPI.h>
#include <SD.h>
#include <Nextion.h>
// ==== Analog Pins =====
float potpinIE_ratio = 0;
int potpinTidVol = 1;
int potpinBPM = 5;
int pinguage_mask = 4;
int pinguage_expiration = 3;
int pinguage_diff = 2;
// ===== Other vars ======
float check_value;
float IE_ratio;
float TidVol;
float BPM;
float separation;
float sensorvalue;
//float pressure_mask;
//float pressure_expiration;
//float pressure_diff;
//====== Serial COnnection with NODEMCU =====
SoftwareSerial SUART(2, 3); //SRX=Dpin-2; STX-DPin-3
//====== LCD Variables ==============
int id_1 = 5;
int ch = 0;
int id_2 = 4;
int id_3 = 3;
String ad = "add ";
static char buffer[10] = {};
static char buffer_2[10] = {};
static char buffer_3[10] = {};
static char buffer_mode[10] = {};
String set_mode = "ACV";
NexText t_ie_ratio = NexText(0, 8, "t_ie_ratio");
NexText t_bpm = NexText(0, 9, "t_bpm");
NexText t_tidvol = NexText(0, 10, "t_tidvol");
NexText t_mode = NexText(0, 12, "t_mode");
NexButton b0 = NexButton(0, 2, "b0");
NexButton b1 = NexButton(0, 3, "b1");
float pressure_mask = 4.55;
float pressure_diff = 5.55;
float pressure_expiration = 6.55;
NexTouch *nex_listen_list[] = {&b0, &b1, NULL};
void b0PopCallback(void *ptr) {
set_mode = "ACV";
//set_mode.toCharArray(buffer_mode,5);
t_mode.setText(set_mode.c_str());
}
//Button b1 component popcallback function
// When OFF button is released the LED turns OFF and the state text changes
void b1PopCallback(void *ptr) {
set_mode = "SIMV";
t_mode.setText(set_mode.c_str());
}
// ==== Sensor Offset =====
const float guageSensorOffset = 41;
const float pressureDiffSensorOffset = 41;
//===== Variables =====
Servo servoright;
int pos = 0;
//======= SD Card File ===========
File myFile;
String mode = "";
void setup() {
Serial.begin(9600);
SUART.begin(9600);
servoright.attach(9);
pinMode(10, OUTPUT);
if (!SD.begin(4)) {
Serial.println("initialization failed!");
return;
}
Serial.println("SD Card Initialization done.");
nexInit();
b0.attachPop(b0PopCallback, &b0);
b1.attachPop(b1PopCallback, &b1);
}
void loop() {
// put your main code here, to run repeatedly:
myFile = SD.open("example.txt", FILE_WRITE);
if(myFile){
Serial.println("The file is open");
myFile.close();
}
else
{
Serial.println("Error opening this file");
myFile.close();
}
// Run ventilator
send_to_screen_values(BPM, IE_ratio, TidVol);
if (set_mode == "ACV") {
myFile = SD.open("example.txt", FILE_WRITE);
acv_mode();
myFile.close();
}
else if (set_mode == "SIMV") {
myFile = SD.open("example.txt", FILE_WRITE);
simv_mode();
myFile.close();
}
}
void acv_mode()
{
float IE_ratio;
float TidVol;
float BPM;
float per_breath_time;
float per_inspiration_time;
float per_expiration_time;
float human_effort;
float separation;
uint32_t cycleEndTime;
bool firstRun = true;
mode = "ACV";
// Fetch all potentiometer values
IE_ratio = map(analogRead(potpinIE_ratio), 0, 1023, 1.00, 4.00);
TidVol = map(analogRead(potpinTidVol), 0, 1023, 40.00, 90.00);
BPM = map(analogRead(potpinBPM), 0, 1023, 8.00, 30.00);
separation = (60 / BPM - (1 + IE_ratio));
if (separation < 0)
{ IE_ratio = 60 / BPM - 1;
separation = 60 / BPM - (1 + IE_ratio);
}
// Fetch pressure sensor values
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset) * 10.1972 / 92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset) * 10.1972 / 92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset) * 10.1972 / 92;
// Initiate the cycle
if (firstRun)
{
inspiration(TidVol, mode);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio, mode);
firstRun = false;
}
// ========= Identify trigger and initiate the cycle =============
if (millis() - cycleEndTime >= (uint32_t)separation * 1000 || pressure_mask < -1)
{
inspiration(TidVol, mode);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio, mode);
}
send_to_screen_values(BPM, IE_ratio, TidVol);
}
void inspiration(float TidVol, String mode)
{
int pos;
for (pos = 30; pos <= TidVol + 30; pos += 2) // goes from 0 degrees to 180 degrees
{
servoright.write(pos);
delay(1000 / TidVol);
// ============ Update pressure values =========
//pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
//pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
//pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
String data = mode + "," + String(pressure_mask) + "," + String(pressure_diff) + "," + String(pressure_expiration) + ";";
myFile.println(data);
send_to_screen_graph(pressure_mask, pressure_expiration, pressure_diff);
//send_to_screen_values(BPM, IE_ratio, TidVol);
//nexLoop(nex_listen_list);
}
transmit(BPM, IE_ratio, pressure_mask, pressure_expiration, TidVol, pressure_diff);
}
// =====================
// Expiration Function
// =====================
uint32_t expiration(float TidVol, float IE_ratio, String mode)
{
for (pos = TidVol + 30; pos >= 30; pos -= 2) // goes from 180 degrees to 0 degrees
{
//nexLoop(nex_listen_list);
servoright.write(pos);
delay(1000 * IE_ratio / TidVol);
// ============ Update pressure values =========
//pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
//pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
//pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
//Serial.println("Here inside inspiration");
String data = mode + "," + String(pressure_mask) + "," + String(pressure_diff) + "," + String(pressure_expiration) + ";";
myFile.println(data);
send_to_screen_graph(pressure_mask, pressure_expiration, pressure_diff);
//send_to_screen_values(BPM, IE_ratio, TidVol);
}
transmit(BPM, IE_ratio, pressure_mask, pressure_expiration, TidVol, pressure_diff);
return millis();
}
void simv_mode()
{
uint32_t cycleEndTime;
bool firstRun = true;
mode = "SIMV";
// Fetch all potentiometer values
IE_ratio = map(analogRead(potpinIE_ratio), 0, 1023, 1.00, 4.00);
TidVol = map(analogRead(potpinTidVol), 0, 1023, 40.00, 90.00);
BPM = map(analogRead(potpinBPM), 0, 1023, 8.00, 30.00);
separation = (60 / BPM - (1 + IE_ratio));
if (separation < 0)
{ IE_ratio = 60 / BPM - 1;
separation = 60 / BPM - (1 + IE_ratio);
}
// Fetch pressure sensor values
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset) * 10.1972 / 92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset) * 10.1972 / 92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset) * 10.1972 / 92;
// Initiate the cycle
if (firstRun)
{
pressure_mask = average_pressure_mask();
cycleEndTime = simv_logic(pressure_mask, TidVol, IE_ratio, mode);
firstRun = false;
}
// ========= Identify trigger and initiate the cycle =============
if (millis() - cycleEndTime >= (uint32_t)separation * 1000 || average_pressure_mask() < -1)
{
pressure_mask = average_pressure_mask();
cycleEndTime = simv_logic(pressure_mask, TidVol, IE_ratio, mode);
}
send_to_screen_values(BPM, IE_ratio, TidVol);
}
// =======================
// SIMV Logic Function
// =======================
uint32_t simv_logic(float pressure_mask, float TidVol, float IE_ratio, String mode)
{
uint32_t cycleEndTime;
pressure_mask = int(floor(pressure_mask));
switch (int(pressure_mask)) {
case -6:
case -5:
case -4:
TidVol = TidVol * 0.25;
inspiration(TidVol, mode);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio, mode);
break;
case -3:
TidVol = TidVol * 0.50;
inspiration(TidVol, mode);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio, mode);
break;
case -2:
TidVol = TidVol * 0.75;
inspiration(TidVol, mode);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio, mode);
break;
case -1:
TidVol = TidVol * 0.75;
inspiration(TidVol, mode);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio, mode);
break;
default:
inspiration(TidVol, mode);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio, mode);
break;
}
return cycleEndTime;
}
// =======================
// Average Pressure Function
// =======================
float average_pressure_mask()
{
pressure_mask = 0;
for (int i = 0; i < 5; i++)
{
pressure_mask = pressure_mask + (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset) * 10.1972 / 92;
delay(3);
}
return (pressure_mask/5);
}
// =====================
// Print to Screen
// =====================
void send_to_screen_graph(float pressure_mask, float pressure_expiration, float pressure_diff) {
float p_mask = map(pressure_mask, 5.00, 20.00, 0, 255);
float p_expiration = map(pressure_mask, 5.00, 20.00, 0, 255);
float p_diff = map(pressure_mask, 5.00, 20.00, 0, 255);
String to_send_p_mask = ad + id_1 + "," + ch + "," + int(p_mask);
print_screen(to_send_p_mask);
String to_send_p_diff = ad + id_2 + "," + ch + "," + int(p_diff);
print_screen(to_send_p_diff);
String to_send_p_exp = ad + id_3 + "," + ch + "," + int(p_expiration);
print_screen(to_send_p_exp);
}
void send_to_screen_values(float BPM, float IE_ratio, float TidVol) {
dtostrf(BPM, 6, 2, buffer);
t_bpm.setText(buffer);
dtostrf(IE_ratio, 6, 2, buffer_2);
t_ie_ratio.setText(buffer_2);
dtostrf(TidVol, 6, 2, buffer_3);
t_tidvol.setText(buffer_3);
t_mode.setText(set_mode.c_str());
}
void print_screen(String to_send) {
Serial.print(to_send);
Serial.print("\xFF\xFF\xFF");
}
// =====================
// Transmit to DB
// =====================
void transmit(float BPM, float IE_ratio, float pressure_mask, float pressure_expiration, float TidVol, float pressure_diff){
Serial.println("Inside the transmit function");
String message = "";
boolean messageReady = false;
while(SUART.available()) {
message = SUART.readString();
Serial.println(message);
messageReady = true;
}
if(messageReady) {
// The only messages we'll parse will be formatted in JSON
const int capacity_data = JSON_OBJECT_SIZE(7);
StaticJsonBuffer<capacity_data> jb_data;
JsonObject& doc = jb_data.createObject();
doc["type"].set("response");
doc["BPM"].set(BPM);
doc["IE_ratio"].set(IE_ratio);
doc["pressure_mask"].set(pressure_mask);
doc["pressure_expiration"].set(pressure_expiration);
doc["TidVol"].set(TidVol);
doc["pressure_diff"].set(pressure_diff);
doc.printTo(SUART);
doc.printTo(Serial);
}
}
#ifdef ESP32
#include <WiFi.h>
#include <HTTPClient.h>
#else
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#endif
#include <ArduinoJson.h>
#include <Wire.h>
#include <FirebaseArduino.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include<SoftwareSerial.h>
SoftwareSerial SUART(4, 5); //SRX=Dpin-D2; STX-DPin-D1
#define FIREBASE_HOST "respire-447da.firebaseio.com"
#define FIREBASE_AUTH "vsloiSErdIEyQMV6ydzwaELOPVSP5dPqiOobAURm"
#define NTP_OFFSET 60 * 60 // In seconds
#define NTP_INTERVAL 60 * 1000 // In miliseconds
#define NTP_ADDRESS "europe.pool.ntp.org"
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, NTP_ADDRESS, NTP_OFFSET, NTP_INTERVAL);
//=======================================
unsigned long time_1;
bool test_2;
String last_char = "]";
time_t start_time;
//const byte numChars = 300;
//char receivedChars[numChars]; // an array to store the received data
// Replace with your network credentials
const char* ssid = "NETGEAR28";
const char* password = "bluesky089";
// REPLACE with your Domain name and URL path or IP address with path
const char* serverName = "http://respire.000webhostapp.com/post-esp-data.php";
// Keep this API Key value to be compatible with the PHP code provided in the project page.
// If you change the apiKeyValue value, the PHP file /post-esp-data.php also needs to have the same key
String apiKeyValue = "xPmAT5Ab3j7F6";
String sensorName = "MPXDIFF";
String sensorLocation = "San Diego";
boolean newData = false;
void setup() {
Serial.begin(9600); //enable Serial Monitor
SUART.begin(9600); //enable SUART Port
WiFi.begin(ssid, password);
Serial.println("Connecting");
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to WiFi network with IP Address: ");
Serial.println(WiFi.localIP());
Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
Firebase.setFloat("test_number", 42.0);
Serial.println("Connected to Firebase");
timeClient.begin();
}
void loop() {
timeClient.update();
const int capacity = JSON_OBJECT_SIZE(1);
StaticJsonBuffer<capacity> jb;
JsonObject& doc = jb.createObject();
doc["type"] = "request";
String message = "";
String test = "";
boolean messageReady = false;
doc.printTo(SUART);
start_time = millis();
while(messageReady == false) { // blocking but that's ok
message = SUART.readString();
Serial.println("message was received");
if(message == ""){
return;
}
messageReady = true;
}
send_data(message);
jb.clear();
delay(1000);
}
//======================================
void send_data(String message) {
if(WiFi.status()== WL_CONNECTED){
String time_now = timeClient.getFormattedTime();
Firebase.setString(time_now, message);
Serial.println(message);
Serial.println("The string was pushed");
}}
#include <Servo.h>
Servo servoright;
int pos = 0;
// ==== Analog Pins =====
float potpinIE_ratio = 0;
int potpinTidVol = 1;
int potpinBPM = 5;
int pinguage_mask = 4;
int pinguage_expiration = 3;
int pinguage_diff = 2;
// ==== Analog Pins =====
int inPin = 2;
// ==== Sensor Offset =====
const float guageSensorOffset = 41;
const float pressureDiffSensorOffset = 41;
// ===== Other vars ======
float valIE_ratio;
float valTidVol;
float valBPM;
float separation;
float sensorvalue;
float pressure_mask;
float pressure_expiration;
float pressure_diff;
int display_IE_ratio;
int display_valBPM;
int display_valTidVol;
int display_sensorvalue_cmh2o;
int display_sensorvalue_gp_cmh2o;
// ======= Mode changing vars =========
int state = HIGH; // the current state of the output pin
int reading; // the current reading from the input pin
int previous = LOW; // the previous reading from the input pin
long time = 0; // the last time the output pin was toggled
long debounce = 200; // the debounce time, increase if the output flickers
void setup()
{
servoright.attach(9); // attaches the servo on pin 9 to the servo object
Serial.begin(9600);
}
void loop()
{
// ** Main update call for the guino
//guino_update();
// ========== Read all analog input & Detecting Mode Settings =============
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
if (reading == HIGH && previous == LOW && millis() - time > debounce) {
if (state == HIGH){
valIE_ratio = analogRead(potpinIE_ratio); // reads the value of the potentiometer (value between 0 and 1023)
valIE_ratio = map(valIE_ratio, 0, 1023, 1.00, 4.00); // scale it to use it with the servo (value between 0 and 180)
valTidVol = analogRead(potpinTidVol); // reads the value of the potentiometer (value between 0 and 1023)
valTidVol = map(valTidVol, 0, 1023, 40.00, 90.00); // scale it to use it with the servo (value between 0 and 180)
valBPM = analogRead(potpinBPM); // reads the value of the potentiometer (value between 0 and 1023)
valBPM = map(valBPM, 0, 1023, 8.00, 30.00); // scale it to use it with the servo (value between 0 and 180)
state = LOW;
}
else {
valIE_ratio = 2;
valTidVol = 50;
valBPM = 15;
state = HIGH;
}
}
// ====== Copmute respiration separation time based on pot inputs ==========
separation = 60/valBPM - (1+valIE_ratio);
if (separation < 0)
{
valIE_ratio = 60/valBPM - 1;
separation = 60/valBPM - (1+valIE_ratio);
}
// ========= Servo a-Clockwise motion =============
for(pos = 30; pos <= valTidVol+30; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
servoright.write(pos);
delay(1000/valTidVol);
// ============ Update pressure values =========
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
Serial.println(pressure_mask);
Serial.println(pressure_diff);
Serial.println(pressure_expiration);
}
delay(15);
// ========= Servo Clockwise motion ============
for(pos = valTidVol+30; pos>=30; pos-=1) // goes from 180 degrees to 0 degrees
{
servoright.write(pos);
delay(1000*valIE_ratio/valTidVol);
// ============ Update pressure values =========
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
Serial.println(pressure_mask);
Serial.println(pressure_diff);
Serial.println(pressure_expiration);
}
delay(separation*1000);
previous = reading;
}
#ifdef ESP32
#include <WiFi.h>
#include <HTTPClient.h>
#else
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#endif
#include <ArduinoJson.h>
#include <Wire.h>
#include <FirebaseArduino.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include<SoftwareSerial.h>
SoftwareSerial SUART(4, 5); //SRX=Dpin-D2; STX-DPin-D1
#define FIREBASE_HOST "respire-447da.firebaseio.com"
#define FIREBASE_AUTH "vsloiSErdIEyQMV6ydzwaELOPVSP5dPqiOobAURm"
#define NTP_OFFSET 60 * 60 // In seconds
#define NTP_INTERVAL 60 * 1000 // In miliseconds
#define NTP_ADDRESS "europe.pool.ntp.org"
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, NTP_ADDRESS, NTP_OFFSET, NTP_INTERVAL);
//=======================================
unsigned long time_1;
bool test_2;
String last_char = "}";
time_t t;
// Replace with your network credentials
const char* ssid = "NETGEAR43";
const char* password = "smilingnest196";
// REPLACE with your Domain name and URL path or IP address with path
const char* serverName = "http://respire.000webhostapp.com/post-esp-data.php";
// Keep this API Key value to be compatible with the PHP code provided in the project page.
// If you change the apiKeyValue value, the PHP file /post-esp-data.php also needs to have the same key
String apiKeyValue = "xPmAT5Ab3j7F6";
String sensorName = "MPXDIFF";
String sensorLocation = "San Diego";
void setup() {
Serial.begin(9600); //enable Serial Monitor
SUART.begin(9600); //enable SUART Port
WiFi.begin(ssid, password);
Serial.println("Connecting");
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to WiFi network with IP Address: ");
Serial.println(WiFi.localIP());
Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
Serial.println("Connected to Firebase");
timeClient.begin();
}
void loop() {
timeClient.update();
const int capacity = JSON_OBJECT_SIZE(1);
StaticJsonBuffer<capacity> jb;
JsonObject& doc = jb.createObject();
doc["type"] = "request";
String message = "";
String test = "";
boolean messageReady = false;
doc.printTo(test);
Serial.println(test);
doc.printTo(Serial);
doc.printTo(SUART);
SUART.println(test);
while(messageReady == false) { // blocking but that's ok
if(SUART.available()) {
message = SUART.readString();
Serial.println("message was received");
Serial.println(message);
test_2 = message.endsWith(last_char);
Serial.println(test_2);
if (!(test_2)){
return;
}
messageReady = true;
}
}
send_data(message);
delay(3000);
}
//======================================
void send_data(String message) {
if(WiFi.status()== WL_CONNECTED){
t = now();
String time_now = String(t);
Serial.println(time_now);
Firebase.pushString(time_now, message);
if(Firebase.success()){
Serial.println("The push was successful");
}
else
{
Serial.println("The push to Firebase failed");
}
}}
#include <Servo.h>
#include<SoftwareSerial.h>
#include <ArduinoJson.h>
#include <SPI.h>
#include <SD.h>
#include <Nextion.h>
//======== Information about SD Card ====
/*
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4
*/
//====== Serial COnnection with NODEMCU =====
SoftwareSerial SUART(2, 3); //SRX=Dpin-2; STX-DPin-3
//====== LCD Variables ==============
int id_1 = 1;
int ch = 0;
int id_2 = 8;
int id_3 = 9;
String ad = "add ";
char buffer[100] = {0};
char buffer_2[100] = {0};
char buffer_3[100] = {0};
NexText t0 = NexText(0, 2, "t0");
NexText t1 = NexText(0, 3, "t0");
NexText t2 = NexText(0, 4, "t2");
//===== Variables =====
Servo servoright;
int pos = 0;
//======= SD Card File ===========
File ventilator_data;
// ==== Analog Pins =====
float potpinIE_ratio = 0;
int potpinTidVol = 1;
int potpinBPM = 5;
int pinguage_mask = 4;
int pinguage_expiration = 3;
int pinguage_diff = 2;
// ==== Analog Pins ====
int inPin = 4;
// ==== Sensor Offset =====
const float guageSensorOffset = 41;
const float pressureDiffSensorOffset = 41;
// ===== Other vars ======
float check_value;
float IE_ratio;
float TidVol;
float BPM;
float separation;
float sensorvalue;
float pressure_mask;
float pressure_expiration;
float pressure_diff;
int display_IE_ratio;
int display_BPM;
int display_TidVol;
int display_sensorvalue_cmh2o;
int display_sensorvalue_gp_cmh2o;
// ======= Mode changing vars =========
int state = HIGH; // the current state of the output pin
int previous = LOW; // the previous reading from the input pin
long t_time = 0; // the last time the output pin was toggled
long debounce = 200; // the debounce time, increase if the output flickers
String mode = "";
void setup()
{
servoright.attach(9); // attaches the servo on pin 9 to the servo object
Serial.begin(9600);
SUART.begin(9600); //enable SUART Port for communication with NODEMCU
pinMode(10,OUTPUT);
if (!SD.begin(4)) {
Serial.println("initialization failed!");
return;
}
Serial.println("SD Card Initialization done.");
ventilator_data = SD.open("ventilator_data.txt",FILE_WRITE);
}
void loop()
{
if (digitalRead(inPin) == LOW)
{
while(digitalRead(inPin)==LOW)
{
simv_mode();
}
}
else
{ while(digitalRead(inPin) == HIGH)
{
acv_mode();
}
}
}
// =======================
// ACV MODE Function
// =======================
void acv_mode()
{
float IE_ratio;
float TidVol;
float BPM;
float per_breath_time;
float per_inspiration_time;
float per_expiration_time;
float human_effort;
float separation;
uint32_t cycleEndTime;
bool firstRun = true;
mode = "ACV";
while(digitalRead(inPin) == HIGH)
{
// Fetch all potentiometer values
IE_ratio = map(analogRead(potpinIE_ratio), 0, 1023, 1.00, 4.00);
TidVol = map(analogRead(potpinTidVol), 0, 1023, 40.00, 90.00);
BPM = map(analogRead(potpinBPM), 0, 1023, 8.00, 30.00);
separation = (60/BPM - (1+IE_ratio));
if (separation < 0)
{ IE_ratio = 60/BPM - 1;
separation = 60/BPM - (1+IE_ratio);
}
// Fetch pressure sensor values
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
// Initiate the cycle
if(firstRun)
{
inspiration(TidVol, mode);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio, mode);
firstRun = false;
}
// ========= Identify trigger and initiate the cycle =============
if(millis() - cycleEndTime >= (uint32_t)separation*1000 || pressure_mask < -1)
{
inspiration(TidVol, mode);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio, mode);
}
transmit(BPM, IE_ratio, pressure_mask, pressure_expiration, TidVol, pressure_diff);
send_to_screen(BPM, IE_ratio, pressure_mask, pressure_expiration, TidVol, pressure_diff);
}
}
// =======================
// SIMV Logic Function
// =======================
uint32_t simv_logic(float pressure_mask, float TidVol, float IE_ratio, String mode)
{
uint32_t cycleEndTime;
pressure_mask = int(floor(pressure_mask));
switch(int(pressure_mask)){
case -6:
case -5:
case -4:
TidVol = TidVol*0.25;
inspiration(TidVol, mode);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio, mode);
break;
case -3:
TidVol = TidVol*0.50;
inspiration(TidVol, mode);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio, mode);
break;
case -2:
TidVol = TidVol*0.75;
inspiration(TidVol, mode);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio, mode);
break;
case -1:
TidVol = TidVol*0.75;
inspiration(TidVol, mode);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio, mode);
break;
default:
inspiration(TidVol, mode);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio, mode);
break;
}
return cycleEndTime;
}
// =======================
// SIMV MODE Function
// =======================
void simv_mode()
{
uint32_t cycleEndTime;
bool firstRun = true;
mode = "SIMV";
while(digitalRead(inPin) == LOW)
{
// Fetch all potentiometer values
IE_ratio = map(analogRead(potpinIE_ratio), 0, 1023, 1.00, 4.00);
TidVol = map(analogRead(potpinTidVol), 0, 1023, 40.00, 90.00);
BPM = map(analogRead(potpinBPM), 0, 1023, 8.00, 30.00);
separation = (60/BPM - (1+IE_ratio));
if (separation < 0)
{ IE_ratio = 60/BPM - 1;
separation = 60/BPM - (1+IE_ratio);}
// Fetch pressure sensor values
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
// Initiate the cycle
if(firstRun)
{
pressure_mask = average_pressure_mask();
cycleEndTime = simv_logic(pressure_mask, TidVol, IE_ratio, mode);
firstRun = false;
}
// ========= Identify trigger and initiate the cycle =============
if(millis() - cycleEndTime >= (uint32_t)separation*1000 || average_pressure_mask() < -1)
{
pressure_mask = average_pressure_mask();
cycleEndTime = simv_logic(pressure_mask, TidVol, IE_ratio, mode);
}
transmit(BPM, IE_ratio, pressure_mask, pressure_expiration, TidVol, pressure_diff);
send_to_screen(BPM, IE_ratio, pressure_mask, pressure_expiration, TidVol, pressure_diff);
}
}
// =======================
// Average Pressure Function
// =======================
float average_pressure_mask()
{
pressure_mask = 0;
for(int i=0;i<5;i++)
{
pressure_mask = pressure_mask + (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
delay(3);
}
return (pressure_mask/5);
}
// =======================
// Inspiration Function
// =======================
void inspiration(float TidVol, String mode)
{ int pos;
for(pos = 30; pos <= TidVol+30; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
servoright.write(pos);
delay(1000/TidVol);
// ============ Update pressure values =========
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
String data = mode + "," + pressure_mask + "," + pressure_diff + "," + pressure_expiration + ";";
ventilator_data.println(data);
}
}
// =====================
// Expiration Function
// =====================
uint32_t expiration(float TidVol, float IE_ratio, String mode)
{
for(pos = TidVol+30; pos>=30; pos-=1) // goes from 180 degrees to 0 degrees
{
servoright.write(pos);
delay(1000*IE_ratio/TidVol);
// ============ Update pressure values =========
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
String data = mode + "," + pressure_mask + "," + pressure_diff + "," + pressure_expiration + ";";
ventilator_data.println(data);
}
return millis();
}
// =====================
// Transmit to DB
// =====================
void transmit(float BPM, float IE_ratio, float pressure_mask, float pressure_expiration, float TidVol, float pressure_diff){
String message = "";
boolean messageReady = false;
while(SUART.available()) {
message = SUART.readString();
Serial.println(message);
messageReady = true;
}
if(messageReady) {
// The only messages we'll parse will be formatted in JSON
const int capacity = JSON_OBJECT_SIZE(7);
StaticJsonBuffer<capacity> jb;
JsonObject& doc = jb.parseObject(message);
//DynamicJsonDocument doc(1024); // ArduinoJson version 6+
// Attempt to deserialize the message
if(!(doc.success())){
Serial.println("Doc conversion failed");
messageReady = false;
doc["type"] = "incorrect";
}
if(doc["type"] == "request") {
doc["type"] = "response";
doc["BPM"] = BPM;
doc["IE_ratio"] = IE_ratio;
doc["pressure_mask"] = pressure_mask;
doc["pressure_expiration"] = pressure_expiration;
doc["TidVol"] = TidVol;
doc["pressure_diff"] = pressure_diff;
doc.printTo(SUART);
}
}
}
// =====================
// Print to Screen
// =====================
void send_to_screen(float BPM, float IE_ratio, float pressure_mask, float pressure_expiration, float TidVol, float pressure_diff){
float p_mask = map(pressure_mask, 5.00, 20.00, 0, 255);
float p_expiration = map(pressure_mask, 5.00, 20.00, 0, 255);
float p_diff = map(pressure_mask, 5.00, 20.00, 0, 255);
String to_send_p_mask = ad + id_1 + "," + ch + "," + int(p_mask);
print_screen(to_send_p_mask);
String to_send_p_diff = ad + id_2 + "," + ch + "," + int(p_diff);
print_screen(to_send_p_diff);
String to_send_p_exp = ad + id_3 + "," + ch + "," + int(p_expiration);
print_screen(to_send_p_exp);
dtostrf(BPM, 6, 2, buffer);
t0.setText(buffer);
dtostrf(IE_ratio,6,2,buffer_2);
t1.setText(buffer_2);
dtostrf(TidVol,6,2,buffer_3);
t2.setText(buffer_3);
}
void print_screen(String to_send){
Serial.print(to_send);
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
}
#include <Guino.h>
#include <Servo.h>
#include<SoftwareSerial.h>
#include <ArduinoJson.h>
//====== Serial COnnection with NODEMCU =====
SoftwareSerial SUART(2, 3); //SRX=Dpin-2; STX-DPin-3
Servo servoright;
int pos = 0;
// ==== Analog Pins =====
float potpinIE_ratio = 0;
int potpinTidVol = 1;
int potpinBPM = 5;
int pinguage_mask = 4;
int pinguage_expiration = 3;
int pinguage_diff = 2;
// ==== Analog Pins ====
int inPin = 4;
// ==== Sensor Offset =====
const float guageSensorOffset = 41;
const float pressureDiffSensorOffset = 41;
// ===== Other vars ======
float check_value;
float IE_ratio;
float TidVol;
float BPM;
float separation;
float sensorvalue;
float pressure_mask;
float pressure_expiration;
float pressure_diff;
int display_IE_ratio;
int display_BPM;
int display_TidVol;
int display_sensorvalue_cmh2o;
int display_sensorvalue_gp_cmh2o;
// ======= Mode changing vars =========
int state = HIGH; // the current state of the output pin
int mode; // the current reading from the input pin
int previous = LOW; // the previous reading from the input pin
long t_time = 0; // the last time the output pin was toggled
long debounce = 200; // the debounce time, increase if the output flickers
void setup()
{
servoright.attach(9); // attaches the servo on pin 9 to the servo object
Serial.begin(9600);
SUART.begin(9600); //enable SUART Port for communication with NODEMCU
// attachInterrupt(0, pin_ISR, CHANGE);
}
void loop()
{
if (digitalRead(inPin) == LOW)
{
while(digitalRead(inPin)==LOW)
{
simv_mode();
}
}
else
{ while(digitalRead(inPin) == HIGH)
{
acv_mode();
}
}
}
// =======================
// ACV MODE Function
// =======================
void acv_mode()
{
float IE_ratio;
float TidVol;
float BPM;
float per_breath_time;
float per_inspiration_time;
float per_expiration_time;
float human_effort;
float separation;
uint32_t cycleEndTime;
bool firstRun = true;
while(digitalRead(inPin) == HIGH)
{
// Fetch all potentiometer values
IE_ratio = map(analogRead(potpinIE_ratio), 0, 1023, 1.00, 4.00);
TidVol = map(analogRead(potpinTidVol), 0, 1023, 40.00, 90.00);
BPM = map(analogRead(potpinBPM), 0, 1023, 8.00, 30.00);
separation = (60/BPM - (1+IE_ratio));
if (separation < 0)
{ IE_ratio = 60/BPM - 1;
separation = 60/BPM - (1+IE_ratio);
}
// Fetch pressure sensor values
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
// Initiate the cycle
if(firstRun)
{
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
firstRun = false;
}
// ========= Identify trigger and initiate the cycle =============
if(millis() - cycleEndTime >= (uint32_t)separation*1000 || pressure_mask < -1)
{
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
}
transmit(BPM, IE_ratio, pressure_mask, pressure_expiration, TidVol, pressure_diff);
}
}
// =======================
// SIMV Logic Function
// =======================
uint32_t simv_logic(float pressure_mask, float TidVol, float IE_ratio)
{
uint32_t cycleEndTime;
pressure_mask = int(floor(pressure_mask));
switch(int(pressure_mask)){
case -6:
case -5:
case -4:
TidVol = TidVol*0.25;
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
case -3:
TidVol = TidVol*0.50;
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
case -2:
TidVol = TidVol*0.75;
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
case -1:
TidVol = TidVol*0.75;
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
default:
inspiration(TidVol);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio);
break;
}
return cycleEndTime;
}
// =======================
// SIMV MODE Function
// =======================
void simv_mode()
{
uint32_t cycleEndTime;
bool firstRun = true;
while(digitalRead(inPin) == LOW)
{
// Fetch all potentiometer values
IE_ratio = map(analogRead(potpinIE_ratio), 0, 1023, 1.00, 4.00);
TidVol = map(analogRead(potpinTidVol), 0, 1023, 40.00, 90.00);
BPM = map(analogRead(potpinBPM), 0, 1023, 8.00, 30.00);
separation = (60/BPM - (1+IE_ratio));
if (separation < 0)
{ IE_ratio = 60/BPM - 1;
separation = 60/BPM - (1+IE_ratio);}
// Fetch pressure sensor values
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
// Initiate the cycle
if(firstRun)
{
pressure_mask = average_pressure_mask();
cycleEndTime = simv_logic(pressure_mask, TidVol, IE_ratio);
firstRun = false;
}
// ========= Identify trigger and initiate the cycle =============
if(millis() - cycleEndTime >= (uint32_t)separation*1000 || average_pressure_mask() < -1)
{
pressure_mask = average_pressure_mask();
cycleEndTime = simv_logic(pressure_mask, TidVol, IE_ratio);
}
transmit(BPM, IE_ratio, pressure_mask, pressure_expiration, TidVol, pressure_diff);
}
}
// =======================
// Average Pressure Function
// =======================
float average_pressure_mask()
{
pressure_mask = 0;
for(int i=0;i<5;i++)
{
pressure_mask = pressure_mask + (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
delay(3);
}
return (pressure_mask/5);
}
// =======================
// Inspiration Function
// =======================
void inspiration(float TidVol)
{ int pos;
for(pos = 30; pos <= TidVol+30; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
servoright.write(pos);
delay(1000/TidVol);
// ============ Update pressure values =========
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
Serial.println(pressure_mask);
//Serial.println(pressure_diff);
//Serial.println(pressure_expiration);
}
}
// =====================
// Expiration Function
// =====================
uint32_t expiration(float TidVol, float IE_ratio)
{
for(pos = TidVol+30; pos>=30; pos-=1) // goes from 180 degrees to 0 degrees
{
servoright.write(pos);
delay(1000*IE_ratio/TidVol);
// ============ Update pressure values =========
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
Serial.println(pressure_mask);
//Serial.println(pressure_diff);
//Serial.println(pressure_expiration);
}
return millis();
}
// =====================
// Transmit to DB
// =====================
void transmit(float BPM, float IE_ratio, float pressure_mask, float pressure_expiration, float TidVol, float pressure_diff){
String message = "";
boolean messageReady = false;
while(SUART.available()) {
message = SUART.readString();
Serial.println(message);
messageReady = true;
}
if(messageReady) {
// The only messages we'll parse will be formatted in JSON
const int capacity = JSON_OBJECT_SIZE(7);
StaticJsonBuffer<capacity> jb;
JsonObject& doc = jb.parseObject(message);
//DynamicJsonDocument doc(1024); // ArduinoJson version 6+
// Attempt to deserialize the message
if(!(doc.success())){
Serial.println("Doc conversion failed");
messageReady = false;
doc["type"] = "incorrect";
}
if(doc["type"] == "request") {
doc["type"] = "response";
doc["BPM"] = BPM;
doc["IE_ratio"] = IE_ratio;
doc["pressure_mask"] = pressure_mask;
doc["pressure_expiration"] = pressure_expiration;
doc["TidVol"] = TidVol;
doc["pressure_diff"] = pressure_diff;
doc.printTo(SUART);
}
}
}
#include <Guino.h>
#include <Servo.h>
#include<SoftwareSerial.h>
#include <ArduinoJson.h>
#include <SPI.h>
#include <SD.h>
//======== Information about SD Card ====
/*
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4
*/
//====== Serial COnnection with NODEMCU =====
SoftwareSerial SUART(2, 3); //SRX=Dpin-2; STX-DPin-3
Servo servoright;
int pos = 0;
//======= SD Card File ===========
File ventilator_data;
// ==== Analog Pins =====
float potpinIE_ratio = 0;
int potpinTidVol = 1;
int potpinBPM = 5;
int pinguage_mask = 4;
int pinguage_expiration = 3;
int pinguage_diff = 2;
// ==== Analog Pins ====
int inPin = 4;
// ==== Sensor Offset =====
const float guageSensorOffset = 41;
const float pressureDiffSensorOffset = 41;
// ===== Other vars ======
float check_value;
float IE_ratio;
float TidVol;
float BPM;
float separation;
float sensorvalue;
float pressure_mask;
float pressure_expiration;
float pressure_diff;
int display_IE_ratio;
int display_BPM;
int display_TidVol;
int display_sensorvalue_cmh2o;
int display_sensorvalue_gp_cmh2o;
// ======= Mode changing vars =========
int state = HIGH; // the current state of the output pin
int previous = LOW; // the previous reading from the input pin
long t_time = 0; // the last time the output pin was toggled
long debounce = 200; // the debounce time, increase if the output flickers
String mode = "";
void setup()
{
servoright.attach(9); // attaches the servo on pin 9 to the servo object
Serial.begin(9600);
SUART.begin(9600); //enable SUART Port for communication with NODEMCU
pinMode(10,OUTPUT);
if (!SD.begin(4)) {
Serial.println("initialization failed!");
return;
}
Serial.println("SD Card Initialization done.");
ventilator_data = SD.open("ventilator_data.txt",FILE_WRITE);
}
void loop()
{
if (digitalRead(inPin) == LOW)
{
while(digitalRead(inPin)==LOW)
{
simv_mode();
}
}
else
{ while(digitalRead(inPin) == HIGH)
{
acv_mode();
}
}
}
// =======================
// ACV MODE Function
// =======================
void acv_mode()
{
float IE_ratio;
float TidVol;
float BPM;
float per_breath_time;
float per_inspiration_time;
float per_expiration_time;
float human_effort;
float separation;
uint32_t cycleEndTime;
bool firstRun = true;
mode = "ACV";
while(digitalRead(inPin) == HIGH)
{
// Fetch all potentiometer values
IE_ratio = map(analogRead(potpinIE_ratio), 0, 1023, 1.00, 4.00);
TidVol = map(analogRead(potpinTidVol), 0, 1023, 40.00, 90.00);
BPM = map(analogRead(potpinBPM), 0, 1023, 8.00, 30.00);
separation = (60/BPM - (1+IE_ratio));
if (separation < 0)
{ IE_ratio = 60/BPM - 1;
separation = 60/BPM - (1+IE_ratio);
}
// Fetch pressure sensor values
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
// Initiate the cycle
if(firstRun)
{
inspiration(TidVol, mode);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio, mode);
firstRun = false;
}
// ========= Identify trigger and initiate the cycle =============
if(millis() - cycleEndTime >= (uint32_t)separation*1000 || pressure_mask < -1)
{
inspiration(TidVol, mode);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio, mode);
}
transmit(BPM, IE_ratio, pressure_mask, pressure_expiration, TidVol, pressure_diff);
}
}
// =======================
// SIMV Logic Function
// =======================
uint32_t simv_logic(float pressure_mask, float TidVol, float IE_ratio, String mode)
{
uint32_t cycleEndTime;
pressure_mask = int(floor(pressure_mask));
switch(int(pressure_mask)){
case -6:
case -5:
case -4:
TidVol = TidVol*0.25;
inspiration(TidVol, mode);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio, mode);
break;
case -3:
TidVol = TidVol*0.50;
inspiration(TidVol, mode);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio, mode);
break;
case -2:
TidVol = TidVol*0.75;
inspiration(TidVol, mode);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio, mode);
break;
case -1:
TidVol = TidVol*0.75;
inspiration(TidVol, mode);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio, mode);
break;
default:
inspiration(TidVol, mode);
delay(15);
cycleEndTime = expiration(TidVol, IE_ratio, mode);
break;
}
return cycleEndTime;
}
// =======================
// SIMV MODE Function
// =======================
void simv_mode()
{
uint32_t cycleEndTime;
bool firstRun = true;
mode = "SIMV";
while(digitalRead(inPin) == LOW)
{
// Fetch all potentiometer values
IE_ratio = map(analogRead(potpinIE_ratio), 0, 1023, 1.00, 4.00);
TidVol = map(analogRead(potpinTidVol), 0, 1023, 40.00, 90.00);
BPM = map(analogRead(potpinBPM), 0, 1023, 8.00, 30.00);
separation = (60/BPM - (1+IE_ratio));
if (separation < 0)
{ IE_ratio = 60/BPM - 1;
separation = 60/BPM - (1+IE_ratio);}
// Fetch pressure sensor values
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
// Initiate the cycle
if(firstRun)
{
pressure_mask = average_pressure_mask();
cycleEndTime = simv_logic(pressure_mask, TidVol, IE_ratio, mode);
firstRun = false;
}
// ========= Identify trigger and initiate the cycle =============
if(millis() - cycleEndTime >= (uint32_t)separation*1000 || average_pressure_mask() < -1)
{
pressure_mask = average_pressure_mask();
cycleEndTime = simv_logic(pressure_mask, TidVol, IE_ratio, mode);
}
transmit(BPM, IE_ratio, pressure_mask, pressure_expiration, TidVol, pressure_diff);
}
}
// =======================
// Average Pressure Function
// =======================
float average_pressure_mask()
{
pressure_mask = 0;
for(int i=0;i<5;i++)
{
pressure_mask = pressure_mask + (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
delay(3);
}
return (pressure_mask/5);
}
// =======================
// Inspiration Function
// =======================
void inspiration(float TidVol, String mode)
{ int pos;
for(pos = 30; pos <= TidVol+30; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
servoright.write(pos);
delay(1000/TidVol);
// ============ Update pressure values =========
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
String data = mode + "," + pressure_mask + "," + pressure_diff + "," + pressure_expiration + ";";
ventilator_data.println(data);
}
}
// =====================
// Expiration Function
// =====================
uint32_t expiration(float TidVol, float IE_ratio, String mode)
{
for(pos = TidVol+30; pos>=30; pos-=1) // goes from 180 degrees to 0 degrees
{
servoright.write(pos);
delay(1000*IE_ratio/TidVol);
// ============ Update pressure values =========
pressure_mask = (map(analogRead(pinguage_mask), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
pressure_diff = (map(analogRead(pinguage_diff), 0, 1023, 0, 1023) - pressureDiffSensorOffset)*10.1972/92;
pressure_expiration = (map(analogRead(pinguage_expiration), 0, 1023, 0, 1023) - guageSensorOffset)*10.1972/92;
String data = mode + "," + pressure_mask + "," + pressure_diff + "," + pressure_expiration + ";";
ventilator_data.println(data);
}
return millis();
}
// =====================
// Transmit to DB
// =====================
void transmit(float BPM, float IE_ratio, float pressure_mask, float pressure_expiration, float TidVol, float pressure_diff){
String message = "";
boolean messageReady = false;
while(SUART.available()) {
message = SUART.readString();
Serial.println(message);
messageReady = true;
}
if(messageReady) {
// The only messages we'll parse will be formatted in JSON
const int capacity = JSON_OBJECT_SIZE(7);
StaticJsonBuffer<capacity> jb;
JsonObject& doc = jb.parseObject(message);
//DynamicJsonDocument doc(1024); // ArduinoJson version 6+
// Attempt to deserialize the message
if(!(doc.success())){
Serial.println("Doc conversion failed");
messageReady = false;
doc["type"] = "incorrect";
}
if(doc["type"] == "request") {
doc["type"] = "response";
doc["BPM"] = BPM;
doc["IE_ratio"] = IE_ratio;
doc["pressure_mask"] = pressure_mask;
doc["pressure_expiration"] = pressure_expiration;
doc["TidVol"] = TidVol;
doc["pressure_diff"] = pressure_diff;
doc.printTo(SUART);
}
}
}
/*
Rui Santos
Complete project details at https://RandomNerdTutorials.com/esp32-esp8266-mysql-database-php/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
*/
#ifdef ESP32
#include <WiFi.h>
#include <HTTPClient.h>
#else
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#endif
#include <Wire.h>
//#include <Adafruit_Sensor.h>
//#include <Adafruit_BME280.h>
// Replace with your network credentials
const char* ssid = "1.21 Jiggawatts!";
const char* password = "itburnswhenIP";
// REPLACE with your Domain name and URL path or IP address with path
const char* serverName = "https://respire.000webhostapp.com/post-esp-data.php";
// Keep this API Key value to be compatible with the PHP code provided in the project page.
// If you change the apiKeyValue value, the PHP file /post-esp-data.php also needs to have the same key
String apiKeyValue = "xPmAT5Ab3j7F6";
String sensorName = "MPXDIFF";
String sensorLocation = "SD";
/*#include <SPI.h>
#define BME_SCK 18
#define BME_MISO 19
#define BME_MOSI 23
#define BME_CS 5*/
//#define SEALEVELPRESSURE_HPA (1013.25)
//Adafruit_BME280 bme; // I2C
//Adafruit_BME280 bme(BME_CS); // hardware SPI
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.println("Connecting");
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to WiFi network with IP Address: ");
Serial.println(WiFi.localIP());
// (you can also pass in a Wire library object like &Wire2)
//bool status = bme.begin(0x76);
//if (!status) {
//Serial.println("Could not find a valid BME280 sensor, check wiring or change I2C address!");
//while (1);
}
void loop() {
//Check WiFi connection status
if(WiFi.status()== WL_CONNECTED){
HTTPClient http;
// Your Domain name with URL path or IP address with path
http.begin(serverName);
// Specify content-type header
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
// Prepare your HTTP POST request data
String httpRequestData = "api_key=" + apiKeyValue + "&sensor=" + sensorName
+ "&location=" + sensorLocation + "&value1=" + String("Sample_value_1")
+ "&value2=" + String("Sample_Value_2") + "&value3=" + String("Sample_value_3") + "";
Serial.print("httpRequestData: ");
Serial.println(httpRequestData);
// You can comment the httpRequestData variable above
// then, use the httpRequestData variable below (for testing purposes without the BME280 sensor)
//String httpRequestData = "api_key=tPmAT5Ab3j7F9&sensor=BME280&location=Office&value1=24.75&value2=49.54&value3=1005.14";
// Send HTTP POST request
int httpResponseCode = http.POST(httpRequestData);
// If you need an HTTP request with a content type: text/plain
//http.addHeader("Content-Type", "text/plain");
//int httpResponseCode = http.POST("Hello, World!");
// If you need an HTTP request with a content type: application/json, use the following:
//http.addHeader("Content-Type", "application/json");
//int httpResponseCode = http.POST("{\"value1\":\"19\",\"value2\":\"67\",\"value3\":\"78\"}");
if (httpResponseCode>0) {
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
}
else {
Serial.print("Error code: ");
Serial.println(httpResponseCode);
}
// Free resources
http.end();
}
else {
Serial.println("WiFi Disconnected");
}
//Send an HTTP POST request every 30 seconds
delay(30000);
}
Comments