Bomb-Defusing Robot

The main goal of the Bomb Defusing Robot project was to teach students how to use Embedded C programming language and apply it in real-world scenarios. Specifically, the project aimed to create a robot capable of searching for an infrared beacon signal representing a bomb and attempting to defuse it.

This project demonstrated hardware and software integration expertise in a mechatronic system through the implementation of the following key components and features:

  • Hardware Assembly: The project involved assembling the electronic hardware necessary for the robot's operation, including the Microchip PIC18F4331 microcontroller, motors, IR sensors, and an RFID reader. 3D printing was also used for custom-made mounting brackets.

  • Embedded C Programming: Embedded C was used to program the microcontroller chip on the robot, instructing it to interact with various components and sensors.

  • PWM Speed Control: A Pulse-Width Modulation (PWM) speed control scheme was coded to control the robot's electric motors and its track drive system.

  • Infrared Signal Detection: The robot was equipped with a pair of infrared receivers to detect and lock onto the infrared signal emitted by the "bomb".

  • Target Approach: Once the robot detected the signal by rotating at its starting position, it accelerated toward the target using its electric motors.

  • RFID Sensor: An RFID sensor located at the front of the robot was used to detect contact with the "bomb." Upon contact, the RFID sensor sent an instruction to the Microchip PIC18F4331 microcontroller.

  • Safety and Recovery: The microcontroller, upon receiving the RFID signal, instructed the robot to reverse its motion and return to its starting position. This ensured the robot's safety after detecting and simulating the defusal of the "bomb."

Below is a snippet of the code that was used to control this robot. This code corresponds to the main program although several other scripts were implemented as includes:

#include "dc_motor.h"
#include "LCD.h"
#include <stdio.h>
#include <string.h>
#include "RFID.h"  
#include "IR.h"
#include "Robot_Control.h"

#define PWMcycle 199 //This was calculated.
#pragma config MCLRE=OFF, LVP=OFF, OSC = IRCIO, WDTEN = OFF //Needed in case code does not run with PICkit3 connected. Internal oscillator selected, WDT off.

char buf = 0;            //buffer for characters for LCD
char RFIDData[11];     //to store RFID tag data
char counter = 0;       //counts 10 RFID characters to be displayed 
int timeCounter = 0;    //Seconds counter for motor
int distanceTime = 0;   //Variable to store time/distance travelled
char reached = 0;       //Boolean value to signal if the RFID tag has been reached

//High priority interrupt routine to handle the reading of the RFID tag.
void __interrupt(high_priority)InterruptHandlerHigh(void)
{
    if (PIR1bits.RCIF) {
        PIR1bits.RCIF = 0; //Clear interrupt flag.
        distanceTime = timeCounter;
        reached = 1;

        RFIDData[10] = 0; //to register as a string.
        buf = getCharSerial();
        if (buf == 0x02) {
            SendLCD(0b00000001, 0); //Display CLEAR
            __delay_ms(2);
            SetLine(2); //Set Line 2
            while (counter < 10) { //Only read the 10 Data bytes.
                buf = getCharSerial();
                SendLCD(buf, 1); //output string to LCD
                counter++;
            }
            counter = 0;

            //The EUSART receive buffer, RCREG, is full (cleared when RCREG is read).
            SetLine(1);
            LCD_String("RFID FOUND      ");
        }
    }
}

//Low priority interrupt routine to count seconds.
void __interrupt(low_priority)InterruptHandlerLow(void) 
{
    if (INTCONbits.TMR0IF) {
        timeCounter++; //Counter to count number of seconds
        //Initiate timer with a base value to get 1/2 sec at overflow
        TMR0H = 0b00001011;
        TMR0L = 0b11011100;
        INTCONbits.TMR0IF = 0; //Clear the interrupt flag to return to main code
    }
}

//Main Function
void main(void) {

    struct DC_motor motorL, motorR; //declare 2 motor structures

    OSCCON = 0x72; //Set clock to 8MHz
    while (!OSCCONbits.IOFS); //wait until stable

    InitPWM(PWMcycle); //setup PWM registers

    //Assign initial values of each structure
    motorL.power = 0; //zero power to start
    motorL.direction = 1; //set default motor direction
    motorL.dutyLowByte = (unsigned char *) (&PDC1L); //store address of PWM duty low byte
    motorL.dutyHighByte = (unsigned char *) (&PDC1H); //store address of PWM duty high byte
    motorL.dir_pin = 2; //pin RB2/PWM2 controls direction
    motorL.PWMperiod = PWMcycle; //store PWMperiod for motor

    motorR.power = 0; //zero power to start
    motorR.direction = 1; //set default motor direction
    motorR.dutyLowByte = (unsigned char *) (&PDC0L); //store address of PWM duty low byte
    motorR.dutyHighByte = (unsigned char *) (&PDC0H); //store address of PWM duty high byte
    motorR.dir_pin = 0; //pin RB0/PWM0 controls direction
    motorR.PWMperiod = PWMcycle; //store PWMperiod for motor

    InitTimer(); //Initialise the Timer0 module to count time for motors ON.
    InitIR(); //Initialise the IR
    InitLCD(); //Initialise the LCD
    InitSerial(); //Initialise the RFID Serial Interface

    TRISCbits.RC3 = 1; //Set pin RC3 to input;
    
    SetLine(1);
    LCD_String("PRESS BUTTON    "); //Instructions for user

    while (!PORTCbits.RC3); //check until the button is pressed to start the routine.
    while (reached==0) {
            SendLCD(0b1,0); //Clear the screen before every start.
            __delay_ms(2);

            findBeacon(&motorL, &motorR); //Find the beacon

            SendLCD(0b1, 0);    //Clear LCD display
            __delay_ms(2);
            SetLine(1);
            LCD_String("BEACON FOUND    ");

            timeCounter = 0; //Start the time counter that ticks when TMR0 module overflows.
            while (reached == 0 && timeCounter<12) { //Run this loop until RFID tag is reached or until timeCounter reaches 12 seconds (i.e. the robot has gone past it and missed it by then)
                 moveMotors(&motorL, &motorR, 1, 1, 80); //Set both motors forward to go to beacon
            }

            reverse(&motorL, &motorR, distanceTime); //Reverse towards the starting position

            stop(&motorL, &motorR); //Stop the robot
    }
}
Previous
Previous

Formula Student EV3

Next
Next

Key Turner