Arduino: Portable Two-Axis Stepper Control

Adding the Screen

In a previous tutorial we have seen how to run two stepper motors synchronously from a given start position to a defined destination using an Arduino and a very simple “user interface”. That user interface was restricted to some microswitches and LEDs, both installed on a breadboard.

As promised, this new instructable shows

  • how to add a small OLED screen,
  • how to run the Arduino, the motors, and the screen from one power supply, and
  • how to put it all in a fancy control box.

In the end, you will have a device for controlling the steppers not only at home, but also “in the wild”, e.g. from a USB power bank / portable charger.


  • 1x Arduino Nano
  • 2x 28BYJ-48 Stepper Motors (5V version) + ULN 2003 Driver Boards
  • 1x OLED Display 0.96 inch (160x80px, SPI, 8 pins, e.g. this one)
  • 3x Microswitches (optional, for testing)
  • 1x Breadboard (830 holes, optional, for testing)
  • 15x Jumper Cables (male-to-male, 10…20 cm, optional, for testing)
  • 12x Jumper Cables (male to-female, 10…20 cm, optional, for testing)
  • 1x Perfboard (70 mm x 30 mm – 24 x 10 holes)
  • 1x DC Barrel Jack Socket 5.5 mm/2.1 mm (for Panel Mount, w/ M7 Nut)
  • 3x Pushbuttons (7mm diameter, like these)
  • 1x Electrolytic Capacitor (100µF)
  • 1x 5V Power Supply
  • 1x 3D printer or 3D printing service (optional, a plastic box or wooden box would be ok, too)

Step 1: Adding the Screen

Adding the ScreenAs a first step, we revisit the circuit from the previous instructable and add the small 0.96″ OLED screen to the breadboard. This step is optional for testing all the components. Alternatively, you may skip it and proceed with Step 2.

Set-up your breadboard as shown in the pictures above:

  • Connect GND and 5V of the power supply to the upper red and blue rails of the breadboard.
  • Connect the upper and lower (blue) ground rails and the GND pin of the Arduino to one of it.
  • Pins D2 to D5 of the Arduino go to In1 to In4 of the first ULN2003 board.
  • Pins D6 to D9 of the Arduino go to In1 to In4 of the second ULN2003 board.
  • Pin D11 of the Arduino goes to the SDA (or Data or MOSI) pin of the display.
  • Pin D13 of the Arduino goes to the SCL (or CLK or SCK) pin of the display.
  • Pin A3 of the Arduino goes to the DC (or SA0 or A0) pin of the display.
  • Pin A4 of the Arduino goes to the CS pin of the display.
  • Connect the RST pin of the Arduino to the RST (or RES) pin of the display.
  • Connect the GND pin of the display to one of the ground rails and the Vin pin of the display to the 5V pin of the Arduino.
  • Connect the Arduino pins A1 to A3 to the microswitches. Connect the other side of the microswitches to GND. We will not use any resistors to avoid short circuits here, because we use the pull-up that are already integrated in the Arduino.

Please note: The 0.96” display I have used (see link under “supplies”) officially asks for a 3.3V operating voltage. Hence, all pings (i.e. Vin and signals) do not match the voltage of the output pins of the Arduino Uno/Nano/Mega which have 5V. Thus, you would need to connect the Vin pin to 3.3V and you need to add signal converters for the other lines either by using a bi-directional logic level shifter chip as presented here or a resistor-based voltage dividers as shown here. But: other tutorials like this one or this one propose to connect at least the signal lines directly to the output pins of the Arduino as I did in the sketch above, because the display is typically 5V-tolerant. Furthermore, some users in Arduino forums found the display flickering or entirely black when connecting Vin to 3.3V – which was my experience, too. Hence, I recommend to test your display first with the signal lines directly connected to the Arduino and Vin connected to 3.3V. If that does not work, switch Vin to 5V as in my approach described above.

Step 2: Adding the Software

