Nerf Gun Robot

By Bria Matthews and Lionel Jones

Description

The robot is phone controlled through a bluetooth app called Adafruit Bluefruit BLE. You can control the vehicle's movement as well as shoot the nerf gun through this app.

Materials

Setup

The robot shadow chassis can be set up using instructions from Shadow robot kit. Don't attach the top chassis plate.The motor driver can be attached as demonstrated in Motor. And the bluetooth module can be setup using Adafruit Bluefruit LE UART Friend - Bluetooth Low Energy (BLE).

The trigger of the Nerf gun is pulled by a servo motor. To set this up, the Nerf gun and servo were mounted onto a plank of wood as shown below: /media/uploads/LJKing3/nerf_gun_mount2.jpg

First, to mount the servo, trace the servo onto the plank of wood. Cut out the shape using a drill and a small saw. Next, put the servo into the cutout and trace out the 4 mounting holes. Drill the holes and mount the servo using small screws and nuts.

Next, place the Nerf gun on the plank of wood and mark 3 or more spots into which to screw standoffs. These will keep the gun in place when the servo pulls the trigger. Drill holes into the marked spots and insert the standoffs.

Below is the layout of the Nerf gun [1]: /media/uploads/LJKing3/nerf_gun_label.jpg

The important parts are 5 (the trigger) and 6 (the motor trigger).

To setup the trigger pull mechanism, place a zip tie around the trigger. Pull the zip tie as tight as possible without depressing the trigger. Next, loop a thin, long string inside the zip tie and into a hole on the servo. Pull this as tight as possible without depressing the trigger. Next, hold down the motor trigger with a rubber band or tape.

Connections

The first battery pack (BP1) will power the mbed and Servo motor. The second battery pack (BP2) will power the two motors, hall sensors, and Bluetooth module.

Motor Connections

mbedH-bridgeLeft MotorRight MotorBP2
A01black wire
A02red wire
B01red wire
B02black wire
p21PWMA
p15AI2
p16AI1
ST/BY5V
p26BI1
p25BI2
p24PWMB
GndGND

Bluetooth Connections

mbedAdafruitBP2
GndGND
Vin5V
p9RXI
p10TXO
CTSGND

Servo Connections

mbedHS-6450mgBP1
p22signal
+5v
-GND

Hall Effect Sensor Connections

mbedLeft sensorRight SensorBP2
p5signal
p6signal
++5V
--GND

Here's the completed breadboard: /media/uploads/LJKing3/img_0039_-1-.jpg

Code

Below is the mbed code:

#include "mbed.h"
#include "Servo.h"
#include "rtos.h"
#include "motordriver.h"

//create threads
Thread thread1;
Thread thread2;

//mutexs
Mutex motors;


//motor 
Motor ml(p21, p15, p16, 1); // pwm, fwd, rev, can brake motor a
Motor mr(p24, p25, p26, 1); // pwm, fwd, rev, can brake motor b                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
float sr = 0.0;
float sl = 0.0;
float speedincrement = 0.12;
float turndiff = 0.3;
bool turn = 1; //0: straight movemnt 1: turning or stopped
bool forw =0; //0: backwards 1: forwards


//hall effect
volatile long int countl = 0;
volatile long int countr = 0;

//bluetooth
RawSerial  blue(p9,p10);

//Serial
DigitalOut myled(LED1);
Serial pc(USBTX, USBRX);

//Servos for shooting
Servo b1(p22);
//Servo b2(p23);
float pos = 0.1;

//counter class for hall effect
class Counter {
public:
    Counter(PinName pin) : _interrupt(pin) {        // create the InterruptIn on the pin specified to Counter
        _interrupt.mode(PullUp);
        _interrupt.rise(this, &Counter::increment); // attach increment function of this counter instance
    }

    void increment() {
        _count++;
        if(turn){
            _count = 0;
        }
    }

    int read() {
        return _count;
    }
    void reset(){
        _count = 0;
    }

private:
    InterruptIn _interrupt;
    volatile int _count;
};

