Close
0%
0%

Microplate Reader

A High School project

Public Chat
Similar projects worth following
Micro Plate Reader Build

Here, three high school students will report the full process of creating their own low-cost micro plate reader. 

JPEG Image - 136.28 kB - 12/25/2020 at 02:52

Preview
Download

JPEG Image - 3.61 MB - 11/21/2020 at 06:50

Preview
Download

  • Week 13

    steven zhang4 days ago 0 comments

    This week is the first week after the Chinese new year break, we continued with the construction of the x/y axis of the plate reader. we redesigned the joint that connects the belt and reprinted the 3D model of the bumper. 

  • Week12 Day 3

    wwang01/23/2021 at 08:45 0 comments

    Today we mainly worked on fitting all the final versions of our models that we created, for instance, tightening our belts that control our X and Y axis again. Adding on, we continued working on our code that control the X and Y axis movements of the plate holder. For example, stopping when it hits the switch on the end of the track, and moving to the (0,0) position when activated. Along the way, we met quite a few difficulties such as short-circuiting, connecting the wrong wires with the Arduino board, and not finding the bugs in our codes. However, we were able to solve most of our issues in our code and looking forward to coding the LED lights next week!

    Our Code:

    // System Inialization Setup
    String protocolString = "";
    boolean protocolWait = false;
    String parsedString = "";
    int startIndex = 0;
    String totalString = "";
    String ledString = "";
    unsigned long Timecount1;
    unsigned long Durationcount1;
    unsigned long Time1;
    unsigned long Duration1;
    unsigned long Timecount2;
    unsigned long Durationcount2;
    unsigned long Time2;
    unsigned long Duration2;
    unsigned Direction1;
    unsigned Direction2;
    int DIRCount1 = 0;
    int DIRCount2 = 1;
    const int DIRPin1 = 2;
    const int STEPPin1 = 3;
    const int ENNPin1 = 8;
    const int DIRPin2 = 4;
    const int STEPPin2 = 7; 
    const int ES1 = 12;
    const int ES2 = 13;
    int STEPState1 = LOW;
    int DIRState1 = HIGH;
    int STEPState2 = LOW;
    int DIRState2 = HIGH;
    unsigned int XPosition;
    unsigned int YPosition;

    void initOutput() {
      //digitalWrite(ENNpin,HIGH);   // Disable motors
      //We are going to overwrite the Timer1 to use the stepper motors
      // STEPPER MOTORS INITIALIZATION
      // TIMER1 CTC MODE
      TCCR1B &= ~(1<<WGM13);
      TCCR1B |=  (1<<WGM12);
      TCCR1A &= ~(1<<WGM11); 
      TCCR1A &= ~(1<<WGM10);

      // output mode = 00 (disconnected)
      TCCR1A &= ~(3<<COM1A0); 
      TCCR1A &= ~(3<<COM1B0); 

      // Set the timer pre-scaler
      // Generally we use a divider of 8, resulting in a 2MHz timer on 16MHz CPU
      TCCR1B = (TCCR1B & ~(0x07<<CS10)) | (2<<CS10);

      //OCR1A = 125;  // 16Khz
      //OCR1A = 100;  // 20Khz
      OCR1A = 250;   // 8Khz
      TCNT1 = 0;

      TIMSK1 |= (1<<OCIE1A);  // Enable Timer1 interrupt
      //digitalWrite(ENNpin, LOW);   // Enable stepper drivers
    }
    void setup() {
      // put your setup code here, to run once:
      Serial.begin(115200);
      while (!Serial) {
        ; // wait for serial port to connect. Needed for native USB
      }
      pinMode(DIRPin1, OUTPUT);
      pinMode(STEPPin1, OUTPUT);
      pinMode(DIRPin2, OUTPUT);
      pinMode(STEPPin2, OUTPUT);
      pinMode(ENNPin1, OUTPUT);
      pinMode(ES1, INPUT);
      pinMode(ES2, INPUT);
      digitalWrite(DIRPin1, HIGH);
      digitalWrite(STEPPin1, LOW);
      digitalWrite(DIRPin2, LOW);
      digitalWrite(STEPPin2, HIGH);
      digitalWrite(ENNPin1, LOW);
      XPosition = 1;
      YPosition = 1;
      initOutput();
        while (HIGH != digitalRead(ES1) && HIGH != digitalRead(ES2)) {
        digitalWrite (DIRPin1, LOW);
        if (STEPState1 == LOW) {
          STEPState1 = HIGH;
          delayMicroseconds(100);
        } else {
          STEPState1 = LOW;
          delayMicroseconds(100);
        }
        digitalWrite (DIRPin2, LOW);
        if (STEPState1 == LOW) {
          STEPState2 = HIGH;
          delayMicroseconds(100);
        } else {
          STEPState2 = LOW;
          delayMicroseconds(100);
        }
        XPosition = 0;
        YPosition = 0;
      }
    }

    void loop() {
    //  Serial.println("pass");
      if (Serial.available() > 0) {
        protocolString = Serial.readString();
        Serial.println(protocolString);
        for (int i = 0; i <= protocolString.length(); i++){ // Analyze command string one character at a time
          parsedString...

    Read more »

  • Week 12

    wwang01/20/2021 at 08:53 0 comments

    As Spring Break begins, we have again several consistent days where we can come everyday to the lab. Yesterday and today are two quite busy ones, as we worked on several different aspects of this project, the 3D model parts, opto-mechanical parts, and also parts that needs to be laser cutted and fitted together for the optical areas of the microplate reader. We also designed and 3D printed several appropriate models used to place the switches along the X and Y axis, these are used to make the plate holder stop when it hits the extremes of the axes. 

    Adding on, we also used CNC to drill holes that are missing in the kits we purchased for the opto-mechanical parts. 

    Last but not least, we also worked drawing a few figures on Inkscape in order to laser cut them and fit all the optical components together. We kept redesigning these components since we had to constantly test out new ones, to see whether they worked better than the failed prototypes we designed earlier.

  • Week 11

    steven zhang01/19/2021 at 04:29 0 comments

    This week, we updated the circuit board (light and motor control board) for our micro-plate reader, it envolved  diffrent stages: 1. Design and update components on the previous board( the one we used before) and reroute the electric wire on the whole board. 2. update all the files to lichuang EDA ( BOM fule, pick and place file and Gerber file). 3. Order the board online and wait for EDA to manufacture and produce the board. As shown below, we are measuring the length between two female headers( the outlet). 

    https://www.bilibili.com/video/BV1ch411f7CY

    <iframe src="//player.bilibili.com/player.html?aid=203253323&bvid=BV1ch411f7CY&cid=271620831&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"> </iframe>   

    Here's the link to a video that shows how the micro-plate functions and how we adjust the detail of it. 

  • Week 9 +2/3 Days

    wwang12/27/2020 at 09:18 0 comments

    On Day 2 of Week 9, we suffered great loss, our belt receiving gear left us forever, so we decided to remake it with a higher infill rate. And today we finally assembled the X-axis and Y-axis components of the motor, with the belt included and gears needed to receive the belt! Actually a few days ago we already had 3D printed most of the components, however, many of the first draft components broke due to insufficient infill and  not careful handling. Therefore, we had to revise the models and reassemble them onto the assembled aluminium beams. 

    After we finished assembling these components, we then worked on the code to control both motors' movements and directions. Although it took some time, we were finally able to figure out the code suited: 

    // System Inialization Setup
    String protocolString = "";
    boolean protocolWait = false;
    String parsedString = "";
    int startIndex = 0;
    String totalString = "";
    String ledString = "";
    unsigned long Timecount1;
    unsigned long Durationcount1;
    unsigned long Time1;
    unsigned long Duration1;
    unsigned long Timecount2;
    unsigned long Durationcount2;
    unsigned long Time2;
    unsigned long Duration2;
    unsigned Direction1;
    unsigned Direction2;
    int DIRCount1 = 0;
    int DIRCount2 = 1;
    const int DIRPin1 = 2;
    const int STEPPin1 = 3;
    const int ENNPin1 = 7;
    const int DIRPin2 = 6;
    const int STEPPin2 = 5; 
    int STEPState1 = LOW;
    int DIRState1 = HIGH;
    int STEPState2 = LOW;
    int DIRState2 = HIGH;

    void initOutput() {
      //digitalWrite(ENNpin,HIGH);   // Disable motors
      //We are going to overwrite the Timer1 to use the stepper motors
      // STEPPER MOTORS INITIALIZATION
      // TIMER1 CTC MODE
      TCCR1B &= ~(1<<WGM13);
      TCCR1B |=  (1<<WGM12);
      TCCR1A &= ~(1<<WGM11); 
      TCCR1A &= ~(1<<WGM10);

      // output mode = 00 (disconnected)
      TCCR1A &= ~(3<<COM1A0); 
      TCCR1A &= ~(3<<COM1B0); 

      // Set the timer pre-scaler
      // Generally we use a divider of 8, resulting in a 2MHz timer on 16MHz CPU
      TCCR1B = (TCCR1B & ~(0x07<<CS10)) | (2<<CS10);

      //OCR1A = 125;  // 16Khz
      //OCR1A = 100;  // 20Khz
      OCR1A = 250;   // 25Khz
      TCNT1 = 0;

      TIMSK1 |= (1<<OCIE1A);  // Enable Timer1 interrupt
      //digitalWrite(ENNpin, LOW);   // Enable stepper drivers
    }
    void setup() {
      // put your setup code here, to run once:
      Serial.begin(115200);
      while (!Serial) {
        ; // wait for serial port to connect. Needed for native USB
      }
      pinMode(DIRPin1, OUTPUT);
      pinMode(STEPPin1, OUTPUT);
      pinMode(DIRPin2, OUTPUT);
      pinMode(STEPPin2, OUTPUT);
      pinMode(ENNPin1, OUTPUT);
      digitalWrite(DIRPin1, HIGH);
      digitalWrite(STEPPin1, LOW);
      digitalWrite(DIRPin2, LOW);
      digitalWrite(STEPPin2, HIGH);
      digitalWrite(ENNPin1, LOW);
      initOutput();
    }

    void loop() {
    //  Serial.println("pass");
      if (Serial.available() > 0) {
        protocolString = Serial.readString();
        Serial.println(protocolString);
        for (int i = 0; i <= protocolString.length(); i++){ // Analyze command string one character at a time
          parsedString = protocolString.substring(i,i+1); 
          if (parsedString == "~"){ // '~' Symbolizes the end of a command
            if (protocolString.substring(startIndex, startIndex+3) == "LED"){
              totalString = protocolString.substring(startIndex,i);
              Serial.println(totalString.length());
              if (totalString.length() <= 4){
                ledString = protocolString.substring(startIndex+3,i);
                if (ledString == "1"){
                  digitalWrite(2, !digitalRead(2));
                  }
                else if (ledString == "2"){...

    Read more »

  • week 10

    steven zhang12/27/2020 at 06:42 0 comments

    In the morning, we finalized the prototype for the x-y axis of the micro plate reader. Despite it is not the final model that we will be using, the prototype is functioning properly as it moves along the x-axis and y-axis. In the image below, you can see that the micro plate is ready !( somehow). 

    This is the position where the optical train will operate and illuminate the sample( just to show the idea). 

    In the afternoon, we learnt the coding part.  Our attempt is to expand our knowledge on coding and create a program for the blinking of LED light( we will replace LED light with motor when we master the coding part) However, all of us but warren failed to complete the program. ( warren is drawing the sketch for the prototype !!! featuring warren and Dr. xu). 

  • Week 9

    wwang12/24/2020 at 07:26 0 comments

    This week, we will be having four continuous days that we can utilize to continue work on our microplate reader, and because its Christmas Eve today we were all super happy!

    As we try try again to write out the code to control the number of times the LED light will blink, the duration of the light to be on, and the duration of the light to be off, one of us finally succeeded in writing out the code in the afternoon! The reason why we tried to write out the code to manipulate a LED light was because the code behind controlling a motor, in which regulates how the plate holder will move in both X and Y directions, is actually quite similar to the code controlling the LED light. The number of times the LED light will blink corresponds to the number of times the motor will move and the duration of each blink corresponds to the movement of each step of the motor's movements.

    Adding on, we also assembled the beams, the belt, and the track that regulates how the plate holder will move along the X-axis with those that control the plate holder moving along the Y-axis. 

    The sense of accomplishment, finally getting things done after weeks of preparation, drilling holes, 3D printing models, and learning how to code, feels just so good as our hears are filled with pride and happiness. 

  • week 8

    steven zhang12/19/2020 at 10:08 0 comments

    This week, we finalized the hole drilling part for our aluminium beam and constructed them together( as shown below). 

    This part will become our Y-axis of the micro plate reader. (ps: we are still printing the accessory for immobilization).

    In addition, we tried to figure out how to program the advanced code for the  microplate reader using Arduino.( we are testing it with the program of LED light. ( here's our progress, featuring Warren's laptop). 

  • Week 7

    liugodric12/12/2020 at 06:28 0 comments

    We finish the drilling of the aluminum bars for the x and y-axis of the microplate on the CNC. The milling model uploaded was designed last week. We ran the process without the blade once to make sure no errors were made. 

    We started to write the program to turn the LED lights on and off on the apparatus. The pin on the Arduino Uno we chose were 2 and 4. We utilized serial transmission to send the command to the Uno. Then, the serial monitor was used to sending commends that were present in the program to the Arduino. The lights are able to be controlled now. Parts of the program were referencing alternating sources. 

  • Week 6

    liugodric12/12/2020 at 05:57 0 comments

    We were not able to upload and report our progress last week, therefore, we are publishing week 5's log this week. Last week, after we successfully connected the belt, which allows the motor to control the plate holder to move along the X-axis, with the plate holder, we started to devise ways to enable the plate holder to move along the Y-axis. Since we cannot do the same thing with the Y-axis to make the plate holder move sideways because the beams have fixed positions and the only way to make the plate holder move along the Y-axis is to make the whole setup move altogether. Therefore, we begin to plan how are we going to drill the holes on the aluminum beams. We first created a 3D image of the beam via Fusion 360 and then utilized the manufacturing features of it and came up with the pathway of how the holes of the beams shall be drilled by CNC. Unfortunately, the builder we were working in had an interrupted electricity supply and we were not able to use anything, including machines, the wifi, and the plugs, that used electricity, so we went home early:)

View all 15 project logs

Enjoy this project?

Share

Discussions

steven zhang wrote 12/12/2020 at 04:14 point

http://labmedical.en.hisupplier.com/product-1196543-Microplate-Culture-Plate.html

Hi,  here is a link to the image of a "Micro Plate". 

They are used as small test tubes in modern enzyme-linked immunosorbent assay (ELISA).It is a fundamental tool in modern medical testing. 

  Are you sure? yes | no

Bharbour wrote 12/24/2020 at 11:08 point

Thanks! Interesting stuff

  Are you sure? yes | no

Bharbour wrote 10/31/2020 at 13:13 point

What is a "Micro Plate" ? What are they used for?

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates