engtong82Wai Weng KongDIAN MIAO LING
Published

Building a Sumo Robot

This post aims to assist the beginners who want to build a sumo robot for competition for the first time.

IntermediateFull instructions provided6 hours4,981
Building a Sumo Robot

Things used in this project

Hardware components

Sumo Robot Controller
Cytron Technologies Sumo Robot Controller
×1
Infrared Sensor (3cm-80cm)
×5
JSumo Silicone Wheel Set (52mm x 30mm)
×2
IR Line Tracking Module
×2
12V 380RPM 1.4kgfcm DC Geared Motor
×4
11.1V 1300mAh LiPo Battery
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

LiPo Battery Charger

Story

Read more

Custom parts and enclosures

3D CAD Files

Code

Sample Code

C/C++
/*******************************************************************************
 * THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTY AND SUPPORT
 * IS APPLICABLE TO THIS SOFTWARE IN ANY FORM. CYTRON TECHNOLOGIES SHALL NOT,
 * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR CONSEQUENTIAL
 * DAMAGES, FOR ANY REASON WHATSOEVER.
 ********************************************************************************
 * DESCRIPTION:
 *
 * This is the example of Sumo Robot based on the URC10 Sumo Robot Controller.
 * 
 *
 *
 * AUTHOR   : Kong Wai Weng
 * COMPANY  : Cytron Technologies Sdn Bhd
 * WEBSITE  : www.cytron.io
 * EMAIL    : support@cytron.io
 *
 *******************************************************************************/

#include <CytronMotorDriver.h>


// Wiring Connections.
#define LED0          0   // Onboard LED 0
#define LED1          1   // Onboard LED 1
#define BUTTON        13  // Start button
#define EDGE_L        12  // Left edge sensor
#define EDGE_R        11  // Right edge sensor
#define OPPONENT_L    3   // Left opponent sensor
#define OPPONENT_R    10  // Right opponent sensor
#define OPPONENT_FR   A0  // Front right opponent sensor
#define OPPONENT_FC   A1  // Front center opponent sensor
#define OPPONENT_FL   A2  // Front left opponent sensor

// Direction.
#define LEFT    0
#define RIGHT   1


// Global variables.
uint8_t searchDir = LEFT;


// Configure the motor driver.
CytronMD motorL(PWM_DIR, 5, 4);
CytronMD motorR(PWM_DIR, 6, 7);



/*******************************************************************************
 * Start Routine
 * This function should be called once only when the game start.
 *******************************************************************************/
 void startRoutine() {
  // Start delay.
  delay(1000);

  // Turn right around 45 degress.
  motorL.setSpeed(255);
  motorR.setSpeed(0);
  delay(180);

  // Go straight.
  motorL.setSpeed(255);
  motorR.setSpeed(255);
  delay(450);

  // Turn left until opponent is detected.
  motorL.setSpeed(-0);
  motorR.setSpeed(255);
  uint32_t startTimestamp = millis();
  while (digitalRead(OPPONENT_FC)) {
    // Quit if opponent is not found after timeout.
    if (millis() - startTimestamp > 400) {
      break;
    }
  }
  
 }


/*******************************************************************************
 * Back Off
 * This function should be called when the ring edge is detected.
 *******************************************************************************/
void backoff(uint8_t dir) {
  // Stop the motors.
  motorL.setSpeed(0);
  motorR.setSpeed(0);
  delay(100);
  
  // Reverse.
  motorL.setSpeed(-255);
  motorR.setSpeed(-255);
  delay(200);

  // Stop the motors.
  motorL.setSpeed(0);
  motorR.setSpeed(0);
  delay(100);

  // Rotate..
  if (dir == LEFT) {
    motorL.setSpeed(-150);
    motorR.setSpeed(150);
  } else {
    motorL.setSpeed(150);
    motorR.setSpeed(-150);
  }
  delay(100);

  // Start looking for opponent.
  // Timeout after a short period.
  uint32_t uTurnTimestamp = millis();
  while (millis() - uTurnTimestamp < 300) {
    // Opponent is detected if either one of the opponent sensor is triggered.
    if ( !digitalRead(OPPONENT_FC) ||
         !digitalRead(OPPONENT_FL) ||
         !digitalRead(OPPONENT_FR) ||
         !digitalRead(OPPONENT_L) ||
         !digitalRead(OPPONENT_R) ) {
          
      // Stop the motors.
      motorL.setSpeed(0);
      motorR.setSpeed(0);
      delay(100);

      // Return to the main loop and run the attach program.
      return;
    }
  }

  // If opponent is not found, move forward and continue searching in the main loop..
  motorL.setSpeed(255);
  motorR.setSpeed(255);
  delay(200);
}


/*******************************************************************************
 * Search
 *******************************************************************************/
void search() {
  // Move in circular motion.
  if (searchDir == LEFT) {
    motorL.setSpeed(100);
    motorR.setSpeed(255);
  } else {
    motorL.setSpeed(255);
    motorR.setSpeed(100);
  }
}


