DNA electrowetter device

Hi, I am quite new to arduino, and I have been working on a project with more biochemical applications. The project involves using two L3 motor shields, an arduino uno, muliple solenoid valves, and a micro SD card reader. The goal was to have sequentially pulsating electrodes, with solenoid valves activating when a letter was read from a text file on the micro SD card. I have been going at this every way I can, and still only the electrode portion is working, since the solenoid valves are not turning on. Here is my full code:

#include <Arduino.h>
#include <stdint.h>
#include <SD.h>
#include <SPI.h>

int dataPin = 10; // DIOA
int blPin = 11; // BL
int polPin = 12; // POL
int dirPin = 13; // DIR
int clockPin = 14; // CLK
int latchPin = 15; // LE
int solenoidPin1 = 1;
int solenoidPin2 = 2;
int solenoidPin3 = 3;
int solenoidPin4 = 4;
int solenoidPin5 = 5;

int A = solenoidPin1;
int G = solenoidPin2;
int C = solenoidPin3;
int T = solenoidPin4;
int U = solenoidPin5;

uint64_t one = 1;
uint64_t data;
int d = 2000;
int solenoidPin6 = 6;
int solenoidPin7 = 7;
int solenoidPin8 = 8;

void writeData(uint64_t data) {
  char* arr = (char*) &data;
  digitalWrite(latchPin, LOW);
  for (int i=0; i < 8; ++i) {
    char c = arr[i];
    shiftOut(dataPin, clockPin, LSBFIRST, c); 
  }
  digitalWrite(latchPin, HIGH);
}
int index = 0;








byte incomingByte;
byte note;
byte velocity;
byte midichannel;



byte serialData[1];
int nBytes = 0;





// PINS
#define PIN_FEEDBACK (A0)
#define PIN_LE (A1)
#define PIN_CLK (A2)
#define PIN_BL (A3)
#define PIN_DI (A4)
#define PIN_SWA (12)
#define PIN_SWB (11)

// SETTINGS
#define ELECTRODE_ARRAY_WIDTH 8
#define ELECTRODE_ARRAY_HEIGHT 8
const byte HV507_LOOKUP_TABLE [] = {4,5,6,7,12,13,15,14,20,22,23,21,28,31,30,29,36,39,38,37,47,46,45,44,55,62,61,53,54,63,60,52,51,59,56,49,58,50,57,48,43,42,41,40,34,33,32,35,26,25,24,27,18,16,17,19,9,8,10,11,0,1,2,3};
#define BAUD_RATE 115200
#define SERIAL_BUFFER_LENGTH 10
#define TEST_PROG

// VARS
bool electrodes[ELECTRODE_ARRAY_WIDTH][ELECTRODE_ARRAY_HEIGHT];
char serialBuffer[SERIAL_BUFFER_LENGTH];
uint8_t currentIndex=0;

// Electrode array code
void clearElectrodes() {
  for (int x = 0; x <ELECTRODE_ARRAY_WIDTH ; x++) 
    for (int y = 0; y <ELECTRODE_ARRAY_HEIGHT ; y++) 
      setElectrode(x,y,false);
}

void setElectrodes() {
  for (int x = 0; x <ELECTRODE_ARRAY_WIDTH ; x++) 
    for (int y = 0; y <ELECTRODE_ARRAY_HEIGHT ; y++) 
    setElectrode(x,y,true);
}

void setElectrode(int x,int y,bool state) {
  if(state != electrodes[x][y]) {
    electrodes[x][y]=state;
    sendElectrode(x,y);
  }
}

void sendElectrode(int x,int y){
  Serial.print(x);
  Serial.print(",");
  Serial.print(y);
  Serial.print(",");
  Serial.print(electrodes[x][y]);
  Serial.print("\n");
}

// Refer to HV507 datasheet
void writeHV507() {
  digitalWrite(PIN_LE, LOW);
  digitalWrite(PIN_CLK, LOW);
   
  for (int i = 0; i <64 ; i++) {
    digitalWrite(PIN_DI,electrodes[HV507_LOOKUP_TABLE[i]%8][HV507_LOOKUP_TABLE[i]/8]);
    digitalWrite(PIN_CLK, HIGH);
    digitalWrite(PIN_CLK, LOW);
  }

  digitalWrite(PIN_LE, HIGH);
  digitalWrite(PIN_LE, LOW);
}
File file;
String txtMsg = "";
int relay = 2;

