momani
Published © MIT

Advanced Brushless Sumo Robot

The Ultimate Brushless Advanced Sumo Robot! in this project I will teach you how to build the best Sumo robot in the world!

IntermediateFull instructions providedOver 2 days211
Advanced Brushless Sumo Robot

Things used in this project

Hardware components

Maxynos THOR 2318 Geared Brushless Motor
×6
MAXYNOS 45A Bidirectional ESC - Brushless Motor Controller
×6
High Grip Robot Wheels
×6
HSS Sumo Robot Blade No:1
×2
Benewake TFmini Plus
×8
Micro Line Sensor ML1
×4
MG90S 9G Micro Servo Motor Metal Geared Motor
×2
Arduino Nano ESP32
×1
Arduino nano Terminal Adapter Expansion Board
×1
GeeekPi 6Pack TXS0108E 8 Channel Logic Level Converter Bi-Directional High Speed Full Duplex Shifter 3.3V 5V for Arduino Raspberry Pi
×1
Micro ATmega32U4
×4
5V Buck Converter Module 5 Packs DC 5-30V to 5V Step-Down Regulator Board 1.8A Output
×2
Countersunk M3 screw 8 mm and nuts
×10
50pcs M6 Hex Nut
×8
M6 x 14mm Button Head Hex Socket Cap Screws Bolts
×8
M6 x 30mm Hex Head Bolts Hexagon Screws
×8
Black Door Hinges, 4 Inch
×2
M2 x12mm flat head screw
×24
M3 Heat Set Insert for 3D Printing
×4
3S Lipo Battery 2200mAh 11.1V 50C
×1
High Purity Tin Lead Rosin Core Solder Wire for Electrical Soldering
×1
Solder Flux
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Hot Air Gun for heat shrinks
LiPo Battery Charger
DC power Supply
Digital multimeter
3D Printer (generic)
3D Printer (generic)

Story

Read more

Custom parts and enclosures

Base

Sketchfab still processing.

Blade Holder

Sketchfab still processing.

Sensors Mid Plate Holder

Sketchfab still processing.

Servo Arm

Sketchfab still processing.

Top Cover

Sketchfab still processing.

Motors Front and back Cover

Sketchfab still processing.

Schematics

Line sensors

TFmini S with Micro pro MCU

Voltage logic level shifter connection

sensors connection

Code

Two TF mini Sensor test with Arduino Leonardo

Arduino
#include <SoftwareSerial.h>
#include "TFMini.h"

#define TIMER_THRESHOLD 300     // Timeout in milliseconds
int rangeLimit = 40;            // Detection threshold in cm

// Sensor 1: RX = 8 green, TX = 7
SoftwareSerial tfSerial1(8, 7);
TFMini tfmini1;

// Sensor 2: RX = 10 green, TX = 9
SoftwareSerial tfSerial2(10, 9);
TFMini tfmini2;

// Output pins
const int output1 = 5;
const int output2 = 6;

void setup() {
  Serial.begin(9600);

  tfSerial1.begin(TFMINI_BAUDRATE);
  tfSerial2.begin(TFMINI_BAUDRATE);

  tfmini1.begin(&tfSerial1);
  tfmini2.begin(&tfSerial2);

  pinMode(output1, OUTPUT);
  pinMode(output2, OUTPUT);
}

// Read and parse data frame from TFMini
void getTFminiData(SoftwareSerial& serial, int* distance, int* strength, bool* validReading) {
  static char i = 0;
  char j = 0;
  int checksum = 0;
  static int rx[9];
  if (serial.available()) {
    rx[i] = serial.read();
    if (rx[0] != 0x59) {
      i = 0;
    } else if (i == 1 && rx[1] != 0x59) {
      i = 0;
    } else if (i == 8) {
      for (j = 0; j < 8; j++) {
        checksum += rx[j];
      }
      if (rx[8] == (checksum % 256)) {
        *distance = rx[2] + rx[3] * 256;
        *strength = rx[4] + rx[5] * 256;
        *validReading = true;
      }
      i = 0;
    } else {
      i++;
    }
  }
}

