Introduction: Open Source Mechanical Ventilator

About: Father of 3, husband of one, I never can stand still and I am constantly either fixing something or building something.

This device has not been certified nor has been tested on any human or animal. I am sharing this project to inspire other Makers to create and develop better devices or as a starting point for companies that want to use this idea to develop for a medically approved ventilator.

This device does not include the expiratory valve nor the mask.




Arduino Nano

Voltage regulator (step down)

On-off switch


Servo (2 servos if you need more power)

3 potentiometers

Power supply (I am using a random 12 volts power supply)

Hard plastic sheets or thin plywood for the base

M3 screws (or similar)

M3 threaded rod (2*20 cm pieces)

2 skateboard ball bearings (or 4 if you use 2 servos)

2 short pieces of 8 mm rod (mine is carbon fiber, but wood, aluminum or steel is ok too)

Some pipe (silicon if possible. I do not have any, so I used gardening pipe for my model)

3D printer

Hand drill and drill bits

150 inox chimney pipe (other diameters can be used, but you will have to modify the piston and the cylinder retainers)

Hot Glue

1010 Aluminum extrusion for the arch (you can also use wood or plastic for the arch)

Step 1: Building Steps

Watch this video first:

Building the base:

My base is 30 x 30 centimeters and 4.5 cm tall. You can make it bigger, but not smaller than this because the pipes underneath would not fit.


See the attached schema.

Voltage regulator steps down to 6 volts. Do not run the servo power through the Arduino. You will burn it. Ground the servo to the Arduino.

Assembling the Breather:

Watch the video to learn how to assemble the cylinder, the rods, the piston, bridge, valves and pipes.

The cylinder is a piece of standard inox chimney pipe. I cut a 14 cm chunk out of a longer piece. I used metal scissors for that.

I used felt as piston rings. It took me some time to figure out how big those rings should be to properly seal the piston to the cylinder walls. In the 3D design, I have put a center piece that can be used or not, depending on the thickness of the felt you are using or is you want to have 2 seals or just one. In any case, you put the felt between the head and the tail of the piston, and you close the whole thing with 4 M3 screws.

Make sure the 2 valves are placed in the right direction. Both valves are installed in the same direction (slanted part on top)

Please note that if your servo cannot cope with the piston, you can add a second one by installing a second bridge with another servo. The piston tail can accommodate either one piston rod or 2. Both servos can be connected to the same Arduino pin (D9).

Step 2: Code

#include <Servo.h>
//Include LCD library
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

Servo myservo;  // create servo object to control a servo

int potpinvol = 0;  // analog pin used to connect the air volume potentiometer
int potpinvel = 1;  // analog pin used to connect the speed potentiometer

int valvol;    // variable to store the volume 
int valvel;    // variable to read the value from the analog pin
int dispvol;
int dispvel;

int pos = 0;    // variable to store the servo position
int vel = 0;    // variable to store the servo speed
void setup() {
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.

  lcd.print(" TLR Respirator");
  lcd.setCursor(0, 0);
  lcd.print("                ");

void loop() {
  valvol = analogRead(potpinvol);            // reads the value of the potentiometer (value between 0 and 1023)
  valvol = map(valvol, 0, 1023, 180, 0);     // scale it to use it with the servo (value between 0 and 180)

  for (pos = 0; pos <= valvol; pos += 2) {
    // in steps of 1 degree
    velocidad ();
    delay(valvel*2 );

  for (pos = valvol; pos >= 0; pos -= 2) {
    velocidad ();

void velocidad () {
  valvel = analogRead(potpinvel);            // reads the value of the potentiometer (value between 0 and 1023)
  valvel = map(valvel, 0, 1023, 10, 2);     // scale it to use it with the servo

void pantalla() {
  lcd.setCursor(0, 0);
  lcd.print("Volume: ");
  lcd.setCursor(9, 0);
  lcd.print ("   ");
  lcd.setCursor(9, 0);
  dispvol = map(valvol, 0, 178, 0, 100);

  lcd.print (dispvol, DEC);
  lcd.setCursor(13, 0);

  lcd.setCursor(0, 1);
  lcd.print("Speed: ");
  lcd.setCursor(7, 1);
  lcd.print ("   ");

  lcd.setCursor(7, 1);
  dispvel = map(valvel, 10, 2, 5, 30);
  lcd.print (dispvel, DEC);


Step 3: Print All This!

All elements are here:

Check the video. Some pieces need to be printed twice.

3D Printed Contest

Participated in the
3D Printed Contest