Skip to main content

Project: Arduino XZ dip coater

This project outlines, without going into too much detail, how to build a small XZ robot based on Arduino Uno and Firgelli miniature linear actuators. The electronics and programming skills needed are low. Mechanical skills required (to build something sturdy) are average to okay, meaning, you have to be able to make something solid ;)

(Note: this is an old project, so stuff might be outdated.)

What you'll need:
  • Arduino Uno
  • Motor shield:
  • LCD:
  • 12V/2A power supply and a power connector for the Arduino
  • Either a lot of jumper wires or some pcb, pinheaders and wires
  • Two Firgelli linear actuators (12V, linear position feedback, choose stroke and ratio to your needs): L12-P and L16-P
  • Ball bearings, aluminium strips and screws+bolts
    • (Update 2018: I see that Firgelli sells drawer slides nowadays! What a coincidence :) )
  • The Arduino sketches and libraries. I've used Arduino version 1.0.6 to compile the firmware (newer versions might not work, for some reason).

Put it all together

The complete system is drawn schematically in the figure below. The Arduino will hold the firmware to control the motor shield and read the current position of the linear actuators, while displaying any useful information on the LCD.

Motor shield

The Velleman motor shield is a nice product, apart from the fact that Arduino pin A5 is used to monitor the external power supply, since we need pin A5 for I2C control of the LCD. So, if you plan to install an LCD (or other I2C hardware), remove (or don't mount) R9, R10 and C3 (10k, 100k and 22uF) from the Velleman board. Jumper settings for this project are: PWMA:6, DIRA:7, PWMB:9, DIRB:8, power:EXT. After the motor shield is correctly assembled and configured, place it on the Arduino board.
Alternative, the official Arduino motor shield can be used. In this case, change PWM and DIR pins in /libraries/XY/XY.cpp to the pins used by this shield. Also, disable (cut) the current sensing jumpers on the back of the board.

Linear actuators

The Firgelli linear actuators are composed of two parts. A servo motor controls the speed at which the actuator moves. A multiturn potentiometer is connected to the servo motor and is used for position feedback. Simply: the resistance of the potentiometer gives the position of the actuator. Since we want to accurately control the position of the actuators, the firmware has a so-called PID controller that reads the current position (from the potentiometer) and sets the speed of the actuator until the actual position equals the desired position.
For each actuator, connect the red wire to output 1/3 of the motor shield. Black wire goes to 2/4. Connect the yellow wires to Arduino's AREF pin, and the orange wires to GND. The purple wires each go to an Arduino analog input: A0 and A1.



If you want to connect an I2C LCD, connect SDA and SCL to Arduino pins A4 and A5, respectively, and connect the power supply wires to GND and 5V. For LCDs with the LCD03 protocol, the firmware works out of the box. For different LCDs, change /sketches/dipcoater.ino to suit your needs: change the include at the top to the desired library, then change the instantiation and initialization of the LCD in the code.

Power supply

Connect the 12V power supply both to the Arduino power input and to the motor shield power input.

Mechanical hardware 

From a local hardware shop, I got some ball bearings that are used for drawers (the thingies that make drawers slide in/out). I sandwiched these between aluminum strips which are held apart with some screws and bolts. This works amazingly well!

Running the dip coater

The idea behind this dip coater is that it can submerge something in a solution for a certain time, a second solution for a certain time, a third ... etc., while repeating this cycle as often as you want. The firmware (/sketches/dipcoater.ino) has few parameters to control the sequence, which are stated at the top of the code just below the includes. A short explanation follows.

NUM_CYCLESint#The total number of cycles the dip coater has to run.
NUM_STEPint#The total number of steps in each cycle.
x_dist[NUM_STEP]doublecmDistance between each dipping container. Starting at X=X_START, the dipping sequence advances by x_dist(current_step) between steps.
x_wait[NUM_STEP]intsecThe number of seconds the dip coater is down (dipping) at each step.
X_STARTdoublecmStarting position in the X direction. Should only be changed for a good reason (e.g. obstruction of the dip coater at X=0). If the first dipping jar is not at X=0, set the position using the first number in the x_dist[] array.
Y_UPdoublecmUp position of the dip coater.
Y_DOWNdoublecmDown position of the dip coater.

Look at this little video to get an impression:

Running your own program

The sketch /sketches/random/random.ino contains the bare minimum code, and does random walks over the entire range the actuators can span. Use this sketch if you want to build your own functionality into anything containing one or two linear actuators. IMPORTANT:If you change the linear actuator stroke (mine are 10 and 14 cm for the L12-P and L16-P, respectively), you have to change the TRAVERSE_X and TRAVERSE_Y constants in /libraries/XY/XY.h to match the maximum actual stroke difference you measure between fully retracted and fully contracted actuator shafts.

Fine-tuning the PID

Adjust the PID values according to the forces the actuators have to exert on the system you built them into. To do this, change the values in /libraries/XY/XY.cpp. Parameters given to the functions PIDX.SetTunings(0.1,0.1,0) and PIDY.SetTunings(0.1,0.1,0) are P, I and D, respectively. A quick guide to heuristic PID tuning can be found here.


  1. Hi,

    Firstly, thanks for detailed explanation. I built the given procedure with some components. It worked as expected. But, now I want to replace Velleman with official Arduino Motor Shield. I changed the source code and disable the current sensor. But,
    Now, It does not work correctly. Because, disable current sensor on A0 and A1 is not applicable for Arduino. I think these values are required for XY pid function. But, You suggest to disable the sensor. I am confused with this step. Please clarify the below statement:

    Also, disable (cut) the current sensing jumpers on the back of the board.

    Thanks in Advance

    1. Hi retto,

      Thanks for the nice comment. I'm very glad that you built this project!

      The statement refers to the official Arduino Motor Shield ( On that page, it says: "If you don't need the Brake and the Current Sensing and you also need more pins for your application you can disable this features [sic] by cutting the respective jumpers on the back side of the shield."

      So, you have to cut the current sense jumpers going to A0/A1 on the back of the official motor shield. The reason is that I've used those input pins to read out the linear actuators' position potentiometers. I guess (but I'm not sure) that you could also use A2/A3 for the potentiometer readout, and leave the current sense intact. For some reason I chose not do that, but to be honest I cannot remember why I made this decision (it's a few years ago that I made this).

      I hope this helps! If not, please let me know and I'll try to dig a bit deeper into it.

      Cheers, René

    2. Hi Becker,

      Thanks for your detailed response. I solved the problem. Currently, It is working as expected with Official Motor Shield. I changed the pins to A2/A3 and update the software. So, It is working as expected.

      Thanks In Advance


Post a Comment

Popular posts from this blog

Tutorial: freeDSP classic and Ubuntu 16.04

So, last week I ordered a freeDSP kit, assembled it and tried to program it on an Ubuntu machine using the freeUSBi programmer. I couldn't get this to work, so I switched from the freeUSBi programmer to an Arduino micro. Since I now finally got it to work, I'll share my experiences and what I find the easiest way to work with Linux and freeDSP.

Hardware needed:
A freeDSP classic board + power supply (for testing, I'm using a USB port's 5V supply)An Arduino micro Software needed:
Arduino IDE (install the latest version from (install the latest version from Windows 7 inside VirtualboxInstall SigmaStudio inside Windows 7 (from Before getting started, please read the Getting started manual created by the freeDSP people. Most of the information I got from there, with some tweaks to get it working from Ubuntu.

Step 1. Create a firmware (hex) file Boot Windows 7 inside Virtualbox, start SigmaStudio and create a new projec…

Project: Floating book shelves

I decided I wanted to make bookshelves in our living room. On one of our stranger walls. It is 1 m wide, 3 m high and after 1.5 m up it slowly starts to extend to the right, over our desk and maps.

This is the result - "floating" book shelves:

What you'll need:
Wooden planks (I used scaffolding planks: 18~19 cm x 250 cm, 3 cm thick)Wooden rods, 3 cm thickDowel pins, 10 mm x 4 cmWood glueScrews and plugs (screws should be 2 cm longer than the plugs) for wall-mountingOptional: paint (for either/both spacers, pillars and shelves) Step 1. Design As I like to make stuff as cheap as possible while still looking awesome, I started with sourcing cheap wood. Since a few years, hipsters in Amsterdam are being 'creative' with scaffolding planks ("steigerplanken"), which come in lengths up to 3 m with a fixed width of a little less than 20 cm and which are generally made of spruce ("vuren") or pine ("grenen"). This'd make great wood for the b…