Código / Code

/*******************************************************************

Prueba Miguel para ReaMima

Marzo 2020

V 0.6

*******************************************************************/


#include <M5Stack.h>

#include <Wire.h>

#include <Adafruit_Sensor.h>

#include <Adafruit_BME280.h>


/***************************************************************************

This is a library for the BME280 humidity, temperature & pressure sensor

Designed specifically to work with the Adafruit BME280 Breakout

----> http://www.adafruit.com/products/2650

These sensors use I2C or SPI to communicate, 2 or 4 pins are required

to interface. The device's I2C address is either 0x76 or 0x77.

Adafruit invests time and resources providing this open source code,

please support Adafruit andopen-source hardware by purchasing products

from Adafruit!

Written by Limor Fried & Kevin Townsend for Adafruit Industries.

BSD license, all text above must be included in any redistribution

See the LICENSE file for details.

***************************************************************************/


#define BME_SCK 22 //SCL 22 el conector Grove Integrado

#define BME_MOSI 21 //SDA 21 el connector Grove Integrado

#define SEALEVELPRESSURE_HPA (1013.25)


Adafruit_BME280 bme; // I2C


float k = 2 * 3.1416 /360 ;


unsigned long delayTime,prevMillis,interval,tacu;

int temp;float presion;float humedad;

int fase=1; // fase =1, inspiracion, 2 pausa, 3 expiracion.

long resp=0; // contador de respiraciones

int alarma=0; // Codigo de alarma


float frecuencia = 1.5;

int ciclo,volumenCorriente=500,ti,tp,te,tv,tc,tiempocambio,cambiando=0; // VolumenCorriente, 6-10 ml/kg de peso ideal

int IE1=1,IE2=1;// IE, relacion inspiracion/expiracion, 1:3, epoc 1:4 IE1=1;IE2=3

float presionInicio,presionPico,presionMeseta,PEEP = 2.0;

float presionResistida,difPresion,alarmaMaxima=6.0,alarmaBanda=2.0,sensibilidad,IPAP,EPAP;

float preInst [330],preMedia [330];

float preAlarma;


int bomba1 = 2 ;int bomba2 = 5; // Salidas digitales reles inspiracion


// PresionPico, máximo inicial, Presion resistida = pico - meseta,

// Velocidad flujo respiratorio, de 60 a 120 l/min

// Peep aprox. 5cm+, presion base para mantener abiertos alveolos

// Sensibilidad, si detecta -2cm aire ayuda a respirar

// IPAP presion positiva inspiracion, 10-15 cm H2O , EPAP , presion de expiracion, 5-8 cm H2O

// Para SDRA, 6ml/kg, F=25/min, Vflujo=60 L/min, Peep 15 cm H2O

// ti,tp,te,tv,tc,tacu; tiempo de inspiracion,pausa,expiracion,visualización, ciclo=ti+tp+te, tacu tiempo acumulado



//__________________________ SET UP __________________________________________________________

void setup() {

M5.begin();

Serial.begin(115200);

Serial.println(F("Mig Mad "));

pinMode(bomba1,OUTPUT);

pinMode(bomba2, OUTPUT);

bool status;


status = bme.begin(0x76);

if (!status) {

Serial.println("No se puede encontrar un sensor de presion valido, comprueba el cableado!");

while (1);

}


delayTime = 10;


Serial.println();

M5.Lcd.fillScreen(TFT_BLACK);

M5.Lcd.setTextColor(TFT_RED, TFT_BLACK);

M5.Lcd.drawString(" Espera inicio", 80, 160, 4);


M5.Lcd.setTextColor(TFT_BLACK,TFT_YELLOW ); M5.Lcd.fillTriangle(180, 120,250,0, 320, 120, TFT_YELLOW);

M5.Lcd.drawString("ESPERA", 200, 90, 4); M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);


M5.update();

}



//______________________________________________ Loop _________________________________________________

void loop() {

calculos();

tiempos();

sensor();

dibuja();

cambia();

switch (fase){

case 1: //Inspiracion

inspiracion();

break;

case 3: // Expiración

expiracion();

break;

default:

break;

}

alarmas();

M5.update();

}