/*******************************************************************************
 * Attack
 * Track and attack the opponent in full speed.
 * Do nothing if opponent is not found.
 *******************************************************************************/
void attack() {
  uint32_t attackTimestamp = millis();

  // Opponent in front center.
  // Go straight in full speed.
  if (!digitalRead(OPPONENT_FC)) {
    motorL.setSpeed(255);
    motorR.setSpeed(255);
  }

  // Opponent in front left.
  // Turn left.
  else if (!digitalRead(OPPONENT_FL)) {
    motorL.setSpeed(0);
    motorR.setSpeed(255);
  }

  // Opponent in front right.
  // Turn right.
  else if (!digitalRead(OPPONENT_FR)) {
    motorL.setSpeed(255);
    motorR.setSpeed(0);
  }

  // Opponent in left side.
  // Rotate left until opponent is in front.
  else if (!digitalRead(OPPONENT_L)) {
    motorL.setSpeed(-150);
    motorR.setSpeed(150);
    while (digitalRead(OPPONENT_FC)) {
      // Quit if opponent is not found after timeout.
      if (millis() - attackTimestamp > 400) {
        break;
      }
    }
  }

  // Opponent in right side.
  // Rotate right until opponent is in front.
  else if (digitalRead(OPPONENT_R) == 0) {
    motorL.setSpeed(150);
    motorR.setSpeed(-150);
    while (digitalRead(OPPONENT_FC)) {
      // Quit if opponent is not found after timeout.
      if (millis() - attackTimestamp > 400) {
        break;
      }
    }
  }
  
}



/*******************************************************************************
 * Setup
 * This function runs once after reset.
 *******************************************************************************/
void setup() {
  pinMode(BUTTON, INPUT_PULLUP);
  pinMode(EDGE_L, INPUT_PULLUP);
  pinMode(EDGE_R, INPUT_PULLUP);
  pinMode(OPPONENT_L, INPUT_PULLUP);
  pinMode(OPPONENT_R, INPUT_PULLUP);
  pinMode(OPPONENT_FL, INPUT_PULLUP);
  pinMode(OPPONENT_FC, INPUT_PULLUP);
  pinMode(OPPONENT_FR, INPUT_PULLUP);

  pinMode(LED0, OUTPUT);
  pinMode(LED1, OUTPUT);

  // Turn off the LEDs.
  // Those LEDs are active low.
  digitalWrite(LED0, HIGH);
  digitalWrite(LED1, HIGH);
  
  // Stop the motors.
  motorL.setSpeed(0);
  motorR.setSpeed(0);

  // Wait until button is pressed.
  while (digitalRead(BUTTON)) {
    // While waiting, show the status of the edge sensor for easy calibration.
    if (!digitalRead(EDGE_L)) {
       digitalWrite(LED1, LOW);
    } else {
      digitalWrite(LED1, HIGH);
    }

    if (!digitalRead(EDGE_R)) {
       digitalWrite(LED0, LOW);
    } else {
      digitalWrite(LED0, HIGH);
    }
  }

  // Wait until button is released.
  while (!digitalRead(BUTTON));

  // Turn on the LEDs.
  digitalWrite(LED0, LOW);
  digitalWrite(LED1, LOW);
  
  // Start routine..
  startRoutine();
}


/*******************************************************************************
 * Main program loop.
 *******************************************************************************/
void loop() {
  // Edge is detected on the left.
  if (!digitalRead(EDGE_L)) {
    // Back off and make a U-Turn to the right.
    backoff(RIGHT);

    // Toggle the search direction.
    searchDir ^= 1;
  }
  
  // Edge is detected on the right.
  else if (!digitalRead(EDGE_R)) {
    // Back off and make a U-Turn to the right.
    backoff(LEFT);
    
    // Toggle the search direction.
    searchDir ^= 1;
  }

  // Edge is not detected.
  else {
    // Keep searching if opponent is not detected.
    if ( digitalRead(OPPONENT_FC) &&
         digitalRead(OPPONENT_FL) &&
         digitalRead(OPPONENT_FR) &&
         digitalRead(OPPONENT_L) &&
         digitalRead(OPPONENT_R) ) {
      search();
    }
    
    // Attack if opponent is in view.
    else {
      attack();
    }
  }

  // Stop the robot if the button is pressed.
  if (!digitalRead(BUTTON)) {
    // Stop the motors.
    motorL.setSpeed(0);
    motorR.setSpeed(0);

    // Loop forever here.
    while (1);
  }

}

Credits

engtong82

engtong82

14 projects • 9 followers
Built first mobile robot at 20s, first company at 22s, first baby at 36s...
Wai Weng Kong

Wai Weng Kong

4 projects • 6 followers
Embedded system engineer, maker, drones and RC aircraft hobbyist.
DIAN MIAO LING

DIAN MIAO LING

1 project • 3 followers

Comments