Reflection: The intent of the project was to build a rain-tube like machine, where the marbles hitting against the pegs as they rolled down the tube would create a soothing sound. The user input is positioning the sensor. If the user wants the tube to continuously spin, the user can place the sensor away from the tube. If the user wants the tube to rock back and forth, the user can place the sensor near the tube.
If we could redo aspects of this project, we would work out the spacing of the pegs better so that not all the balls would just flow down the sides when the tube is turned over slowly. We can also experiment with different modes of user input, such as the user pressing a button when they want the tube to turn. As well as implementing more interactive sensing which might give the user angle control in addition to speed control. We would also like to experiment with networking and other interfaces to increase the compatibility of the music we can create
Video: https://drive.google.com/file/d/1IrCWwKjV1mRumPzaRAGrWUcxnvIRX1Br/view?usp=sharing
# This assumes a Pololu DRV8833 dual motor driver has been wired up to the Pico as follows: # Pico pin 24, GPIO18 -> AIN1 # Pico pin 25, GPIO19 -> AIN2 # Pico pin 26, GPIO20 -> BIN2 # Pico pin 27, GPIO21 -> BIN1 # any Pico GND -> GND # DRV8833 carrier board: https://www.pololu.com/product/2130 ################################################################ # CircuitPython module documentation: # time https://circuitpython.readthedocs.io/en/latest/shared-bindings/time/index.html # math https://circuitpython.readthedocs.io/en/latest/shared-bindings/math/index.html # board https://circuitpython.readthedocs.io/en/latest/shared-bindings/board/index.html # pwmio https://circuitpython.readthedocs.io/en/latest/shared-bindings/pwmio/index.html ################################################################################ # print a banner as reminder of what code is loaded print("Starting dual_spin script.") # load standard Python modules import math, time # load the CircuitPython hardware definition module for pin definitions import board # load the CircuitPython pulse-width-modulation module for driving hardware import pwmio from digitalio import DigitalInOut, Direction, Pull import analogio import digitalio import random #-------------------------------------------------------------------------------- # Class to represent a single dual H-bridge driver. class DRV8833(): def __init__(self, AIN1=board.GP18, AIN2=board.GP19, BIN2=board.GP20, BIN1=board.GP21, pwm_rate=20000): # Create a pair of PWMOut objects for each motor channel. self.ain1 = pwmio.PWMOut(AIN1, duty_cycle=0, frequency=pwm_rate) self.ain2 = pwmio.PWMOut(AIN2, duty_cycle=0, frequency=pwm_rate) self.bin1 = pwmio.PWMOut(BIN1, duty_cycle=0, frequency=pwm_rate) self.bin2 = pwmio.PWMOut(BIN2, duty_cycle=0, frequency=pwm_rate) def write(self, channel, rate): """Set the speed and direction on a single motor channel. :param channel: 0 for motor A, 1 for motor B :param rate: modulation value between -1.0 and 1.0, full reverse to full forward.""" # convert the rate into a 16-bit fixed point integer pwm = min(max(int(2**16 * abs(rate)), 0), 65535) if channel == 0: if rate < 0: self.ain1.duty_cycle = pwm self.ain2.duty_cycle = 0 else: self.ain1.duty_cycle = 0 self.ain2.duty_cycle = pwm else: if rate < 0: self.bin1.duty_cycle = pwm self.bin2.duty_cycle = 0 else: self.bin1.duty_cycle = 0 self.bin2.duty_cycle = pwm #-------------------------------------------------------------------------------- # Create an object to represent a dual motor driver. print("Creating driver object.") driver = DRV8833() #-------------------------------------------------------------------------------- # Begin the main processing loop. This is structured as a looping script, since # each movement primitive 'blocks', i.e. doesn't return until the action is # finished. # Set up built-in green LED for output. led = DigitalInOut(board.LED) # GP25 led.direction = Direction.OUTPUT # Set up an analog input on ADC0 (GP26), which is physically pin 31. # E.g., this may be attached to photocell or photointerrupter with associated pullup resistor. # sensor = analogio.AnalogIn(board.A0) sensor_direction = analogio.AnalogIn(board.A1) # These may be need to be adjusted for your particular hardware. The Pico has # 12-bit analog-to-digital conversion so the actual conversion has 4096 possible # values, but the results are scaled to a 16-bit unsigned integer with range # from 0 to 65535. lower_threshold = 8000 upper_threshold = 45000 state_index = False #switch = DigitalInOut(board.GP15) #switch.direction = Direction.INPUT last_change_time = time.time() start_time = time.time() print("Starting main script.") change_action_time = 0 prev_direction = 1 SENSOR_THRESHOLD = 1000 state_index = False while True: motor_power = 1 sensor_direction_level = sensor_direction.value if state_index is False: if sensor_direction_level < lower_threshold: led.value = True state_index = True print("On") elif state_index is True: if sensor_direction_level > upper_threshold: led.value = False state_index = False print("Off") prev_direction *= -1 driver.write(1, prev_direction * motor_power) time.sleep(0.5) driver.write(1, prev_direction * motor_power) # uncomment the following to print tuples to plot with the mu editor # print((sensor_level, motor_power)) # time.sleep(0.02) # slow sampling to avoid flooding
Leave a Reply
You must be logged in to post a comment.