pachterlab / poseidon

poseidon system - open source syringe pumps and microscope for laboratories
https://pachterlab.github.io/poseidon
BSD 2-Clause "Simplified" License
171 stars 54 forks source link

Recoding the arduino code #14

Closed Xqua closed 5 years ago

Xqua commented 5 years ago

Hi,

I'm cleaning the code of the arduino code. It's really hard to debug because of the very high number of switch case statements ! So I'm putting it all in loops. For example, runfew() becomes


void runFew() {
  // First we determine the direction of movement. If 1, then it's forward, otherwise it's -1.
  // We use 1 and -1 so that we can multiply any number and reverse the math, minimizing lines of code 
  int direction = 1;
  if (strcmp(dir, "B") == 0) {
    direction = -1;
  }
  // Second we set the distance to move for each stepper.
  // We use direction and multiply the value saved in the distances array;
  // The distances array is set above to default to 999999 if 'RUN' else, the value set.  
  for (int i = 0; i < 3; i += 1) {
    if (motors[i] == 1) {
      toMove = direction * distances[i];
      steppers[i].move(toMove);
    }
  }
  // Finally the main loop where we move and check the steppers status
  // We declare an array to store the status of each stepper  
  int stepperStatus[3] = [0, 0, 0];
  // Then we loop until that sum is equal to the number of selected steppers
  // That number is stored in the motors array, 1 for selected, 0 otherwise
  // If we have 1 and 3 for example motors = [1, 0, 1] => sum = 2 
  while (array_sum(stepperStatus) != array_sum(motors)) {
    // We iterate over the 3 possible steppers
    for (int i = 0; i < 3; i += 1) {
      // If this stepper is selected
      if (motors[i] == 1) {
        // Ask the stepper to move to position at constant speed. 
        steppers[i].runSpeedToPosition();
        // Check if it reached it's position
        if ((direction * steppers[i].distanceToGo()) => 0) {
          // If yes then store that value in the stepperStatus array.
          stepperStatus[i] = 1;
        }
      }
    }
    getDataFromPC();
  }
  clearVariables();
}

I have a few questions though! Why do you use the runSpeedToPosition() instead of the run() function ? It will work just fine, but will not allow for the use of the acceleration parameter as per the documentation (https://www.airspayce.com/mikem/arduino/AccelStepper/classAccelStepper.html#a9270d20336e76ac1fd5bcd5b9c34f301)

I don't think for microfluidics application that the acceleration matters?

Anyhow I'll be doing a series of PR soon.

sbooeshaghi commented 5 years ago

Clever solution! This was my first time coding in Arduino and my first 'naive' solution was switch cases.

Also apologies for getting back to you so late, I was on vacation and school just started back up. This looks good! I am now available and will review the PR's as they come in.

To answer your questions: I was using runSpeedToPosition() in the testing phase since I was first and foremost concerned with testing constant speed flow rates. I do think the run() function should be used with an acceleration parameter as you suggested for the following reason:

The use case when using acceleration would be to do whats called "gradient flow" pumping, where the acceleration is set as constant such that the flow rate increases from 0 to a maximum value over the course of an experiment.

Xqua commented 5 years ago

Awesome !

I'm finished the first pass of cleaning. Now I'm testing the new code. I'll let you know as soon as it's functional ;)

Xqua commented 5 years ago

Also, why do you run the servos at 1/32 microstepping ? It's veryyyy fine grain ! Any reason ?

sbooeshaghi commented 5 years ago

Great question! So I opted for 1/32 microstepping to get flow rates ~900 µL/hr using a 3mL syringe. This is necessary for the types of biological experiments we are doing in the lab (droplet based microfluidics).

Take a look at this paper https://www.nature.com/articles/nprot.2016.154#f1. We pump oil and water (with a few other chemicals) to create hydrogel beads! These beads are then used in a single-cell RNA sequencing experiment, here's a good paper describing the application (which may not be good depending on your background): https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5900446/

I am currently in the process of characterizing the "accessible" flow rates for each microstepping setting to see what flow rates an experimenter can achieve with the different microsteps. For example, if I set my microstepping to 1/32, can I get carriage speeds of 10mm/s? First pass experiments say no, and as such I would like to find what is the maximum carriage speed achievable under 1/32 microstepping, and under 1/16, and under 1/8 etc..

I have used 1/32 microstepping in the pumps to make hydrogel beads, using microfluidics, and have successfully synthesized the beads (of the appropriate size) as described in the paper above. So I know that 1/32 works for pumping at ~900µL/hr flow rates! The goal now is to be more concrete about microstep setting and achievable flow rate, and thats what these next basic tests that I am running, are for.

Xqua commented 5 years ago

so I've pushed a PR https://github.com/pachterlab/poseidon/pull/13 I have one question about it. When I perform my tests, I see that 4000 steps == 1mm, whereas you had something more on the 200 steps. But we have the same hardware ... is it a discrepancy ?

Xqua commented 5 years ago

Ok I see about your 1/32 ... The only advantage I can see is for slower yet SMOOTH flow rate ! Say ... 100ul/h and yet smooth. It might be the good setting !

I know of thoose beads ;) I'm building this rig for doing inDrop ^^

Munfred commented 5 years ago

I know of thoose beads ;) I'm building this rig for doing inDrop ^^

Oh nice! We're also setting up inDrops. Which lab do you work at?

Xqua commented 5 years ago

Extavour Lab at Harvard

sbooeshaghi commented 5 years ago

Thank you again @Xqua for the suggestions! I went ahead and merged your PR. I also made a few updates to the code which allow for changing the microstepping value in the GUI (but an associated hardware change is still needed.)

Im going to close out this issue since I think everything is resolved. Please let me know if you come across anything else!

Xqua commented 5 years ago

Sounds good ! I'll let you know if I see other bugs as I'm.using this or if I do other enhancements. On Jan 12, 2019 22:31, Sina Booeshaghi notifications@github.com wrote:Closed #14.

—You are receiving this because you were mentioned.Reply to this email directly, view it on GitHub, or mute the thread.