Precise Peristaltic Pump

Intro: Precise Peristaltic Pump

We are a student team from different disciplines of the RWTH Aachen
University and have created this project in the context of the 2017 iGEM competition.

After all the work that went into our pump, we would like to share our results with you!

We built this peristaltic pump as generally applicable liquid handling solution for any project which requires transportation of liquids. Our pump is capable of precise dosing and pumping, providing a wide range of dosing volumes and flow rates to maximize possible applications. Through 125 dosing experiments we were able to demonstrate and quantify the accuracy of our pump. For a tubing with 0,8 mm inner diameter and any flowrate or dosing volume within the specifications we could show an accuracy better than 2% deviation from the set value. Given the results of the measurements, the accuracy can be improved even further if the speed of the calibration is adjusted to the required flow rate.

The pump can be controlled without programming knowledge via the built-in LCD display and a rotary knob. In addition, the pump can be remotely controlled via USB by serial commands. This simple way of communication is compatible with common software and programming languages (MATLAB, LabVIEW, Java, Python, C#, etc.).

The pump is simple and inexpensive to manufacture, with all the parts totaling less than $100 compared to $1300 for the cheapest comparable commercial solution we could find. Besides a 3D printer, only common tools are needed. Our project is open source in terms of hardware and software. We provide the CAD files for the 3D printed parts, a complete list of all required commercial components and their sources, and the source code used in our pump.

Step 1: Check Specifications

Check the specifications and the discussion of accuracy attached below.

Does the pump meet your requirements?

Step 2: Gather Components

1x Arduino Uno R3/ compatible board
1x Stepper motor (WxHxD): 42x42x41 mm, Shaft (ØxL): 5x22 mm
1x Power supply 12 V/ 3 A, connector: 5.5 / 2.1 mm
1x Step motor driver A4988
1x LCD module 16x2, (WxHxD): 80x36x13 mm
3x Needle bearing HK 0408 (IØ x OØ x L) 4 mm x 8 mm x 8mm
1x Encoder 5 V, 0.01 A, 20 switch postions, 360 °
1x Pump tubing, 1.6mm wall thickness, 0.2m
4x Foot self-adhesive (L x W x H) 12.6 x 12.6 x 5.7 mm
3x Straight pin (Ø x L) 4 mm x 14 mm
1x Control knob (Ø x H) 16.8 mm x 14.5 mm
1x Potentiometer/ Trimmer 10k
1x 220 Ohm Resistor
1x Capacitor 47µF, 25V

Wiring:
1x PCB (L x W) 80 mm x 52 mm, Contact spacing 2.54 mm (CS)
2x Pin strip, straight, CS 2.54, nominal current 3A, 36 pins
1x Socket strip, straight, CS 2.54, nominal currrent 3A, 40 pins
1x Cables, different colors (e.g. Ø 2.5 mm, cross section 0,5 mm² )
Heat shrink (suitable for cables, e.g. Ø 3 mm)

Screws:
4x M3, L = 25 mm (length without head), ISO 4762 (hex head)
7x M3, L = 16 mm, ISO 4762 (hex head)
16x M3, L = 8 mm, ISO 4762 (hex head)
4x Small tapping screw (for LCD, Ø 2-2.5mm, L = 3-6 mm)
1x M3, L=10mm grub screw, DIN 916
1x M3, nut, ISO 4032

3D printed parts: (Thingiverse)
1x Case_main
2 x Case_side (3D print not necessary => milling/cutting/sawing)
1x Pump_case_bottom
1x Pump_case_top_120°
1x Bearing_mount_bottom
1x Bearing_mount_top

Step 3: Post Processing of 3D Prints

The 3D printed parts have to be cleaned after printing
to remove any residues from the printing process. The tools we recommend for postprocessing are a small file and a thread cutter for M3 threads. After the printing process most of the holes have to be widened by using a suitable drill. For the holes that contain M3 screws, a thread has to be cut with the above mentioned thread cutter.

Step 4: Cables & Wiring

The core of the circuit consists of the Arduino and a perfboard. On the perfboard is the stepper motor driver, the trimmer for the LCD, the 47µF capacitor and connections for the power supply of the various components. In order to turn off the Arduino by the power switch, the power supply of the Arduino was interrupted and led to the Perfboard. For this purpose, the diode which is located on the Arduino directly behind the power jack was unsoldered and brought to the perfboard instead.

Step 5: Hardware Settings

There are three settings that need to be made directly on the circuit.

First the current limit for the step motor driver must be set, by adjusting the little screw on the A4988. For example, if the voltage V_ref between screw and GND in the on state is 1V, the current limit is twice the value: I_max = 2A (this is the value we used). The higher the current, the higher the torque of the motor, allowing higher speeds and flow rates. However, also the power consumption and the heat development increases.

Furthermore, the mode of the stepper motor can be set via the three pins which are located on the top left of the stepper motor driver (MS1, MS2, MS3). When MS2 is at + 5V, as shown in the wiring diagram, the motor is operated in quarter step mode, which we used. This means that exactly one step (1.8 °) is performed for four pulses that the stepper motor driver receives at the STEP pin.

As last value to set, the trimmer on the perfboard can be used to adjust the contrast of the LCD.

Step 6: Test Circuit and Components

Before assembly it is recommended to test the components and the circuit on a breadboard. On this way, it is easier to find and fix possible mistakes.

You can already upload our software to the Arduino, to try all functions beforehand. We published the source code on GitHub:

https://github.com/iGEM-Aachen/Open-Source-Peristaltic-Pump

Step 7: Assembly

The video shows the assembly of the components in the intended sequence without the wiring. All connectors should first be attached to the components. The wiring is best done at the point where all the components are inserted, but the side walls have not yet been fixed. The hard to reach screws can be easily reached with a hex-wrench.

1. Insert the power switch and the encoder into their designated hole and fix them to the case. Attach the control knob to the encoder – be careful – once you attached the knob, it might destroy the encoder if you try to remove it again.

2. Attach the LCD display with small tapping screws, make sure to solder the resistor and wiring to the display before assembly.

3. Fix the Arduino Uno board to the case using 8 mm M3 screws.

4. Insert the step motor and attach it to the case together with the 3D printed part (Pump_case_bottom) using four 10 mm M3 screws.

5. Attach the perfboard to the case – make sure you soldered all components to the perfboard as shown in the wiring diagram.

6. Wire the electronic parts inside the case.

7. Close the case by adding the side panels using 10x 8 mm M3 screws.

8. Assemble the bearing mount as shown in the video and attach it to the motor’s shaft using a 3 mm grub screw

9. Finally, attach the counter support for holding the tube (Pump_case_top_120°) with two 25 mm M3 screws and insert the tubing. Insert two 25 mm M3 screws to keep the tubing in place during the pump process

Step 8: Insert Tubing

Step 9: Get Familiar With the User Interface (manual Control)

The user interface provides a comprehensive control of the peristaltic pump. It consists of a LCD display, a control knob and a power switch. The control knob can be turned or pushed.

Turning the knob allows to select from different menu items, the menu item on the upper line is currently selected. Pushing the knob will activate the selected menu item, indicated by a blinking rectangle. The blinking rectangle implies that the menu item is activated.

Once the menu item is activated, it starts depending on the selected item either an action or allows the change of the corresponding value by turning the knob. For all menu items connected to a numerical value the knob can be held to reset the value to zero or double pushed to increase the value by one-tenth of its maximal value. To set the selected value and deactivate a menu item the knob needs to be pushed a second time.

The power switch will immediately shut down the pump and all its components (Arduino, step motor, step motor driver, LCD), except when the pump is connected via USB. The Arduino and the LCD can be powered by USB, so that the power switch will not affect them.

The pumps menu has 10 items, which are listed and described below:

0|Start
Start pumping, the operation mode is depending on the mode selected at “6) Mode”

