Serial Controlled Motor Driver Hookup Guide

Contributors: MTaylor
Favorited Favorite 3

Example 3: Two slaves, 5 motors, 1 bridged (SPI control)

This demonstrates more advanced usage of the serial driver. Here, we have a couple slaves attached, with one being configured as a bridged mode. This is a good example of how the motor numbering scheme works.


alt text

The motor drivers are connected on a breadboard for test.

alt text

The master is configured as SPI ("0001"), and has pull up resistors enabled for the expansion bus.

alt text

Slaves boards should be set to "0010" with no pull up resistors enabled, as the master is doing it.


Connect the Arduino and Level Shifter to the motor drvier as follows. This connects to the standard SCL, MOSI, and MISO positions, and uses pin 10 as a chip select.

alt text

The user port connections for this example

While this example will operate with only a master, add slaves to the expansion port to get the full experience.

The expansion port allows multiple SCMDs to be run from the same I2C address, SPI select line, or UART instance. The port can support up to 16 SCMDs set as slave by a common I2C interface, and daisy-chained config-in to config-out wiring

alt text

A diagram showing the expansion bus usage

Notice that the expansion I2C lines are connected to a common bus while the config lines are connected from one board's 'Out' to the next's 'In'. More slaves can be added onto the end of the chain.

alt text

The expansion bus connections

When power is applied, the master will assign addresses to the slaves. This may take a couple seconds. When complete, the slaves should all have a faintly lit, blinking status LED indicating communication.

Example Code

The example, also available from the drop-down menu in Arduino (It's called DriverChainWithBridging), is as follows:

//This example demonstrates some of the more advanced usage of the motor driver.
//It uses 3 motor drivers, with the master attached as SPI.  One slave is bridged,
//and the sketch test drives each motor. (There will be a break when the overtaken motor
//channel is activated.)
//This also shows how to count the number of connected slaves and report, as well as
//arbitrary register access.

#include <Arduino.h>
#include <stdint.h>
#include "SCMD.h"
#include "SCMD_config.h" //Contains #defines for common SCMD register names and values
#include "Wire.h"


//***** Create the Motor Driver object*****//
SCMD myMotorDriver;

void setup()

  Serial.println("Starting sketch.");

  //***** Configure the Motor Driver's Settings *****//

  //  .commInter face can be I2C_MODE or SPI_MODE
  myMotorDriver.settings.commInterface = I2C_MODE;
  //myMotorDriver.settings.commInterface = SPI_MODE;

  //  set address if I2C configuration selected with the config jumpers
  myMotorDriver.settings.I2CAddress = 0x5A; //config pattern "0101" on board for address 0x5A
  //  set chip select if SPI selected with the config jumpers
  myMotorDriver.settings.chipSelectPin = 10;

  delay(2500); //Give the serial driver time to check for slaves

  //  initialize the driver and enable the motor outputs
  uint8_t tempReturnValue = myMotorDriver.begin();
  while ( tempReturnValue != 0xA9 )
    Serial.print( "ID mismatch, read as 0x" );
    Serial.println( tempReturnValue, HEX );
    tempReturnValue = myMotorDriver.begin();
  Serial.println( "ID matches 0xA9" );

  Serial.print("Waiting for enumeration...");
  while ( myMotorDriver.ready() == false );

  //  Report number of slaves found
  uint8_t tempAddr = myMotorDriver.readRegister(SCMD_SLV_TOP_ADDR);
  if ( tempAddr >= START_SLAVE_ADDR )
    Serial.print("Detected ");
    Serial.print(tempAddr - START_SLAVE_ADDR + 1); //Top address minus bottom address + 1 = number of slaves
    Serial.println(" slaves.");
    Serial.println("No slaves detected");

  //Configure bridging modes
  myMotorDriver.bridgingMode( 1, 1 ); //( DriverNum 1, bridged state = 1 )  This will bridge the first slave

  //Uncomment to set inversion

  //myMotorDriver.inversionMode(0, 1); //invert master, channel A
  //myMotorDriver.inversionMode(1, 1); //invert master, channel B
  //myMotorDriver.inversionMode(2, 1); //invert slave 1, channel A
  //    no need to configure motor 3, this position does nothing because the slave is bridged.
  //myMotorDriver.inversionMode(4, 1); //invert slave 2, channel A
  //myMotorDriver.inversionMode(5, 1); //invert slave 2, channel B

  //Enable the motors.

  pinMode(8, INPUT_PULLUP);


void loop()
  //***** Operate the Motor Driver *****//
  //  This walks through all 34 motor positions driving them forward and back.
  //  It uses .setDrive( motorNum, direction, level ) to drive the motors.
  //  Notice that when i == 3, no motor spins.  This position is made inactive by bridging the first slave.
  Serial.println("Now stepping through the motors.");
  for (int i = 0; i < 6; i++)
    Serial.print("Driving motor ");

    myMotorDriver.setDrive( i, 1, 255); //Drive motor i forward at full speed
    myMotorDriver.setDrive( i, 0, 255); //Drive motor i backward at full speed
    myMotorDriver.setDrive( i, 1, 0);

The example works by counting through the 6 motor positions and commanding them forward, then back.

Things to note:

  • Only a single SCMD object is used, all slaves are accessed through the master.
  • begin is periodically ran until the returned ID word is valid.
  • Setup waits for isReady() to become true before going on to the drive section
  • Slaves are counted by directly accessing the registers. ALL_CAPS_VALUES are #defined in SCMD_config.h.
  • bridgingMode( ... ) is called to bridge, by number of motor driver (master is driver 0).
  • Motor 3 is excluded because the channel gets connected to motor 2 by brdiging. Though it can still be commanded, it will have no effect.
  • enable() is called to activate the motors. This happens after the bridging configuration is set to protect the drivers.