Initial Design

Today we brainstormed our ideas regarding the construction of our titration project. We thought about how we will be using air cylinders and VEX parts in order to create a final sketch for our construction. It will require that we 3D print a couple of parts for the arm and turntable connections. Our complex design will require the usage of counterweights to balance out the weight of the DC motor and 4 inch air cylinder.

        In addition to sketching, we planned out the location of various electrical components on our breadboard by sketching them on a colored piece of paper. Some of the components we will be using are an H-bridge, 3 MOSFETs, 3 buttons, I2C LCD screen, 3 diodes, and a Vernier breadboard adapter. We planned everything out so that all those components can fit onto our full-sized solderless breadboard.

IMG_1900.JPG

An initial design that became our final design

One of our initial designsIMG_6754.JPG

Another of our initial designs

5/15/17

        Until today, we made a lot of progress on making 3D models for our project. We have to make parts to secure the air cylinders as well as for the DC motor and pH sensor. In addition, we designed a new stirrer for our DC motor. In chemistry, we wrote the code for automatic titration, which was successful. We were able to titrate 3D printer bath solution, which is very basic with the pH of 12. We used 1.0 M HCl to titrate it. Our system got it from pH of 12 to 8, which can be perfected with further trials and code changes. Also, we started building an arm using VEX parts mounted on top of a turntable. We will soon incorporate two air cylinders to lift the arm and push the turntable.

5/17/17

Today we finished 3D modelling all our parts to hold the motor and pH sensor in place. Additionally, we created the code for the pneumatic system and the tests we did produced promising results. We need to continue fine tuning this, however, to make sure it works consistently. Lastly, we finalized our vex structure and it has maintained a sturdy and stable position throughout all our tests.IMG_3890.JPG

IMG_3891.JPG

5/19/17

        Today we worked on the placement of various components onto the board. We finally got our DC motor and pH sensor holder, which we attached to our arm. We used a ziptie to secure the DC motor in its spot. We used multiple screws to attach the turntable and the 7 in air cylinder to our base. We ran our full code, and it was successful in general, apart from the holder occasionally hitting it styrofoam cup. We will fix this by adjusting some positioning and cutting the cup down slightly to prevent contact with the pH sensor during our official run.

IMG_3902.JPG

This is our holder for the motor and sensor

IMG_3897.JPG

Our initial design for the holder that we later adjusted

IMG_3899.JPG

Us trying to adjust the height of the cup by putting wood under it

IMG_3901.JPG

Trying on our holder with the DC motor, stirrer, and pH sensor

IMG_3898.JPG

Our tray with the base from the 3D printer in a bottle

Code

/***

 ** Code and Project Made By **

 *  Mykyta Y. Solonko  *

 *  Ahmed T. Malik  *

 *  Jesus R. Crespo  *

 *

 * Project Started

 * April 12th, 2017

 *

 * Twitter Accounts

 * @m_solonko

 * @HackmedMalik

 * @JES_Crespo

 *

 * Personal Websites

 * msolonko.net

 * hackmedmalik.com

 * jchtml.com

***/

#include <Wire.h>

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F,16,2);

double ph, volume, deltaPH, slope;

int run = 1;

bool a = false;

void setup()

{

   

    /*** initialize the LCD ***/

    lcd.init();

    lcd.backlight();

    lcd.clear();

    /*** REMINDER: DO NOT CHANGE FROM PULLUP ***/

    pinMode(3, INPUT_PULLUP);

    pinMode(4, INPUT_PULLUP);

    pinMode(5, INPUT_PULLUP);

    pinMode(2, OUTPUT);

    pinMode(6,OUTPUT);

    pinMode(10, OUTPUT);

    digitalWrite(6, HIGH);

    Serial.begin(9600);

    ph = volume =0;

    //xOuts(3,2);

    //xOuts(15,1);

    //xOuts(200,0);

}

void loop()