void setup() {
  Serial.begin(BAUD_RATE);
  
  pinMode(PIN_LE, OUTPUT);
  digitalWrite(PIN_LE,LOW);
  pinMode(PIN_CLK, OUTPUT);
  digitalWrite(PIN_CLK,LOW);
  pinMode(PIN_BL, OUTPUT);
  digitalWrite(PIN_BL,HIGH);
  pinMode(PIN_DI, OUTPUT);
  digitalWrite(PIN_DI,LOW);
  
  pinMode(PIN_SWA, INPUT_PULLUP);
  pinMode(PIN_SWB, INPUT_PULLUP);

  clearElectrodes();
  writeHV507();
  digitalWrite(PIN_BL,HIGH);

  for (int x = 0; x <ELECTRODE_ARRAY_WIDTH ; x++) 
    for (int y = 0; y <ELECTRODE_ARRAY_HEIGHT ; y++) 
      sendElectrode(x,y);

  pinMode(13, OUTPUT);
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);  
  pinMode(clockPin, OUTPUT);
  pinMode(blPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
  pinMode(polPin, OUTPUT);
  pinMode(solenoidPin1, OUTPUT);
  pinMode(solenoidPin2, OUTPUT);
  pinMode(solenoidPin3, OUTPUT);
  pinMode(solenoidPin4, OUTPUT);
  pinMode(solenoidPin5, OUTPUT);
  pinMode(solenoidPin6, OUTPUT);
  pinMode(solenoidPin7, OUTPUT);
  pinMode(solenoidPin8, OUTPUT);

  pinMode(1, OUTPUT); //Sets the pin as an output
pinMode(2, OUTPUT); //Sets the pin as an output
pinMode(3, OUTPUT); //Sets the pin as an output
pinMode(4, OUTPUT); //Sets the pin as an output
pinMode(5, OUTPUT); //Sets the pin as an output
pinMode(6, OUTPUT); //Sets the pin as an output
pinMode(7, OUTPUT); //Sets the pin as an output
pinMode(8, OUTPUT); //Sets the pin as an output
  Serial.begin(9600);
  digitalWrite(blPin, LOW);
  digitalWrite(polPin, LOW); // INVERTING ALL OUTPUT
  digitalWrite(clockPin, LOW);
  digitalWrite(dataPin, LOW);
  digitalWrite(latchPin, HIGH);
  digitalWrite(dirPin, LOW);
  delay(1000);
  digitalWrite(blPin, HIGH);

while (!Serial) {

SD.exists("oligo.txt");

Serial.begin(9600);
  pinMode(relay, OUTPUT);
  pinMode(16, OUTPUT);
  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
file = SD.open("oligo.TXT", FILE_READ);
while (file.available()) {
      Serial.write(file.read());
      if (file) {
Serial.println("test.txt:");
    }
    int string1 [500000000000000000];
    File file = SD.open("oligo.txt");
if (file) {
  for (index = 0; index <= 9; index++) {
    int input = file.parseInt();
    string1[index] = input;
    Serial.println(input);
  }
  file.close();
}
}

}
}
 
  



#ifdef TEST_PROG
  int step = 0;
  long unsigned int lastT = millis();
#endif

