Motor Controller (BV4603/4)



*** See also newer products **

  • I2CN17 I2C for controlling / Driving 3 stepper motors
  • I2CN16 DC Motor controller comming soon

The two motor controllers shown here have identical firmware and operate in the same way. The difference is that one is fitted with an L293 (BV4603) Motor driver that can switch up to 1.2A and the other is fitted with an L298 that can switch up to 4A (BV4604)

The motor controller is a microstepping controller that can also drive two DC motors if required. It is fully controlled by software and has three interfaces:

  • Serial
  • I2C
  • Step pin and direction

The step pin and direction is for precise control of two or more devices that need to work in unison so that accurate arc's and lines can be drawn. The serial or I2C can still be used in this mode to control the power and other options.

A unique feature is the Sideways Stackable (SWS) connector that allows many units to be joined together without messy wiring.

The serial interface is addressable and so up to 26 devices can be joined in this way. Other devices can also be stacked such as relays.

Windows Serial

This is the easiest method of control as it is much easier to debug than I2C. Even if using with I2C it may be worth running through some serial commands first.

The motor supply is separate from the logic (+L) supply so that the device can be powered from either 3.3V or 5V, this power can be supplied by the USB to serial convertor.

The motor supply will also supply the L293/8 logic via a 5V regulator. The motor supply can use the +V pin on the SWS connector or use the separate connector provided. See the data sheet for more details on this. See also the sideways stackable connector page.

Once connected use BV_COM, this is free and does not need installing, just run the exe.

Set echo on, set the correct COM port.

When using the serial command, all commands are preceded by an address, by default the BV4603 uses 'b' and the BV4604 uses 'd' - sown in the example therefore is the BV4603

  1. type bH (that is lower case f, upper case H followed by enter). The device will respond with ACK ([06]).
  2. type bD to get the device number and the result will be 4603[06]
  3. type ba1023,1 applied full power to M1-M2 connections

Above is what you should expect using BV_COM.

A better way but more complex to set up is to use the Python 'sws' programs that have been provided. Full instructions for downloading and running are in the software section. Once installed it will give access to this dialog.

This has most of the parameters for controlling either a DC motor or a stepper motor.

Windows I2C

There is no output on a Windows PC that will give I2C and so some other device is required. For this a BV4221_V2 device is used that allows an I2C device to be connected via the USB. The Python code '' is given in the link as the BV4221_V2 does require setting up for this it is best to follow the instructions on that link. If you have the dialog box running above then you can run the '' code and obtain the dialog box as above but this time via the I2C interface.

Raspberry Pi Serial

Install the serial software as given in the instructions on this site. The connections to the RPi are as shown above. Note that the 3v3 supply is used to provide the logic, this is important as the TX line from the device will input to the RPi at that voltage.

The +V must be supplied separately, see the data sheet for the device to get the limits on this voltage. All the grounds of course must be connected together.

Raspberry Pi I2C

Special Note: By default this device is serial. I2C is activated by the pull up resistors on the I2C bus. The implication is that when connecting to the Rpi, the SDA and SCL lines must be connected BEFORE connecting the power to this board. This is only necessary if the board is connected to the RPi that is already switched on.

Connection to the RPi via the I2C lines. Here the logic voltage is not important as the PRi will control this with its own internal pull up resistors.

Before using I2C install notsmb. This makes interfacing with I2C far easier than using smbus. The easiest way now is to use the sws software but it is possible to use Python interactively without the overhead of the GUI.

Getting Going with I2C

The device is much easier to use with serial as it allows a human readable interface. This text has some pointers and tips for getting the device to work with I2C.

  1. Establish communication with the device and confirm it by using the ID command (0xa1). This should return 2 values 17 and 251 or 252 depending on if it is a BV4603 or BV4604
  2. Connect the motor and send the test command 17

The motor should now be turning or doing something. If not then you need to diagnose the problem, look at the motor itself, how it is connected and the power supply to the motor. If it is buzzing or being erratic then experiment with different wire combinations so that it is at least turning in one direction.

  1. Assuming the set command worked okay, check that the mode is set to 1 using the eeprom read 0x90 command
  2. Set it to 0 using the 0x91 command.
  3. Now disconnect the power and reconnect - it will only take effect after a reset.
  4. Re-check the mode, it will not work in i2c without mode set to 0
  5. Send step command 2500 steps at 2500 steps per second

Any problems then re-cycle the power, I2C can be finicky when experimenting with it.

