Drive up to 8 stepper motors in DMX with arpschuino.

driver and steppers

New update of our stepper motor tutorial (May 2023), one of the most visited, with the arrival of firmware 1.2 of the arpschuino32.

We are going to see how to drive powerful stepper motors, in DMX, with arpschuino (2 or 32) and different types of drivers.

arpschuino, arpstepper and steppers

Materials required:

  • arpschuino² or arpschuino32.
  • stepper (bipolar or unipolar).
  • stepper driver, type pololu or TMC2208 for small motors, or like that for more than 1.5A motors.
  • power supply for motors (more choice and top quality at Meanweel*).
  • arp>terminals² adapter or arpstepper.
  • HE10 ribbon.
  • power supply for arpschuino (from 6V to 15V DC)*.
  • Option : Limit switchs*.
  • * We have no connection with the companies mentioned, images and links are provided as an example.

    In this tutorial, we'll look at :

    1. The choice of motor.
    2. The choice of power supply.
    3. The configuration of Pololu type drivers.
    4. The configuration of the drivers for the motors of more than one ampere.
    5. The configuration of the unipolar steppers.
    6. The wiring.
    7. The switchs.
    8. With an arpschuino32 : configuration.
    9. With an arpschuino² : the code.

    The choice of motor

    Reminder: this tutorial is written for bipolar stepper motors (4 wires).

    There are several factors to take into account: the number of steps per revolution, the maximum speed and especially the maximum torque.

    Bipolar motors usually have 200 steps per revolution (1.8 ° per step ), sometimes 400 (0.9 °), but keep in mind that drivers allow micro-steps, which will allow us to multiply this number up to 16 times (or more).

    An essential element is the value of maximum torque. It is the "power" of the engine. It can be expressed in different units (converter here).

    Calculate the torque you need is not easy, it's not necessarily our specialty! You will find directions to help you on the internet.

    Remember that the torque value of a motor depends on the speed of rotation and the supply voltage (example). We advise you in all cases to oversize a little.

    Bipolar steppers

    Take into account that the use of micro steps generates a reduction in the available torque, because in this case, the currents are lower than the nominal currents.

    Since firmware 1.2, the arpschuino32 allows the use of direct drive unipolar steppers such as the 28BYJ-48. They are small inexpensive motors, equipped with gearboxes, easy to integrate useful for many applications.

    Unipolar steppers

    Note also that there are motors with double shafts, helical shafts, reduction gear ... But here it is up to you to decide according to your needs.

    The choice of power supply

    For maximum torque, the highest voltage will be preferred, referring to the torque curve (torque curve) of the motor.

    The output current of the power supply (in amperes) must be greater than the current per phase of the motor. Do not hesitate to oversize it a little, by 30% for example.

    The arpschuino can be supplied with the same power supply as the motor if it does not exceed 13V, 24V if the arpschuino is equipped with the optional pre-regulator.

    Configuration of Pololu type drivers (depending on the model, from 1A to 1.5A maximum)

    The most common are the A4988 and DRV8825, they are found everywhere , on the pololu website of course, also on online stores and on stores offering equipment for 3D printers .

    You can also choose the TMC2208 if you are looking for particularly quiet drivers. Note: if you are using an arpstepper of a version lower than 2.1, you will have to connect the EN pin to ground, by soldering a cable like here. This is no longer necessary from version 2.1 of the arpstepper.

    Our arpsteppers allow you to simply connect these drivers to the arpschuino. Each arpstepper can receive up to 4 drivers and you can connect 2 arpsteppers to an arpschuino for a total of 8 motors.


    For each driver, it is necessary to adjust the current intensity. By adjusting the reference voltage (Vref), we adjust the current per phase delivered to the motor.

    To do this, you need to connect the arpstepper to the arpschuino32 with the HE10 ribbon cable. Then first power the arpschuino32, and then the arpstepper. However, do not connect the stepper motor to the arpstepper yet.

    This adjustment is made by turning the small screw on the driver and measuring the voltage with a multimeter, as in the image below.

    Depending on your driver, you must refer to the manufacturers' documentation. On the pololu website for A4988 and the DRV8825. For TMC2208, it's here, with a calculator.

    réglage DRV8825

    The number of steps per revolution is adjusted using the jumpers present on the arpstepper. Depending on the driver used, the settings tables differ a little.

    arpstepper jumper

    A4988 microsteps setting:

    MS1 MS2 MS3 Microstep Resolution
    Low Low Low Full step
    High Low Low Half step
    Low High Low Quarter step
    High High Low Eighth step
    High High High Sixteenth step

    DRV8825 microsteps setting :

    MODE0 MODE1 MODE2 Microstep Resolution
    Low Low Low Full step
    High Low Low Half step
    Low High Low 1/4 step
    High High Low 1/8 step
    Low Low High 1/16 step
    High Low High 1/32 step
    Low High High 1/32 step
    High High High 1/32 step

    TMC2208 microsteps setting (two jumpers only):

    MS 1 MS 2 Microstep Resolution
    High Low 1/2 step
    Low High 1/4 step
    Low Low 1/8 step
    High High 1/16 step

    For other compatible drivers, see the documentation.

    Driver configuration for motors over 1 ampere

    It will be based here on the table printed on the driver housing.


    The first three dip switches are used to define the number of steps per revolution. For the moment, we are going to start with a value of 800 steps. For this driver, on-off-off.

    The next three are used to adjust the intensity of the current delivered by the driver. Choose a value less or equal to the intensity of your motor. Our motor is 4.2A, so we choose 3.5A (off-off-off).

    dip switchs

    Configuration for unipolar stepper motors.

    No special setting with this type of driver. No micro steps, half steps are possible but this is an adjustment to be made from the arpschuino.

    28BYJ-48 unipolar driver

    The 28BYJ-48 has only 32 steps per revolution, but a reduction of 1/64 brings it to 2048 or even 4096 steps in half-step mode. Don't expect it to spin much faster than 30 rpm.

    Leave the jumper in place. Depending on the motor model, the power supply is 5v or 12v.


    Always perform wiring with the power off.

    The following picture shows how to wire a arpstepper :

    arpstepper wiring

    Wiring with boxed drivers is not much more complicated. .

    First connect the power supply, GND (-) and VCC (+), then the 4 motor cables, the colors generally correspond to the photo but it is in any case preferable to refer to the data sheet of your motor.


    We will use the arp>terminals adapter (we could also chose the arp> breadboard ) to connect the driver to the arpschuino.

    Connect the + 5v to the DIR+(+5v) and PULL+(+5v). Then Arp0 from the arpschuino to the PULL- input (blue wire). And finally Arp1 from the arpschuino, at the DIR- entry (yellow wire).


    Some drivers have the 5v input in common, the names may vary slightly but the principle remains the same.

    other types of drivers

    If you need to mix the two types of drivers, it is possible with the stepper bridge. Placed in place of a Pololu driver, it allows the step and dir commands to be derived to an boxed driver, as shown in the following illustration.

    stepper bridge

    Transistor-based unipolar motor drivers are wired as follows:


    The power supply can be 5v or 12v depending on the motor used.

    The easiest way to connect to arpschuino is to use an arp>breadboard and two ribbons, HE10 on the arpschuino side and Dupont 4 conductors, as in the photo:


    The switches

    Using motors, the use of limit switches is often very useful, if not necessary. This is perfectly possible with the arpschuinos, since version 1.2 they are suported in the firmware of the arpschuino32.

    limit switch

    To work properly, these switches must be equipped with pull-up resistors and small capacitors.

    schemat switch

    If you use port A or B of the arpschuino, the outputs are equipped with internal pullups. By using the arp>terminal-C, you will have the small capacitors.

    If you use the input port of the arpschuino32, which does not have internal pullups, use the input terminal to benefit from its pullups and capacitors.

    photo arp>terminal-C and input terminal

    In both cases, connect one pole of the switch to ground and the other to the input.

    These switches should in no way be considered as emergency stop type safety devices.

    On the other hand, you can benefit from a homing system (the engine automatically resets to the zero point on start-up), and even an autocalibration device!

    With an arpschuino32: configuration

    Since firmware version 1.2, many improvements have been developed: adjustable acceleration, limit switches, homing at start-up and self-calibration.

    If you have an arpschuino32 with older firmware, update it as described here.

    No need to program the arpschuino32, you simply configure it via a web browser, as described in this tutorial.

    Stepper page

    With an arpschuino² : the code

    The default code of the arpschuino² does not allow stepper motors to be controlled, the card will have to be reprogrammed.

    To do that we need the arduino IDE.

    If it's not already done, install the core arpschuino as described in this tutorial.

    Since version 1.1.0, the arpstepper library is installed automatically with the arpschuino core. If you have an earlier version, please update as shown in the same tutorial.

    We are going to use the arpschuino_4steppers code which is available in the examples of the ArpStepper library, from version 1.1.0 of the arpschuino core.

    code source

    This code is functional, but some adjustments are necessary to adapt it to your configuration, but rest assured: no need to be a programmer to tackle this task!

    The parts in light gray and/or preceded by // are comments, they are not taken into account in the program, they are addressed to the human who reads this code (you).

          Lines preceded by // = commented lines (disabled)

    definition of the number of motors to be controlled:

    	#define nbr_motor 4

    Creation of objects :

    	// configuration matérielle, connexion et réglage du pilote :
    	//hardware configuration, driver connection and adjustment :
    	//(pin dir,pin pull, step_per_revolution)					
    	ArpStepper stepper0(Arp1,Arp0,200);
    	ArpStepper stepper1(Arp3,Arp2,6400);
    	ArpStepper stepper2(Arp5,Arp4,200);
    	ArpStepper stepper3(Arp7,Arp6,800);					
    	//ArpStepper stepper4(Arp9,Arp8,800);
    	//ArpStepper stepper5(Arp11,Arp10,800);
    	//ArpStepper stepper6(Arp13,Arp12,800);
    	//ArpStepper stepper7(Arp15,Arp14,800);

    We "create" our stepper objects in the code. Here we called them stepper0, stepper1 ... But we could have given them any name.

    In brackets we indicate, respectively, the pin of the arpschuino connected to the DIR of the driver, the one connected to the PULL (or STEP) and finally the number of steps per revolution that we defined when configuring the driver.

    In this example, 4 of these objects are created, the following are commented out (disabled).

    Depending on your usage, comment out (by putting // at the start of the line), or uncomment part of these lines to create the number of motors you want.

    Support for the arpdress board :


    Here we tell the arpschuino to support the arpdress board. If you do not use it, comment this line and define a fixed address by writing for example:



    	//(RPM_min(>0), RPM_max , revolutions, resolution(default 255))				
    	stepper0.init(1, 200, 12, _8bits);
    	stepper1.init(1, 100, 12, _16bits);
    	stepper2.init(2, 300);
    	stepper3.init(2, 300, 12);  
    	//  stepper4.init(2, 300, 12, _8bits);
    	//  stepper5.init(2, 300, 12, _8bits);
    	//  stepper6.init(2, 300, 12, _8bits);
    	//  stepper7.init(2, 300, 12, _8bits);  

    Here we will initialize the behavior of our steppers.

    Depending on the number of motors used, we comment or uncomment, as for the creation of objects.

    The first two parameters in brackets concern speed: minimum speed and maximum speed in revolutions per minute. The maximum attainable speed depends on the motor used, if you request too high a speed the motor will lock ...

    The third parameter defines the total revolutions of the motor in number of revolutions. You can put a floating-point values here.

    The last parameter is optional and concerns the command, _8bits for a command with a single DMX channel, _16bits for a command on two channels as for an automated projector. If this last parameter is not filled in, the command will be in 8 bit by default.

    The line //stepper0.invert_rotation(true); is commented here, uncommenting it reverses the direction of rotation of the motor concerned.

    action !

    	//  stepper4.perform(); 
    	//  stepper5.perform();
    	//  stepper6.perform();
    	//  stepper7.perform();  

    We indicate here the action to be performed, 2 are available, perform () and continuous ().

    With perform() we precisely control the position of the motor, according to the total revolutions defined previously.

    With continuous(), the motor is in continuous rotation mode. We control the direction and the speed.

    patch :

    The refresh() function updates the orders given to the motors. In our case the order is in DMX but the library also lends itself to other types of control, MIDI, OSC or potentiometer.

    Placed here (in the frame_received() loop), this function will be executed each time a DMX frame is received.

    So we indicate here which DMX circuits will be used to control our motors

       stepper0.refresh(DMX.RxBuffer[0], DMX.RxBuffer[1]);

    DMX.RxBuffer[0], c'est la valeur DMX reçue. Le [0] (entre crochets) s'aditionne à l'adresse DMX de l'arpschuino definie plus haut. Autrement dit c'est l'adresse 1 si l'arpschuino est adressé en 1, 24 s'il est adressé en 24... Adresse de la carte + [0].

    Dans notre exemple, la position du stepper0 est controllé par le premier circuit, sa vitesse par le second.

       uint16_t position_stepper1 =(DMX.RxBuffer[2]<<8) | (DMX.RxBuffer[3]); 
       stepper1.refresh(position_stepper1, DMX.RxBuffer[4]);

    We had initialized stepper1 in _16BITS mode, so the position is controlled by 2 circuits.

    The line uint16_t position_stepper1 =(DMX.RxBuffer[2]<<8) | (DMX.RxBuffer[3]); transform the 8-bit levels of two channels into a single 16-bit value (called position_stepper1).

    All that remains is to report it in refresh () : stepper1.refresh(position_stepper1, DMX.RxBuffer[4]);

       stepper2.refresh(DMX.RxBuffer[5], DMX.RxBuffer[6]);
       stepper3.refresh(DMX.RxBuffer[7], DMX.RxBuffer[8]);

    Same for the last two engines. The stepper2 is in continuous mode, the first parameter controls the direction of rotation, the second is speed.

    Let's try ?

    All you have to do now is to power the arpschuino (the red led should light up) and the driver and to connect the Dmx cable (or send Artnet wifi with the arpschuino32). As soon as we receive a signal, the green LED starts flashing rapidly.

    We can now test the assembly by raising the levels of the DMX addresses concerned.

    In perform mode, you precisely control the position of the motor. The first DMX parameter (or the first two, in 16-bit mode) defines the position. The second (or third), speed.

    In continuous mode, the motor rotates continuously. The first DMX parameter controls the direction, the second the speed.

    Is the stepper motor run ?

    Yeh it's work !

    In case of difficulties, do not hesitate to ask questions on the arpschuino forum .