//____________________________________________________________________________________________________


void inspiracion(){

digitalWrite(bomba1, HIGH);digitalWrite(bomba2, LOW);

if (preInst[ciclo]>=presionPico){presionPico=preInst[ciclo];}

if (ciclo==1 && resp>=1){presionPico=0.0;}

if (resp>=1){

if (resp>=1){

M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);

M5.Lcd.drawFloat(presionPico,2, 10, 190, 2); M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);

Serial.print(" fase ");Serial.println(fase );


}}}


void pausa(){

}

void expiracion(){

digitalWrite(bomba1, LOW);digitalWrite(bomba2, HIGH);

}

void cambia(){

if (M5.BtnA.wasReleased()) {cambiando+=1;Serial.print(" Cambiando = ++++++1 ");}

if (cambiando>10){cambiando=0;}


Serial.print(" Cambiando ");Serial.println(cambiando);

switch (cambiando){

case 1: //Frecuencia

M5.Lcd.setTextColor(TFT_BLACK,TFT_WHITE);

M5.Lcd.drawFloat(frecuencia,0, 60, 190, 2);

if (M5.BtnB.wasReleased()) {frecuencia+=1;}

if (M5.BtnC.wasReleased()) {frecuencia-=1;}

if (frecuencia>9){frecuencia=9;}if (frecuencia<1){frecuencia=0;} // Limites

break;

case 2: //PEEP

M5.Lcd.setTextColor(TFT_WHITE,TFT_BLACK);

M5.Lcd.drawFloat(frecuencia,0, 60, 190, 2);

M5.Lcd.setTextColor(TFT_BLACK,TFT_WHITE);

M5.Lcd.drawFloat(PEEP,1, 98, 190, 2);

if (M5.BtnB.wasReleased()) {PEEP+=0.2;}

if (M5.BtnC.wasReleased()) {PEEP-=0.2;}

if (PEEP>20.0){PEEP=20.0;}if (PEEP<0.2){PEEP=0.0;} // Limites

break;

case 3: // Volumen medio

M5.Lcd.setTextColor(TFT_WHITE,TFT_BLACK);

M5.Lcd.drawFloat(PEEP,1, 98, 190, 2);

M5.Lcd.setTextColor(TFT_BLACK,TFT_WHITE);

M5.Lcd.drawFloat(volumenCorriente,0, 138, 190, 2);

if (M5.BtnB.wasReleased()) {volumenCorriente+=50.0;}

if (M5.BtnC.wasReleased()) {volumenCorriente-=50.0;}

if (volumenCorriente>900.0){volumenCorriente=900.0;}if (volumenCorriente<100.0){volumenCorriente=100.0;} // Limites


break;

case 4: // IE1

M5.Lcd.setTextColor(TFT_WHITE,TFT_BLACK);

M5.Lcd.drawFloat(volumenCorriente,0, 138, 190, 2);

M5.Lcd.setTextColor(TFT_BLACK,TFT_WHITE);

M5.Lcd.drawFloat(IE1,0, 185, 190, 2);

if (M5.BtnB.wasReleased()) {IE1+=1;}

if (M5.BtnC.wasReleased()) {IE1-=1;}

if (IE1>10){IE1=10;}if (IE1<1){IE1=1;} // Limites


break;

case 5: // IE1

M5.Lcd.setTextColor(TFT_WHITE,TFT_BLACK);

M5.Lcd.drawFloat(IE1,0, 185, 190, 2);

M5.Lcd.setTextColor(TFT_BLACK,TFT_WHITE);

M5.Lcd.drawFloat(IE2,0, 220, 190, 2);

if (M5.BtnB.wasReleased()) {IE2+=1;}

if (M5.BtnC.wasReleased()) {IE2-=1;}

if (IE2>10){IE2=10;}if (IE2<1){IE2=1;} // Limites


break;

case 6: // IE1

M5.Lcd.setTextColor(TFT_WHITE,TFT_BLACK);

M5.Lcd.drawFloat(IE2,0, 220, 190, 2);

M5.Lcd.setTextColor(TFT_BLACK,TFT_WHITE);

M5.Lcd.drawFloat(alarmaBanda,0, 270, 190, 2);

if (M5.BtnB.wasReleased()) {alarmaBanda+=0.5;}

if (M5.BtnC.wasReleased()) {alarmaBanda-=0.5;}

if (alarmaBanda>10.0){alarmaBanda=10.0;}if (alarmaBanda<0.5){alarmaBanda=0.5;} // Limites


break;

default:

case 7: // IE1

M5.Lcd.setTextColor(TFT_WHITE,TFT_BLACK);

M5.Lcd.drawFloat(alarmaBanda,0, 270, 190, 2);

cambiando=0;


break;

M5.Lcd.drawFloat(alarmaBanda,0, 270, 190, 2);

break;

}

}


