diff --git a/compLIB/ADC.py b/compLIB/ADC.py new file mode 100644 index 0000000..bb7e5b8 --- /dev/null +++ b/compLIB/ADC.py @@ -0,0 +1,35 @@ +import smbus + +SINGLE_ENDED = 0x84 +ADDRESS = 0x48 + +bus = smbus.SMBus(1) + + +class ADC: + + @staticmethod + def read(channel) -> float: + """ + Read from adc channel + 0 -> Left IR Sensor + 1 -> Right IR Sensor + 2 -> Battery voltage / 3 + :param channel: Channel between 0 and 2 + :return: voltage + """ + + """Select the Command data from the given provided value above""" + command = SINGLE_ENDED | ((((channel << 2) | (channel >> 1)) & 0x07) << 4) + bus.write_byte(ADDRESS, command) + + while "Koka is great": + value1 = bus.read_byte(ADDRESS) + value2 = bus.read_byte(ADDRESS) + if value1 == value2: + break + + voltage = value1 / 255.0 * 3.3 # calculate the voltage value + voltage = round(voltage, 2) + + return voltage diff --git a/compLIB/Battery.py b/compLIB/Battery.py new file mode 100644 index 0000000..bb08b03 --- /dev/null +++ b/compLIB/Battery.py @@ -0,0 +1,22 @@ +from compLIB.ADC import ADC + + +BATTERY_CHANNEL = 2 +BATTERY_COUNT = 2 +BATTERY_MULTIPLIER = 3 +BATTERY_MIN_VOLTAGE = 3.6 +BATTERY_MAX_VOLTAGE = 4.1 + +adc = ADC() + + +class Battery(object): + + @staticmethod + def percent() -> int: + """ + Get battery percentage between 0 and 100 + :return: + """ + voltage = adc.read(BATTERY_CHANNEL) * BATTERY_MULTIPLIER + return int((voltage - BATTERY_MIN_VOLTAGE) / BATTERY_MAX_VOLTAGE * 100) diff --git a/compLIB/Buzzer.py b/compLIB/Buzzer.py new file mode 100644 index 0000000..2021301 --- /dev/null +++ b/compLIB/Buzzer.py @@ -0,0 +1,18 @@ +import RPi.GPIO as GPIO + +GPIO.setwarnings(False) +Buzzer_Pin = 17 +GPIO.setmode(GPIO.BCM) +GPIO.setup(Buzzer_Pin, GPIO.OUT) + + +class Buzzer: + + @staticmethod + def set(on: bool): + """ + Turn the buzzer on / off + :param on: True if on, False if off + :return: None + """ + GPIO.output(Buzzer_Pin, on) \ No newline at end of file diff --git a/compLIB/IRSensor.py b/compLIB/IRSensor.py new file mode 100644 index 0000000..64f673d --- /dev/null +++ b/compLIB/IRSensor.py @@ -0,0 +1,65 @@ +from compLIB.ADC import ADC +import RPi.GPIO as GPIO + +TOP_LEFT_CHANNEL = 0 +TOP_RIGHT_CHANNEL = 1 + +TOP_IR_MIN_VOLTAGE = 0.0 +TOP_IR_MAX_VOLTAGE = 3.3 + +BOTTOM_LEFT_PIN = 14 +BOTTOM_MIDDLE_PIN = 15 +BOTTOM_RIGHT_PIN = 23 + +adc = ADC() + +GPIO.setmode(GPIO.BCM) + +GPIO.setup(BOTTOM_LEFT_PIN, GPIO.IN) +GPIO.setup(BOTTOM_MIDDLE_PIN, GPIO.IN) +GPIO.setup(BOTTOM_RIGHT_PIN, GPIO.IN) + + +class IRSensor(object): + + @staticmethod + def top_left_percent() -> int: + """ + Get left infrared sensor percentage between 0 and 100 + :return: + """ + voltage = adc.read(TOP_LEFT_CHANNEL) + return int((voltage - TOP_IR_MIN_VOLTAGE) / TOP_IR_MAX_VOLTAGE * 100) + + @staticmethod + def top_right_percent() -> int: + """ + Get right infrared sensor percentage between 0 and 100 + :return: + """ + voltage = adc.read(TOP_RIGHT_CHANNEL) + return int((voltage - TOP_IR_MIN_VOLTAGE) / TOP_IR_MAX_VOLTAGE * 100) + + @staticmethod + def bottom_left() -> bool: + """ + Get status of bottom infrared sensor + :return: bool + """ + return GPIO.input(BOTTOM_LEFT_PIN) + + @staticmethod + def bottom_middle() -> bool: + """ + Get status of bottom infrared sensor + :return: bool + """ + return GPIO.input(BOTTOM_MIDDLE_PIN) + + @staticmethod + def bottom_right() -> bool: + """ + Get status of bottom infrared sensor + :return: bool + """ + return GPIO.input(BOTTOM_RIGHT_PIN) \ No newline at end of file diff --git a/compLIB/Motor.py b/compLIB/Motor.py index 393152a..f5197dc 100644 --- a/compLIB/Motor.py +++ b/compLIB/Motor.py @@ -1,4 +1,11 @@ -from compLIB import * +from compLIB.PCA9685 import PCA9685 + +pwm = PCA9685(0x40, debug=True) +pwm.setPWMFreq(50) + +MOTOR_COUNT = 4 +MAX_MOTOR_SPEED = 4095.0 +MOTOR_PERCENTAGE_MULT = MAX_MOTOR_SPEED / 100.0 class Motor(object): @@ -16,6 +23,10 @@ class Motor(object): percent = abs(percent) forward = False + # bottom left motor is inverted - REEEEEEEEEEEE + if port == 1: + forward = not forward + adjusted_speed = int(min(max(0, percent), 100) * MOTOR_PERCENTAGE_MULT) if forward: diff --git a/compLIB/Ultrasound.py b/compLIB/Ultrasound.py new file mode 100644 index 0000000..6cfbd89 --- /dev/null +++ b/compLIB/Ultrasound.py @@ -0,0 +1,106 @@ +import time +from Motor import * +import RPi.GPIO as GPIO +from servo import * +from PCA9685 import PCA9685 + + +class Ultrasonic: + def __init__(self): + GPIO.setwarnings(False) + self.trigger_pin = 27 + self.echo_pin = 22 + GPIO.setmode(GPIO.BCM) + GPIO.setup(self.trigger_pin, GPIO.OUT) + GPIO.setup(self.echo_pin, GPIO.IN) + + def send_trigger_pulse(self): + GPIO.output(self.trigger_pin, True) + time.sleep(0.00015) + GPIO.output(self.trigger_pin, False) + + def wait_for_echo(self, value, timeout): + count = timeout + while GPIO.input(self.echo_pin) != value and count > 0: + count = count - 1 + + def get_distance(self): + distance_cm = [0, 0, 0, 0, 0] + for i in range(3): + self.send_trigger_pulse() + self.wait_for_echo(True, 10000) + start = time.time() + self.wait_for_echo(False, 10000) + finish = time.time() + pulse_len = finish - start + distance_cm[i] = pulse_len / 0.000058 + distance_cm = sorted(distance_cm) + return int(distance_cm[2]) + + def run_motor(self, L, M, R): + if (L < 30 and M < 30 and R < 30) or M < 30: + self.PWM.setMotorModel(-1450, -1450, -1450, -1450) + time.sleep(0.1) + if L < R: + self.PWM.setMotorModel(1450, 1450, -1450, -1450) + else: + self.PWM.setMotorModel(-1450, -1450, 1450, 1450) + elif L < 30 and M < 30: + PWM.setMotorModel(1500, 1500, -1500, -1500) + elif R < 30 and M < 30: + PWM.setMotorModel(-1500, -1500, 1500, 1500) + elif L < 20: + PWM.setMotorModel(2000, 2000, -500, -500) + if L < 10: + PWM.setMotorModel(1500, 1500, -1000, -1000) + elif R < 20: + PWM.setMotorModel(-500, -500, 2000, 2000) + if R < 10: + PWM.setMotorModel(-1500, -1500, 1500, 1500) + else: + self.PWM.setMotorModel(600, 600, 600, 600) + + def run(self): + self.PWM = Motor() + self.pwm_S = Servo() + for i in range(30, 151, 60): + self.pwm_S.setServoPwm('0', i) + time.sleep(0.2) + if i == 30: + L = self.get_distance() + elif i == 90: + M = self.get_distance() + else: + R = self.get_distance() + while True: + for i in range(90, 30, -60): + self.pwm_S.setServoPwm('0', i) + time.sleep(0.2) + if i == 30: + L = self.get_distance() + elif i == 90: + M = self.get_distance() + else: + R = self.get_distance() + self.run_motor(L, M, R) + for i in range(30, 151, 60): + self.pwm_S.setServoPwm('0', i) + time.sleep(0.2) + if i == 30: + L = self.get_distance() + elif i == 90: + M = self.get_distance() + else: + R = self.get_distance() + self.run_motor(L, M, R) + + +ultrasonic = Ultrasonic() +# Main program logic follows: +if __name__ == '__main__': + print('Program is starting ... ') + try: + ultrasonic.run() + except KeyboardInterrupt: # When 'Ctrl+C' is pressed, the child program destroy() will be executed. + PWM.setMotorModel(0, 0, 0, 0) + ultrasonic.pwm_S.setServoPwm('0', 90) \ No newline at end of file diff --git a/compLIB/__init__.py b/compLIB/__init__.py index 405a9c4..b3c06d4 100644 --- a/compLIB/__init__.py +++ b/compLIB/__init__.py @@ -1,10 +1 @@ -from compLIB.PCA9685 import PCA9685 - -__version__ = "0.0.1" - -pwm = PCA9685(0x40, debug=True) -pwm.setPWMFreq(50) - -MOTOR_COUNT = 4 -MAX_MOTOR_SPEED = 4095.0 -MOTOR_PERCENTAGE_MULT = MAX_MOTOR_SPEED / 100.0 \ No newline at end of file +__version__ = "0.0.1" \ No newline at end of file diff --git a/copy.sh b/copy.sh new file mode 100755 index 0000000..ba4c513 --- /dev/null +++ b/copy.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +scp -r compLIB pi@10.20.85.225:/home/pi/compLIB \ No newline at end of file diff --git a/oldLib/ADC.py b/oldLib/ADC.py index 2343221..73dcdb0 100644 --- a/oldLib/ADC.py +++ b/oldLib/ADC.py @@ -44,6 +44,7 @@ class Adc: voltage = round(voltage, 2) return voltage + def recvADS7830(self, channel): """Select the Command data from the given provided value above""" COMMAND_SET = self.ADS7830_CMD | ((((channel << 2) | (channel >> 1)) & 0x07) << 4)