SoftwareStart the Arduino IDE and open the attached .ino-file. The software structure is much the same as in the previous tutorial. Additionally, the Adafruit GFX library and the Adafruit ST7735 library will be required. If these are not yet installed, open please navigate to “Tools” → “Manage Libraries…”, then look for these libraries and hit the “Install” button. After all libraries are installed, compile the code download the resulting binary to your Arduino. If you have skipped Step 2 (i.e. if you did not set-up the elements on a breadboard), please go on with the next step now. Otherwise, the display should should look like on the picture above. Now, you can toggle the system through five menus using the left button. In each menu, the middle and right button will have different functions:

  • In the menu “Execute” you can start both motors for moving them synchronously to their start and end positions. Directly after power-on, this does not make much sense as we did not teach any start or stop positions, so they are all set to the positions where the motors have been when starting the system. Hence, please toggle the left button to go to the next menu.
  • In the following menus (“M1 – Start”, “M2 – Start”, “M1 – End”, “M2 – End”) you can drive each motor back and forth by pressing the the middle and right buttons in order to set their start or end positions for a later joint movement to be triggered in the “Execute” menu. You may toggle through menus as often as wanted to adjust the positions. If you enter one of these menus, you will see the current position of the addressed motor on top and the currently stored start or end position in brackets below. If you hit the middle or right button, you will overwrite the start or end position of this motor with a new value (which – after moving the motor back and forth) will be the position of the motor when leaving the menu. If you do not touch the middle or right button, the position will remain unchanged.
  • The last menu (“speed”) can be used for changing the system speed using the middle and right button. The display will show the speed (in degrees per second) and the resulting time it needs for the joint move between the currently selected start and stop positions.
  • After positions and speed are set, toggle the left button once more for going back to “Execute” where you can now move both motors synchronously to the end positions (right button) or back to the start positions (middle button).

Step 3: Soldering

Soldering 1 (2)Now, we want to get rid of the separated power sources for the motors (external power supply) and the Arduino with the attached display (powered over USB so far). As the motors are running with 5V, the simplest way is to disconnect the USB port and to connect the Arduino to the same 5V power source – not to the Vin pin (which expects at least 6V) but to the 5V pin. This is totally ok for the Arduino but please make sure that you use a regulated power supply or a battery set-up that does not exceed this value much. According to the manufacturers of the chips on the Arduino Nano/Uno/Mega, it is ok to go a bit higher than 5V, but you should not go over 5.5V. Usually, keeping the voltage constant is no problem for common power supplies, but there is one more thing taken to be into account: The 28BYJ-48 motors draw around 240mA each (see details here), and the Arduino and display together need around 100 mA. In total, this is not a big deal, but it will be slightly more than 500 mA, so

  1. do not power the entire set-up from an USB port of your PC or laptop and
  2. make sure the used power supply is rated for more than 500 mA output current.

Please note: When using one power source, we will link the 5V and GND lines of the motors and the Arduino. While you should not run the motors in this configuration from the USB port, it is totally ok to connect the system to the USB-port e.g. for changing the program of the Arduino if you do not start the motors. So, for reprogramming, please disconnect the external power supply, connect the device to the USB port, change the code and download it, disconnect the USB port, and start the motors only after re-plugging the external power supply.

Although the Arduino and the ULN2003 breakout boards cost next to nothing, I always like to keep the option to reuse them in other projects. Therefore, I suggest the following approach for the electrical circuit:

  • Use a 70 x 30 mm perfboard (24 x 10 holes).
  • On one side of the perfbard, solder two 15 pin (or 16 pin) female headers to it in the locations shown in the picture “Front View”. Then solder two short bridge cables (red for +, black for GND) on the same side.
  • Solder the cables (for the buttons and motors around 8…10 cm, for the display around 10…12 cm) to the board in the highlighted holes. (Note: All the soldering is done on the back side really, but all the cables and the header are placed on the front side).
  • Flip the board. Refer to the “Back View” picture and use some solder to make bridges between the headers and the cables which are marked by a darker brown tone. (Please note: The cables will come in from the front side, they are just shown for here for a better overview).
  • Next, add a 100µF electrolytic capacitor to the front side (…and solder it on the back side…) as shown, and complete the bridges. This capacitor is in its place to help the Arduino and the power supply to overcome power drops, if the motors are temporarily producing high loads. With a proper battery or power adapter, this is probably unnecessary for the used steppers, as they draw very constant and low currents. Furthermore, the ULN2003 breakout boards feature a small 100nF capacitor themselves. However, it is a good practice to place the 100µF capacitor here to protect and help the Arduino with power spikes or drops.

