The device we created is very complex and can be difficult to use as is. This is why we decided to create a software to act as an interface between the user and the machine.

The aim of the software is to simplify the use of the system to the maximum. That means that the user should be able to use it without any background knowledge on informatics, mechanics, and without even having used the machine before.

We decided to program the software using Python as it is a language that is widely documented and open-source.

Try it yourself! Download link

The first window that appears when the program is launched is the main window:

This window gives different choices to the user:

  1. If the user wants to create a new protocol, he can press the “Create a new Protocol” button.
  2. If the user wants to open a previously made protocol, he can press the “Modify an existing Protocol”.
  3. If the protocol is already defined, then the user can load the protocol, this will change the window showing the selected protocol, and the path of the chosen protocol will appear.

Once a protocol is loaded, the user can start the execution of the protocol, by pressing the “Begin Measure”.

When the user presses the “Create a new Protocol” button, a window appears:

This window is slightly modified once a protocol has been selected to be modified. By opening an already existing protocol, the protocol appears on the protocol part (right) of the window:

The way to create or modify a protocol is very simple. Let’s take a simple example: we have a solution and we want to measure the luminescence of this solution.

The first step will be to pipette a volume of this solution, and place it on the EWOD plate. Then we will have to move the drop from the pad where we dropped it to the pad where we can measure the luminescence, and finally take a measure of the luminescence.

From those three steps, we can easily define a protocol. We want to pipette a solution so we will press the “Pipet a solution” button. A new window opens:

This window allows the user to choose the solution from which to pipette. It also allows to define the volume. Note that our device has a certain resolution when pipetting a volume. The software has a built-in function that detects if there is a problem in defining this value. If a problem is detected, an information window appears to inform the user that his input can not be pipetted with the precision he desired. This same window offers to change the desired volume by a volume that the device is able to pipette.

Once the user is happy with the volume, pressing the “OK” button will close the window and save the choices. The command is then displayed on the main protocol window in the “Protocol” section:

This command does a little more than pipette a solution. In fact, it will pipette the solution, and move it on the EWOD plate. This means that our solution is now on the EWOD plate, on a pad signaled by a “D”:

To move the drop, we only have to select the pad where the drop is and then the pad where we want the drop to be. Once we have selected the two pads, a window appears to confirm the movement. The easiest way we found to verify the right positioning of the drops is by referring to their coordinates.

In our case we want to position the drop right under the light detector. The two pads we will therefore choose will be the pad marked with a D and the one marked with a C. Once the user is happy with the command, a new line appears on the protocol window:

Now that we have our solution right where we want it to be, we can measure its luminescence. This is done by pressing the “Measure the luminescence” button. A new window appears:

On this window, we can choose to do a series of measures. This is interesting if we want to see an evolution in the behaviour of a solution. As the captor is really precise and the measure is done automatically, we can perform a great number of measurements.

Once the parameters have been entered, the user only has to press the “OK” button to confirm his choice. Note that the hardware was not made to control the temperature at the sensor location. This could be an issue and thus the program informs the user if the time between measurement is too long or the number of measurements is too high. Here again, once the button pressed, a new line appears on the protocol.

All the commands are as easy to use as the ones presented. However, where our system is very interesting, is on the last command: “apply another protocol”.
Let’s take a concrete example of its use: we are measuring ten different solutions, each of them having to perform a thermic cycle before each measurement, and each cycle being different. In the lab this is a nightmare, as we would have to constantly change the program of a machine that could perform the heat cycle, then pipette the solution and measure it. Our solution allows to do this very easily: for each solution, we define a protocol that describes the cycle it has to undergo, by creating a path on the EWOD plate and by imposing the temperatures at each step of the cycle. Once the protocol is made for each solution, we just need to create another protocol that does all the previous protocols in a row, and ask the program to execute it as many times as we want. You can see that as a “for loop” but for biological protocols.

Now that we have seen how to create a protocol, let’s talk about executing it in our hardware. Once the protocol is done, the user must save it.

Once the protocol is saved, it is only a matter of loading it onto the software via the “Load a Protocol” button on the main window. Once the protocol is loaded, the path of the protocol will appear on the right panel of the main window.

Then, the user needs to press the “Begin Measure” button. At this point, the software will look for the hardware, connect to it and send the protocol, step by step. During the transmission, a feedback loop is applied, allowing the software to verify that the hardware applies the steps as commanded to. The data from the measurements will be saved temporarily on a “temp.txt” file, and at the end of the process, a window will ask the user to save it elsewhere on the computer. The output of the program is a .txt file. This allows any data manager to open it and use it.