void calculos()

{

tc=60000/frecuencia; ti=(tc/(IE1+IE2))*IE1; te=tc-ti; tv=tc/320;

alarmaMaxima= alarmaBanda + 2.0;

}


void tiempos(){

// Va calculando el tiempo en milisegundos

// Calculo de intervalo con proteccion de desborde

if (millis() - prevMillis <= 0) {

interval = prevMillis - millis();

}

else

{

interval = millis()-prevMillis;

}

prevMillis = millis();


tacu += interval;

if (tacu>= tc){tacu=0;resp=resp+1;}

if (tacu<=ti){fase=1;}else{fase=3;}

ciclo = tacu/tv;

if (ciclo<=1){presionInicio=presion;}

if (presion-presionInicio>0){

preInst[ciclo]=presion-presionInicio;}

else

{preInst[ciclo]=0;

}

if (resp>1){preMedia[ciclo]=((preMedia[ciclo]*5.0)+preInst[ciclo])/6.0;}else{preMedia[ciclo]=preInst[ciclo];}


Serial.print(" tiempo ciclo ");Serial.print(interval); Serial.print(" tacu ");Serial.print(tacu);

//Serial.print(" P inst");Serial.print(preInst[ciclo]); Serial.print(" P media");Serial.print(preMedia[ciclo]);

Serial.print(" Respiraciones : ");Serial.print(resp);

Serial.print(" ciclo ");Serial.println(ciclo);

}

void dibuja() {

// Dibuja solo la primera vez

if (ciclo==1){M5.Lcd.fillScreen(BLACK); M5.Lcd.drawLine( 0,120,320,120,0x7bef);

M5.Lcd.drawLine( 0,165,320,165,WHITE);M5.Lcd.drawLine( 0,210,320,210,WHITE);M5.Lcd.drawLine( 319,165,319,210,WHITE);

M5.Lcd.drawLine( 0,165,0,210,WHITE);M5.Lcd.drawLine( 55,165,55,210,WHITE); // Frec

M5.Lcd.drawLine( 95,165,95,210,WHITE);M5.Lcd.drawLine( 135,165,135,210,WHITE);

M5.Lcd.drawLine( 178,165,178,210,WHITE); M5.Lcd.drawLine( 255,165,255,210,WHITE);

M5.Lcd.drawLine( 0,0,0,120,0x7BEF); M5.Lcd.setTextColor(TFT_RED, TFT_BLACK);

M5.Lcd.drawString("P. Pico",5,170,2); M5.Lcd.drawString("Frec",60,170,2); M5.Lcd.drawString("PEEP",98,170,2);

M5.Lcd.drawString("Vm",148 ,170,2);

M5.Lcd.drawString("I E",205 ,170,2);

M5.Lcd.drawString("P .Desvio",260 ,170,2);

M5.Lcd.setTextColor(TFT_ORANGE, TFT_BLACK);

M5.Lcd.drawString("Temp C : ",5 ,140,2);

M5.Lcd.drawString("Hum % :",98 ,140,2);

M5.Lcd.setTextColor(TFT_YELLOW, TFT_BLACK);

M5.Lcd.drawFloat(temp,1, 60, 140, 2);

M5.Lcd.drawFloat(humedad,1,160 , 140, 2);

// Valores

M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);

M5.Lcd.drawFloat(frecuencia,0, 60, 190, 2);

M5.Lcd.drawFloat(PEEP,1, 98, 190, 2);

M5.Lcd.drawFloat(volumenCorriente,0, 138, 190, 2);

M5.Lcd.drawFloat(IE1,0, 185, 190, 2); M5.Lcd.drawString(":",210 ,190,2);

M5.Lcd.drawFloat(IE2,0, 220, 190, 2);

M5.Lcd.drawFloat(alarmaBanda,0, 270, 190, 2);

// Cursores

M5.Lcd.fillTriangle(55, 215, 55, 235, 65, 225, WHITE);

M5.Lcd.fillTriangle(145, 239, 160, 215, 175, 239, WHITE);

M5.Lcd.fillTriangle(250, 215, 265, 239, 280, 215, WHITE);



///// Grafica en tiempo real

if (resp>1){

for ( int i = 1 ; i<320 ; i++)

{ float a2 = i , a1= i-1 ;

float b2= 100 -( preMedia[i]*50) , b1= 100 - (preMedia[(i-1)]*50) ;

M5.Lcd.drawLine(a1, b1, a2, b2,0xFF80 );

}

}

}

