/*******************************************************************
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;}
}
}
Comments