Control robot via serial port

Drive hardware platform with commands via serial connection

Simple platform made of Arduino board with a Motor shield (H-bridge DC motor driver), two motors with gearboxes and wheels, battery (“power-bank”) and cardboard as a chassis.

ArduinoWithMotorDriveShieldSimplePlatform

Arduino Motor-shield is setup on the Arduino board and connected to the battery by wire. Arduino board is connected to the battery by its own wire and it is connected to a computer by USB cable – for uploading a program. Two motors (each with a gearbox and a wheel) connected to a Arduino Motor-shield. USB-to-UART adapter is connected to the Arduino board’s RX, TX pins (digital pins 0, 1) and by USB cable to a computer. Battery is secured to a cardboard chassis by a melting glue. A plastic ball is hold by thick still wire glued to the battery – so it is a third rolling point of the platform.

1. Type, copy/paste or download from GitHub a program in the Arduino IDE

Code on GitHub

/*
Awaiting text commands via serial port #1 - digital pins 0 (RX1), 1 (TX1)
Max command length - 64 chars
Command ends with "new-line" char
Diagnostics messages are sent back to serial port #1

Commands control two motors drived by a Motor shield

Following commands are supported (case-sensitive):
 "start" - start moving
 "stop" - stop moving
 "left" - turn left
 "right" - turn right
 "forward" - move forward
 "backward" - move backward

This code is in the public domain.
Copyright © 2014, foreglance.com
*/
//--- constants ---
const int SerialPortBaudRate = 9600;
const int MaxCommandLength = 64;
const char LF = '\n';
const String EmptyString = "";
//right side
const int pinRightMotorDirection = 4; //this can be marked on motor shield as "DIR A"
const int pinRightMotorSpeed = 3; //this can be marked on motor shield as "PWM A"
//left side
const int pinLeftMotorDirection = 7; //this can be marked on motor shield as "DIR B"
const int pinLeftMotorSpeed = 6; //this can be marked on motor shield as "PWM B"

//--- fields ---
String command = EmptyString;
int commandLength = 0;
char inputChar;
boolean awaitingCommand = true;

//--- setup ---
void setup() {
  command.reserve(MaxCommandLength);
  initPins();
  initSerialPort1();
  runRightMotorForward();
  runLeftMotorForward();
  awaitCommand();
}

//--- main loop ---
void loop() {
  processCommand();
  readSerialData();
}

//--- commands ---
void commandStart(){
  startMotors();
  sendMessage("Start moving");
}

void commandStop(){
  stopMotors();
  sendMessage("Stop moving");
}

void commandLeft(){
  runLeftMotorBackward();
  runRightMotorForward();
  sendMessage("Turn left");
}

void commandRight(){
  runRightMotorBackward();
  runLeftMotorForward();
  sendMessage("Turn right");
}

void commandForward(){
  runRightMotorForward();
  runLeftMotorForward();
  sendMessage("Move forward");
}

void commandBackward(){
  runRightMotorBackward();
  runLeftMotorBackward();
  sendMessage("Move backward");
}

void commandHelp(){
  sendMessage("Following commands are supported (case-sensitive):");
  sendMessage("start - start moving");
  sendMessage("stop - stop moving");
  sendMessage("left - turn left");
  sendMessage("right - turn right");
  sendMessage("forward - move forward");
  sendMessage("backward - move backward");
}

//--- methods ---

//invoke command methods
void processCommand(){
  if(awaitingCommand)
    return;

  if(command == "start")
    commandStart();
  else if(command == "stop")
    commandStop();
  else if(command == "right")
    commandRight();
  else if(command == "left")
    commandLeft();
  else if(command == "forward")
    commandForward();
  else if(command == "backward")
    commandBackward();
  else if(command == "help")
    commandHelp();
  else
    sendMessage("Unknown command:" + command);

  awaitCommand();
}

//initialize the serial port #1
void initSerialPort1(){
  Serial1.begin(SerialPortBaudRate);
  while(!Serial1){}//wait while the serial port is ready
}

//request for a new command
void awaitCommand(){
  command = EmptyString;
  commandLength = 0;
  awaitingCommand = true;
}

//read data for the buffer of the serial port #1
void readSerialData() {
  //when command is not awaited 
  // and data do not exist in the buffer of the serial port
  if(!awaitingCommand || !Serial1.available()) 
    return; // do not read data

  // take a char from the buffer
  inputChar = (char)Serial1.read(); 

  //if taken char is "new-line" 
  // and no other data were taken earlier
  if(LF == inputChar && 0 == commandLength)
    return; // do not change the command text

  commandLength++; // length of the command text with taken char

  //if taken char is not "new-line"
  // and the command text with this char not longer tham Max 
  if(LF != inputChar && MaxCommandLength > commandLength)
    command += inputChar; //add this char to the command text
  else
    awaitingCommand = false; //define the command as received
}

void sendMessage(String message){
  Serial1.println(message);
}

//--- init pins of the board ---
void initPins(){
  pinMode(pinRightMotorDirection, OUTPUT);
  pinMode(pinRightMotorSpeed, OUTPUT);
  pinMode(pinLeftMotorDirection, OUTPUT);
  pinMode(pinLeftMotorSpeed, OUTPUT);
}

//--- motor controll ---
void startMotors(){
  setMotorSpeed(pinRightMotorSpeed, 255);
  setMotorSpeed(pinLeftMotorSpeed, 255);
}

void stopMotors(){
  setMotorSpeed(pinRightMotorSpeed, 0);
  setMotorSpeed(pinLeftMotorSpeed, 0);
}

void runRightMotorForward(){
  runMotorForward(pinRightMotorDirection);
}

void runLeftMotorForward(){
  runMotorForward(pinLeftMotorDirection);
}

void runRightMotorBackward(){
  runMotorBackward(pinRightMotorDirection);
}

void runLeftMotorBackward(){
  runMotorBackward(pinLeftMotorDirection);
}

void runMotorForward(int pinMotorDirection){
  digitalWrite(pinMotorDirection, HIGH); //set direction forward
}

void runMotorBackward(int pinMotorDirection){
  digitalWrite(pinMotorDirection, LOW); //set direction backward
}

void setMotorSpeed(int pinMotorSpeed, int motorSpeed){
    analogWrite(pinMotorSpeed, motorSpeed);
}

2. Start “CuteCom” and and open the device where the USB-to-UART adapter is connected to

3. Type a text “start” (do not use capital letters) in the field “Input” and hit Enter – text “Start moving” should be printed in the output field and motors of the platform should start running – this is how commands are sent to the program working on the Arduino board

4. Send a command “backward” – text “Move backward ” should be printed and motors should change direction of rotation

5. Send a command “left”, “right”, “forward” – motors should change direction of rotation, text describing commands should be printed

6. Send a command “stop” – text “Stop moving” should be printed, motors should stop rotation

7. Send any other command – text “Unknown command:” followed by this command should be printed. Command “help” prints all supported commands

CuteComSendCommandsControllingMotorsToUCB2UARTAdapter

Facebooktwittergoogle_plusredditpinterestlinkedintumblrmail