1|Volume
Set the dosing volume, is only considered if “Dose” is selected at “6) Mode”

2|V.Unit:
Set the volume unit, options are:
“mL”: mL
“uL”: µL
“rot”: rotations (of the pump)

3|Speed
Set the flow rate, is only considered if “Dose” or “Pump” is selected at “6) Mode”

4|S.Unit:
Set the volume unit, options are:
“mL/min”: mL/min
“uL/min”: µL/min
“rpm”: rotations/min

5|Direction:
Choose pumping direction: “CW” for clockwise rotation, “CCW” for counterclockwise

6|Mode:
Set operation mode:
“Dose”: dose the selected volume (1|Volume) at the selected flow rate (3|Speed) when started
“Pump”: pump continuously at the selected flow rate (3|Speed) when started
“Cal.”: Calibration, pump will perform 30 rotations in 30 seconds when started

7|Cal.
Set calibration volume in mL. For calibration, the pump is run once in calibration mode and the resulting calibration volume which was pumped is measured.

8|Save Sett.
Save all settings to Arduinos EEPROM, values are retained during power off and reloaded, when the power is turned on again

9|USB Ctrl
Activate USB Control: Pump reacts to serial commands sent via USB

Step 10: Calibration and Try Dosing

Performing a proper calibration before using the pump is crucial for precise dosing and pumping. The calibration will tell the pump how much liquid is moved per rotation, so the pump can calculate how many rotations and which speed is needed to meet the set values. To start the calibration, select the Mode “Cal.” and start pumping or send the calibration command via USB. The standard calibration cycle will perform 30 rotations in 30 seconds. The volume of liquid pumped during this cycle (calibration volume) should be measured precisely. Ensure, that the measurement is not affected by drops sticking to the tubing, the weight of the tubing itself or any other interferences. We recommend using a microgram scale for calibration, as you can easily calculate the volume, if density and weight of the pumped amount of liquid is known. Once you measured the calibration volume you can adjust the pump by setting the value of menu item “7|Cal.” or attaching it to your serial commands.

