Skip to content

Instantly share code, notes, and snippets.

@cyrus007
Last active October 6, 2017 19:21
Show Gist options
  • Save cyrus007/783b238c0e11cc7e963f6b7c4a38a7ae to your computer and use it in GitHub Desktop.
Save cyrus007/783b238c0e11cc7e963f6b7c4a38a7ae to your computer and use it in GitHub Desktop.
Use uBit to control rctoy + rpi via BLE
"""
© 2017 [email protected]
Module rpidriver.py - rpi library to handle dc motor
driven rc car using uBit controller
The program reads the Accelerometer:x,y,z values
coming from uBit via BLE and control motor using it
"""
import sys
import time
import math
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD) #set GPIO to board mode
from bluezero import microbit
IN1 = 11 # Digital IN1 on L298n Board
IN2 = 13 # Digital IN2 on L298n Board
ENA = 12 # PWM GPIO18 to ENA on L298n Board
IN3 = 3 # Digital IN3 on L298n Board
IN4 = 5 # Digital IN4 on L298n Board
ENB = 7 # Digital to ENB on L298n Board
# Setup forward/backward motor
GPIO.setup(IN1, GPIO.OUT)
GPIO.setup(IN2, GPIO.OUT)
GPIO.setup(ENA, GPIO.OUT)
pwm = GPIO.PWM(ENA, 100)
pwm.start(0)
# Setup left/right motor
GPIO.setup(IN3, GPIO.OUT)
GPIO.setup(IN4, GPIO.OUT)
GPIO.setup(ENB, GPIO.OUT)
class Driver:
def __init__(self, triggerpin):
self.tpin = triggerpin
self.ubit = None
def initialize(self):
if self.ubit is None:
self.ubit = microbit.Microbit(adapter_addr='##:##:##:##:##:##', device_addr='##:##:##:##:##:##')
return self.connect()
def kill(self):
try:
self.ubit.disconnect()
self.ubit = None
except:
self.ubit = None
return False
def connect(self):
self.dir = 0 # 0 = straight, 1 = right, -1 = left
self.motion = 0 # 0 = stop, 1 = reverse, -1 = forward
# Now connect to uBit
print('Connecting to uBit', file=sys.stderr)
try:
self.ubit.connect()
return True
except:
print('No BLE connection yet', file=sys.stderr)
return False
def command(self, action):
if self.ubit.button_a > 0:
return self.start()
elif self.ubit.button_b > 0:
return self.stop()
else:
return action
def start(self):
self.ubit.pixels = [0b01110,
0b11000,
0b01111,
0b00011,
0b01110]
time.sleep(0.25)
return True
def stop(self):
self.ubit.pixels = [0b10001,
0b01010,
0b00100,
0b01010,
0b10001]
time.sleep(0.25)
return False
def acceldata(self):
return self.ubit.accelerometer
def move(self, x, y):
if x > 0.2:
self.right()
elif x < -0.2:
self.left()
else:
self.straight()
if y > 0.2:
dc = math.floor((y - 0.15) * 100 / 1.5)
self.reverse(dc)
elif y < -0.2:
dc = math.floor((abs(y) - 0.15) * 100 / 1.5)
self.forward(dc)
else:
dc = 0
self.stall()
# print('Direction: {} | Motion: {} | Power: {}'.format(self.dir, self.motion, dc), file=sys.stderr)
def right(self):
if self.dir != 1:
self.dir = 1
GPIO.output(IN3, True)
GPIO.output(IN4, False)
GPIO.output(ENB, True)
def left(self):
if self.dir != -1:
self.dir = -1
GPIO.output(IN3, False)
GPIO.output(IN4, True)
GPIO.output(ENB, True)
def straight(self):
self.dir = 0
GPIO.output(IN3, False)
GPIO.output(IN4, False)
GPIO.output(ENB, False)
def reverse(self, dc):
if self.motion != 1:
self.motion = 1
GPIO.output(IN1, True)
GPIO.output(IN2, False)
pwm.ChangeDutyCycle(dc)
GPIO.output(ENA, True)
def forward(self, dc):
if self.motion != -1:
self.motion = -1
GPIO.output(IN1, False)
GPIO.output(IN2, True)
pwm.ChangeDutyCycle(dc)
GPIO.output(ENA, True)
def stall(self):
self.motion = 0
GPIO.output(ENA, False)
"""
© 2017 [email protected]
Main program to run in background listening for
rc commands
"""
import driver as driver
import signal
import sys
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD) #set GPIO to board mode
GPIO.setwarnings(False)
GPIO.setup(15, GPIO.IN, pull_up_down=GPIO.PUD_UP) #use to trigger action
GPIO.setup(16, GPIO.OUT)
# Handle interrupt
def signal_handler(signal, frame):
print('You pressed Ctrl+C exiting!')
driver.kill()
GPIO.cleanup()
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
print("START!! Press Ctrl+C to exit", file=sys.stderr)
status = False
move = False
driver = driver.Driver(15) #create a driver class with triggerpin
try:
while True:
if not status and GPIO.input(15):
GPIO.output(16, GPIO.HIGH) #indicate that it is on
status = driver.initialize()
print("Switched on...status={}".format(status), file=sys.stderr)
elif status and not GPIO.input(15):
GPIO.output(16, GPIO.LOW) #indicate that it is off
status = driver.kill()
print("Switched off...status={}".format(status), file=sys.stderr)
if status:
move = driver.command(move)
x, y, z = driver.acceldata()
print('move = {}, X = {}, Y = {}, Z = {}'.format(move,x,y,z))
if move:
driver.move(x, y)
except KeyboardInterrupt: # If CTRL+C is pressed, exit cleanly
print("You pressed Ctrl+C, exiting...", file=sys.stderr)
GPIO.cleanup()
finally:
GPIO.cleanup()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment