In this project our final objective is to create a remote controlled robot capable of flashing different colored lights and traversing a given path. The difference between RC and autonomous is that an RC is being controlled live while an autonomous is self-controlled through a premade code. We needd the tobot to be stable and drive properly and be wired correctly. We had to save our code and create parts of the robot in onshape. We had to use a single point perspective sketch to design our robot and keep in mind the 14"x8"x10" size limit.
The first phase of the robot was its autonomous stage. In this stage, our robot used code that was saved onto its Pico to traverse a set path. The code included functions for different motions, including: Left, Right, Forwards, and Backwards. During the autonomous stage, we had to account for the unique slipping/off-balances of our wheels, uneven surfaces, and just random chance. We had to keep all this in mind when writing our code. In my case, I had to use a pseudo code because my robot's movements were too unpredictable and variable.
Bluetooth control was the second phase of our prototypes. In this stage, we used a Dabble module to receive signals from our phones. We had to properly wire and attach the module to our breadboard for it to function properly.
My robot had 2 main features: Movement and Lighting. I had to import variables for all physical components, including the neopixels, servos, and dabble. I had to assign them to certain pins and make sure they were connected to power. I had to control the speed of the servos by setting a number 0-180. 0 is the max speed counter-clockwise, and 180 is the max speed clockwise. I had to set my servos to one. I also had to code the number of pixels shown. To let all this work continually, I had to code loops. I used for loops for the neopixels to constantly show, and I used while True loops to run the autonomous code. The most important part of the Bluetooth coding was creating functions for the movements and light patterns that I can call later. After I made functions for each specific movement and pattern I assigned them each to a different button I'd press on my phone so that the robot would respond once connected.
import binascii
import board
import busio
import digitalio
import time
from dabble import Dabble
import board
from rainbowio import colorwheel
import neopixel
# ** Change this value to connnect the DIN wire to a different pin on the Pico
pixel_pin = board.GP3
# ** Change this number to be the number of LEDs on your strips
num_pixels = 10
# This line initialized the library used to control the neopixel strip
pixels = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=0.3, auto_write=False)
# Different colors are made by mixing different amounts of
# Red, Green and Blue light. The color wheel for light
# is different from mixing paint!
#
# Here are some RGB values for some common colors.
# 0 == LED off and 255 == full brightness
RED = (255, 0, 0) # 100% red, 0% green, 0% blue
GREEN = ( 0, 255, 0) # 0% red, 100% green, 0% blue
BLUE = ( 0, 0, 255) # 100% blue
CYAN = ( 0, 255, 255) # 0% red, 100% green, 100% blue
YELLOW = (255, 150, 0) # 100% red, 55% green, 0% blue
WHITE = (100, 100, 100) # 100% of all colors
BLACK = ( 0, 0, 0) # 0% of all colors (turns the LED off)
# ** Can you figure out the values for these colors?
#LIGHTBLUE = (?, ?, ?)
#LIGHTPINK = (?, ?, ?)
#ORANGE = (?, ?, ?)
#CYAN = (?, ?, ?)
#PURPLE = (?, ?, ?)
#MAGENTA = (?, ?, ?)
# ** Make your own colors and see what happens!
#MYCOLOR1 RGB(?, ?, ?)
#MYCOLOR2 RGB(?, ?, ?)
#MYCOLOR3 RGB(?, ?, ?)
#MYCOLOR4 RGB(?, ?, ?)
# *****************************************************************************
# ** These are the functions used to make different patterns.
# ** Skip down to "while True:" below to start making your changes to the code
# *****************************************************************************
def green():
for i in range(num_pixels):
pixels[i] = GREEN
pixels.show()
green()
def white():
for i in range(num_pixels):
pixels[i] = WHITE
pixels.show()
def color_chase(color, wait):
for i in range(num_pixels):
pixels[i] = color
time.sleep(wait)
pixels.show()
time.sleep(0.5)
def rainbow(wait):
for count in range(256):
for pixel_num in range(len(pixels)):
pixels[pixel_num] = colorwheel((pixel_num + count) % 255)
pixels.show()
time.sleep(wait);
def rainbow_cycle(wait):
for j in range(255):
for i in range(num_pixels):
rc_index = (i * 256 // num_pixels) + j
pixels[i] = colorwheel(rc_index % 255)
pixels.show()
time.sleep(wait)
# theater_chase(color, wait)
# Theatre-style crawling lights.
# color - The color to use for the LEDs
# wait - The number of seconds to wait between turning the LEDs on and off.
def theater_chase(color, wait):
for j in range(10): #do 10 cycles of chasing
for q in range(3):
for i in range(0, len(pixels)-1, 3):
pixels[i+q] = color # turn every third pixel on
pixels.show()
time.sleep(wait);
for i in range(0, len(pixels)-1, 3):
pixels[i+q] = BLACK # turn every third pixel off
# theater_chase2(color, wait)
# Theatre-style crawling lights with 2 colors.
# color1 - A color to use for the LEDs
# color2 - A second color to follow the first
# wait - The number of seconds to wait between turning the LEDs on and off.
def theater_chase2(color1, color2, wait):
for j in range(10): #do 10 cycles of chasing
for q in range(3):
for i in range(0, len(pixels)-1, 3):
pixels[i+q] = color1
pixels[i+q+1] = color2
pixels.show()
time.sleep(wait);
for i in range(0, len(pixels)-1, 3):
pixels[i+q] = BLACK # turn every third pixel off
# Theatre-style crawling lights with 3 colors.
# color1 - A color to use for the LEDs
# color2 - A second color
# color3 - A third color
# wait - The number of seconds to wait between turning the LEDs on and off.
def theater_chase3(color1, color2, color3, wait):
for j in range(10): #do 10 cycles of chasing
for q in range(4):
for i in range(0, len(pixels)-3, 4):
pixels[i+q] = color1
pixels[i+q+1] = color2
pixels[i+q+2] = color3
pixels.show()
time.sleep(wait);
for i in range(0, len(pixels)-3, 4):
pixels[i+q] = BLACK # turn every third pixel off
# Theatre-style crawling lights with rainbow colors.
# color - The color to use for the LEDs
# wait - The number of seconds to wait between turning the LEDs on and off.
def theater_chase_rainbow(wait):
for j in range(0, 255, 5): #
for q in range(3):
for i in range(0, len(pixels)-1, 3):
pixels[i+q] = colorwheel((i + j) % 255) # turn every third pixel on
pixels.show()
time.sleep(wait);
for i in range(0, len(pixels)-1, 3):
pixels[i+q] = BLACK # turn every third pixel off
##############################################################################
# This is the main body of your code
"""CircuitPython Essentials Servo standard servo example"""
import pwmio
from adafruit_motor import servo
# create a PWMOut object on Pin A2.
pwm = pwmio.PWMOut(board.GP22, duty_cycle=2 ** 15, frequency=50)
pwm2 = pwmio.PWMOut(board.GP17, duty_cycle=2 ** 15, frequency=50)
dabble = Dabble(board.GP0, board.GP1, debug=True)#defines the bluetooth hardware componenent and names it dabble.
# Create a servo object, my_servo.
left_servo = servo.Servo(pwm)
right_servo = servo.Servo(pwm2)
def foward():
left_servo.angle = 180
right_servo.angle = 0
def left():
left_servo.angle = 0
right_servo.angle = 0
def right():
left_servo.angle = 180
right_servo.angle = 180
def backward():
left_servo.angle = 0
right_servo.angle = 180
def stop():
left_servo.angle = 90
right_servo.angle = 90
while True:#do everthing indented below forever
message = dabble.read_message()#listening for a message (repeatedly) and naming what is sent "message"
if (message != None):#if theres a message
print("Message: " + str(message))
# Implement tank steering on a 2 wheeled robot
if (message.up_arrow_pressed):
print("Move both motors forward")
foward()
elif (message.down_arrow_pressed):
print("Move both motors backward")
backward()
elif (message.right_arrow_pressed):
print("Move left motor forward and right motor backward")
right()
elif (message.left_arrow_pressed):
print("Move left motor backward and right motor forward")
left()
elif (message.no_direction_pressed):
print("Stop both motors")
stop()
else:
print("Something crazy happened with direction!")
if (message.triangle_pressed):
print("Raise arm")
blue()
elif (message.circle_pressed):
print("Lower arm")
white()
elif (message.square_pressed):
print("Squirt water")
elif (message.cross_pressed):
print("Fire laser")
elif (message.start_pressed):
print("Turn on LED")
elif (message.select_pressed):
print("Do victory dance")
elif (message.no_action_pressed):
print("No action")
else:
print("Something crazy happened with action!")
While designing my prototype, I came to the realization that using CAD would be better suited for the Mario Kart inspired design I came up with. I had to rely heavily on the extrude tool to make my sketches 3-dimensional. I used the property tool to assign colors to the parts I created, so I could visualize the product better. Another important tool was the image import. This allowed me to have an image of a Mario Kart in the workspace to use as a reference while modeling my own. I included a bottom area that was hollow, so I could fit my breadboard while keeping it hidden. This was one of the many constraints I had to keep in mind while creating this design. I also had an elevated surface for my servo mounts to sit upon so that my wheels would have sufficient space to rotate, doing this, as well as making a hole for my servo to fit through required precise measurements and scaling.
During this project i had alot of fun and now have a better understanding of all the concepts. I'm now much better at Onshape, lasercutting, and overall craftsmanship. If i could do this project again I eould change my design to hide my wheelsso they could move better. I learned resillience and flexibility from all the failed prints. Overall this project helped my enginering skills and developed my ability to think as an engineer.