int delayTime = 250;
void loop() {
  if(serialReadCommand()){
    writeHV507();
  }

  // Test program
  #ifdef TEST_PROG
    if(millis()-lastT>500){
      lastT = millis();
      switch(step){
    
        case 0: setElectrode(4,3,false);
        setElectrode(4,4,true);
        break;
        case 1:setElectrode(4,4,false);
        setElectrode(4,5,true);
        break;
        case 2:setElectrode(4,5,false);
        setElectrode(5,5,true);
        break;
        case 3:setElectrode(5,5,false);
        setElectrode(5,4,true);
        break;
        case 4:setElectrode(5,4,false);
        setElectrode(5,3,true);
        break;
        case 5:setElectrode(5,3,false);
        setElectrode(4,3,true);
        break;
        case 6:setElectrode(3,4,true);
        setElectrode(4,3,true);      }
      writeHV507();
      step ++;
      if(step > 5) step = 0;
    }
  
  
  
  

  if (Serial.readBytes((char*)'U',1) == U){
digitalWrite(solenoidPin5, HIGH); //Switch Solenoid ON
  delay(1000); //Wait 1 Second
digitalWrite(solenoidPin5, LOW); //Switch Solenoid ON
delay(1000); //Wait 1 Second
digitalWrite(solenoidPin6, HIGH);
delay(1000);
digitalWrite(solenoidPin6, LOW);
digitalWrite(solenoidPin7, HIGH);
delay(1000);
digitalWrite(solenoidPin7, LOW);
}
else{digitalWrite(solenoidPin5, LOW);
}
  
  if (Serial.readBytes((char*)'T',1) == T){
    digitalWrite(solenoidPin4, HIGH); //Switch Solenoid ON
  delay(1000); //Wait 1 Second
digitalWrite(solenoidPin4, LOW); //Switch Solenoid ON
delay(1000); //Wait 1 Second
digitalWrite(solenoidPin6, HIGH);
delay(1000);
digitalWrite(solenoidPin6, LOW);
digitalWrite(solenoidPin7, HIGH);
delay(1000);
digitalWrite(solenoidPin7, LOW);
  }
  else{digitalWrite(solenoidPin4, LOW);
}
  if (Serial.readBytes((char*)'C',1) == C){
    digitalWrite(solenoidPin3, HIGH); //Switch Solenoid ON
  delay(1000); //Wait 1 Second
digitalWrite(solenoidPin3, LOW); //Switch Solenoid ON
delay(1000); //Wait 1 Second
digitalWrite(solenoidPin6, HIGH);
delay(1000);
digitalWrite(solenoidPin6, LOW);
digitalWrite(solenoidPin7, HIGH);
delay(1000);
digitalWrite(solenoidPin7, LOW);
  }
  else{digitalWrite(solenoidPin3, LOW);
}
  if (Serial.readBytes((char*)'G',1) == G){

    digitalWrite(solenoidPin2, HIGH); //Switch Solenoid ON
  delay(1000); //Wait 1 Second
digitalWrite(solenoidPin2, LOW); //Switch Solenoid ON
delay(1000); //Wait 1 Second
digitalWrite(solenoidPin6, HIGH);
delay(1000);
digitalWrite(solenoidPin6, LOW);
digitalWrite(solenoidPin7, HIGH);
delay(1000);
digitalWrite(solenoidPin7, LOW);
}
else{digitalWrite(solenoidPin2, LOW);
}
  if (Serial.readBytes((char*)'A',1) == A){
    digitalWrite(solenoidPin1, HIGH); //Switch Solenoid ON
  delay(1000); //Wait 1 Second
digitalWrite(solenoidPin1, LOW); //Switch Solenoid ON
delay(1000); //Wait 1 Second
digitalWrite(solenoidPin6, HIGH);
delay(1000);
digitalWrite(solenoidPin6, LOW);
digitalWrite(solenoidPin7, HIGH);
delay(1000);
digitalWrite(solenoidPin7, LOW);
   }
   else{digitalWrite(solenoidPin1, LOW);
}
  writeData(one<<43);
  delay(delayTime);
  writeData(one<<42);
  delay(delayTime);
  writeData(one<<41);
  delay(delayTime);
  writeData(one<<40);
  delay(delayTime);
  writeData(one<<41);
  delay(delayTime);
  writeData(one<<42);
  delay(delayTime);

  


#endif

}



uint8_t serialReadCommand(){
  uint8_t number_of_commands = 0;
  while (Serial.available() > 0) {
    char recieved = Serial.read();

    serialBuffer[currentIndex] = recieved;
    currentIndex ++;
    if (currentIndex >= SERIAL_BUFFER_LENGTH) {
      // Invalid command: command is too long
      currentIndex = 0;
    }

    if (recieved == '\n' || recieved == '\r') {
      // Close string
      serialBuffer[currentIndex-1] = '\0';
      
      // Clear buffer for next serial transaction
      currentIndex = 0; 

      // Split the string
      char* commaIndex = strchr(serialBuffer, ',');
      if (commaIndex==NULL) {
        // Invalid command: command is malformed
        continue;
      }
      commaIndex[0] = '\0';
      char* secondCommaIndex = strchr(commaIndex+1, ',');
      if (secondCommaIndex==NULL) {
        // Invalid command: command is malformed
        continue;
      }
      secondCommaIndex[0] = '\0';

      int x = atoi(serialBuffer);
      int y = atoi(commaIndex+1);
      if(x<0 || x>=ELECTRODE_ARRAY_WIDTH || y<0 || y>=ELECTRODE_ARRAY_HEIGHT){
        // Invalid command: out of bound
        continue;
      }
      
      setElectrode(x,y,strcmp(secondCommaIndex+1,"0")!=0);
      number_of_commands += 1;
    }
  }
  return number_of_commands;
}

/*void btnMatrixTest(){
  for (int y = 0; y <ELECTRODE_ARRAY_WIDTH ; y++) 
    for (int x = 0; x <ELECTRODE_ARRAY_HEIGHT ; x++){
      clearElectrodes();
      electrodes[x][y]=true;
      writeHV507();
      Serial.print(x);
      Serial.print("\t");
      Serial.println(y);
      delay(500);
      while(digitalRead(PIN_SWA)){}
    }
}*/

I have tried using file.read() in the if statements, as well as only if (Serial.readBytes((char*)'C',1), and lots of mixes between the two. Each letter that is going to be read is only going to be either A, C, G, T, or U.
Could anyone could provide some input as to why the solenoid valves aren't working?

Could be a code, wiring, controller or power supply problem. Almost all of the information needed to even guess is lacking, so consider posting the required details.

The best approach to a complex project is to get one bit of it working at a time, then add another feature. If that fails, fix it before moving on. For example, you could start by writing a program that just turns on and off a solenoid.

You have some severe problems just in the setup routine, I did not look farther.

There are three Serial.begin() statements.
One of the Serial.begin() statements is within the "if (!Serial)", which also contains the code to initialize the SD card. On an UNO, !Serial will always be false, so none of that code will ever be executed.
You are setting pin 1 as an output - pins 0 and 1 are used by Serial, so you cannot use as input/output pins at the same time. You are also setting the pinMode of several pins a couple of times each - first with a variable name, then using the actual pin number.

Alright, I made said changes by removing the if (!Serial) component of the code, and changing pin outputs to fit the arrangement in the boards, however after compiling and uploading for test the valves still wouldn't work. I am gathering from this that there are more errors in the SD card initialization and array formatting. I had also changed around the character array for the SD card file text to be positioned after the SD card read code in the void setup(), which I suppose was hoping to be a bigger deal than it was. I am stacking two L3 motor shields on top of each other, on top of the arduino uno and wiring like that. Do you think this makes a difference? Or do you think there is an issue elsewhere?

Who knows if you don't answer @jremington 's questions.

Several more issues in the code, plus several issues in the wiring, the controller AND the power supply.

Hello abuet
What is a DNA electrowetter device?
Take some time and describe the desired function of the sketch in simple words and this very simple.
Have a nice day and enjoy coding in C++.

You may have other problems but it looks like you are focusing, at the moment, on reading from the SD card and interpreting the results.
Find a tutorial and set up a small environment, with the SD card reader, which you can test easily separate from your main code. If you have then a problem, post the smallest sketch which demonstrates it.
Interesting project by the way.

A DNA electrowetter is essentially a DNA synthesizer. It works by having a multi-electrode pad, which alternating charges on each can move a droplet from one to the next according to the charge direction. Using this, you can add reagents to the pad using solenoid valves and direct them to a reaction site for assembly. The goal is to have different solenoid valves add different nucleotide solutions according to a text file sequence, and follow them with both an oxidation reagent and a deblocking reagent. The final step would be to add en elution reagent solution, which would essentially remove the finished oligonucleotide from the reaction pad.

Ok so I have worked out some different code to try to get a more definite read of different letters from an SD card text file. I also wanted to share my fritzing blueprint of the circuit since I feel like the error lies in the pin connections, and thus my code cant act on the solenoids. Here is my fritzing circuit:


It should be noted that this circuit does not include the electrode pad for electrowetting, however that part is functioning fine. Although i did include the wiring up until the resistors connecting wires to the electrodes. And one thing that couldn't be shown on this image was that the arduino Uno would be stacked with the motor shield, with the motor shield on top.
If there are any ideas, it would be greatly appreciated!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.