// Read one sensor and print status
void readSensor(TFMini& sensor, SoftwareSerial& serial, int pinOut, const char* label) {
  int distance = 0, strength = 0;
  bool validReading = false;
  unsigned long start = millis();

  serial.listen();  // Activate listening on this serial port

  // Try to read new data within timeout
  while (!validReading && (millis() - start < TIMER_THRESHOLD)) {
    getTFminiData(serial, &distance, &strength, &validReading);
  }

  if (validReading) {
    if (distance <= rangeLimit) {
      digitalWrite(pinOut, HIGH);
      //Serial.print(label); Serial.println(": HIGH (Target Detected)");
    } else {
      digitalWrite(pinOut, LOW);
      //Serial.print(label); Serial.println(": LOW (Target Out of Range)");
    }

    Serial.print(label); Serial.print(" Distance: ");
    Serial.print(distance); Serial.println(" cm");
  } else {
    digitalWrite(pinOut, LOW);
    //Serial.print(label); Serial.println(": TIMEOUT (No Response)");
  }
}

void loop() {
  readSensor(tfmini1, tfSerial1, output1, "Sensor 1");
  readSensor(tfmini2, tfSerial2, output2, "Sensor 2");

  //delay(100);
}

FinalCodeTFmini.ino

Arduino
testing Opponent sensors detection and motors - this is the final code but without the line sensors
#include <ESP32Servo.h>


// Create Servo objects for each motor
Servo escRight;
Servo escLeft;
Servo myServo;

// Define ESC pins (use only PWM-capable pins!)
const int pinRight = 2;
const int pinLeft = 3;
// Define servo motor pin
const int servoPin = 12;

// Individual sensor pins
const int sensor1 = 4;
const int sensor2 = 5;
const int sensor3 = 6;
const int sensor4 = 7;
const int sensor5 = 8;
const int sensor6 = 9;
const int sensor7 = 10;
const int sensor8 = 11;
unsigned long attackTimer = 0;
bool actionDone = false;  // Flag to ensure the action happens only once

void setup() {
  //Serial.begin(115200);
  // Set PWM frequency to 80Hz for ESCs
  escRight.setPeriodHertz(80);
  escLeft.setPeriodHertz(80);

  // Attach ESCs with min/max PWM signal
  escRight.attach(pinRight, 1000, 2000);
  escLeft.attach(pinLeft, 1000, 2000);

  // Servo motor setup and single open/close action
  myServo.setPeriodHertz(50);  // 50 Hz standard servo
  myServo.attach(servoPin, 500, 2400);
  delay(4000);

  myServo.write(180);  // Open
  delay(500);
  myServo.write(15);  // Close
  delay(500);         // Wait for 3.3 seconds


  // Set all sensor pins as input
  pinMode(sensor1, INPUT);
  pinMode(sensor2, INPUT);
  pinMode(sensor3, INPUT);
  pinMode(sensor4, INPUT);
  pinMode(sensor5, INPUT);
  pinMode(sensor6, INPUT);
  pinMode(sensor7, INPUT);
  pinMode(sensor8, INPUT);






  //myServo.detach();
}

void loop() {

  if (!actionDone) {  // Check if the action has already occurred
    writeAll(1500);
    delay(200);
    writeAll(2000);
    delay(200);
    writeAll(1500);
    delay(600);

    actionDone = true;  // Set the flag to true to prevent repeating
  }

  int s1 = digitalRead(sensor1);
  int s2 = digitalRead(sensor2);
  int s3 = digitalRead(sensor3);
  int s4 = digitalRead(sensor4);
  int s5 = digitalRead(sensor5);
  int s6 = digitalRead(sensor6);
  int s7 = digitalRead(sensor7);
  int s8 = digitalRead(sensor8);

  if (s3 == 1) {
    writeAll(1100);  // Move forward to attack
  }

  else if (s7 == 1) {
    writeAll(1900);  // Move forward to attack
  }


  else if ((s1 == 1) || (s5 == 1)) {
    attackTimer = millis();
    while (((!digitalRead(sensor3)) || (!digitalRead(sensor7))) && ((millis() - attackTimer) < 600)) {
      escRight.writeMicroseconds(1800);
      escLeft.writeMicroseconds(1200);

      if ((digitalRead(sensor3) == 1) || (digitalRead(sensor7) == 1)) {
        break;
      }
    }
  }


  else if ((s2 == 1) || (s6 == 1)) {
    attackTimer = millis();
    while (((!digitalRead(sensor3)) || (!digitalRead(sensor7))) && ((millis() - attackTimer) < 300)) {
      escRight.writeMicroseconds(1800);
      escLeft.writeMicroseconds(1200);

      if ((digitalRead(sensor3) == 1) || (digitalRead(sensor7) == 1)) {
        writeAll(1500);
        break;
      }
    }
  }


  else if ((s4 == 1) || (s8 == 1)) {
    attackTimer = millis();
    while (((!digitalRead(sensor3)) || (!digitalRead(sensor7))) && ((millis() - attackTimer) < 300)) {
      escRight.writeMicroseconds(1200);
      escLeft.writeMicroseconds(1800);

      if ((digitalRead(sensor3) == 1) || (digitalRead(sensor7) == 1)) {
        writeAll(1500);
        break;
      }
    }
  }




  else {
    // If no enemy detected, stop
    writeAll(1500);
  }
}

// Helper function to write the same signal to all ESCs
void writeAll(int pulse) {
  escRight.writeMicroseconds(pulse);
  escLeft.writeMicroseconds(pulse);
}

Full Code with Line Sensors

Arduino
this is the Final Code
#include <ESP32Servo.h>
// Create Servo objects for each motor
Servo escRight;
Servo escLeft;
Servo myServo;


// Define ESC pins (use only PWM-capable pins!)
const int pinRight = 2;
const int pinLeft = 3;
// Define servo motor pin
const int servoPin = 12;
// Individual sensor pins
const int sensor1 = 4;
const int sensor2 = 5;
const int sensor3 = 6;
const int sensor4 = 7;
const int sensor5 = 8;
const int sensor6 = 9;
const int sensor7 = 10;
const int sensor8 = 11;
unsigned long attackTimer = 0;
bool actionDone = false;  // Flag to ensure the action happens only once

// edge sensors
int ferValue;
int felValue;
int berValue;
int belValue;
// Define pins for edge sensors, these edge sensors with output HIGH if a white color is detected
const int FER_PIN = A1;  // Front Edge Right
const int FEL_PIN = A2;  // Front Edge Left
const int BER_PIN = A3;  // Back Edge Right
const int BEL_PIN = A4;  // Back Edge Left
// Variables to store the last edge speed for searching for the opponent
int lastLeftEdgeSpeed = 1630;
int lastRightEdgeSpeed = 1610;