Counter risel(p6);
Counter riser(p5);


//correct wheel movement with hall affect
void hall(){
    int diff;
    while(1) {
        diff = riser.read() - risel.read();
        riser.reset();
        risel.reset();
        if(!turn){
            if(forw){//if moving forward
                if(diff < -5) sl -= speedincrement;
                else if (diff > 5) sr -= speedincrement;
                if((sl<0.5)|| (sl<0.5)){
                     sl += 0.5;
                     sr += 0.5;
                }
            }
            else{
                if(diff < -5) sl += speedincrement;
                else if (diff > 5) sr += speedincrement;
                if((sl>-0.5)|| (sl>-0.5)){
                     sl += 0.5;
                     sr += 0.5;
                }
            }
            
        }
        //drive motor
        ml.speed(sl);
        mr.speed(sr);
//        motors.unlock();
        Thread::wait(100); 
    }
}
//servo help
//https://os.mbed.com/questions/55410/Servo-only-move-90-deg/

int main() { 
    b1.calibrate(0.00085,180.0); 
    b1 = 1.0;
    thread2.start(hall);
    
    //receive command from bluetooth and execute
    char bnum=0;
    char bhit=0;
    while(1) {
        //motors.lock();
        if (blue.getc()=='!') {
            if (blue.getc()=='B') { //button data packet
                bnum = blue.getc(); //button number
                bhit = blue.getc(); //1=hit, 0=release
                if (blue.getc()==char(~('!' + 'B' + bnum + bhit))) { //checksum OK?
                    //myled = bnum - '0'; //current button number will appear on LEDs
                    switch (bnum) {
                        case '1': //number button 1
                            if (bhit=='1') {// fire button
                                b1 = 0.6; //shoot by turning servo
                                Thread::wait(1000);
                                b1 = 0.0;
                                Thread::wait(500);
                                b1 = 0.2; //shoot by turning servo
                                Thread::wait(1000);
                                b1 = 1.0;                      
                            } else {
                                //add release code here
                            }
                            break;
                        case '2': //number button 2
                            if (bhit=='1') {
                                //add hit code here
                            } else {
                                //add release code here
                            }
                            break;
                        case '3': //number button 3
                            if (bhit=='1') {
                                //add hit code here
                            } else {
                                //add release code here
                            }
                            break;
                        case '4': //number button 4
                            if (bhit=='1') {
                                //add hit code here
                            } else {
                                //add release code here
                            }
                            break;
                        case '5': //button 5 up arrow
                            if (bhit=='1') {
//                                if(sr<1) sr += speedincrement;
//                                else sr = 1;
//                                if(sl<1) sl += speedincrement;
//                                else sl = 1;
                                sl = 1.0;
                                sr = 1.0;
                                turn = 0;
                                forw = 1;
                                //pc.printf("go/n");
                            } else {
                                sl = 0.0;
                                sr = 0.0;
                                turn = 1;
                                //pc.printf("stop/n");
                            }
                            break;
                        case '6': //button 6 down arrow
                            if (bhit=='1') {
                                sr= -1.0;
                                forw = 0;
                                turn = 0;
                            } else {
                                sl = 0.0;
                                sr = 0.0;
                                turn = 1;
                            }
                            break;
                        case '7': //button 7 left arrow
                            if (bhit=='1') {
                                sr = 1.0;
                                sl = sr - turndiff;
                                
                                turn = 1;
                            } else {
                                sl = 0.0;
                                sr = 0.0;
                            }
                            break;
                        case '8': //button 8 right arrow
                            if (bhit=='1') {
                                sl = 1.0;
                                sr = sl - turndiff;
                                turn = 1;
                            } else {
                                sl = 0.0;
                                sr = 0.0;
                            }
                            break;
                        default:
                            break;
                    }
                }
            }
        }
        Thread::wait(300); //wait 300ms
    }
}

Demo

Below is a video of the phone control of the robot:

References

[1] https://www.instructables.com/id/Beginners-Stryfe-Modification/


Please log in to post comments.