///// Grafica en tiempo real y valores en tiempo real

else{


float x2 = ciclo, x1 = x2-1 ;

float y2= 120 - (preInst[ciclo] * 50), y1= 120 - (preInst[(ciclo-1)] * 50) ;

M5.Lcd.drawLine(x1, y1, x2, y2,RED );

}

}



void sensor()

{

temp = bme.readTemperature();

presion = bme.readPressure() / 100.0F;

humedad = bme.readHumidity();

Serial.print("Temperatura = "); Serial.print(temp); Serial.println(" *C");

Serial.print("Presion = "); Serial.print(presion); Serial.println(" hPa");

Serial.print("Presion = "); Serial.print(presion / 98.0665F); Serial.println(" cm H2O");

Serial.print("Humedad = "); Serial.print(humedad); Serial.println(" %");


Serial.println();

}

void alarmas()

{

if(preInst[ciclo]>=preMedia[ciclo]+alarmaBanda && alarma==0){alarma=2;} // Aviso presion superior a la tendencia 5 ultimas respiraciones

if(preInst[ciclo]> alarmaMaxima && resp>=1){alarma=1;preAlarma=preInst[ciclo];} // Aviso presion > presion pico alarma



if(alarma==1){

M5.Speaker.tone(461, 50); //frequency 461, with a duration of 200ms

M5.Speaker.tone(661, 50); //frequency 661, with a duration of 200ms

M5.Lcd.setTextColor(TFT_BLACK,TFT_YELLOW ); M5.Lcd.fillRect(180, 0,320,40, TFT_YELLOW);

M5.Lcd.drawString("ALARMA", 200, 10, 4); M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);

Serial.print("*****************ALARMA 1 Sobrepresion= "); Serial.println(preAlarma);

if ((ciclo/25)*25==(ciclo/50)*50){M5.Lcd.setTextColor(TFT_BLACK,TFT_YELLOW);M5.Lcd.drawString("P.Pico Alta", 230, 210, 2);}

else{M5.Lcd.setTextColor(TFT_YELLOW,TFT_BLACK);M5.Lcd.drawString("P.Pico Alta", 230, 210, 2);}


if (M5.BtnC.wasReleased()) {

alarma=0;}

}

if(alarma==2){

M5.Speaker.tone(461, 10); //frequency 461, with a duration of 200ms

M5.Speaker.tone(661, 50); //frequency 661, with a duration of 200ms

M5.Lcd.setTextColor(TFT_BLACK,TFT_ORANGE ); M5.Lcd.fillRect(220, 0 , 320, 40, TFT_ORANGE);

M5.Lcd.drawString("AVISO", 230, 10, 4); M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);


if ((ciclo/25)*25==(ciclo/50)*50){M5.Lcd.setTextColor(TFT_BLACK,TFT_ORANGE);M5.Lcd.drawString("Tendencia", 230, 210, 2);}

else{M5.Lcd.setTextColor(TFT_ORANGE,TFT_BLACK);M5.Lcd.drawString("Tendencia", 230, 210, 2);}


if (M5.BtnC.wasReleased()) {

alarma=0;}

}



}