Arduino code for Contolling Motors with Serial Commands

Here, we’ll dive into an interesting project where we control two DC motors using an Arduino. The code provided reads serial input for motor directions and speeds, processes it, and then controls the motors accordingly. By understanding the code and its functionality, you'll be able to create a system where you can control two motors through serial communication with the Arduino.

Project Overview

The idea behind this project is simple: control two motors by sending a set of values through the serial port. The input values consist of motor direction and speed for each motor, formatted as MotoADir,MotoASpe,MotorBDir,MotoBSpe.

Components Required

  • Arduino board (any model that supports serial communication)
  • Two DC motors
  • L298N Motor Driver or a similar motor driver to interface motors with the Arduino
  • Jumper wires
  • Serial communication setup (via the Serial Monitor or external interface)

The Code Breakdown

Let's take a look at the code in detail and understand how it works.

const int fields = 4; // amount of values excluding the commas
int motorPins[] = {12, 13, 3, 11}; // Motor Pins
int index = 0; // the current field being received
int values[fields]; // array holding values for all the fields

In this section, we define:

  • fields: The number of values we expect to receive (4 in total: two motor directions and two speeds).
  • motorPins[]: The array stores the pins on the Arduino connected to the motor driver. These pins will control the motor direction and speed.
  • index: A helper variable that tracks the current field we are processing.
  • values[]: An array that stores the values received through serial communication.

Setting up the Motors

In the setup() function, we initialize the serial communication and configure the motor pins as outputs:

void setup()
{
Serial.begin(9600); // Initialize serial port to send and receive at 9600 baud
for (int i = 0; i <= 3; i++) // set motor pinMode to output
{
pinMode(motorPins[i], OUTPUT);
}
Serial.println("The Format is: MotoADir,MotoASpe,MotorBDir,MotoBSpe\n");
}


  • Serial.begin(9600): Opens the serial port at a baud rate of 9600.
  • pinMode(motorPins[i], OUTPUT): Sets all motor control pins as outputs so we can control the motors.

Reading Serial Data and Processing

In the loop() function, we read serial data to control the motors. Here’s how the data is processed:

void loop()
{
if( Serial.available()) // check if data is available on the serial port
{
char ch = Serial.read(); // read the incoming character
if(ch >= '0' && ch <= '9') // If it is a number 0 to 9
{
// convert the character to an integer and store it in the values array
values[index] = (values[index] * 10) + (ch - '0');
}
else if (ch == ',') // if a comma is received, move to the next field
{
if(index < fields - 1)
index++; // increment index to point to the next field
}
else // when we receive a character other than a number or comma
{
// Display the values for each motor
for(int i=0; i <= index; i++)
{
if (i == 0)
{
Serial.println("Motor A Direction:");
Serial.println(values[i]);
}
else if (i == 1)
{
Serial.println("Motor A Speed:");
Serial.println(values[i]);
}
else if (i == 2)
{
Serial.println("Motor B Direction:");
Serial.println(values[i]);
}
else if (i == 3)
{
Serial.println("Motor B Speed:");
Serial.println(values[i]);
}

// Writing values to the motor pins
if (i == 0 || i == 2) // If the index is equal to 0 or 2 (direction)
{
digitalWrite(motorPins[i], values[i]);
}
else if (i == 1 || i == 3) // If the index is equal to 1 or 3 (speed)
{
analogWrite(motorPins[i], values[i]);
}
values[i] = 0; // reset the value to 0 after processing
}
index = 0; // reset the index for the next input
}
}
}


How the Code Works

  1. Serial Input Handling:

    • The Serial.available() function checks if data is available from the serial port.
    • Characters (digits) are read one by one, and if they are between '0' and '9', they are converted to integers and stored in the values[] array. The character ch - '0' converts the character to its numeric equivalent.
    • When a comma is received, the code moves to the next index in the values[] array. This allows us to separate the four fields (MotoADir, MotoASpe, MotorBDir, and MotoBSpe).
  2. Command Processing:

    • After receiving the serial input, the code prints the values for each motor: the direction (0 or 1) and the speed (a value between 0 and 255).
    • Motor directions are written using digitalWrite() (since direction is binary), while the speeds are controlled using analogWrite() for PWM output, which modulates the motor speed.
  3. Reset Values:

    • After the command is processed, the values[] array is reset to zeros, and the index is set back to 0, preparing the code for the next command.

Example Input and Output

Suppose you send the following data through the serial monitor:

1,255,0,128
  • This input means:
    • Motor A should rotate in direction 1 (forward) at full speed (255).
    • Motor B should rotate in direction 0 (backward) at half speed (128).

The output in the serial monitor would look like this:

 

Code Issues and Improvements

While the current code functions correctly for basic operation, there are a couple of issues that can be improved:

  • Logical Errors in Direction and Speed Control: The comments in the code point out a logical error when using digitalWrite() and analogWrite() for direction and speed. The correct pin assignments for direction and PWM control should be reviewed to avoid unexpected behavior.
  • Error Handling: There is no error handling for out-of-range inputs, like sending values higher than 255 for motor speed. Adding validation can make the code more robust.

Conclusion

This project demonstrates how you can control multiple motors using serial input with an Arduino. By parsing serial data and controlling motor direction and speed using digital and PWM signals, we can easily manage motor control from a PC or other serial input sources. This setup can be adapted for various applications, including robotics and automation projects.

Make sure to test the system carefully and adjust the code as needed to fit your motor driver and motor specifications.

Post a Comment

Previous Post Next Post