Notifications
Clear all

Wiring vs. Code for Defining Motor Spin Direction in a 2-Wheeled Bot

13 Posts
5 Users
2 Reactions
305 Views
(@rhammell)
Member
Joined: 3 months ago
Posts: 9
Topic starter  

I'm working on a 2-wheeled Arduino bot with the following setup:

  • Motors: 2 N20 DC motors (one on each side of the bot)
  • Motor Driver: Adafruit DRV8833
  • Microcontroller: Arduino Nano ESP32

I’m trying to decide the best approach for defining the motor spin directions, as the motors need to spin in opposite directions to move the bot forward (one clockwise and one counterclockwise, since they're mounted on opposite sides).

From what I understand, there are two common ways to handle this:

  1. Define Spin Direction in Wiring:
    Swap the polarity of one motor by switching the wires on the motor driver outputs (e.g., swapping OUT1 and OUT2 for one motor). With this approach, the same logic signal (e.g., HIGH for AIN1 and BIN1) makes one motor spin clockwise and the other counterclockwise.

  2. Define Spin Direction in Code:
    Keep the wiring identical for both motors and adjust the control logic in code. For example, to drive forward, you’d send HIGH/LOW to one motor and LOW/HIGH to the other.

Here’s an example of how the driveForward() function might look in the two approaches:

Wiring Approach (Motors pre-wired to spin correctly):

void driveForward() { 
    // Send the same signals to both motors 
    digitalWrite(AIN1, HIGH); 
    digitalWrite(AIN2, LOW); 
    digitalWrite(BIN1, HIGH); 
    digitalWrite(BIN2, LOW); 
}
 
Code Approach (Adjust signals for each motor):

void driveForward() {
  // Left motor forward (Motor A clockwise)
  digitalWrite(AIN1, HIGH);
  digitalWrite(AIN2, LOW);

  // Right motor forward (Motor B counterclockwise)
  digitalWrite(BIN1, LOW);
  digitalWrite(BIN2, HIGH);
}
 

My Question:

Which approach do you recommend?

Is one way a more standard convention that is typically used over the other? 

I’d love to hear your thoughts, experiences, and best practices! Thanks!


   
Quote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 4 years ago
Posts: 8047
 

@rhammell The code should read correctly otherwise reading and debugging will give you a headache. Then to make it work, You reverse the wiring on one side. I never even considered a different approach.

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, 360, fairly knowledge in PC plus numerous MPU's & MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.


   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 6 years ago
Posts: 2332
 

@rhammell

I use your first suggestion:

"Swap the polarity of one motor by switching the wires on the motor driver outputs.'

 

// Motor A
const int enA = 11;
const int in1 = 10;
const int in2 = 9;
// Motor B
const int in3 = 7;
const int in4 = 6;
const int enB = 5;

void forwardA(int rate){
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  analogWrite(enA, rate);  
}

void forwardB(int rate){
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  analogWrite(enB, rate);  
}

void reverseA(int rate){
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
  analogWrite(enA, rate);  
}

void reverseB(int rate){
  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);
  analogWrite(enB, rate);  
}

void turnOffMotorA(){
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
}

void turnOffMotorB(){
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
}

 

 

 

 


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 4 years ago
Posts: 8047
 

@robotbuilder One of us is confused, if you swap the wires, shouldn't the code then be both motors get the same signal, i.e. both HIGH for forward.

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, 360, fairly knowledge in PC plus numerous MPU's & MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.


   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 6 years ago
Posts: 2332
 

@zander 

There are two terminals outputs for each motor. I swap the output terminals of the L298 connections of one of the motors. 

https://dronebotworkshop.com/dc-motors-l298n-h-bridge/

This link includes the schematic of the ic h bridges and their gate control.

https://howtomechatronics.com/tutorials/arduino/arduino-dc-motor-control-tutorial-l298n-pwm-h-bridge/

motorConnections

 

Actual wiring. Note the motor (red and black wire) connections are the reverse of each other.

The other wires from the motor are from hall effect encoders. The encoders also have a connection I haven't used that gives the direction of rotation.

Encoders are important as they enable you to control the speed of the motors. The speed for different motors can vary even if the same PWM value used. Encoders can signal that the motor have stalled (due to say hitting an obstacles).

wiringMotor

 


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 4 years ago
Posts: 8047
 

@robotbuilder And?

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, 360, fairly knowledge in PC plus numerous MPU's & MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.


   
ReplyQuote
THRandell
(@thrandell)
Brain Donor
Joined: 4 years ago
Posts: 274
 

Hi @rhammell

I prefer wiring the polarity of the two motors differently.  Here is a circuit of a PCB that I'm currently work with.  I'm using the same motors as you but with a Pico to pull it all together.

https://forum.dronebotworkshop.com/raspberry-pi/pico-robotics-main-board/#post-50526

Tom

To err is human.
To really foul up, use a computer.


   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 6 years ago
Posts: 2332
 

Posted by: @zander

@robotbuilder And?

