오픈소스 코로나19 인공호흡기 - 아두이노 기반 DIY 호흡 보조 시스템
부품 및 소모품
| 부품 | 비고 | 수량 |
| 아두이노 우노 | 아두이노 버전용 | 1 |
| 아두이노 4 릴레이 실드 | 아두이노 버전용 | 1 |
| 디지털 서보 MG995 | 모든 버전용 | 1 |
| LM2596S 모듈 | 모든 버전용 | 2 |
| 10k 리니어 멀티턴 포텐셔미터 | 모든 버전용 | 1 |
| Digilent 60W PCIe 12V 5A 파워 서플라이 | 모든 버전용 | 1 |
| 5mm LED: 빨강 | 모든 버전용 | 1 |
| 5mm LED: 초록 | 모든 버전용 | 1 |
| 영숫자 LCD, 20x4 | 모든 버전용 | 1 |
| 스위치 버튼 220V | 모든 버전용 | 1 |
| 스노클 풀페이스 마스크 | | 1 |
| 솔레노이드 밸브, 2 Way | | 1 |
필요한 도구 및 기계
- 3D 프린터 (일반, A8 모델)
- 300-001 라이트박스, UV 노광기
앱 및 온라인 서비스
- 아두이노 IDE
- PCB Elegance
- Autodesk Fusion 360
프로젝트 소개
오픈소스 비침습적 인공호흡기입니다. 저비용으로 제작이 용이하며, 인공호흡기가 부족한 코로나19 보건 위기 상황에서 진정이나 기관내 삽관이 필요하지 않은 환자를 위한 응급 호흡기로 활용할 수 있습니다.
이 프로젝트는 전직 교사이자 친구인 세라핌 피레스가 스페인 프로젝트를 보여주며 세계적 위기 극복을 위한 프로젝트 개발을 제안하면서 시작되었습니다.
비침습적 환기에 대한 여러 연구와 학습 후, 기존 두 가지 기술을 기반으로 이 기능성 프로토타입을 제작했습니다.
모든 테스트가 성공적이었으며, 20일 이상 문제나 중단 없이 기능 테스트를 완료했습니다.
비침습적 환기는 페이스마스크나 비강 마스크를 사용하여 설정된 양의 가압 공기를 폐로 밀어 넣는 방식입니다. 이는 질병으로 폐 기능이 저하되었을 때 자연 호흡 과정을 지원하여 신체가 감염과 싸우고 회복할 수 있도록 돕습니다.
이탈리아에서 수행된 연구를 바탕으로, 데카트론 스노클 마스크를 코로나19 환자를 위한 응급 인공호흡기로 개조하는 기술을 프로젝트에 적용했습니다. 이는 코로나19 팬데믹 정점기의 인공호흡기 부족을 완화하는 데 기여했습니다.
이 마스크들은 저렴한 비용과 쉬운 개조 덕분에 전 세계 여러 지역에서 적응되어 사용되었습니다.
결과는 뚜렷했으며, 최근에는 포르투갈의 산타렝 병원에서도 이 기술이 사용되었습니다.
포르투갈 신문 보도
지역 라디오 인터뷰가 포르투갈 소셜 네트워크에서 입소문을 탔습니다.
소량의 공기와 15회 호흡 주기를 사용한 최초 작동 테스트로, 시연을 위해 호흡 빈도와 PEEP를 변경했습니다.
경고: 이 프로토타입은 아직 공식 기관의 검증을 받지 않았으며, 사용에 대한 모든 책임을 지지 않습니다.
또한, 이는 최후의 수단으로 훈련된 의료진에 의해 사용되어야 하며, 극한의 정점 상황에서 생명을 구하기 위한 장비입니다.
비영리 프로젝트로, 포르투갈 관할 당국의 승인 시 대량 복제가 가능합니다.
코드
INOVT_COVID19_Version_2.2.ino (아두이노)
/* 프로그램: INOVT COVID-19 폐 인공호흡기 버전 2.2
* 작성자: David Pascoal
* 장비는 테스트 및 검증됨, 압력 센서로 보안, 알람 출력으로 부저 작동
*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
#define PIN_SERVO 6
#define PIN_FREQ A1
#define PIN_PEEP A0
#define PIN_LED 2
#define PIN_LED2 3
#define PIN_Alarm_Relay 8
#define PIN_Safety_Valve 9
#define SENSOR_FLOW A3
#define EXPIRANDO 0
#define INSPIRANDO 1
#define MIN_ANGLE 92
#define MAX_ANGLE 139
int frecuencia = 0;
int valInspira = 0;
int valExpira = 0;
int valPeep = 0;
int aux;
int x = 500;
int y = 1000;
unsigned long time;
Servo myServo;
int frecuencia_ant;
int valPeep_ant;
int estado;
void logo() { /* 로고 표시 코드 */ }
void initior() { /* 초기화 애니메이션 코드 */ }
void maobc() { /* 엄지 척/내림 애니메이션 코드 */ }
void thumbdownA() { /* 엄지 내림 문자 생성 */ }
void thumbsup() { /* 엄지 척 문자 생성 */ }
void setServo() {
if (millis() > time) {
if (estado == EXPIRANDO) {
digitalWrite(PIN_LED2, LOW);
digitalWrite(PIN_LED, HIGH);
myServo.write(MIN_ANGLE);
time = millis() + (valInspira * 100);
estado = INSPIRANDO;
lcd.setCursor(8, 2);
lcd.print("EXPIRANDO > ");
} else if (estado == INSPIRANDO) {
digitalWrite(PIN_LED2, HIGH);
digitalWrite(PIN_LED, LOW);
myServo.write(MAX_ANGLE - valPeep);
time = millis() + (valExpira * 100);
estado = EXPIRANDO;
lcd.setCursor(8, 2);
lcd.print("INSPIRANDO < ");
}
}
}
void setup() {
myServo.attach(PIN_SERVO);
myServo.write(92);
pinMode(PIN_FREQ, INPUT_PULLUP);
pinMode(PIN_PEEP, INPUT_PULLUP);
pinMode(SENSOR_FLOW, INPUT);
pinMode(PIN_LED, OUTPUT);
pinMode(PIN_LED2, OUTPUT);
pinMode(PIN_Alarm_Relay, OUTPUT);
pinMode(PIN_Safety_Valve, OUTPUT);
lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0, 0);
logo();
lcd.setCursor(4, 2);
lcd.print("OPEN-SOURCE");
lcd.setCursor(0, 3);
lcd.print("Pulmonary Ventilator");
delay(4000);
lcd.clear();
lcd.print("....Initializing....");
initior();
delay(500);
lcd.clear();
maobc();
lcd.clear();
if (digitalRead(SENSOR_FLOW) == LOW) {
thumbsup();
lcd.setCursor(0, 0);
lcd.print("SYSTEM");
lcd.setCursor(2, 1);
lcd.print("OK");
delay(5000);
lcd.clear();
} else {
myServo.write(139);
thumbdownA();
lcd.setCursor(0, 0);
lcd.print("SYSTEM");
lcd.setCursor(1, 1);
lcd.print("FAIL");
delay(5000);
lcd.clear();
Serial.begin(9600);
time = millis();
frecuencia_ant = -1;
valPeep_ant = -1;
}
delay(500);
estado = EXPIRANDO;
}
void loop() {
digitalRead(SENSOR_FLOW);
aux = analogRead(PIN_FREQ);
frecuencia = map(aux, 0, 1023, 10, 60);
valInspira = ((1.0 / frecuencia) * 600.0) * (1.0 / 3.0);
valExpira = ((1.0 / frecuencia) * 600.0) * (2.0 / 3.0);
aux = analogRead(PIN_PEEP);
valPeep = map(aux, 0, 1023, 0, 10);
if ((frecuencia_ant != frecuencia) || (valPeep_ant != valPeep)) {
Serial.print("Frecuencia: "); Serial.println(frecuencia);
Serial.print("Inspira: "); Serial.println(valInspira);
Serial.print("Expira: "); Serial.println(valExpira);
Serial.print("Peep: "); Serial.println(valPeep);
lcd.setCursor(1, 0); lcd.print("FREQUENCIA: "); lcd.setCursor(13, 0); lcd.print(frecuencia);
lcd.setCursor(1, 1); lcd.print("PEEP: "); lcd.setCursor(13, 1); lcd.print(valPeep);
lcd.setCursor(0, 2); lcd.print("ESTADO: ");
lcd.setCursor(0, 3); lcd.print("VENTILADOR D.PASCOAL ");
frecuencia_ant = frecuencia;
valPeep_ant = valPeep;
}
if (digitalRead(SENSOR_FLOW) == HIGH) {
myServo.write(139);
digitalWrite(PIN_Alarm_Relay, HIGH);
digitalWrite(PIN_Safety_Valve, HIGH);
lcd.clear();
thumbdownA();
lcd.setCursor(0, 0); lcd.print("SYSTEM");
lcd.setCursor(1, 1); lcd.print("FAIL");
lcd.setCursor(1, 2); lcd.print("******************");
lcd.setCursor(3, 3); lcd.print("Check AR flow");
lcd.setCursor(12, 1); lcd.print("ALARM");
digitalWrite(PIN_LED, HIGH);
digitalWrite(PIN_LED2, HIGH);
delay(500);
lcd.setCursor(12, 1); lcd.print(" ");
delay(500);
lcd.setCursor(12, 1); lcd.print("ALARM");
digitalWrite(PIN_LED, LOW);
digitalWrite(PIN_LED2, LOW);
delay(1000);
lcd.clear();
} else {
digitalWrite(PIN_Alarm_Relay, LOW);
digitalWrite(PIN_Safety_Valve, LOW);
setServo();
delay(10);
}
}
INOVT_COVID19_Version_2.2.rar (C/C++, 다운로드만 가능)
커스텀 파트 및 인클로저
3D 프린터로 출력해야 합니다. 정밀도가 필요합니다.
다이빙 마스크를 가압 호흡 마스크로 개조하는 완전한 단계별 지침
고해상도 3D 프린터 필요 inovt_covid19_version_2_0_david_pascoal_0mbFUa0ce1.rar
회로도
자율 버전 다이어그램, 병원 공기 공급 장치 불필요
버전 2.2, 안전 가드 및 알람 출력 포함