Log in to unlock Raspberry Pi 5 for $60 (was $80) with $100+ in eligible purchases.
from __future__ import division
import RPi.GPIO as GPIO
from time import sleep
from serial import Serial
import json
import Adafruit_PCA9685
class Car(object):
def __init__(self, BT_Port, laser_pin):
GPIO.setmode(GPIO.BCM)
self.ser = Serial(BT_Port, baudrate=9600,timeout=0)
self.laser_pin = laser_pin
self.laser_state = False
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 configServos(self):
self.pwm = Adafruit_PCA9685.PCA9685()
self.servo_min = 150
self.servo_max = 600
self.pwm.set_pwm_freq(60)
def deg_to_pulse(self, degree):
pulse = (degree - 0) * (self.servo_max - self.servo_min) / (180 - 0) + 150
print('Pulse: '+str(pulse))
return int(pulse)
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
#except IOError:
#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 move_turret(self, turret_deg, barrel_deg):
self.pwm.set_pwm(0, 0, self.deg_to_pulse(turret_deg))
self.pwm.set_pwm(1, 0, self.deg_to_pulse(barrel_deg))
def fire_laser(self, state):
GPIO.output(self.laser_pin, state)
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.laser_state = self.json_obj["shoot"]
self.fire_laser(self.json_obj["shoot"])
elif "turret" in self.cmd:
val1 = self.json_obj["turret"][0]
val2 = self.json_obj["turret"][1]
self.move_turret(val1, val2)
except TypeError:
pass
sleep(.01)
import car
bt_port = "/dev/rfcomm3"
laser_pin = 20
rc_car = car.Car(bt_port, laser_pin)
rc_car.configMotors(6,5,19,13, invertLR=True)
rc_car.configServos() #Turret drive servo, barrel servo
while 1:
rc_car.update()
#include "Timer.h"
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
int JS_VALS[2] = {};
int JS_VALS_R[2] = {};
const int JS_PINS[4] = {A0, A1, A2, A3}; //L_X, L_Y, R_X, R_Y
const int led_pins[4] = {4,5,6,7};
const int button_pin = 3;
const int deadzone = 8;
bool laser = false;
const int servo_limits[5] = {0, 180, 50, 95, 75}; //Left, Right, Lower, Upper, Middle limits for the turret
int turret_positions[2] = {90, servo_limits[4]}; //Initial positions
unsigned long last_time = 0;
long motor_delay = 30; //Delay 30 ms between motor control polls
long turret_delay = 150; //Delay 150 ms between turret control polls
long reloadSpeed = 8000;
float driveSpeed = 1.0;
int crewValues[4] = {3,3,2,1};
bool crewLeft[4] = {true,true,true,true};
int crewLeftNum = 4;
int reloadTimer, crewReplaceTimer, fireTimer;
bool is_reloaded= true;
bool can_move = true;
bool can_fire = true;
LiquidCrystal_I2C lcd(0x3F, 16, 2);
Timer t;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
lcd.init();
lcd.backlight();
lcd.print("Begin fighting!");
delay(2000);
lcd.clear();
lcd.home();
pinMode(button_pin, INPUT_PULLUP);
Serial.println("Begin");
t.every(motor_delay, control_motors);
t.every(turret_delay, control_turret);
t.every(50, checkButton);
for(int i=0;i<4;i++){
pinMode(led_pins[i], OUTPUT);
}
updateCrew();
}
void loop() {
/*control_motors();
control_turret();
delay(150);*/
t.update();
if(Serial.available()>0){
String data = Serial.readStringUntil('\n');
if(data=="HG"){
crewLeft[0] = false;
crewLeftNum -= 1;
reloadSpeed += 2000;
can_fire = false;
crewReplaceTimer = t.after(6000, replaceCrew);
}
else if(data=="HD"){
crewLeft[1] = false;
crewLeftNum -= 1;
driveSpeed -= .2;
can_move = false;
crewReplaceTimer = t.after(6000, replaceCrew);
}
else if(data=="HC"){
crewLeft[2] = false;
crewLeftNum -= 1;
driveSpeed -= .1;
reloadSpeed += 1500;
crewReplaceTimer = t.after(6000, replaceCrew);
}
else if(data=="HM"){
crewLeft[3] = false;
crewLeftNum -= 1;
crewReplaceTimer = t.after(6000, replaceCrew);
}
updateCrew();
}
if(crewLeftNum<=1){
lcd_clear();
lcd.print("You lose");
while(1);
}
}
void checkButton(){
if(digitalRead(button_pin)==0){
fire_laser();
}
}
void replaceCrew(){
if(crewLeft[0]==false){
if(crewLeft[2]==true){
crewLeft[2] = false;
crewLeft[0] = true;
can_fire = true;
}
else if(crewLeft[3]==true){
crewLeft[3] = false;
crewLeft[0] = true;
can_fire = true;
}
}
else if(crewLeft[1]==false){
if(crewLeft[2]==true){
crewLeft[2] = false;
crewLeft[1] = true;
can_move = true;
}
else if(crewLeft[3]==true){
crewLeft[3] = false;
crewLeft[1] = true;
can_move = true;
}
}
updateCrew();
t.stop(crewReplaceTimer);
}
void updateCrew(){
for(int i=0;i<4;i++){
digitalWrite(led_pins[i],crewLeft[i]);
}
}
void lcd_clear(){
lcd.clear();
lcd.home();
}
void fire_laser(){
if(is_reloaded){
if(can_fire){
lcd.clear();
lcd.print("Firing laser");
is_reloaded = false;
String json_string = "{\"motor\":[" + String(0)+","+String(0)+"]}"; //Stop tank before firing
Serial.println(json_string);
laser = true;
fireTimer = t.after(2000, stopLaser);
}
}
}
void stopLaser(){
t.stop(fireTimer);
laser = false;
lcd_clear();
lcd.print("Reloading");
reloadTimer = t.after(reloadSpeed, reloadGun);
}
void reloadGun(){
lcd_clear();
lcd.print("Reloaded");
is_reloaded = true;
t.stop(reloadTimer);
}
void control_motors(){
JS_VALS[0] = analogRead(JS_PINS[0]);
JS_VALS[1] = analogRead(JS_PINS[1]);
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;
}
motor1 = int(float(motor1)*driveSpeed);
motor2 = int(float(motor2)*driveSpeed);
if(can_move==false){
motor1 = 0;
motor2 = 0;
}
String json_string = "{\"motor\":[" + String(motor1)+","+String(motor2)+"]}";
Serial.println(json_string);
String json_string2;
if(laser){
json_string2 = "{\"shoot\":1}";
Serial.println(json_string2);
}
else if(!laser){
json_string2 = "{\"shoot\":0}";
Serial.println(json_string2);
}
}
void control_turret(){
JS_VALS_R[0] = analogRead(JS_PINS[2]); //Get X values
JS_VALS_R[1] = analogRead(JS_PINS[3]); //Get Y values
int x = map(JS_VALS_R[0]+10, 0, 1023, 5, -5);
x = constrain(x, -5, 5); //Catch outliers
int y = map(JS_VALS_R[1], 0, 1023, 2, -2);
y = constrain(y, -2, 2);
turret_positions[0] += x;
turret_positions[1] += y;
if(turret_positions[0] <= servo_limits[0]){
turret_positions[0] = servo_limits[0];
}
else if(turret_positions[0] >= servo_limits[1]){
turret_positions[0] = servo_limits[1];
}
if(turret_positions[1] <= servo_limits[2]){
turret_positions[1] = servo_limits[2];
}
else if(turret_positions[1] >= servo_limits[3]){
turret_positions[1] = servo_limits[3];
}
String json_string = "{\"turret\":[" + String(turret_positions[0])+","+String(turret_positions[1])+"]}";
Serial.println(json_string);
}