Please note that any change after calibration to the tubing mount or the pressure difference will affect the precision of the pump. Try to perform the calibration always at the same conditions, at which the pump will be used later. If you remove the tubing and install it again in the pump, the calibration value will change up to 10%, since to small differences in positioning and force applied to the screws. Pulling on the tubing will also change the positioning and therefore the calibration value. If the calibration is performed without pressure difference and the pump is later used to pump liquids at another pressure it will affect precision. Remember even a level difference of one meter can create a pressure difference of 0.1 bar, which will have a slight influence on the calibration value, even if the pump can reach a pressure of at least 1.5 bar using the 0.8 mm tubing.

Step 11: Serial Interface – Remote Control Via USB

The serial interface is based on the Arduino’s serial communication interface via USB (Baud 9600, 8 data bits, no parity, one stop bit). Any software or programming language capable of writing data to a serial port can be used to communicate with the pump (MATLAB, LabVIEW, Java, python, C#, etc.). All functions of the pump are accessible by sending the corresponding command to the pump, at the end of each command a new line character '\n' (ASCII 10) is required.

Dose: d(volume in µL),(speed in µL/min),(calibration volume in µL)'\n'

e.g.: d1000,2000,1462'\n' (dosing 1mL at 2mL/min, calibration volume = 1.462mL)

Pump: p(speed in µL/min),(calibration volume in µL)'\n'

e.g.: p2000,1462'\n' (pump at 2mL/min, calibration volume = 1.462mL)

Calibrate: c'\n'

Stop: x'\n'

The Arduino environment (Arduino IDE) has a built-in serial monitor, which can read and write serial data, therefore serial commands can be tested without any written code.

Step 12: Share Your Experiences and Improve the Pump

If you have built our pump, please share your experiences and improvements in software and hardware on:

Thingiverse (3D printed parts)

GitHub (software)

Instructables (instructions, wiring, general)

Step 13: Curious About IGEM?

The iGEM (international Genetically Engineered Machine) Foundation is an independent, non-profit organization dedicated to education and competition, the advancement of synthetic biology, and the development of an open community and collaboration.

iGEM runs three main programs: the iGEM Competition - an international competition for students interested in the field of synthetic biology; the Labs Program - a program for academic labs to use the same resources as the competition teams; and the Registry of Standard Biological Parts - a growing collection of genetic parts used for building biological devices and systems.

http://igem.org/Main_Page

Share

    Recommendations

    • Audio Contest 2018

      Audio Contest 2018
    • Optics Contest

      Optics Contest
    • Electronics Tips & Tricks Challenge

      Electronics Tips & Tricks Challenge

    21 Discussions

    0
    None
    AdamB454

    Question 5 weeks ago

    Would it be at all possible add in the menu dosing times and how much to dose? And or a extra motor?

    0
    None
    NataliaT

    Question 2 months ago on Step 5

    I´m continuining with your design, perfboard details (pictures from back of the board) not here to confirm some connections but even though moving forward. All my connections are on place, motor fairly moved but nothing else. Now measuring Vref on driver and no V detected, not sure how the driver burnt out. Paying attention to the circuit, ENABLE pin from driver is not connected and is not at the setup of the code, I thought ENABLE was critical to make a motor work. Can you explain me why you are not using it for this circuit so I can learn from this project? Maybe I burnt my popolu due to bad perfbaord connection and not using ENABLe pin. Your answer and a picture from back side of the perfboard with final connections and 12V inlet will help me a lot. Thanks!

    1 more answer
    0
    None
    iGEM_AachenNataliaT

    Answer 2 months ago

    I'm sorry, I have no access to the pumps right now and can't send you the picture of the back side of the perfboard. The wiring diagram of step 4 should provide all necessary information.

    The enable pin can be left unconnected, since the ENABLED pin is set to LOW (=enabled) by default on the motor driver PCB. https://forum.pololu.com/t/a4988-and-nothing-happ...

    There are many good tutorials on how to run a stepper motor using an A4988 driver and an arduino. Maybe this one could help, to get your stepper motor running: https://howtomechatronics.com/tutorials/arduino/ho...

    If you are unsure, if your motor driver is damaged, have a look at this discussion: https://forum.pololu.com/t/how-to-check-if-a4988-i...

    I would recommend that you test each component (stepper motor, LCD, encoder) of our pump individually using a breadboard and small self written arduino programs. This way you can familiarize yourself with all the functions, learning step by step how to build the pump.

    I hope that helps and good luck on your project :)

    0
    None
    NataliaT

    Question 3 months ago

    Hi, question again! How did you connect power source to the power switch? Did you add a ac-DC female adaptor (wiring the switch to the power female terminal board?) as you are not using arduino power plug anymore? Can you upload pictures of the real perfboard finished (not the diagram) and the power plug solution connected to the switch? The diodo from arduino is really tiny, how did you manage to sold it to the perfboard and to disolder from arduino without burning out the board? Many thanks again for your support and patience!!!

    0
    None
    NataliaT

    Question 3 months ago on Step 4

    is it possible for you to share a closer pic of the pcb? I´m not able to distinguish the diode you desoldered from arduino on pcb and how everything is connected there. It will be my first arduino project so I´m learning sorry! I want to add 3 more steppers to have a 4 motor pump to dose things on my lab. Do you think that replicating the dsign for one motor but for 4 is possible? I read that I will need to use a I2C adaptor for lcd to decrease de amount of pins used. No idea then about the code, but want to merge other project on instructables (a perisltatic pump system with 4 motors to dose dye and prepare colored paint) with yours. Thanks for your guidance, I love your machine!

    2 more answers
    0
    None
    NataliaTNataliaT

    Answer 3 months ago

    thanks for being so gentle uploading the pics!! You rock. I´ve ordered the I2C adaptro to reduce pins and add more motor...Will try to change the code, not sure if I´m gonna make it as I´m so newbie! Will share results with you all if God helps me! LOL

    0
    None
    iGEM_AachenNataliaT

    Answer 3 months ago

    We are glad that you are interested in building our pump! I added a few close ups to step 4, additionally you can download Fritzing (http://fritzing.org/home/) and have a look at the original wiring file (attached to step 4).

    It should be possible to control 4 pumps, if you have enough pins. The additional pumps and the I2C control of the LCD will require some changes in the code, though.

    Good luck on your project :)

    0
    None
    StasN3

    Question 4 months ago

    Thank you for your Peristaltic pump project.

    I assembled the pump according to your instructions, but the stepper motor can not turn around (rests on the hose). But when I connect this stepper motor to my 3d printer and rotate the axis using the encoder, it rotates perfectly. Prompt please in what there can be a problem?

    1 more answer
    0
    None
    iGEM_AachenStasN3

    Answer 4 months ago

    There are several possible reasons, you could try to narrow down the problem:
    Does the stepper motor turn, if no tubing is inserted?

    If it does, the torque is too low to compress the flexible tube. Maybe the motor current is too low (check power supply, if it's strong enough, see step 4 => increase current limit). Another possible cause is, that the gap between bearings and 3D-printed part is too small for the tubing (imprecise print, try to increase the gap size using sandpaper on the printed arc, or slightly loosen the screws on the arc).

    If it does not turn, there is probably a problem in the wiring or the step motor driver is damaged. (check wiring & step motor driver)

    0
    None
    paul_80

    Question 7 months ago

    Hi

    I really like this project. I have sourced the parts and and waiting for them to arrive

    However, I am having trouble uploading the ino file to my Ardunio

    I have installed both library files but get the following error message:

    Arduino: 1.6.11 (Mac OS X), Board:
    "Arduino/Genuino Uno"

    failed MSpanList_Insert 0x310000
    0x66fd094baff2 0x0

    fatal error: MSpanList_Insert

    runtime stack:

    runtime.throw(0x2b050b)

    /usr/local/go/src/runtime/panic.go:491
    +0xad fp=0x7ffeefbff430 sp=0x7ffeefbff400

    runtime.MSpanList_Insert(0x2ce168,
    0x310000)

    /usr/local/go/src/runtime/mheap.c:692
    +0x8f fp=0x7ffeefbff458 sp=0x7ffeefbff430

    MHeap_FreeSpanLocked(0x2cad60, 0x310000,
    0x100)

    /usr/local/go/src/runtime/mheap.c:583
    +0x163 fp=0x7ffeefbff498 sp=0x7ffeefbff458

    MHeap_Grow(0x2cad60, 0x8, 0x0)........and so on.

    3 more answers
    0
    None
    iGEM_Aachenpaul_80

    Answer 7 months ago

    We are glad that you build our pump - if you like, let us know when your pump is working :)

    The warnings point out that we did a problematic conversion from one data type to another. Some char* varibales were initialized with string constants (char* var = "text"), which can cause errors if one tries to write to the variables afterwards. The program worked fine despite the warnings, since we never changed these variables.

    With some small changes the problem seem to be completly solved. I uploaded the new code as v1.01 on GitHub.

    0
    None
    paul_80paul_80

    Answer 7 months ago

    Sorted, just re-installed library files and uploaded fine!

    0
    None
    paul_80paul_80

    Answer 7 months ago

    Update: I updated Arduino software to version1.8.5 but now get the following errors:

    Arduino: 1.8.5 (Mac OS X), Board: "Arduino/Genuino Uno"

    Desktop/Peristaltic_Pump_Software_v1.0/Peristaltic_Pump_Software_v1.0.ino:108:17:
    warning: deprecated conversion from string constant to 'char*'
    [-Wwrite-strings]

    menu[0].suffix = "RUNNING!";

    .....followed by a stream of similar errors



    0
    None
    fdonskoj

    Question 8 months ago on Step 6

    Hello. I downloaded your sketch program for arduino. But she does not want to compile on, Wednesday arduino 1.8.5. How can I fill a sketch in Arduino Uno R3?

    4 more answers
    0
    None
    iGEM_Aachenfdonskoj

    Answer 8 months ago

    I can't reproduce the same error, but I get another error message stating that our file name is invalid. After changing the file name there is no error anymore - at least when I try to open the file.
    Try to download the renamed file from GitHub, can you open it?

    If it's still not working, can you open other Arduino Sketches? Additionally you could try to copy the source code as text from GitHub and insert it into an empty Arduino file you created.

    0
    None
    fdonskojfdonskoj

    Answer 8 months ago

    Farther. I click OK. An empty window is opened and the error is in the bottom.

    Имя файла Arduino Software - Open Source Peristaltic Pump.ino неверное: проигнорировано
    java.io.IOException: Не найдено правильных файлов с кодом
    at processing.app.Sketch.listSketchFiles(Sketch.java:117)
    at processing.app.Sketch.(Sketch.java:54)
    at processing.app.Editor.handleOpenInternal(Editor.java:1938)
    at processing.app.Editor.(Editor.java:340)
    at processing.app.Base.handleOpen(Base.java:838)
    at processing.app.Base.handleOpen(Base.java:824)
    at processing.app.Base.handleOpen(Base.java:820)
    at processing.app.Base.handleOpen(Base.java:816)
    at processing.app.Base.handleOpenPrompt(Base.java:803)
    at processing.app.Editor$7.actionPerformed(Editor.java:547)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
    at javax.swing.AbstractButton.doClick(AbstractButton.java:376)
    at javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:833)
    at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:877)
    at java.awt.Component.processMouseEvent(Component.java:6533)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
    at java.awt.Component.processEvent(Component.java:6298)
    at java.awt.Container.processEvent(Container.java:2236)
    at java.awt.Component.dispatchEventImpl(Component.java:4889)
    at java.awt.Container.dispatchEventImpl(Container.java:2294)
    at java.awt.Component.dispatchEvent(Component.java:4711)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
    at java.awt.Container.dispatchEventImpl(Container.java:2280)
    at java.awt.Window.dispatchEventImpl(Window.java:2746)
    at java.awt.Component.dispatchEvent(Component.java:4711)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
    at java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:90)
    at java.awt.EventQueue$4.run(EventQueue.java:731)
    at java.awt.EventQueue$4.run(EventQueue.java:729)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

    0
    None
    fdonskojfdonskoj

    Answer 8 months ago

    He says what:
    Error while opening sketch: "C:\Arduino Software - Open Source Peristaltic Pump\Arduino Software - Open Source Peristaltic Pump.ino"

    0
    None
    iGEM_Aachenfdonskoj

    Answer 8 months ago

    Hi, we are using the same version of the Arduino IDE.

    My first guess would be that the ClickEncoder and TimerOne library are missing. By the end of our project we were so familiar with Arduino, that we forgot to mention some basic steps in our instructions.

    Our software uses two libraries (ClickEncoder.h & TimerOne.h), which are required to be installed from a .zip-file before. You can find a brief tutorial on how to install libraries here:
    https://www.arduino.cc/en/Guide/Libraries#toc4

    Required libraries:
    https://github.com/0xPIT/encoder
    http://playground.arduino.cc/Code/Timer1

    If thats not working, do you get an error message if you try compiling? If so, what does it say?

    0
    None
    iGEM_AachenJamesD452

    Answer 8 months ago

    We are happy to hear that you are interested in our pump! We did the wiring on both sides of the perfboard to avoid most of the cross-overs. The diagram in step 4 shows all required connections on the topside for a better overview. There are no hidden connections on the underside.

    I noticed that a small part of the 5V line was missing - this is corrected now. Was this missing part the reason for your question?

    Sadly, we have no picture of the underside, but I uploaded the original Fritzing file if you would like to have a closer look at the connections. Please feel free to ask, if you have any further questions.