void setup() {
  //Serial.begin(115200);
  // Set PWM frequency to 80Hz for ESCs
  escRight.setPeriodHertz(80);
  escLeft.setPeriodHertz(80);
  // Attach ESCs with min/max PWM signal
  escRight.attach(pinRight, 1000, 2000);
  escLeft.attach(pinLeft, 1000, 2000);
  // Servo motor setup and single open/close action
  myServo.setPeriodHertz(50);  // 50 Hz standard servo
  myServo.attach(servoPin, 500, 2400);
  delay(4000);
  myServo.write(180);  // Open
  delay(500);
  myServo.write(15);  // Close
  delay(500);         // Wait for 3.3 seconds
  // Set all sensor pins as input
  pinMode(sensor1, INPUT);
  pinMode(sensor2, INPUT);
  pinMode(sensor3, INPUT);
  pinMode(sensor4, INPUT);
  pinMode(sensor5, INPUT);
  pinMode(sensor6, INPUT);
  pinMode(sensor7, INPUT);
  pinMode(sensor8, INPUT);
  //Edge sensors
  pinMode(FER_PIN, INPUT);
  pinMode(FEL_PIN, INPUT);
  pinMode(BER_PIN, INPUT);
  pinMode(BEL_PIN, INPUT);
}
void loop() {
  if (!actionDone) {  // Check if the action has already occurred
    writeAll(1500);
    delay(200);
    writeAll(2000);
    delay(200);
    writeAll(1500);
    delay(600);
    actionDone = true;  // Set the flag to true to prevent repeating
  }
  int s1 = digitalRead(sensor1);
  int s2 = digitalRead(sensor2);
  int s3 = digitalRead(sensor3);
  int s4 = digitalRead(sensor4);
  int s5 = digitalRead(sensor5);
  int s6 = digitalRead(sensor6);
  int s7 = digitalRead(sensor7);
  int s8 = digitalRead(sensor8);
  //  Edge digital sensor  values
  ferValue = digitalRead(FER_PIN);
  felValue = digitalRead(FEL_PIN);
  berValue = digitalRead(BER_PIN);
  belValue = digitalRead(BEL_PIN);
  if (s3 == 1) {
    writeAll(1100);  // Move forward to attack
  } else if (s7 == 1) {
    writeAll(1900);  // Move forward to attack
  }



  else if (ferValue == 0) {  // Front Edge Right detected
    lastRightEdgeSpeed = 1330;
    lastLeftEdgeSpeed = 1350;
    escRight.writeMicroseconds(1330);
    escLeft.writeMicroseconds(1350);
    delay(400);
  } else if (felValue == 10) {  // Front Edge Left detected
    lastRightEdgeSpeed = 1350;
    lastLeftEdgeSpeed = 1330;
    escRight.writeMicroseconds(1350);
    escLeft.writeMicroseconds(1330);
    delay(400);

  } else if (berValue == 0) {  // Back Edge Right detected
    lastRightEdgeSpeed = 1630;
    lastLeftEdgeSpeed = 1590;
    escRight.writeMicroseconds(1630);
    escLeft.writeMicroseconds(1590);
    delay(400);

  } else if (belValue == 0) {  // Back Edge Left detected
    lastRightEdgeSpeed = 1590;
    lastLeftEdgeSpeed = 1630;
    escRight.writeMicroseconds(1590);
    escLeft.writeMicroseconds(1630);
    delay(400);


  }


  else if ((s1 == 1) || (s5 == 1)) {
    attackTimer = millis();
    while (((!digitalRead(sensor3)) || (!digitalRead(sensor7))) && ((millis() - attackTimer) < 600)) {
      escRight.writeMicroseconds(1800);
      escLeft.writeMicroseconds(1200);
      if ((digitalRead(sensor3) == 1) || (digitalRead(sensor7) == 1)) {
        break;
      }
    }
  } else if ((s2 == 1) || (s6 == 1)) {
    attackTimer = millis();
    while (((!digitalRead(sensor3)) || (!digitalRead(sensor7))) && ((millis() - attackTimer) < 300)) {
      escRight.writeMicroseconds(1800);
      escLeft.writeMicroseconds(1200);
      if ((digitalRead(sensor3) == 1) || (digitalRead(sensor7) == 1)) {
        writeAll(1500);
        break;
      }
    }
  } else if ((s4 == 1) || (s8 == 1)) {
    attackTimer = millis();
    while (((!digitalRead(sensor3)) || (!digitalRead(sensor7))) && ((millis() - attackTimer) < 300)) {
      escRight.writeMicroseconds(1200);
      escLeft.writeMicroseconds(1800);
      if ((digitalRead(sensor3) == 1) || (digitalRead(sensor7) == 1)) {
        writeAll(1500);
        break;
      }
    }
  } else {
    escRight.writeMicroseconds(lastRightEdgeSpeed);
    escLeft.writeMicroseconds(lastLeftEdgeSpeed);
  }
}
// Helper function to write the same signal to all ESCs
void writeAll(int pulse) {
  escRight.writeMicroseconds(pulse);
  escLeft.writeMicroseconds(pulse);
}

Brushless motors test with Maxynos ESC 45A

Arduino
#include <ESP32Servo.h>

Servo esc;
int escPin = 4;  // Choose any PWM-capable pin

void setup() {
  esc.setPeriodHertz(80);          // Standard 50Hz for ESC
  esc.attach(escPin, 1000, 2000);  // Min and Max pulse width in microseconds
  esc.writeMicroseconds(1500);     // Neutral (Stop)
  delay(2000);                     // Wait to arm ESC
}

void loop() {

  // Forward (1800us) for 2 sec
  esc.writeMicroseconds(2000);
  delay(1000);

  // Stop (1500us) for 1 sec
  esc.writeMicroseconds(1500);
  delay(120);

  // Reverse (1200us) for 2 sec
  esc.writeMicroseconds(1000);
  delay(1000);

  // Stop (1500us) for 1 sec
  esc.writeMicroseconds(1500);
  delay(120);
}

Credits

momani
3 projects • 9 followers
Mechanical Engineer

Comments