{

   getph();

    Serial.print("pH:");

    Serial.println(ph);

    Serial.print("Vol: ");

    Serial.println(volume);

    lcd.setCursor(0, 0);

    lcd.print("Vol: ");

    lcd.print(volume);

    lcd.print(" mL");

    lcd.setCursor(0, 1);

    lcd.print("pH: ");

    lcd.print(ph);

    //buttons left to right increase the time interval for the solution being dropped

    /*if (b) {//our program for the actual experiment

       

         //NICK

        analogWrite(9, 150);

        if(ph>10){

            release(1200);

        }

        else if(ph>8.5){

            release(500);

        }

        else if(ph>7){

            release(20);

        } else{

            delay(10000);

            if (ph <= 7) {

                b = false;

                digitalWrite(9, LOW);

            }

        }

        delay(2000);*/

         //NICK

       

        /* //JESUS

       

        */ //JESUS

   // }

    if(a){//this is our actual code for running

        digitalWrite(6, LOW);

        delay(5000);

        digitalWrite(10, HIGH);

        delay(5000*2);

        getph();//reads pH

        digitalWrite(6, HIGH);

        delay(5000);

        getph();

        analogWrite(9, 150);

        releaseVolume(36.0);//function releases a specified volume

        analogWrite(9, 0);

        getph();

        delay(5000);    

        digitalWrite(6, LOW);

        delay(5000*2);

        getph();

        digitalWrite(10, LOW);

        delay(5000*2);

        getph();

        digitalWrite(6, HIGH);

        a = false;

    }

        if(digitalRead(4)==0){

        a = true;

    }

   

}

void xOuts(int num, int type) {

    for (int i = 0; i < num; i++) {//releases a specified number of drops, squirts, or streams

        if (type == 0) {

            release(20);

            delay(40);

        } else if (type == 1) {

            release(500);

            delay(500);

        } else {

            release(1200);

            delay(1200);

        }

    }

}

void release(int ms){//releases fluid for some time

  digitalWrite(2, HIGH);

  delay(ms);

  digitalWrite(2, LOW);

  volume += volumeCalc(ms);

  delay(1000+ms);

}

void releaseVolume(float v){//releases specified volume

digitalWrite(2, HIGH);

delay(v/(30.0/36*8.1/1500*1.15));

digitalWrite(2, LOW);

volume+=v;

 lcd.setCursor(0, 0);

    lcd.print("Vol: ");

    lcd.print(volume);

    lcd.print(" mL");

   

}

double volumeCalc(int ms) {//calculated volume given milliseconds

    return 8.1/1500*ms*1.15;

}

void getph(){//gets pH

   int samples = 20;

    int aRead = 0;

    for (int i = 0; i < samples ; i++)

    {

        aRead += analogRead(A0);

    }

    double voltage = 5.0 * aRead/ (1023 * samples);

    ph = 14 - voltage/0.25;

    lcd.setCursor(0, 1);

    lcd.print("pH: ");

    lcd.print(ph);

}

Final Design

Overall, our project was quite successful. We were able to get a fully functioning pneumatic arm that transfers the pH sensor and motor between two cups. However, this project was not without its issues. Setting up the pneumatic system was significantly more difficult than we anticipated because of how much variability exists within the air pressure setup. Although the pumps extend and contracts exactly the same way every time, that did not ensure that the arm’s movements would follow suit. Thus, we had to conduct a lot of testing and retesting to try to finalize the pattern for the arm. Additionally, obtaining a proper holder for the sensor and motor was quite difficult as well since we had to print several times to discover new flaws in each iteration. The one aspect we had nearly perfected from the start, however, was our dripping system. Throughout our tests our system almost always dispensed the desired amount of liquid with a great deal of accuracy. Eventually, after fine tuning our arm and pneumatic setup, combined with the precision of the dispenser, we produced a successful titration project.

        Overall, we learned that the key to a successful project is simplicity. We were at first planning to make the four inch cylinder elevated in the air, pushing the holder up and down. Soon, however, we realized that we can make a simple first class lever system that is easily attachable to the board. This notion of simplicity definitely applied to the programming part as well. We at first had our automatic titrating code be just three “if” statement. Later, however, we started making the algorithm more complex by calculating the slope of the curve and seeing how close it is to infinity. The close it is, the more neutral our solution is. After many hours of time, we realized that our program mathematically made no sense, which convinced us to go back to the simple solution from the beginning. If we were to do this project again, we would probably make a more stable VEX platform instead of spending a lot of time 3D printing various parts, easily replaceable by VEX.