Now, you have a perfboard that can host the Arduino, but there are a lot of loose cables. Basically, there are three options for connecting them to the screen and the ULN boards:

  1. Solder them directly to the corresponding pins of the breakout boards and the buttons.
  2. Solder them to male/female headers that can be plugged in the board connectors.
  3. Crimp them to such headers for establishing plugged connections.

In the picture, I have chosen the second option because it appears to be the fastest method and I am not planning to plug in/out the connectors many times.

As a last statement on the soldering process, it should be mentioned that there are several different ways to arrange the same elements, e.g.:

  • Instead of soldering the cables to the perfboard, you could solder additional headers in their places. This way, all connections can be done using standard jumper cables.
  • You could solder a female header directly to the Arduino, use jumper cables for connecting all elements from here, and join the common signals (+ and GND) with small clamps. This way, no perfboard is required.
  • You could detach the ULN2003 chips from the breakout boards and solder them together with some 100nF capacitors, the Arduino and the screen to a single perfboard. This way, no additional wiring is required, and you would save a little more power which is “wasted” for lighting the LEDs on the ULN boards.
  • You may solder the buttons directly to the perfboard. The decision is yours. The way proposed above, however, is the way to go if you are willing to use the design for the housing described in the next step.

The decision is yours. The way proposed above, however, is the way to go if you are willing to use the design for the housing described in the next step.

Step 4: Living in a Box

 electronics connectedHaving all the electronics connected is nice, because we can now easily run it everywhere if we have a suitable power source. As we use 5V, standard power banks are perfect for that. But up to now, these electronics are very unprotected, so we need a housing for making the device really “portable”. For doing so, you may mount the elements to any suitable plastic or wooden box.

Alternatively, the design from the attached STL files can be 3D printed (at home or by a 3D printing service). If you have these elements, follow this sequence:

  • Fix the power jack using its M7 nut on the side of the “back housing“.
  • Screw mount the Arduino (4 M2x8 screws and 4 M2 nuts) and the ULN boards (8 M3x8 screws and 8 M3 nuts) to the “back housing”,
  • Next, screw mount pushbuttons (with their M7 nuts) and the display (4 M2x8 screws and 4 M2 nuts) to the “front housing”.
  • Add the motor cables (from ULN boards to 28BYJ-48 motors).
  • Then push-in the “motor-cut filler” and “USB-cut filler” in the “back housing“.
  • As a last step, mount the “front housing” to the “back housing” using 4 M4x25 screws and 4 M4 nuts.
  • The “hook” is optional, if you plan to hang-up the control anywhere.


  • Add the screws from the outside and the nuts to the inside of the housing as shown in the pictures.
  • The housing is quite compact, so you may need to use some tweezers to hold the nuts while fixing the screws.
  • The elements should be sufficiently fixed if you use only two screws and nuts per board.

Concerning the motor cables, some self-made or ready-made extension cables could be very useful as the original cables are too short in many cases. Ready-made cables can be found from different suppliers labeled as “JST-XH 4s balancer cables”. If you buy them, make sure to order “4s” cables, as these have five lines which are required for our motors. In the end, these cables may be curled up badly, as they have only single, non-joined wires. Hence, I found some spiral cable hoses very useful for preventing knotted cables.

Step 5: Where to Go From Here?

 two motors on a LEGO test bench The control box can be applied to various two axis “machines”. The intro video of this tutorials shows a little demo driving two motors on a LEGO test bench with different gear ratios in sync. You can find the used 28BYJ-48-to-Lego adapters in the attached STL files (sorry: LDRAW and Blender files cannot be uploaded here).

Read more: Arduino: Portable Two-Axis Stepper Control

Leave a Comment

Your email address will not be published. Required fields are marked *