Evan Rust
Published © GPL3+

Laser Shootin' Robot

Use a DFRobot MiniQ chassis with Raspberry Pi Zero W to create a robot that can shoot a laser at anything you choose! (Not at eyes, please.)

IntermediateFull instructions provided5 hours6,997

Things used in this project

Hardware components

DFRobot MiniQ Chassis
×1
Raspberry Pi Zero Wireless
Raspberry Pi Zero Wireless
×1
Arduino Nano R3
Arduino Nano R3
×1
Dual H-Bridge motor drivers L293D
Texas Instruments Dual H-Bridge motor drivers L293D
×1
NPN Transistor
×1
5V Regulator 1.5A output
×1
3 Terminal, 2 Position SPDT Switch
×1
HC-05 Bluetooth Module
HC-05 Bluetooth Module
×1
Joystick
×1
1800 mAh LiPo Battery 11.7V
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Custom parts and enclosures

Battery Platform

Schematics

Robot Schematic

Controller Schematic

Code

Controller Code

C/C++
int JS_VALS[2] = {};

const int button_pin = 2;
const int deadzone = 8;

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
pinMode(button_pin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(button_pin), fire_laser, FALLING);
}

void loop() {
  // put your main code here, to run repeatedly:
  JS_VALS[0] = analogRead(A1);
  JS_VALS[1] = analogRead(A2);
  int x = map(JS_VALS[0], 0, 1023, -50, 50);
  x = constrain(x, -100, 100);
  int y = map(JS_VALS[1], 0, 1023, -50, 50);
  y = constrain(y, -100, 100);
  int motor1 = x+y;
  int motor2 = y-x;
  motor1 = constrain(motor1, -100, 100);
  motor2 = constrain(motor2, -100, 100);
  if(abs(motor1) <= deadzone){
    motor1 = 0;
  }
  if(abs(motor2) <= deadzone){
    motor2 = 0;
  }
  //Serial.println("X: "+String(JS_VALS[0])+", Y: "+String(JS_VALS[1]));
  String json_string = "{\"motor\":[" + String(motor1)+","+String(motor2)+"]}";
  Serial.println(json_string);
  delay(30);
}

void fire_laser(){
  String json_string = "{\"shoot\":\"1\"}";
  Serial.println(json_string);
}

Python Robot Class

Python
import RPi.GPIO as GPIO
from time import sleep
from serial import Serial
import json

class Car(object):

	def __init__(self, BT_Port, laser_pin):
		GPIO.setmode(GPIO.BCM)
		self.ser = Serial(BT_Port, baudrate=9600)
                self.laser_pin = laser_pin
                GPIO.setup(self.laser_pin, GPIO.OUT)
		
	def configMotors(self, mL1, mL2, mR1, mR2, invertLR=False):
	    self.motor_array = [mL1, mL2, mR1, mR2]
	    self.invert = invertLR
	    for pin in self.motor_array:
		GPIO.setup(pin, GPIO.OUT)
		#self.motor_pwm.append(GPIO.PWM(pin, 490))
	    self.motorL1_pwm = GPIO.PWM(mL1, 100)
	    self.motorL2_pwm = GPIO.PWM(mL2, 100)
	    self.motorR1_pwm = GPIO.PWM(mR1, 100)
	    self.motorR2_pwm = GPIO.PWM(mR2, 100)
	    self.motorL1_pwm.start(0)
	    self.motorL2_pwm.start(0)
	    self.motorR1_pwm.start(0)
	    self.motorR2_pwm.start(0)
	    
		
	def receive_command(self):
            self.cmd = ""
            if self.ser.inWaiting():
                self.cmd = self.ser.readline()
                if self.cmd != None:
                    try:
                        data = self.cmd.decode('utf-8')
                        data = json.loads(data.strip())
                        print data
                        if data != "":
                            return data
                        else:
                            return ""
                    except ValueError:
                        pass
			
	def turn_wheel(self, motor1, motor2):
            if self.invert:
                temp = motor1
                motor1 = motor2
                motor2 = temp
            motor1 = (motor1 / 2)
            motor2 = (motor2 / 2)
            if motor1<0:
		self.motorL2_pwm.ChangeDutyCycle(motor1*-1)
		self.motorL1_pwm.ChangeDutyCycle(0)#make positive if negative
            else:
		self.motorL1_pwm.ChangeDutyCycle(motor1)
		self.motorL2_pwm.ChangeDutyCycle(0)
		
            if motor2<0:
		self.motorR2_pwm.ChangeDutyCycle(motor2*-1)
		self.motorR1_pwm.ChangeDutyCycle(0)#make positive if negative
            else:
		self.motorR1_pwm.ChangeDutyCycle(motor2)
		self.motorR2_pwm.ChangeDutyCycle(0)
			
        def fire_laser(self):
            GPIO.output(self.laser_pin, GPIO.HIGH)
            sleep(2)
            GPIO.output(self.laser_pin, GPIO.LOW)

	def update(self): #Run to make the robot work
            self.json_obj = self.receive_command()
	    print self.json_obj
	    try:
                if "motor" in self.cmd:
                    if self.json_obj["motor"] != None:
                   	 val1 = self.json_obj["motor"][0]
			# if val1 > 0:
      			 #    val1 += 10
                   	 val2 = self.json_obj["motor"][1]
			# if val2 <0:
			#	val2 += 4
                   	 self.turn_wheel(val1, val2)
		elif "shoot" in self.cmd:
		    self.fire_laser()
            except TypeError:
                pass

Python Robot Main Script (run this one)

Python
import car

bt_port = "/dev/rfcomm0"
laser_pin = pin5
rc_car = car.Car(bt_port, laser_pin)

rc_car.configMotors(pin1,pin2,pin3,pin4, invertLR=False)

while 1:
    rc_car.update()
        

Credits

Evan Rust

Evan Rust

122 projects • 1084 followers
IoT, web, and embedded systems enthusiast. Contact me for product reviews or custom project requests.

Comments