Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Basic pump / inflator use :why not? #62

Open
fredohmygod opened this issue Mar 24, 2020 · 80 comments
Open

Basic pump / inflator use :why not? #62

fredohmygod opened this issue Mar 24, 2020 · 80 comments

Comments

@fredohmygod
Copy link

What about using a basic pump like the one on amazon proposed in the read me ? Has someone tried ?
Any help with which Arduino extension card to purchase to pilot such a motor?

@fredohmygod fredohmygod changed the title Basic pump / inflated use :why not? Basic pump / inflator use :why not? Mar 24, 2020
@adamcullen
Copy link

adamcullen commented Mar 25, 2020

Hi, I've just had a go at building an open source ventilator using the main thread as inspiration. I didn't have access to a CPAP pump, so I decided to give an air mattress pump a go. Here are my findings.

I used (all prices in Australian dollars):

  • 12v DC air pump (A$19)
  • Arduino (I've used a mega as that's whats in my test lab, but in reality I'd use a nano) (about $5)
  • WB291111 motor driver board (which looks to me like an L298N knock off) (about $2)
  • 4 potentiometers (less than $1)
  • washing machine flexible hose (about $30, but I'm sure there must be cheaper options)
  • 3M 6800 full face respirator mask (about A$90, but I had one following the bushfires!)
  • 1 1/4" to 1" BSP reducer (A$2.50)
  • 1" to 3/4" BSP reducer (A$2.50)
  • 3/4" to 20mm pressure pipe adaptor (A$2)

Here are some pics of the testing setup:
IMG_20200325_134845 1
IMG_20200325_134903 1
IMG_20200325_134929 1

IMG_20200325_135533 1
IMG_20200325_135624 1

I decided to re-use my 3M 6800 full face respirator mask, which I have following the last disaster to strike Australia earlier in the year - bushfires. This mask has 3 filter ports, and the large one at the front takes a very course 1 1/4" thread. I found the 1 1/4" BSP thread will get about a 3/4 turn and make a reasonable seal, threadtape or plumbing sealant would make a solid seal in an emergency. This mask has the added advantage of being able to hook up an air feed line to the other 2 ports, which I can add in concentrated oxygen if needed.
https://www.ebay.com.au/itm/Indusry-Safety-Spray-paint-Supplied-Air-Fed-Respirator-System-For-6800-Gas-Gask-/264207440778

I used the 4 potentiometers to control the strength of the pump on in and out, as well as the length of the in and out breath. As you'll see in my crude arduino code, the pots basically divide the analogue signal by 100 and round (so instead of reading 0-1028 on the analogue port, they get a value of 0-10) making the pots able to have 10 steps from 0 to max volume, and I have arbitrarily set the breath (in and out) length to 4000ms.

The only other tricky part was wiring up the L298N motor driver so that it used the A and B motor outs in parallel. The L298N will only drive up to 2A, I needed at least 2.5A, so by running it in parallel I could get up to 4A. This is possible per the spec sheet on page 7, by bridging inputs 1 & 4 and 2 & 3. https://www.st.com/resource/en/datasheet/l298.pdf
Input 1&4 go to 5v, 2&3 to ground, enable A&B go to the arduino analogue pin out (in my code pin 9).

Here's my code for the arduino.

int breath = 1;

void setup() {
  Serial.begin(9600);
  pinMode(9, OUTPUT);
}

void loop() {
  int inP = analogRead(A0); // pot 1 - in breath pressure
  int outP = analogRead(A1); // pot 2 - out breath pressure
  int inT = analogRead(A3); // pot 3 - in breath time
  int outT = analogRead(A2); // pot 4 - out breath time

  int inP_v = round(inP/100)*25.5;  // take the value from the pot, divide by 100 and round, then multiply by 25.5 so the output value is a multiple of 255
  int outP_v = round(outP/100)*25.5;  // take the value from the pot, divide by 100 and round, then multiply by 25.5 so the output value is a multiple of 255
  int inT_v = round(inT/100)*400;  // take the value from the pot, divide by 100 and round, then multiply by 400 to get a proportion of 4000ms
  int outT_v = round(outT/100)*400;  // take the value from the pot, divide by 100 and round, then multiply by 400 to get a proportion of 4000ms

  if (breath !=0) {breath = 0;}
    else breath = 1;

  switch (breath) {
    case 0:
      Serial.print("Breath In. Pressure: "); Serial.print(inP_v); 
      Serial.print(". In Time: "); Serial.print(inT_v); Serial.println("ms.");
      analogWrite(9, inP_v);
      delay(inT_v);
      break;

    case 1:
      Serial.print("Breath Out. Pressure: "); Serial.print(outP_v); 
      Serial.print(". Out Time: "); Serial.print(outT_v); Serial.println("ms.");
      analogWrite(9, outP_v);
      delay(outT_v);
      break;
  }
}

driver
[sorry, there was a mistake in my image, I had wired the pins wrong in the previous image. Again, Pins 2&3 must be wired togehter and Pins 1&4 must be wired together for parallel use of the driver. Very sorry if people have blown their L298N's because of this].

Hopefully this helps someone. I've spoken with an ER doctor friend, who said using an inflation pump cant be any worse in an emergency than someone having to manually "bag" a patient for a couple of weeks! I haven't been able to run a water lift test as my hose isn't opaque, but I'll try to find some and report back. I'd also like to do a test running the pump overnight to see if the motor burns out cycling up and down.

Edit: I can report that the pump has survived an 8 hour test, I'll keep it running for the rest of the day to test for 24 hours. Seems promising so far, no obvious loss of power.

@jcl5m1
Copy link
Owner

jcl5m1 commented Mar 25, 2020

this is really great! eager to hear how it runs over night going through breathing cycles.

@nasocializes nasocializes pinned this issue Mar 25, 2020
@fredohmygod
Copy link
Author

Exactly what I have been looking for. Thanks !
Thinking about mixing it with decathlon snorkeling mask recently adapted by some hospitals in Italy

https://www.google.fr/amp/s/www.01net.com/actualites/comment-decathlon-pourrait-sauver-des-malades-du-coronavirus-grace-au-plan-de-son-masque-de-plongee-1881292.html/amp/

@adamcullen
Copy link

adamcullen commented Mar 25, 2020

I hope it helps you guys in Europe.

@adamcullen
Copy link

Final update: pump has been tested continuously now for more than 32 hours. It is still going strong, so in a dire emergency, I think this represents a viable solution.

@Fearfulbot
Copy link

Where did you source the pumps?

@adamcullen
Copy link

adamcullen commented Mar 26, 2020

Where did you source the pumps?

Just at a local department store like Target. I'm sure you could also source from camping, sports, hardware stores. (Target/Big W in Australia, but something like Walmart in the US)

https://www.target.com.au/p/bestway-sidewinder-ac-dc-air-pump/58980521
https://www.bigw.com.au/product/hinterland-electric-air-pump-12v-dc/p/8296727/
https://www.walmart.com/ip/Coghlan-s-12V-DC-Electric-Air-Pump/8586941
https://www.anacondastores.com/camping-hiking/sleeping/pumps/spinifex-12v-dc-electric-air-pump/BP90028986
https://www.amazon.co.uk/Electric-Versatile-Inflator-Mattresses-Inflatable/dp/B01KXB21LG

Look for air mattress inflation pumps - but they have to be 12v dc, and not battery rechargeable (otherwise it will run at 12v from the battery and you can't vary the speed).

@DaveM135
Copy link

DaveM135 commented Mar 26, 2020 via email

@nasocializes nasocializes unpinned this issue Mar 27, 2020
@nasocializes nasocializes added this to In progress in General Kanban Mar 30, 2020
nasocializes added a commit that referenced this issue Mar 30, 2020
link test basic inflator to issue #62 #62
@ghost
Copy link

ghost commented Mar 31, 2020

Hi friends

Very great respect to Adamcullen for sharing this wonderful tutorial with the Arduino code as a gift. This is exactly what i was looking for and my research was successful, thanks to you dear Adamcullen

I wish you good health, peace, success and happiness. I would share images of the final result, i would have liked to use it with an STM32F103 OR STM8 if possible with the Arduino IDE but as my knowledge is limited i would be content to use an Arduino Uno.

Thank you so much.

@Carter7868
Copy link

Hello, I have been playing around with controlling a DC motor via a Mosfet. The code I have is fairly basic but if possible could someone look over it? I haven't setup potentiometer's yet for settings / speed, currently its just code variables.

// the transistor which controls the motor will be attached to digital pin 9
int motorControl = 9;

//variables
int bpm = 16;
float maxPercent = 1.00;
float minPercent = 0.30;

// the setup routine runs once when you press reset:
void setup() {
  Serial.begin(9600);
  // make the transistor's pin an output:
  pinMode(motorControl, OUTPUT); 
  //led pin 
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop routine runs over and over again forever:
void loop() {
  if(true){
    //LED On
    digitalWrite(LED_BUILTIN, HIGH); 
    // ramp up the motor speed
    for(int x = 255*minPercent; x <= 255*maxPercent; x++){
      analogWrite(motorControl, x);
      delay(60000/bpm/2/(255*(maxPercent-minPercent)));
      Serial.println(x);
      Serial.print(" ");
    }
    digitalWrite(LED_BUILTIN, LOW);
    // ramp down the motor speed
    for(int x = 255*maxPercent; x >= 255*minPercent; x--){
      analogWrite(motorControl, x);
      delay(60000/bpm/2/(255*(maxPercent-minPercent)));
      Serial.println(x);
      Serial.print(" ");
    }    
  }
}

You can set the BPM (beats per minute) as well as the min and max air flow percentage.
(Sorry if I did something wrong this is my first GitHub post)

@adamcullen
Copy link

An update - added an OLED screen to give some visual feedback about in and out breath times and pressures. This requires the use of some libraries, so not quite as straight forward as a raw Arduino code. The inclusion of the OLED screen forced me to be slightly more elegant with the code too, instead of using a raw delay for the timing, I use a set of loops with a constant delay. The number of loops is calculated based on the potentiometers. This allows me to make real time adjustments on the pot, which are output to the pump and to the display, without having to wait until the next cycle before the change takes effect. The most you have to wait is 400ms. Also included comments to make the code more readable.

IMG_20200331_201946

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

int breath = 1;
int i = 0;
int inP=1028; int inT=1028; int inP_v=1028; int inT_v=1028;
int outP=1028; int outT=1028; int outP_v=1028; int outT_v=1028;

void setup() {
  Serial.begin(9600);
  pinMode(9, OUTPUT);

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();

  // Clear the buffer
  display.clearDisplay();
}

void loop() {
  // clear the display and set up initial values

  

  // is the next breath an in or out?  
  if (breath !=0) {breath = 0;}
    else breath = 1;
    Serial.println(breath);

  // apply the in breath or out breath code
  switch (breath) {
    case 0: //breathe in
    i = 0;
    Serial.println(i); Serial.println(inT_v);
      while (i <= inT_v) {
        // read the potentiometers and determin the in breath pressure and time
        inP = analogRead(A0);
        inT = analogRead(A3);
        inP_v = ceil(inP/100)*25.5;
        inT_v = round(inT/100);

        Serial.println("Breath in");

        // used to show the values on the OLED display
        display.clearDisplay();
        display.setCursor(0,0); display.setTextSize(1); display.setTextColor(WHITE);
        display.print(F("DIY Ventilator v1.0")); 
        display.setCursor(0,16); display.setTextSize(2);
        display.print("BREATH IN");
        display.setCursor(0,40); display.setTextSize(1);
        display.print("Pressure: "); display.print(ceil(inP_v/2.55)); display.println("%");
        display.setCursor(0,50);
        display.print("Time: "); display.print(inT_v*400); display.println("ms.");
        display.display();

        // we will output the PWM voltage and delay only 400ms here and loop through a maximum of 10 periods 
        // this allows us to re-read the pressure and time every 400ms instead at the end of each breathing cycle
        analogWrite(9, inP_v); 
        delay(400); 
        i++;        
      }
      break;

    case 1: //breathe out
    i = 0;
      while (i <= outT_v) {
        // read the potentiometers and determin the in breath pressure and time
        outP = analogRead(A1);
        outT = analogRead(A2);
        outP_v = ceil(outP/100)*25.5;
        outT_v = round(outT/100);

        Serial.println("Breath out");
        
        // used to show the values on the OLED display
        display.clearDisplay();
        display.setCursor(0,0); display.setTextSize(1); display.setTextColor(WHITE);
        display.print(F("DIY Ventilator v1.0")); 
        display.setCursor(0,16); display.setTextSize(2);
        display.setCursor(0,16); display.setTextSize(2);
        display.print("BREATH OUT");
        display.setCursor(0,40); display.setTextSize(1);
        display.print("Pressure: "); display.print(ceil(outP_v/2.55)); display.println("%");
        display.setCursor(0,50);
        display.print("Time: "); display.print(outT_v*400); display.println("ms.");
        display.display();
        
        // we will output the PWM voltage and delay only 400ms here and loop through a maximum of 10 periods 
        // this allows us to re-read the pressure and time every 400ms instead at the end of each breathing cycle
        analogWrite(9, outP_v);
        delay(400);
        i++;
      }
      break;
  }
  
}//end loop

@ghost
Copy link

ghost commented Mar 31, 2020

Hello dear Adamcullen

You continue to spoil us, thank you very much for your very informative, understanding and very well explained sharing.

Too bad for me for not having an Oled screen, is it possible to modify it for use with the 1602 I2C screen ? I will do research and shared ...

In any case, Bravo and Respect for the unforgettable Adamcullen.

Thank you.

@adamcullen
Copy link

Hello dear Adamcullen

You continue to spoil us, thank you very much for your very informative, understanding and very well explained sharing.

Too bad for me for not having an Oled screen, is it possible to modify it for use with the 1602 I2C screen ? I will do research and shared ...

In any case, Bravo and Respect for the unforgettable Adamcullen.

Thank you.

A 1602 i2c led will work, it just needs some code modification. The oled is i2c as well, so if you get your addressing right, set up the screen size and how the output works. Sorry, I can't be much more specific than that because every screen will be different.

@ghost
Copy link

ghost commented Apr 1, 2020

Hello dear friend

Thank you very much for the confirmation, i will do my research to succeed in adapting the screen to your project, it is for a personal experience.

Here is an image during the test editing in amateur mode :)

Mon image

Sorry for my amateurism, the potentiometer are worth 500K or 250K?

I go to the job to modify the code in order to adapt it, I would share my final results and my tests to contribute to this very good project.

Respect at Adamcullen

@ghost
Copy link

ghost commented Apr 1, 2020

Hi friends

Result, does not work for me, i notice that the L298N module is different from that of Adamcullen, i do not know if it is also necessary to supply the motor with an external power supply because the outputs of the L298N module do not supply the motor .

Here is the assembly carried out:

Pinout L298N ---> Arduino
ENA / ENB ---> D9
IN1 / IN2 ---> +5V ---> To powered the breadboard
IN3 / IN4 ---> GND

Pinout Pot ---> Arduino
Pot 1 ---> A0
Pot 2 ---> A1
Pot 3 ---> A2
Pot 4 ---> A3

Line 5v breadboard line ---> Arduino +5V
Line GND breadboard line ---> Arduino GND

Pinout L298 ---> To motor
OUT1 ---> Red 12V
OUT2 ---> Black GND

      OUT3 ---> Red 12V
      OUT4 ---> Black GND

The potentiometers are noted 10K i do not know if it is good.

Mon image
Mon image

Thank you so much.

@adamcullen
Copy link

Hi friends

Result, does not work for me, i notice that the L298N module is different from that of Adamcullen, i do not know if it is also necessary to supply the motor with an external power supply because the outputs of the L298N module do not supply the motor .

My advice is to just start with your arduino and the L298N board. If you have a small 12v motor, just wire up one of the motor outs to it and see if you can just control one small motor. if you dont have a motor, a voltmeter or even a 12v light would help fault find.
What you are aiming for is to see if you can control the voltage from one of the motor outputs to make it different from the 12v in. You can run a code that just goes High Low High Low on the pin 9 output and see if you can see a change in voltage at the motor output terminals.
Once you can do that, you can then try bridging both sides of the L298N so that the voltage at motor 1 and motor 2 is the same and changes at the same time with your code.

Have a look at this video: https://www.youtube.com/watch?v=wjFW-TNq8Og and this how to: https://howtomechatronics.com/tutorials/arduino/arduino-dc-motor-control-tutorial-l298n-pwm-h-bridge/

The potentiometers are noted 10K i do not know if it is good.

Any resistance on the pots is fine. You're just supplying 5v from the arduino and reading it back on the arduino through the pot. All pots vary from 0 to their max which will just scale the voltage.

@ghost
Copy link

ghost commented Apr 2, 2020

Hello Adamcullen

Forgive my amateurism, thank you for your patience and your instructions which i will follow to the letter to make tests of good functioning of the module.

Indeed the dissipator was very hot I think that maybe i made a bad assembly or that the module L298N is unfortunately out of service. On the Arduino monitor i can see the unanswered expectations of the module and the potentiometers ...

Thank you again for your confirmation of the value of the potentiometers, thank you for your follow-up and thanks for the links , sincere greetings to King Adamcullen.

@alexandre-leblanc
Copy link

alexandre-leblanc commented Apr 3, 2020

I have an open source design that was intended to use an off-the-shelf DC pump, check it out here:
https://gitlab.com/alex.leblanc/ventilificator

EDIT: note that this has not been through design review yet

@ghost
Copy link

ghost commented Apr 3, 2020

Hello dear Adamcullen, following the functional test of the module L298N + Arduino + motor as you advised me, I notice that the module does not work, no output voltage is available on the outputs OUT1 and OUT2 towards the motor by supplying with + 12V and GND, I will order new L298N modules, no joy for me for the moment. Again thank you again for your support, my respect for you.


Hello Alexandre-leblanc

Thank you for sharing, it's cool to use a more powerful STM32xx than Atmega-328P. I visited your link but i found nothing of "Open Source", no necessary components, no assembly diagram, no code or sketch to inject, this could not be useful for us (the world of Open Source sharing) please specify the components and steps so that people in need try this project to evolve it ...

Thank you for your understanding.

@alexandre-leblanc
Copy link

Hi Col68,

I've just done the hardware (no mech or software) and provided the raw design files (in Altium format). If I have some time later I can generate the outputs (gerbers, fab drawings, assembly drawings, BOM). I haven't set up the outjob file for it yet (nor have I created my fab/assembly notes).

@adamcullen
Copy link

Hello dear Adamcullen, following the functional test of the module L298N + Arduino + motor as you advised me, I notice that the module does not work, no output voltage is available on the outputs OUT1 and OUT2 towards the motor by supplying with + 12V and GND, I will order new L298N modules, no joy for me for the moment. Again thank you again for your support, my respect for you.

Col68, I burned up one of my L298N modules too playing around with them! So don't worry, you're not alone.

The main issue is how to supply 5v to the board so it runs, while using 12v for the motors. I found that if you keep the jumper on the board to supply 5v through the onboard regulator, it also means the maximum output voltage is 5v. I dont know why. Anyway, a way around this is to supply 12v through the screw terminal and 5v and a common ground (by this i mean the wire together your ground from the 12v supply and the ground from your arduino) between the screw terminals on the L298N and the 5v output on your arduino.

In summary, you need to use (from the Arduino) 5v going to IN1&4 as well as the 5v screw terminal. This is the red wire in the diagram below.
Plus you need to run ground from the Arduino to IN2&3 as well as the ground on the screw terminal. This is the black wire below.
Finally, you need 12v going just to the 12v screw terminal. This is the purple wire below. Take all the jumpers off the board.

Then you can control the voltage coming out of the Motor 1 and Motor 2 screw terminals by using pulse width modulation from pin 9 on the arduino to EN1 and EN2 on the L298N. This is shown as the yellow wire below.

L298N wiring

IMG_20200404_114537 1

@ghost
Copy link

ghost commented Apr 4, 2020

Hello dear Adamcullen

Respect and happiness for you, i will try your modification, thank you very much for your support, the diagram and the detailed instructions.
I will try to see if hope is reborn.

I did other experimental tests with a PWM module max 24v but the motor capacitor was extremely hot :), then i used an IRF520 module + 50K potentiometer.

Mon image

The main power supply is a 12V 5 Amp transformer, i used 12V + GND on the VIN / GND outputs of the Arduino and motor inputs on the IRF520 module, i was impressed by the good functioning of the modules.

Mon image

The PWM setting with the 50K potentiometer is very precise and the IRF520 chip has not heated but hey it's still a basic experiment.

I have a lot of STM32F103 and STM8S106 cards but only one arduino uno and one mega available.

Thank you for all your sharing, i wish you peace, success and happiness.

Thank you.

@ghost
Copy link

ghost commented Apr 4, 2020

Adamculleeeeeeeennnnnnnnnnnn :)

Thank you from the bottom of my heart, it works very very well, it's incredible the settings step by step, you are a Genius, it only remains for me to integrate the project in a box and add the tube and the mask for continue the experience in practice to understand the proper functioning, it's incredible i respect you, i will share the result of the final assembly. All the happiness for you.

Long live ADAMCULLEN.

@Pinponcito
Copy link

no voltage in arduino nano 3.0 and L298N, using the diagram from adamcullen

any idea?

Yes my friend you are rigth, and thanks for excelent video, but the video show using arduino Uno, I have arduino Nano V3.0 and sketch arduino from @adamcullen project.

thanks for help to make my project cut work.

BLDC is brushless 3 phase, L298N is brushed DC, diagram attached. The full video is here.
L298N

@adamcullen
Copy link

no voltage in arduino nano 3.0 and L298N, using the diagram from adamcullen

any idea?

My advice is to just start with your arduino and the L298N board. If you have a small 12v motor, just wire up one of the motor outs to it and see if you can just control one small motor. if you dont have a motor, a voltmeter or even a 12v light would help fault find.
What you are aiming for is to see if you can control the voltage from one of the motor outputs to make it different from the 12v in. You can run a code that just goes High Low High Low on the pin 9 output and see if you can see a change in voltage at the motor output terminals.
Once you can do that, you can then try bridging both sides of the L298N so that the voltage at motor 1 and motor 2 is the same and changes at the same time with your code.

Have a look at this video: https://www.youtube.com/watch?v=wjFW-TNq8Og and this how to: https://howtomechatronics.com/tutorials/arduino/arduino-dc-motor-control-tutorial-l298n-pwm-h-bridge/

@Pinponcito
Copy link

Thanks my friend,
the setup and sketch mots have the 4 potentiometter? or can run with out them, I Mean not exist a sketch that can changue the speed (simulation breath ) with out use potentiometer

thaking the exaple from sketch of Johnny Lee @jcl5m1

https://github.com/jcl5m1/ventilator/blob/master/ventilator_control/ventilator_control.ino

thanks Adam

no voltage in arduino nano 3.0 and L298N, using the diagram from adamcullen
any idea?

My advice is to just start with your arduino and the L298N board. If you have a small 12v motor, just wire up one of the motor outs to it and see if you can just control one small motor. if you dont have a motor, a voltmeter or even a 12v light would help fault find.
What you are aiming for is to see if you can control the voltage from one of the motor outputs to make it different from the 12v in. You can run a code that just goes High Low High Low on the pin 9 output and see if you can see a change in voltage at the motor output terminals.
Once you can do that, you can then try bridging both sides of the L298N so that the voltage at motor 1 and motor 2 is the same and changes at the same time with your code.

Have a look at this video: https://www.youtube.com/watch?v=wjFW-TNq8Og and this how to: https://howtomechatronics.com/tutorials/arduino/arduino-dc-motor-control-tutorial-l298n-pwm-h-bridge/

@adamcullen
Copy link

adamcullen commented Apr 13, 2020

Thanks my friend,
the setup and sketch mots have the 4 potentiometter? or can run with out them, I Mean not exist a sketch that can changue the speed (simulation breath ) with out use potentiometer

thaking the exaple from sketch of Johnny Lee @jcl5m1

https://github.com/jcl5m1/ventilator/blob/master/ventilator_control/ventilator_control.ino

Try this. I've just hard coded values in my original sketch where the analog read would be to simulate values it would read from the variable pots. It should breath in for about 2 seconds at full power, then breath out for about 1 second at half power. This should get you started.

int breath = 1;

void setup() {
  Serial.begin(9600);
  pinMode(9, OUTPUT);
}

void loop() {
  int inP = 1028; // was: analogRead(A0); // pot 1 - in breath pressure
  int outP = 512; // was: analogRead(A1); // pot 2 - out breath pressure
  int inT = 512; // was: analogRead(A3); // pot 3 - in breath time
  int outT = 256; // was: analogRead(A2); // pot 4 - out breath time

  int inP_v = round(inP/100)*25.5;  // take the value from the pot, divide by 100 and round, then multiply by 25.5 so the output value is a multiple of 255
  int outP_v = round(outP/100)*25.5;  // take the value from the pot, divide by 100 and round, then multiply by 25.5 so the output value is a multiple of 255
  int inT_v = round(inT/100)*400;  // take the value from the pot, divide by 100 and round, then multiply by 400 to get a proportion of 4000ms
  int outT_v = round(outT/100)*400;  // take the value from the pot, divide by 100 and round, then multiply by 400 to get a proportion of 4000ms

  if (breath !=0) {breath = 0;}
    else breath = 1;

  switch (breath) {
    case 0:
      Serial.print("Breath In. Pressure: "); Serial.print(inP_v); 
      Serial.print(". In Time: "); Serial.print(inT_v); Serial.println("ms.");
      analogWrite(9, inP_v);
      delay(inT_v);
      break;

    case 1:
      Serial.print("Breath Out. Pressure: "); Serial.print(outP_v); 
      Serial.print(". Out Time: "); Serial.print(outT_v); Serial.println("ms.");
      analogWrite(9, outP_v);
      delay(outT_v);
      break;
  }
}

With wiring like this.

https://user-images.githubusercontent.com/23371950/78415437-69fe2e80-766d-11ea-85b1-486723096fc9.JPG

@Pinponcito
Copy link

Excellent Adam I wil try.
in my case Im using a arduino nano V3.0 the wiring are sames pines?
thanks for time to help me on my proyect

Thanks my friend,
the setup and sketch mots have the 4 potentiometter? or can run with out them, I Mean not exist a sketch that can changue the speed (simulation breath ) with out use potentiometer
thaking the exaple from sketch of Johnny Lee @jcl5m1
https://github.com/jcl5m1/ventilator/blob/master/ventilator_control/ventilator_control.ino

Try this. I've just hard coded values in my original sketch where the analog read would be to simulate values it would read from the variable pots. It should breath in for about 2 seconds at full power, then breath out for about 1 second at half power. This should get you started.

int breath = 1;

void setup() {
  Serial.begin(9600);
  pinMode(9, OUTPUT);
}

void loop() {
  int inP = 1028; // was: analogRead(A0); // pot 1 - in breath pressure
  int outP = 512; // was: analogRead(A1); // pot 2 - out breath pressure
  int inT = 512; // was: analogRead(A3); // pot 3 - in breath time
  int outT = 256; // was: analogRead(A2); // pot 4 - out breath time

  int inP_v = round(inP/100)*25.5;  // take the value from the pot, divide by 100 and round, then multiply by 25.5 so the output value is a multiple of 255
  int outP_v = round(outP/100)*25.5;  // take the value from the pot, divide by 100 and round, then multiply by 25.5 so the output value is a multiple of 255
  int inT_v = round(inT/100)*400;  // take the value from the pot, divide by 100 and round, then multiply by 400 to get a proportion of 4000ms
  int outT_v = round(outT/100)*400;  // take the value from the pot, divide by 100 and round, then multiply by 400 to get a proportion of 4000ms

  if (breath !=0) {breath = 0;}
    else breath = 1;

  switch (breath) {
    case 0:
      Serial.print("Breath In. Pressure: "); Serial.print(inP_v); 
      Serial.print(". In Time: "); Serial.print(inT_v); Serial.println("ms.");
      analogWrite(9, inP_v);
      delay(inT_v);
      break;

    case 1:
      Serial.print("Breath Out. Pressure: "); Serial.print(outP_v); 
      Serial.print(". Out Time: "); Serial.print(outT_v); Serial.println("ms.");
      analogWrite(9, outP_v);
      delay(outT_v);
      break;
  }
}

With wiring like this.

https://user-images.githubusercontent.com/23371950/78415437-69fe2e80-766d-11ea-85b1-486723096fc9.JPG

@adamcullen
Copy link

Excellent Adam I wil try.
in my case Im using a arduino nano V3.0 the wiring are sames pines?
thanks for time to help me on my proyect

Ricardo, you should be able to use my sketch with an arduino nano. Use the same wiring and the same sketch. You just need to select the nano from the boards manager.

@timhurdle
Copy link

Hi All, I have been working on a similar device in the UK. I tried to engage with the One Million Ventilators Group with not much response. I am still working on it anyway but been considering that carbon and copper particles from the motor can contaminate the air as there is deliberate low pressure pull through the motor core through the backplate of the impeller rotor (for cooling). Also I heard that brushless motors are needed as 03 (ozone) can be generated by sparks from brush commutation. I think the voltage are too low for that but I have come up with a possible solution if anyone is interested.

@brian-mckeon
Copy link

Hi Tim,
have a look back at my post on Apr 11. I was also concerned about ozone. However I found that the motor cooling airflow in this mattress inflator seemed to be bled off the output pressure side and then out the vents below the motor. A bit different to vacuum cleaners etc but makes sense as the small motor ducts could often be facing a dirt campground and you wouldn't want to be drawing cooling air in from there. I used deflection of a small piece of paper to try and determine airflow and it seemed to be exiting these vents. Let me know if you find different. If you want to go brushless you could simply buy a 12V CPAP motor and pump from DHgate or others, https://www.dhgate.com/product/daniu-wm7040-dc-12v-24v-high-pressure-blower/505193494.html?dspm=pcen.sp.list.1.E97VPnotXnnR3Wuw0dtf&resource_id=#s1-0-1;searl|2412079574:1. They are not that expensive although shipping times would be pretty poor at the moment.

@Pinponcito
Copy link

Hi Tim, Im from Mexico.
with the sipporth of this guys I make my own sketch and make a ventilator made in home with a air pump rigth now are in 24hr work test, and next day we makeing test in pressure PEEP.
Sent to me a email and i cant share my projetc, i will post here in next days but for more quick anser and you can get a ventilator contact to me.
bes regard

Hi All, I have been working on a similar device in the UK. I tried to engage with the One Million Ventilators Group with not much response. I am still working on it anyway but been considering that carbon and copper particles from the motor can contaminate the air as there is deliberate low pressure pull through the motor core through the backplate of the impeller rotor (for cooling). Also I heard that brushless motors are needed as 03 (ozone) can be generated by sparks from brush commutation. I think the voltage are too low for that but I have come up with a possible solution if anyone is interested.

@brian-mckeon
Copy link

Thought I'd mention for anyone thinking about these mattress pumps - they are very noisy! Especially when you are ramping the power up and down. If you listen to a CPAP machine you can appreciate the huge effort that those designers have put into the design of their air pumps to keep them quiet. However I guess if you need a ventilator you aren't going to be too bothered about noise?

@sean4545
Copy link

There is one problem for me with this pump. It inflate at both direction +/-. Somebody can help?
Anyway excellent project Adam Cullen!

@timhurdle
Copy link

timhurdle commented Apr 19, 2020 via email

@timhurdle
Copy link

timhurdle commented Apr 19, 2020 via email

@timhurdle
Copy link

timhurdle commented Apr 19, 2020 via email

@sean4545
Copy link

the flow is fixed, centre port for suction, peripheral port for pressure

On Sun, Apr 19, 2020 at 5:00 PM sean4545 @.***> wrote: There is one problem for me with this pump. It inflate at both direction +/-. Somebody can help? Anyway excellent project Adam Cullen! — You are receiving this because you commented. Reply to this email directly, view it on GitHub <#62 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/APHXBNJQO3DW2NCUIQYCRSDRNMNY3ANCNFSM4LS24XKQ .

Yes, I see that. But can't imagine, how can it work with this arduino setap? No matter if procedure breath in or breath out- pum is still do thesame- do pressure. Should I connect two pipes? Or do something else?
I've not sufficient 12v souce yet, so cant connect pump phisically.

@timhurdle
Copy link

timhurdle commented Apr 19, 2020 via email

@sean4545
Copy link

output port only, pump to inhale, slow down pump to exhale. need a small pressure to stop lung tissue collapsing , about 2 to 4cm of water.

On Sun, 19 Apr 2020, 22:42 sean4545, @.> wrote: the flow is fixed, centre port for suction, peripheral port for pressure … <#m_-140302477150017201_> On Sun, Apr 19, 2020 at 5:00 PM sean4545 @.> wrote: There is one problem for me with this pump. It inflate at both direction +/-. Somebody can help? Anyway excellent project Adam Cullen! — You are receiving this because you commented. Reply to this email directly, view it on GitHub <#62 (comment) <#62 (comment)>>, or unsubscribe https://github.com/notifications/unsubscribe-auth/APHXBNJQO3DW2NCUIQYCRSDRNMNY3ANCNFSM4LS24XKQ . Yes, I see that. But can't imagine, how can it work with this arduino setap? No matter if procedure breath in or breath out- pum is still do thesame- do pressure. Should I connect two pipes? Or do something else? I've not sufficient 12v souce yet, so cant connect pump phisically. — You are receiving this because you commented. Reply to this email directly, view it on GitHub <#62 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/APHXBNKG376HJLET7RJVZGTRNNV4JANCNFSM4LS24XKQ .

Thank you! Now, I understand

1 similar comment
@sean4545
Copy link

output port only, pump to inhale, slow down pump to exhale. need a small pressure to stop lung tissue collapsing , about 2 to 4cm of water.

On Sun, 19 Apr 2020, 22:42 sean4545, @.> wrote: the flow is fixed, centre port for suction, peripheral port for pressure … <#m_-140302477150017201_> On Sun, Apr 19, 2020 at 5:00 PM sean4545 @.> wrote: There is one problem for me with this pump. It inflate at both direction +/-. Somebody can help? Anyway excellent project Adam Cullen! — You are receiving this because you commented. Reply to this email directly, view it on GitHub <#62 (comment) <#62 (comment)>>, or unsubscribe https://github.com/notifications/unsubscribe-auth/APHXBNJQO3DW2NCUIQYCRSDRNMNY3ANCNFSM4LS24XKQ . Yes, I see that. But can't imagine, how can it work with this arduino setap? No matter if procedure breath in or breath out- pum is still do thesame- do pressure. Should I connect two pipes? Or do something else? I've not sufficient 12v souce yet, so cant connect pump phisically. — You are receiving this because you commented. Reply to this email directly, view it on GitHub <#62 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/APHXBNKG376HJLET7RJVZGTRNNV4JANCNFSM4LS24XKQ .

Thank you! Now, I understand

@timhurdle
Copy link

timhurdle commented Apr 19, 2020 via email

@zero48
Copy link

zero48 commented Apr 21, 2020

Hi @adamcullen ,
I'm still waiting for my PCBs to arrive , however I found a sensor I used few years back in a project, which is a MPX5010DP Datasheet . My Idea is to create a sort of spirometer and monitor mass flow air so it can be displayed as well (KPA,PSi,cmh2o). I'm writing some code , would you adapt this calculations to your Sketch? .

@timhurdle
Copy link

timhurdle commented Apr 22, 2020 via email

@brian-mckeon
Copy link

Hi Tim, excellent point about suction blockage possibly changing airflow direction through the motor.

@timhurdle
Copy link

timhurdle commented Apr 23, 2020 via email

@gaurav12294
Copy link

Hi, I've just had a go at building an open source ventilator using the main thread as inspiration. I didn't have access to a CPAP pump, so I decided to give an air mattress pump a go. Here are my findings.

I used (all prices in Australian dollars):

  • 12v DC air pump (A$19)
  • Arduino (I've used a mega as that's whats in my test lab, but in reality I'd use a nano) (about $5)
  • WB291111 motor driver board (which looks to me like an L298N knock off) (about $2)
  • 4 potentiometers (less than $1)
  • washing machine flexible hose (about $30, but I'm sure there must be cheaper options)
  • 3M 6800 full face respirator mask (about A$90, but I had one following the bushfires!)
  • 1 1/4" to 1" BSP reducer (A$2.50)
  • 1" to 3/4" BSP reducer (A$2.50)
  • 3/4" to 20mm pressure pipe adaptor (A$2)

Here are some pics of the testing setup:
IMG_20200325_134845 1
IMG_20200325_134903 1
IMG_20200325_134929 1

IMG_20200325_135533 1
IMG_20200325_135624 1

I decided to re-use my 3M 6800 full face respirator mask, which I have following the last disaster to strike Australia earlier in the year - bushfires. This mask has 3 filter ports, and the large one at the front takes a very course 1 1/4" thread. I found the 1 1/4" BSP thread will get about a 3/4 turn and make a reasonable seal, threadtape or plumbing sealant would make a solid seal in an emergency. This mask has the added advantage of being able to hook up an air feed line to the other 2 ports, which I can add in concentrated oxygen if needed.
https://www.ebay.com.au/itm/Indusry-Safety-Spray-paint-Supplied-Air-Fed-Respirator-System-For-6800-Gas-Gask-/264207440778

I used the 4 potentiometers to control the strength of the pump on in and out, as well as the length of the in and out breath. As you'll see in my crude arduino code, the pots basically divide the analogue signal by 100 and round (so instead of reading 0-1028 on the analogue port, they get a value of 0-10) making the pots able to have 10 steps from 0 to max volume, and I have arbitrarily set the breath (in and out) length to 4000ms.

The only other tricky part was wiring up the L298N motor driver so that it used the A and B motor outs in parallel. The L298N will only drive up to 2A, I needed at least 2.5A, so by running it in parallel I could get up to 4A. This is possible per the spec sheet on page 7, by bridging inputs 1 & 4 and 2 & 3. https://www.st.com/resource/en/datasheet/l298.pdf
Input 1&4 go to 5v, 2&3 to ground, enable A&B go to the arduino analogue pin out (in my code pin 9).

Here's my code for the arduino.

int breath = 1;

void setup() {
  Serial.begin(9600);
  pinMode(9, OUTPUT);
}

void loop() {
  int inP = analogRead(A0); // pot 1 - in breath pressure
  int outP = analogRead(A1); // pot 2 - out breath pressure
  int inT = analogRead(A3); // pot 3 - in breath time
  int outT = analogRead(A2); // pot 4 - out breath time

  int inP_v = round(inP/100)*25.5;  // take the value from the pot, divide by 100 and round, then multiply by 25.5 so the output value is a multiple of 255
  int outP_v = round(outP/100)*25.5;  // take the value from the pot, divide by 100 and round, then multiply by 25.5 so the output value is a multiple of 255
  int inT_v = round(inT/100)*400;  // take the value from the pot, divide by 100 and round, then multiply by 400 to get a proportion of 4000ms
  int outT_v = round(outT/100)*400;  // take the value from the pot, divide by 100 and round, then multiply by 400 to get a proportion of 4000ms

  if (breath !=0) {breath = 0;}
    else breath = 1;

  switch (breath) {
    case 0:
      Serial.print("Breath In. Pressure: "); Serial.print(inP_v); 
      Serial.print(". In Time: "); Serial.print(inT_v); Serial.println("ms.");
      analogWrite(9, inP_v);
      delay(inT_v);
      break;

    case 1:
      Serial.print("Breath Out. Pressure: "); Serial.print(outP_v); 
      Serial.print(". Out Time: "); Serial.print(outT_v); Serial.println("ms.");
      analogWrite(9, outP_v);
      delay(outT_v);
      break;
  }
}

driver
[sorry, there was a mistake in my image, I had wired the pins wrong in the previous image. Again, Pins 2&3 must be wired togehter and Pins 1&4 must be wired together for parallel use of the driver. Very sorry if people have blown their L298N's because of this].

Hopefully this helps someone. I've spoken with an ER doctor friend, who said using an inflation pump cant be any worse in an emergency than someone having to manually "bag" a patient for a couple of weeks! I haven't been able to run a water lift test as my hose isn't opaque, but I'll try to find some and report back. I'd also like to do a test running the pump overnight to see if the motor burns out cycling up and down.

Edit: I can report that the pump has survived an 8 hour test, I'll keep it running for the rest of the day to test for 24 hours. Seems promising so far, no obvious loss of power.

Hey, sorry for being late to the party

Can I use SmartElex 15S DC Motor Driver 15A (30A Peak) (https://robu.in/product/smartelex-15s-dc-motor-driver-13a-30a-peak/?gclid=CjwKCAjwps75BRAcEiwAEiACMazatx_J8pUB3IL4915iBznwlnsVFXsPhPsdaNhSU3eIoQcyIARvUhoC64IQAvD_BwE)
with a 75W (12V) pump

To make the circuit less complex, while using the same code and connections?

@adamcullen
Copy link

adamcullen commented Aug 12, 2020 via email

@gaurav12294
Copy link

gaurav12294 commented Aug 18, 2020

Thanks for all the help, but I am coming across a problem related to the switch control of the motor that I am using.

My switch responds to 1 click (CPAP mode) and 2nd click (BiPAP mode), but does not turn the device off for the 3rd click., additional clicks do not do anything. Below is my code, please suggest some solutions.

int pwm = 5;
int dir = A1;
byte switchPin = 2; // switch is connected to pin 2

byte buttonPresses = 0; // how many times the button has been pressed
byte lastPressCount = 0; // to keep track of last press count

void setup() {
pinMode(switchPin, INPUT); // Set the switch pin as input
digitalWrite(switchPin, HIGH);
pinMode(pwm, OUTPUT);
pinMode(dir, OUTPUT);
Serial.begin(9600); // Set up serial communication at 9600bps
}

void loop(){
if (digitalRead(switchPin) == LOW) // check if button was pressed
{
buttonPresses++; // increment buttonPresses count
delay(100);
}
if (buttonPresses == 4) buttonPresses = 0; // rollover every 4 press
if (lastPressCount != buttonPresses) // only do output if the count has changed

if (buttonPresses == 1){
  digitalWrite(dir, HIGH);
  analogWrite(pwm, 40);   
 
}

if (buttonPresses == 2){
  digitalWrite(dir, HIGH);
  analogWrite(pwm, 250);   
  delay(2000);                      
  analogWrite(pwm, 40);   
  delay(2000);
}



if (buttonPresses == 3){
  
  digitalWrite(pwm, LOW);
  
}

lastPressCount = buttonPresses;

}

@adamcullen
Copy link

adamcullen commented Aug 18, 2020 via email

@gaurav12294
Copy link

Hello everyone, I had built a working prototype with a commercial inflator pump which had a brushed DC motor; but it gave a maximum of 15 cm H2O. I want to improve it by keeping the same housing of the pump and replacing the motor by a better brushless or brushed DC motor.

Can you guys help me with the specifications required for the motor to get pressure of 40 cm H2O. I did not find a concrete motor which was selected in this thread. Any links will be very helpful.

@timhurdle
Copy link

timhurdle commented Sep 25, 2020 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
General Kanban
  
In progress
Development

No branches or pull requests