Maybe I missed your quesion? Rather than a text description I have given exactly how I do it with images and a version of Bill's code example.

 

 


   
ReplyQuote
THRandell
(@thrandell)
Brain Donor
Joined: 4 years ago
Posts: 274
 

Posted by: @robotbuilder

Encoders can signal that the motor have stalled (due to say hitting an obstacles).

Not necessarily, in my experience when a robot runs into an obstacle the wheels just spin in place.  A better approach would be to use a current sensor, like this one https://www.pololu.com/category/312/acs71240-current-sensor-carriers

Place it in series on a motor’s negative wire and connect the sensor’s output to an analog pin and you’re off to the races.

 

Posted by: @robotbuilder

Encoders are important as they enable you to control the speed of the motors.

As I recall you are working on some type of controller that directs the motors in a straight line via encoder output.  Can you share that code?

 

Also, I’d like to add that you can use the DRV8833 to control the speed of a robot by varying the PWM’s duty cycle or by using digital high/low signals. In @rhammell case it looks as if he is using a digital signal.

Screen Shot 2025 01 28 at 2.54.50 PM

It’s been a while since I programmed an Arduino board, but don’t they provide some PWM library?

Tom

To err is human.
To really foul up, use a computer.


   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 6 years ago
Posts: 2332
 

@thrandell 

Good points made Tom. I will respond in my own thread when I get time. Now the xmas break is over I should have time to play around again with the robot project and will share code. Always interested in your experiments and ideas.
John

 


   
ReplyQuote
(@rhammell)
Member
Joined: 3 months ago
Posts: 9
Topic starter  

@robotbuilder
@thrandell

Thanks for the replies so far, here is some further explanation for clarification. 

I have two options to make my two motors spin in the correct directions opposite from eachother to drive my bot forward. 

Option 1:

Wiring:

Screenshot 2025 01 30 at 3.03.44 PM

Code: 

void forward() {
  // Drives left motor 
  digitalWrite(AIN1, LOW);
  digitalWrite(AIN2, HIGH);


  // Drive right motor
  digitalWrite(BIN1, HIGH);
  digitalWrite(BIN2, LOW);
}

 

Here the motors are wired the same, with motor M1 pins and M2 pins going to the A/B 1/2 pins respectively. 

With this wiring, to get the motors to spin in the correct directions, the writing of HIGH/LOW is opposite on two AIN* and BIN* pins. 

Option 2

Screenshot 2025 01 30 at 3.04.59 PM

 

Code: 

void forward() {
  // Drives left motor
  digitalWrite(AIN1, LOW);
  digitalWrite(AIN2, HIGH);

  // Drive right motor
  digitalWrite(BIN1, LOW);
  digitalWrite(BIN2, HIGH);
}

Here the motor M1 and M2 pins of the left motor going to the A 1/2 pins respectively, but this connection is flipped for the right motor pins. 

With this wiriing, to get the motors to spin in the correct directions, the writing of HIGH/LOW is the same on the two AIN* and BIN* pins. 

Both of these options successfully do what I want, which is to drive the motors that are placed on opposite sides of my bot in the correct directions (opposite direction of eachother) to drive the bot forward. 

My question was to see if either option is preferred or recommended

Option 1: Having each motor's M1 and M2 pins go to the input 1 and 2 pins seems logical. However, the having the digitalWrite() HIGH/LOW order feels off. 

Option 2: Flipping the motors M1 and M2 pins on the right motor feels off, but having the digitalWrite() HIGH/LOW match between the motors feels better. 

From the responses here it sounds like Option two is what others have used. 

This post was modified 3 months ago by rhammell

   
Ron reacted
ReplyQuote
TFMcCarthy
(@tfmccarthy)
Member
Joined: 9 months ago
Posts: 331
 

@rhammell 

Posted by: @rhammell

Option 2: Flipping the motors M1 and M2 pins on the right motor feels off, but having the digitalWrite() HIGH/LOW match between the motors feels better. 

From the responses here it sounds like Option two is what others have used. 

This is a really a matter of style.

My 2 cents are that the code and the physical behavior should correspond. Per force, the motors rotate in opposite directions to move forward or backward. Thus, the code should reflect that. This is how someone new to the code (or you in 6 months) will most likely view the algorithm, trying to match the motor movement to the code.

Unless I'm wrong, turning left and right will also corresponds in the code.

The principle is you want the least amount of surprise in the code.

The one who has the most fun, wins!


   
Ron reacted
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 4 years ago
Posts: 8047
 

@tfmccarthy As Tim said, code should reflect the real physical world as closely as possible. The closest analogy I can think of is a conventional skid steer vehicle. Both levers forward to go forward both back to reverse and right forward to turn right left to turn left. In vehicles with a single motor, the reverse wiring happens in the gearing.

I think I will add this to my 'helping filter'. Anyone who wants option 1 is not someone I want to deal with.

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, 360, fairly knowledge in PC plus numerous MPU's & MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.


   
ReplyQuote