The session would look like this using notSMB ans Python:

>>> from notsmb import notSMB
>>> bus = notSMB(0)
>>> bus.detect()
>>> bus.i2c(50,[0xa1],2)
# check i2c is working
[17, 252]
>>> bus.i2c(50,[0x90,20],1)
# check that mode is set to 1
>>> bus.i2c(50,[0x91,20,0],0)
# set mode to 0
>>> bus.i2c(50,[0x90,20],1)
#check that mode is set to 0
Cycle power on BV4603/4
# remove V+ and reconnect IMPORTANT
>>> bus.i2c(50,[9,0,0,0x9,0xc4,0x9,0xc4,1],0) # send 2500 steps at 2500 steps per sec. direction 1


There is currently only the I2C library, other libraries can be made available on request.

I2C Library & examples, the Address for the BV4603 is 0x31 and for the BV4604 is 0x32. To use this library the mode (EEPROM address 20) needs changing to serial (0) otherwise some functions will not work.

MOTOR(char address); Constructor, example MOTOR motor(0x31) for the BV4603

void eeWrite(char address, char value); This will write a value to the EEPROM at a given address. EEPROM values should be only set once and not at each program start as there is a limited (but very large) number of times that an EEPROM can be written to.

void GlobalPower(char power); Sets the global power for the session, this can be adjusted dynamically. There is also a global power that can be set in EEPROM but that is just the default (start up) global power. NOTE: this is a multiplier when DC motors are used, see data sheef footnotes for further information.

DC Motors: there can be two DC motors connected to M1-M2 and M3-M4. Three functions are provided for setting the power and direction. The third function DC3, is for setting power to the motors simultaneously as there can be a slight delay when setting the motors individually. This is useful for example when driving a robot car powered by two motors, if one sets off after the other it will not go in a straight line.

As a general rule; if powering one motor then use DC1 or DC2, if powering 2 motors then use DC3

void DC1(int power, char direction); direction is either 0 to 1
void DC2(int power, char direction); direction is either 0 to 1
void DC3(int power1, char dir1, int power2, char dir2);

Stepper Motors: The number of steps can be specified from 0 to 2,147,483,647 and so this is a 4 byte long number. There is no continuous step command.

long StepsToGo(); Number of steps to go before stopping

void Steps(long steps, int speed, char direction); Main step command, speed is in steps per second. The minimum speed is 70; see the data sheet if you need to go lower than this.

void Stop(); Stops the stepping and clears the steps back to 0


How to get one of those cheap geared motors working

This is the kind of thing but without the controller. Even with the controller these are very cheap. They are very highly geared and so need a lot of steps to see anything happening. It could be that the motor is working okay but it may be going round just too slowly to see.

The have a lot of torque because of the gearing but are VERY slow, probably the maximum speed is about 15RPM. Useful though for things that needs precise positioning, I believe they were originally used for car door wing mirrors.

Despite what it says on the motor to get it going initially with the BV4603 you will need 12V. After experimenting then reduce to 5V but initially and for confidence use 12V first.

Connections for the BV4603 (1.2A) version

M1 to Blue
M2 to Orange
M3 to Yellow
M4 to Pink

Set the EEPROM location 20 on the BV4603 to 0, this is the serial mode, the default is 1. For the serial interface the command is bs16000,4500,1 yes that's right 16,000 steps at 4,500 steps per second, this will give about 1 turn. I think the gearing is 4000:1 and with microstepping on it is times 8, hence 16,000. For I2C the same command is: bus.i2c(0x32,[9,0,0,0x3e,0x80,0x11,0x94,1],0) or

send command 9
send byte 0       // 32 bit number of steps
send byte 0
send byte 0x3e
send byte 0x80
send byte 0x11  // 16 bit steps per second
send byte 0x94
send byte 1       // direction

The motor will probably work better without microsteppeing so experiment by switching it off (setting EEPROM location 18 to 0). With it off, the number of steps need reducing to 2000 and the steps per second to about 700. There are lots of combinations to try to get the best results, this was just a taster.


Version 2.6 Update April 2014 * Added command 'c' to control both DC motors simultaneously.

There is a problem with version 2.5 firmware when used with DC motors: if both motors are required to be started simultaneously, sending one command after the other will not achieve this. To start both motors together then 'pre-load' the motors with a low power value - so that the motors are energised but are not moving. To start both at the same time, send the command again with the correct power.

Thanks to Warren for the work round.