All the protocol are .txt files. This is a simple choice that allows anyone to reuse the protocols for any other project. A series of protocols were developed during the project and can be accessed together with the source code of the program.

Future improvemens of the device

The software we developed is a solid basis for any improvement both on the device or on the project. With the combination of the software and the hardware, anyone can perform experiments that were difficult or impossible before. However, our device can only work for luminescence readings. To do fluorescence or absorption readings, minor changes need to be made on the hardware.

The possibility of reusing the basis we developed to create a more sophisticated machine has been taken into account, and the software is made to be really easily adaptable for any new ability the hardware might get.

As both the code and the hardware are open-source devices, we hope our device will be useful for other scientists that would want an automated machine, for a relatively low cost.

Communication with the hardware and hardware program


The software we have created needs to communicate with the hardware. We have described previously how we can command the device using an Arduino Mega. This means that we only need to find a way to communicate between the computer and the Arduino Mega. The easiest way to do this is to use the serial port. The serial port is a connection port that allows to communicate with an Arduino using a computer. It is used to send data to the Arduino, for example to upload a code to the Arduino. In our case we are going to use this connection port to command the Arduino.

The serial port

The serial port is a bi-directional port. This means that the computer can send and receive data through it (the same goes for the Arduino). This raises one evident issue: how can we be sure that the Arduino and the computer don’t use it at the same time?

The answer we developed is simple: we work on a signal/acknowledge architecture. When a message is sent, the receiver sends an acknowledgement code to tell the sender that it has received the message.

The downside of this technique is that we need to wait for the answer of the receiver before sending a new command. The Arduino is not made to be fast and in our case, this architecture leads to very slow transfer rate. In our case we need one second to transfer any command to the Arduino.

Another difficulty in this type of transfer is the stability of the transfer. Do we really receive the data we sent? To make sure of this, we used a very simple acknowledgement code: we send back the original message. As it happens, the serial port is very stable and we never had any problem with this transfer mode. Anyhow, in case of a problem, the software would detect it, and send the original command again.

This leads to a communication device between the computer and the Arduino that is very unlikely to fail. Now let’s look at the data we are sending

Encoding of the information

The longer the data sent, the more likely it is to be wrongly transmitted. The length of the data is therefore very important. In our case, we therefore worked with relatively short data signals (a few dozens of bytes).

In order to compress the information, we had to encode all the information. The easiest way to encode information is to look at what is paramount. For each command we therefore looked at what was essential, and we got to this structure:

  1. We need to define what we want to command
  2. We need to define the parameters of the thing we want to command

The way we developed this solution is by using a simple numerotation. For example, if we want to pipette something, we will send the number 3 to the arduino, and then we will send the volume and the solution.

This way of communication allows the Arduino to get the information sequentially and thus reduce the possible errors it could make. The same architecture is used to transfer all the commands

Applying the commands sent by the computer

As the computer sends first what it wants to command, and then sends the parameter, we have created a case algorithm. This means that the program will enter sub-programs in function of the type of command.

If we take the example of the pipette previously presented, if we send a 3, then the hardware program will enter the pipette sub-program. This allows the hardware to work a little less: it only has to compare values to get to the right program. This also allows to modify very easily the program if we want to add new specificities to the hardware.

Once we are in the right sub-function of the program, the computer sends another set of data: the command parameters. For example it will send the solution in which to pipette and the volume. Note that if there has been an error in communication to get to the right command, the computer would detect it and no action would be undertaken by the hardware.

At that point, the computer only has to wait for the hardware to finish its task. This type of exchange between the hardware and the computer works really well for all the commands but the temperature command. Let’s describe more in detail this last command.

Controlling the temperature

The control of the temperature is very important as if we heat for too long, or if we cool for too long, we might pass the desired temperature and potentially harm the solutions.

To prevent this, we need to verify constantly that the temperature is correct. This is done by a function that compares the temperature to a desired value sent by the computer. The correction of the temperature is described in the temperature command section of this wiki.

The time between two measurements is one second, which might seem long, but in fact is adapted to our system. As we have a correction that takes into account the behavior of the plate, one second is short enough to get to the right temperature.

This regulation of temperature is constant: after each command received or sent by the Arduino, the function is applied. This ensures that the temperature is correctly applied where it has to be.


To download the Arduino code, click here!